Adds API docs annotations & generator (#927)
* initial commit * fixes category api route * fixes follow api routes --------- Co-authored-by: Christian Beutel <>
This commit is contained in:
@@ -28,7 +28,7 @@ export default defineConfig({
|
||||
{
|
||||
base: 'api-reference',
|
||||
label: 'API Reference',
|
||||
schema: 'wanderer.openapi.yaml',
|
||||
schema: 'wanderer.openapi.json',
|
||||
sidebar: {
|
||||
operations: {
|
||||
|
||||
|
||||
6616
docs/wanderer.openapi.json
Normal file
6616
docs/wanderer.openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
827
web/package-lock.json
generated
827
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
||||
"postcss": "^8.5.6",
|
||||
"svelte": "^5.53.6",
|
||||
"svelte-check": "^4.3.6",
|
||||
"sveltekit-openapi-generator": "^0.1.5",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.9.3",
|
||||
@@ -78,5 +79,10 @@
|
||||
"three": "^0.182.0",
|
||||
"vitest": "^4.1.4",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"overrides": {
|
||||
"sveltekit-openapi-generator": {
|
||||
"vite": "$vite"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { User } from "$lib/models/user";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { users_search } from "$lib/stores/user_store";
|
||||
import { getFileURL } from "$lib/util/file_util";
|
||||
import Search, { type SearchItem } from "./base/search.svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
interface Props {
|
||||
label?: string;
|
||||
value?: string;
|
||||
includeSelf?: boolean;
|
||||
clearAfterSelect?: boolean;
|
||||
onclear?: () => void
|
||||
onclick?: (item: SearchItem) => void
|
||||
}
|
||||
|
||||
let {
|
||||
label = "",
|
||||
value = $bindable(""),
|
||||
includeSelf = true,
|
||||
clearAfterSelect = true,
|
||||
onclear,
|
||||
onclick
|
||||
}: Props = $props();
|
||||
|
||||
let searchItems: SearchItem[] = $state([]);
|
||||
|
||||
async function updateUsers(q: string) {
|
||||
if (!q.length) {
|
||||
searchItems = [];
|
||||
onclear?.();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const users: User[] = await users_search(q, includeSelf);
|
||||
searchItems = users.map((u) => ({
|
||||
text: u.username!,
|
||||
value: u,
|
||||
icon: "user",
|
||||
}));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
show_toast({
|
||||
type: "error",
|
||||
icon: "close",
|
||||
text: "Error during search",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onClick(item: SearchItem) {
|
||||
value = item.value.username ?? value;
|
||||
|
||||
onclick?.(item);
|
||||
searchItems = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<Search
|
||||
onupdate={(q) => updateUsers(q)}
|
||||
onclick={(item) => onClick(item)}
|
||||
placeholder={`${$_("username")}...`}
|
||||
items={searchItems}
|
||||
{clearAfterSelect}
|
||||
{label}
|
||||
bind:value
|
||||
>
|
||||
{#snippet prepend({ item })}
|
||||
<img
|
||||
|
||||
|
||||
class="rounded-full w-8 aspect-square mr-2"
|
||||
src={getFileURL(item.value, item.value.avatar) ||
|
||||
`https://api.dicebear.com/7.x/initials/svg?seed=${item.value.username}&backgroundType=gradientLinear`}
|
||||
alt="avatar"
|
||||
/>
|
||||
{/snippet}
|
||||
</Search>
|
||||
1224
web/src/lib/models/api/openapi_schemas.ts
Normal file
1224
web/src/lib/models/api/openapi_schemas.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,37 +23,6 @@ export async function users_create(user: User) {
|
||||
return createdUser;
|
||||
}
|
||||
|
||||
export async function users_search(q: string, includeSelf: boolean = true) {
|
||||
const user = get(currentUser)
|
||||
|
||||
let r = await fetch('/api/v1/user/anonymous?' + new URLSearchParams({
|
||||
"filter": `username~"${q}"${includeSelf ? '' : `&&id!="${user?.id}"`}`,
|
||||
}), {
|
||||
method: 'GET',
|
||||
})
|
||||
if (!r.ok) {
|
||||
const response = await r.json();
|
||||
throw new APIError(r.status, response.message, response.detail)
|
||||
}
|
||||
|
||||
const response = await r.json()
|
||||
return response.items;
|
||||
|
||||
}
|
||||
|
||||
export async function users_show(id: string, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
|
||||
let r = await f(`/api/v1/user/anonymous/${id}`, {
|
||||
method: 'GET',
|
||||
})
|
||||
if (!r.ok) {
|
||||
const response = await r.json();
|
||||
throw new APIError(r.status, response.message, response.detail)
|
||||
}
|
||||
const response: UserAnonymous = await r.json()
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function users_auth_methods(f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch): Promise<AuthMethodsList> {
|
||||
const r = await f('/api/v1/auth/oauth', {
|
||||
method: 'GET',
|
||||
|
||||
@@ -3,6 +3,32 @@ import { Collection, handleError, show } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import type { APActivity, APRoot } from 'activitypub-types';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/activity/{id}:
|
||||
* get:
|
||||
* summary: Get ActivityPub activity
|
||||
* description: Retrieves an ActivityPub Activity object by ID
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub Activity object
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const a = await show<Activity>(event, Collection.activitypub_activities)
|
||||
|
||||
@@ -3,6 +3,32 @@ import { handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/comment/{id}:
|
||||
* get:
|
||||
* summary: Get ActivityPub comment
|
||||
* description: Retrieves an ActivityPub Comment object by ID (proxied from backend)
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub Comment object
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
const id = event.params.id;
|
||||
|
||||
|
||||
@@ -3,6 +3,32 @@ import { handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/trail/{id}:
|
||||
* get:
|
||||
* summary: Get ActivityPub trail
|
||||
* description: Retrieves an ActivityPub Trail object by ID (proxied from backend)
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub Trail object
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
const id = event.params.id;
|
||||
|
||||
|
||||
@@ -8,6 +8,32 @@ import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { type APActor, type APRoot } from 'activitypub-types';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/user/{handle}:
|
||||
* get:
|
||||
* summary: Get ActivityPub actor profile
|
||||
* description: Retrieves an ActivityPub Person object for a user with public key
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub Person object with publicKey
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -9,6 +9,37 @@ import type { APOrderedCollectionPage, APRoot } from 'activitypub-types';
|
||||
import type { ListResult } from 'pocketbase';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/user/{handle}/followers:
|
||||
* get:
|
||||
* summary: Get ActivityPub followers collection
|
||||
* description: Retrieves an OrderedCollection paginated list of followers for a user
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub OrderedCollectionPage
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
|
||||
export async function GET(event: RequestEvent) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,15 +1,45 @@
|
||||
import { env } from '$env/dynamic/private';
|
||||
import { env as publicEnv } from '$env/dynamic/public';
|
||||
|
||||
import type { Actor } from '$lib/models/activitypub/actor';
|
||||
import type { Follow } from '$lib/models/follow';
|
||||
import { splitUsername } from '$lib/util/activitypub_util';
|
||||
import { handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import type { APOrderedCollectionPage, APRoot } from 'activitypub-types';
|
||||
import type { ListResult } from 'pocketbase';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/user/{handle}/following:
|
||||
* get:
|
||||
* summary: Get ActivityPub following collection
|
||||
* description: Retrieves an OrderedCollection paginated list of accounts the user follows
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub OrderedCollectionPage
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
|
||||
export async function GET(event: RequestEvent) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -4,6 +4,34 @@ import { handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import type { APActivity } from 'activitypub-types';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/user/{handle}/inbox:
|
||||
* post:
|
||||
* summary: Receive ActivityPub activities
|
||||
* description: Receives and processes incoming ActivityPub activities (Create, Update, Delete, Follow, etc.)
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Activity processed
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,40 @@ import type { APActivity, APOrderedCollectionPage, APRoot } from 'activitypub-ty
|
||||
import type { ListResult } from 'pocketbase';
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/activitypub/user/{handle}/outbox:
|
||||
* get:
|
||||
* summary: Get ActivityPub outbox collection
|
||||
* description: Retrieves an OrderedCollection paginated list of activities published by this user
|
||||
* tags:
|
||||
* - ActivityPub
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ActivityPub OrderedCollectionPage
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,62 @@ import { Collection, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { APITokenCreateSchema } from "$lib/models/api/api_token_schema";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/api-token:
|
||||
* get:
|
||||
* summary: List API tokens
|
||||
* description: Retrieves a paginated list of API tokens with optional filtering and sorting
|
||||
* tags:
|
||||
* - API Tokens
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* default: 1
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* default: 30
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* page:
|
||||
* type: integer
|
||||
* perPage:
|
||||
* type: integer
|
||||
* totalItems:
|
||||
* type: integer
|
||||
* totalPages:
|
||||
* type: integer
|
||||
* items:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/APIToken'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<APIToken>(event, Collection.api_tokens);
|
||||
@@ -14,7 +70,37 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/api-token:
|
||||
* put:
|
||||
* summary: Create API token
|
||||
* description: Creates a new API token
|
||||
* tags:
|
||||
* - API Tokens
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/APITokenInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/APIToken'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<APIToken>(event, APITokenCreateSchema, Collection.api_tokens)
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
import { Collection, handleError, remove } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/api-token/{id}:
|
||||
* delete:
|
||||
* summary: Delete API token
|
||||
* description: Deletes an API token by ID
|
||||
* tags:
|
||||
* - API Tokens
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* description: API token ID (15 chars)
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.api_tokens)
|
||||
|
||||
@@ -2,6 +2,28 @@ import { handleError } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/auth/confirm-reset:
|
||||
* post:
|
||||
* summary: Confirm password reset
|
||||
* description: Confirms and applies a password reset with a valid token
|
||||
* tags:
|
||||
* - Authentication
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Password reset completed
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json()
|
||||
|
||||
@@ -2,6 +2,42 @@ import { handleError } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/auth/login:
|
||||
* post:
|
||||
* summary: Authenticate user
|
||||
* description: Authenticates a user with email or username and password
|
||||
* tags:
|
||||
* - Authentication
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - password
|
||||
* properties:
|
||||
* email:
|
||||
* type: string
|
||||
* format: email
|
||||
* username:
|
||||
* type: string
|
||||
* password:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: User authenticated with auth token
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/User'
|
||||
* 400:
|
||||
* description: Bad Request - Invalid credentials
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json();
|
||||
|
||||
@@ -7,6 +7,24 @@ import { handleError } from "$lib/util/api_util";
|
||||
|
||||
const redirectURL = private_env.ORIGIN + "/login/redirect"
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/auth/oauth:
|
||||
* get:
|
||||
* summary: List OAuth providers
|
||||
* description: Lists available OAuth2 authentication methods with provider images
|
||||
* tags:
|
||||
* - Authentication
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OAuth2 providers and configuration
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await event.locals.pb.collection('users').listAuthMethods();
|
||||
|
||||
@@ -2,6 +2,34 @@ import { handleError } from "$lib/util/api_util";
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/auth/reset:
|
||||
* post:
|
||||
* summary: Request password reset
|
||||
* description: Sends a password reset email
|
||||
* tags:
|
||||
* - Authentication
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - email
|
||||
* properties:
|
||||
* email:
|
||||
* type: string
|
||||
* format: email
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Password reset email sent
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json()
|
||||
|
||||
@@ -2,6 +2,44 @@ import type { Category } from "$lib/models/category";
|
||||
import { Collection, handleError, list } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/category:
|
||||
* get:
|
||||
* summary: List categories
|
||||
* description: Retrieves a paginated list of activity categories
|
||||
* tags:
|
||||
* - Categories
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of categories
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Category>(event, Collection.categories);
|
||||
|
||||
@@ -4,6 +4,51 @@ import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { type ListResult } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/comment:
|
||||
* get:
|
||||
* summary: List comments
|
||||
* tags:
|
||||
* - Comments
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: handle
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Federated query parameter
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of comments
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
if (!event.url.searchParams.has("handle")) {
|
||||
|
||||
@@ -3,6 +3,35 @@ import type { Comment } from "$lib/models/comment";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/comment/{id}:
|
||||
* get:
|
||||
* summary: Get comment
|
||||
* tags:
|
||||
* - Comments
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Comment details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Comment'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<Comment>(event, Collection.comments)
|
||||
@@ -12,6 +41,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/comment/{id}:
|
||||
* post:
|
||||
* summary: Update comment
|
||||
* tags:
|
||||
* - Comments
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/CommentUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Comment updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Comment'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Comment>(event, CommentUpdateSchema, Collection.comments)
|
||||
@@ -21,6 +83,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/comment/{id}:
|
||||
* delete:
|
||||
* summary: Delete comment
|
||||
* tags:
|
||||
* - Comments
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Comment deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.comments)
|
||||
|
||||
@@ -2,6 +2,47 @@ import type { FeedItem } from "$lib/models/feed";
|
||||
import { Collection, handleError, list } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/feed:
|
||||
* get:
|
||||
* summary: Get activity feed
|
||||
* description: Retrieves the user's activity feed
|
||||
* tags:
|
||||
* - Feed
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Activity feed
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<FeedItem>(event, Collection.feed);
|
||||
|
||||
@@ -1,6 +1,49 @@
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/files/{collection}/{record}/{file}:
|
||||
* get:
|
||||
* summary: Download file
|
||||
* description: Downloads a file from a record with optional thumbnail generation
|
||||
* tags:
|
||||
* - Files
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: collection
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: path
|
||||
* name: record
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: path
|
||||
* name: file
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: thumb
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File download
|
||||
* content:
|
||||
* application/octet-stream:
|
||||
* schema:
|
||||
* type: string
|
||||
* format: binary
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
|
||||
const safeParams = z.object({
|
||||
|
||||
@@ -7,6 +7,56 @@ import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import type { APOrderedCollectionPage } from 'activitypub-types';
|
||||
import { ClientResponseError, type ListResult } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/follow:
|
||||
* get:
|
||||
* summary: List follows
|
||||
* description: Retrieves follows or ActivityPub follower/following collections. Supports federated queries via handle parameter
|
||||
* tags:
|
||||
* - Follows
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: handle
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: type
|
||||
* schema:
|
||||
* type: string
|
||||
* enum: [followers, following]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of follows or ActivityPub collection
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
if (!event.url.searchParams.has("handle")) {
|
||||
|
||||
@@ -2,6 +2,27 @@ import { Collection, handleError, remove } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/follow/{id}:
|
||||
* delete:
|
||||
* summary: Delete follow
|
||||
* tags:
|
||||
* - Follows
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Follow deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.follows)
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { Integration } from "$lib/models/integration";
|
||||
import { Collection, create, handleError, list } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration:
|
||||
* get:
|
||||
* summary: List integrations
|
||||
* tags:
|
||||
* - Integrations
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of integrations
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Integration>(event, Collection.integrations);
|
||||
@@ -13,9 +53,34 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration:
|
||||
* put:
|
||||
* summary: Create integration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/IntegrationInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Integration created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Integration'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<Comment>(event, IntegrationCreateSchema, Collection.integrations)
|
||||
const r = await create<Integration>(event, IntegrationCreateSchema, Collection.integrations)
|
||||
return json(r);
|
||||
} catch (e) {
|
||||
return handleError(e)
|
||||
|
||||
@@ -3,6 +3,35 @@ import type { Integration } from "$lib/models/integration";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/{id}:
|
||||
* get:
|
||||
* summary: Get integration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Integration details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Integration'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<Integration>(event, Collection.integrations)
|
||||
@@ -12,6 +41,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/{id}:
|
||||
* post:
|
||||
* summary: Update integration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/IntegrationUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Integration updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Integration'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Integration>(event, IntegrationUpdateSchema, Collection.integrations)
|
||||
@@ -21,6 +83,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/{id}:
|
||||
* delete:
|
||||
* summary: Delete integration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Integration deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.integrations)
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
import { handleError } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/hammerhead/login:
|
||||
* get:
|
||||
* summary: Get Hammerhead login endpoint
|
||||
* description: Proxies to backend to get Hammerhead login configuration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Hammerhead login endpoint
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await event.locals.pb.send("/integration/hammerhead/login", {
|
||||
|
||||
@@ -1,6 +1,38 @@
|
||||
import { handleError } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/hammerhead/upload:
|
||||
* post:
|
||||
* summary: Upload via Hammerhead integration
|
||||
* description: Proxies file upload to backend Hammerhead integration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - file
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Upload result
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const formData = await event.request.formData();
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
import { handleError } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/integration/komoot/login:
|
||||
* get:
|
||||
* summary: Get Komoot login endpoint
|
||||
* description: Proxies to backend to get Komoot login configuration
|
||||
* tags:
|
||||
* - Integrations
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Komoot login endpoint
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await event.locals.pb.send("/integration/komoot/login", {
|
||||
|
||||
@@ -4,6 +4,43 @@ import type { ListShare } from '$lib/models/list_share';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list-share:
|
||||
* get:
|
||||
* summary: List list shares
|
||||
* description: Retrieves a paginated list of list shares with optional ActivityPub actor resolution
|
||||
* tags:
|
||||
* - List Shares
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ListResult<ListShare>
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<ListShare>(event, Collection.list_share);
|
||||
@@ -13,6 +50,32 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list-share:
|
||||
* put:
|
||||
* summary: Create list share
|
||||
* description: Creates a new list share. Converts ActivityPub actor IRI to ID
|
||||
* tags:
|
||||
* - List Shares
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListShareInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: List share created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json();
|
||||
|
||||
@@ -3,6 +3,32 @@ import type { ListShare } from "$lib/models/list_share";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list-share/{id}:
|
||||
* get:
|
||||
* summary: Get list share
|
||||
* description: Retrieves a list share by ID
|
||||
* tags:
|
||||
* - List Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ListShare
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<ListShare>(event, Collection.list_share)
|
||||
@@ -12,6 +38,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list-share/{id}:
|
||||
* post:
|
||||
* summary: Update list share
|
||||
* tags:
|
||||
* - List Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListShareUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List share updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<ListShare>(event, ListShareUpdateSchema, Collection.list_share)
|
||||
@@ -21,6 +80,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list-share/{id}:
|
||||
* delete:
|
||||
* summary: Delete list share
|
||||
* tags:
|
||||
* - List Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List share deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.list_share)
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { List } from '$lib/models/list';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list:
|
||||
* get:
|
||||
* summary: List all lists
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of lists
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<List>(event, Collection.lists);
|
||||
@@ -18,6 +58,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list:
|
||||
* put:
|
||||
* summary: Create list
|
||||
* tags:
|
||||
* - Lists
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: List created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/List'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<List>(event, ListCreateSchema, Collection.lists)
|
||||
|
||||
@@ -5,6 +5,80 @@ import { objectToFormData } from "$lib/util/file_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list/{id}:
|
||||
* get:
|
||||
* summary: Get list
|
||||
* description: Retrieves a list by ID. Supports federated queries via handle parameter, fetching from remote instances and remapping file URLs
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: handle
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List with optional federated data
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
* post:
|
||||
* summary: Update list
|
||||
* description: Updates a list by ID
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
* delete:
|
||||
* summary: Delete list
|
||||
* description: Deletes a list by ID
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
if (!event.url.searchParams.has("handle")) {
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
import { Collection, handleError, upload } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import type { List } from "postcss/lib/list";
|
||||
import type { List } from "$lib/models/list";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list/{id}/file:
|
||||
* post:
|
||||
* summary: Upload list file
|
||||
* description: Uploads a file (cover image) for a list
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File uploaded, list updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/List'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await upload<List>(event, Collection.lists);
|
||||
|
||||
@@ -2,6 +2,28 @@ import type { List } from '$lib/models/list';
|
||||
import { Collection, handleError, uploadCreate } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list/form:
|
||||
* put:
|
||||
* summary: Create list with file upload
|
||||
* description: Creates a new list with file upload (avatar)
|
||||
* tags:
|
||||
* - Lists
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 201:
|
||||
* description: List
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadCreate<List>(event, Collection.lists)
|
||||
|
||||
@@ -2,6 +2,36 @@ import type { List } from "$lib/models/list";
|
||||
import { Collection, handleError, uploadUpdate } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/list/form/{id}:
|
||||
* post:
|
||||
* summary: Update list with file upload
|
||||
* description: Updates a list with file upload (avatar)
|
||||
* tags:
|
||||
* - Lists
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadUpdate<List>(event, Collection.lists)
|
||||
|
||||
@@ -2,6 +2,46 @@ import type { Notification } from '$lib/models/notification';
|
||||
import { Collection, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/notification:
|
||||
* get:
|
||||
* summary: List notifications
|
||||
* tags:
|
||||
* - Notifications
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of notifications
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Notification>(event, Collection.notifications);
|
||||
|
||||
@@ -1,11 +1,42 @@
|
||||
import { NotificationUpdateSchema } from "$lib/models/api/notification_schema";
|
||||
import type { Notification } from "$lib/models/notification";
|
||||
import { Collection, handleError, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/notification/{id}:
|
||||
* post:
|
||||
* summary: Update notification
|
||||
* description: Updates a notification by ID (typically to mark as read)
|
||||
* tags:
|
||||
* - Notifications
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Notification
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Comment>(event, NotificationUpdateSchema, Collection.notifications)
|
||||
const r = await update<Notification>(event, NotificationUpdateSchema, Collection.notifications)
|
||||
return json(r);
|
||||
} catch (e: any) {
|
||||
return handleError(e)
|
||||
|
||||
@@ -3,6 +3,32 @@ import { getActorResponseForHandle } from '$lib/util/activitypub_server_util';
|
||||
import { handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/profile/{handle}:
|
||||
* get:
|
||||
* summary: Get user profile
|
||||
* description: Retrieves a user's profile by handle, with optional federation support
|
||||
* tags:
|
||||
* - Profiles
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Profile and actor data
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
const handle = event.params.handle;
|
||||
if (!handle) {
|
||||
|
||||
@@ -6,6 +6,40 @@ import { Collection, handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { ClientResponseError, type ListResult } from 'pocketbase';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/profile/{handle}/feed:
|
||||
* get:
|
||||
* summary: Get user activity feed
|
||||
* description: Retrieves activity feed for a user, with federation support
|
||||
* tags:
|
||||
* - Profiles
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: FeedItem list
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
const handle = event.params.handle;
|
||||
if (!handle) {
|
||||
|
||||
@@ -6,6 +6,47 @@ import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import type { SearchResponse } from 'meilisearch';
|
||||
import { ClientResponseError } from 'pocketbase';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/profile/{handle}/lists:
|
||||
* post:
|
||||
* summary: Search user lists
|
||||
* description: Searches a user's lists via Meilisearch, with federation support
|
||||
* tags:
|
||||
* - Profiles
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - q
|
||||
* properties:
|
||||
* q:
|
||||
* type: string
|
||||
* options:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Meilisearch response with list results
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const handle = event.params.handle;
|
||||
if (!handle) {
|
||||
|
||||
@@ -5,6 +5,40 @@ import { Collection, handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { ClientResponseError, type ListResult } from 'pocketbase';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/profile/{handle}/stats:
|
||||
* get:
|
||||
* summary: Get user summit statistics
|
||||
* description: Retrieves summit log statistics for a user, with federation support
|
||||
* tags:
|
||||
* - Profiles
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: SummitLog statistics
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
const handle = event.params.handle;
|
||||
if (!handle) {
|
||||
|
||||
@@ -5,6 +5,47 @@ import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import type { SearchResponse } from 'meilisearch';
|
||||
import { ClientResponseError } from 'pocketbase';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/profile/{handle}/trails:
|
||||
* post:
|
||||
* summary: Search user trails
|
||||
* description: Searches a user's trails via Meilisearch, with federation support
|
||||
* tags:
|
||||
* - Profiles
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: handle
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - q
|
||||
* properties:
|
||||
* q:
|
||||
* type: string
|
||||
* options:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Meilisearch response with trail results
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const handle = event.params.handle;
|
||||
if (!handle) {
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/search/{index}:
|
||||
* post:
|
||||
* summary: Search Meilisearch index
|
||||
* description: Performs a search on a specific Meilisearch index
|
||||
* tags:
|
||||
* - Search
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: index
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - q
|
||||
* properties:
|
||||
* q:
|
||||
* type: string
|
||||
* options:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Meilisearch search results
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json()
|
||||
|
||||
|
||||
@@ -4,6 +4,38 @@ import { handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { ClientResponseError, type ListResult } from "pocketbase"
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/search/actor:
|
||||
* get:
|
||||
* summary: Search actors
|
||||
* description: Searches for ActivityPub actors by username, combining local and federated results
|
||||
* tags:
|
||||
* - Search
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: q
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: includeSelf
|
||||
* schema:
|
||||
* type: boolean
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Array of matching actors
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/search/multi:
|
||||
* post:
|
||||
* summary: Multi-index search
|
||||
* description: Performs batch searches across multiple Meilisearch indices
|
||||
* tags:
|
||||
* - Search
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - queries
|
||||
* properties:
|
||||
* queries:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Combined Meilisearch results
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json()
|
||||
|
||||
|
||||
@@ -1,10 +1,36 @@
|
||||
import { SettingsCreateSchema } from '$lib/models/api/settings_schema';
|
||||
import type { Settings } from '$lib/models/settings';
|
||||
import { Collection, create } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/settings:
|
||||
* put:
|
||||
* summary: Create settings
|
||||
* tags:
|
||||
* - Settings
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SettingsInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Settings created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Settings'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<Comment>(event, SettingsCreateSchema, Collection.settings)
|
||||
const r = await create<Settings>(event, SettingsCreateSchema, Collection.settings)
|
||||
|
||||
return json(r);
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -4,6 +4,35 @@ import { Collection, handleError, remove, show, update } from "$lib/util/api_uti
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/settings/{id}:
|
||||
* get:
|
||||
* summary: Get settings
|
||||
* tags:
|
||||
* - Settings
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Settings details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Settings'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<Settings>(event, Collection.settings)
|
||||
@@ -13,6 +42,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/settings/{id}:
|
||||
* post:
|
||||
* summary: Update settings
|
||||
* tags:
|
||||
* - Settings
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SettingsInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Settings updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Settings'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Settings>(event, SettingsCreateSchema, Collection.settings)
|
||||
@@ -22,6 +84,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/settings/{id}:
|
||||
* delete:
|
||||
* summary: Delete settings
|
||||
* tags:
|
||||
* - Settings
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Settings deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.settings)
|
||||
|
||||
@@ -4,6 +4,47 @@ import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { type ListResult } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log:
|
||||
* get:
|
||||
* summary: List summit logs
|
||||
* description: Retrieves a paginated list of summit logs with deduplication of federated data
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: handle
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ListResult<SummitLog> with local/remote items deduplicated
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
if (!event.url.searchParams.has("handle")) {
|
||||
@@ -89,6 +130,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log:
|
||||
* put:
|
||||
* summary: Create summit log
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLogInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Summit log created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<SummitLog>(event, SummitLogCreateSchema, Collection.summit_logs)
|
||||
|
||||
@@ -4,6 +4,35 @@ import { Collection, handleError, remove, show, update } from "$lib/util/api_uti
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/{id}:
|
||||
* get:
|
||||
* summary: Get summit log
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Summit log details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<SummitLog>(event, Collection.summit_logs)
|
||||
@@ -13,6 +42,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/{id}:
|
||||
* post:
|
||||
* summary: Update summit log
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLogUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Summit log updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<SummitLog>(event, SummitLogUpdateSchema, Collection.summit_logs)
|
||||
@@ -22,6 +84,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/{id}:
|
||||
* delete:
|
||||
* summary: Delete summit log
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Summit log deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.summit_logs)
|
||||
|
||||
@@ -2,6 +2,44 @@ import type { SummitLog } from "$lib/models/summit_log";
|
||||
import { Collection, upload } from "$lib/util/api_util";
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/{id}/file:
|
||||
* post:
|
||||
* summary: Upload summit log file
|
||||
* description: Uploads a file (photo or GPX) for a summit log
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File uploaded, summit log updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await upload<SummitLog>(event, Collection.summit_logs);
|
||||
|
||||
@@ -2,6 +2,32 @@ import type { SummitLog } from '$lib/models/summit_log';
|
||||
import { Collection, handleError, uploadCreate } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/form:
|
||||
* put:
|
||||
* summary: Create summit log with file upload
|
||||
* description: Creates a new summit log with file upload (photos/GPX) and date normalization
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLogInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Summit log created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadCreate<SummitLog>(event, Collection.summit_logs)
|
||||
|
||||
@@ -2,6 +2,40 @@ import type { SummitLog } from "$lib/models/summit_log";
|
||||
import { Collection, handleError, uploadUpdate } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/summit-log/form/{id}:
|
||||
* post:
|
||||
* summary: Update summit log with file upload
|
||||
* description: Updates a summit log with file upload (photos/GPX) and date normalization
|
||||
* tags:
|
||||
* - Summit Logs
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLogUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Summit log updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SummitLog'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadUpdate<SummitLog>(event, Collection.summit_logs)
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { Tag } from '$lib/models/tag';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/tag:
|
||||
* get:
|
||||
* summary: List tags
|
||||
* tags:
|
||||
* - Tags
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of tags
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Tag>(event, Collection.tags);
|
||||
@@ -13,6 +53,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/tag:
|
||||
* put:
|
||||
* summary: Create tag
|
||||
* tags:
|
||||
* - Tags
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TagInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Tag created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Tag'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<Tag>(event, TagCreateSchema, Collection.tags)
|
||||
|
||||
@@ -3,6 +3,35 @@ import type { Tag } from "$lib/models/tag";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/tag/{id}:
|
||||
* get:
|
||||
* summary: Get tag
|
||||
* tags:
|
||||
* - Tags
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Tag details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Tag'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<Tag>(event, Collection.tags)
|
||||
@@ -12,6 +41,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/tag/{id}:
|
||||
* post:
|
||||
* summary: Update tag
|
||||
* tags:
|
||||
* - Tags
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TagUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Tag updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Tag'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Tag>(event, TagUpdateSchema, Collection.tags)
|
||||
@@ -21,6 +83,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/tag/{id}:
|
||||
* delete:
|
||||
* summary: Delete tag
|
||||
* tags:
|
||||
* - Tags
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Tag deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.tags)
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { TrailLike } from '$lib/models/trail_like';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-like:
|
||||
* get:
|
||||
* summary: List trail likes
|
||||
* tags:
|
||||
* - Trail Likes
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of trail likes
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<TrailLike>(event, Collection.trail_share);
|
||||
@@ -12,6 +52,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-like:
|
||||
* put:
|
||||
* summary: Create trail like
|
||||
* tags:
|
||||
* - Trail Likes
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLikeInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail like created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLike'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<TrailLike>(event, TrailLikeCreateSchema, Collection.trail_like)
|
||||
|
||||
@@ -2,6 +2,32 @@ import type { TrailLike } from "$lib/models/trail_like";
|
||||
import { Collection, handleError, remove, show } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-like/{id}:
|
||||
* get:
|
||||
* summary: Get trail like
|
||||
* description: Retrieves a trail like by ID
|
||||
* tags:
|
||||
* - Trail Likes
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: TrailLike
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<TrailLike>(event, Collection.trail_like)
|
||||
@@ -11,6 +37,27 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-like/{id}:
|
||||
* delete:
|
||||
* summary: Delete trail like
|
||||
* tags:
|
||||
* - Trail Likes
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail like deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.trail_like)
|
||||
|
||||
@@ -3,7 +3,30 @@ import { Collection, handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
|
||||
// this route exists so we can delete a like without knowing its ID
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-like/delete:
|
||||
* post:
|
||||
* summary: Delete trail like by actor and trail
|
||||
* description: Deletes a trail like without needing to know its ID. Uses actor and trail IDs to find and delete
|
||||
* tags:
|
||||
* - Trail Likes
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLikeInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail like deleted
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { TrailLinkShare } from '$lib/models/trail_link_share';
|
||||
import { Collection, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-link-share:
|
||||
* get:
|
||||
* summary: List trail link shares
|
||||
* tags:
|
||||
* - Trail Link Shares
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of trail link shares
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<TrailLinkShare>(event, Collection.trail_link_share);
|
||||
@@ -12,6 +52,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-link-share:
|
||||
* put:
|
||||
* summary: Create trail link share
|
||||
* tags:
|
||||
* - Trail Link Shares
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLinkShareInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail link share created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLinkShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json();
|
||||
|
||||
@@ -3,6 +3,32 @@ import type { TrailLinkShare } from "$lib/models/trail_link_share";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-link-share/{id}:
|
||||
* get:
|
||||
* summary: Get trail link share
|
||||
* description: Retrieves a trail link share by ID
|
||||
* tags:
|
||||
* - Trail Link Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: TrailLinkShare
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<TrailLinkShare>(event, Collection.trail_link_share)
|
||||
@@ -12,6 +38,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-link-share/{id}:
|
||||
* post:
|
||||
* summary: Update trail link share
|
||||
* tags:
|
||||
* - Trail Link Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLinkShareUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail link share updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailLinkShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<TrailLinkShare>(event, TrailLinkShareUpdateSchema, Collection.trail_link_share)
|
||||
@@ -21,6 +80,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-link-share/{id}:
|
||||
* delete:
|
||||
* summary: Delete trail link share
|
||||
* tags:
|
||||
* - Trail Link Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail link share deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.trail_link_share)
|
||||
|
||||
@@ -4,6 +4,43 @@ import type { TrailShare } from '$lib/models/trail_share';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-share:
|
||||
* get:
|
||||
* summary: List trail shares
|
||||
* description: Retrieves a paginated list of trail shares with optional ActivityPub actor resolution
|
||||
* tags:
|
||||
* - Trail Shares
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ListResult<TrailShare>
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<TrailShare>(event, Collection.trail_share);
|
||||
@@ -13,6 +50,32 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-share:
|
||||
* put:
|
||||
* summary: Create trail share
|
||||
* description: Creates a new trail share. Converts ActivityPub actor IRI to ID
|
||||
* tags:
|
||||
* - Trail Shares
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailShareInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail share created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.json();
|
||||
|
||||
@@ -3,6 +3,32 @@ import type { TrailShare } from "$lib/models/trail_share";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-share/{id}:
|
||||
* get:
|
||||
* summary: Get trail share
|
||||
* description: Retrieves a trail share by ID
|
||||
* tags:
|
||||
* - Trail Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: TrailShare
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<TrailShare>(event, Collection.trail_share)
|
||||
@@ -12,6 +38,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-share/{id}:
|
||||
* post:
|
||||
* summary: Update trail share
|
||||
* tags:
|
||||
* - Trail Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailShareUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail share updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailShare'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<TrailShare>(event, TrailShareUpdateSchema, Collection.trail_share)
|
||||
@@ -21,6 +80,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail-share/{id}:
|
||||
* delete:
|
||||
* summary: Delete trail share
|
||||
* tags:
|
||||
* - Trail Shares
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail share deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.trail_share)
|
||||
|
||||
@@ -3,6 +3,43 @@ import type { Trail } from '$lib/models/trail';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail:
|
||||
* get:
|
||||
* summary: List trails
|
||||
* description: Retrieves a paginated list of trails with optional filtering and sorting
|
||||
* tags:
|
||||
* - Trails
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: ListResult<Trail>
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Trail>(event, Collection.trails);
|
||||
@@ -23,6 +60,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail:
|
||||
* put:
|
||||
* summary: Create trail
|
||||
* tags:
|
||||
* - Trails
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailCreateInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<Trail>(event, TrailCreateSchema, Collection.trails)
|
||||
|
||||
@@ -7,6 +7,40 @@ import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import type PocketBase from "pocketbase";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/{id}:
|
||||
* get:
|
||||
* summary: Get trail
|
||||
* description: Retrieves a trail by ID. Supports federated queries via handle parameter, fetching from remote instances and remapping file URLs
|
||||
* tags:
|
||||
* - Trails
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: handle
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: share
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail with optional federated data
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
// try to get the trail simply via the
|
||||
|
||||
@@ -2,6 +2,44 @@ import type { Trail } from "$lib/models/trail";
|
||||
import { Collection, upload } from "$lib/util/api_util";
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/{id}/file:
|
||||
* post:
|
||||
* summary: Upload trail file
|
||||
* description: Uploads a file for a trail
|
||||
* tags:
|
||||
* - Trails
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File uploaded
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await upload<Trail>(event, Collection.trails);
|
||||
|
||||
@@ -2,6 +2,35 @@ import { type TrailBoundingBox, type TrailFilterValues } from '$lib/models/trail
|
||||
import { handleError } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/bounding-box:
|
||||
* get:
|
||||
* summary: Get trail bounding box
|
||||
* description: Retrieves geographic bounding box (lat/lon bounds) for user's trails
|
||||
* tags:
|
||||
* - Trails
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Bounding box coordinates
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* max_lat:
|
||||
* type: number
|
||||
* min_lat:
|
||||
* type: number
|
||||
* max_lon:
|
||||
* type: number
|
||||
* min_lon:
|
||||
* type: number
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
if (!event.locals.pb.authStore.record) {
|
||||
return json({
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
import { handleError } from "$lib/util/api_util";
|
||||
import { type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/download:
|
||||
* post:
|
||||
* summary: Download file from URL
|
||||
* description: Downloads a file from a URL and returns it as a blob
|
||||
* tags:
|
||||
* - Trails
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - url
|
||||
* properties:
|
||||
* url:
|
||||
* type: string
|
||||
* format: uri
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File blob
|
||||
* content:
|
||||
* application/octet-stream:
|
||||
* schema:
|
||||
* type: string
|
||||
* format: binary
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json();
|
||||
|
||||
|
||||
@@ -2,6 +2,39 @@ import { type TrailFilterValues } from '$lib/models/trail';
|
||||
import { handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/filter:
|
||||
* get:
|
||||
* summary: Get trail filter values
|
||||
* description: Retrieves min/max values for trail filtering (distance, elevation gain/loss)
|
||||
* tags:
|
||||
* - Trails
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail filter values (min/max for distance, elevation)
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* min_distance:
|
||||
* type: number
|
||||
* max_distance:
|
||||
* type: number
|
||||
* min_elevation_gain:
|
||||
* type: number
|
||||
* max_elevation_gain:
|
||||
* type: number
|
||||
* min_elevation_loss:
|
||||
* type: number
|
||||
* max_elevation_loss:
|
||||
* type: number
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
if (!event.locals.pb.authStore.record) {
|
||||
return json({
|
||||
|
||||
@@ -2,6 +2,32 @@ import type { Trail } from '$lib/models/trail';
|
||||
import { Collection, handleError, uploadCreate } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/form:
|
||||
* put:
|
||||
* summary: Create trail with file upload
|
||||
* description: Creates a new trail with file upload (GPX/photos) and date normalization
|
||||
* tags:
|
||||
* - Trails
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailCreateInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadCreate<Trail>(event, Collection.trails)
|
||||
|
||||
@@ -2,6 +2,40 @@ import type { Trail } from "$lib/models/trail";
|
||||
import { Collection, handleError, uploadUpdate } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/form/{id}:
|
||||
* post:
|
||||
* summary: Update trail with file upload
|
||||
* description: Updates a trail with file upload (GPX/photos) and date normalization
|
||||
* tags:
|
||||
* - Trails
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/TrailUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Trail updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await uploadUpdate<Trail>(event, Collection.trails)
|
||||
|
||||
@@ -2,6 +2,34 @@ import { TrailRecommendSchema } from '$lib/models/api/trail_schema';
|
||||
import { handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/recommend:
|
||||
* get:
|
||||
* summary: Get trail recommendations
|
||||
* description: Retrieves random trail recommendations from Meilisearch
|
||||
* tags:
|
||||
* - Trails
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: size
|
||||
* schema:
|
||||
* type: integer
|
||||
* default: 10
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Array of recommended trails
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const searchParams = Object.fromEntries(event.url.searchParams);
|
||||
|
||||
@@ -9,6 +9,40 @@ import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
import type { Hits, MeiliSearch } from "meilisearch";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/trail/upload:
|
||||
* put:
|
||||
* summary: Upload and parse GPX file as trail
|
||||
* description: Uploads a GPX file, parses it to extract trail data, performs duplicate detection, and indexes in search
|
||||
* tags:
|
||||
* - Trails
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* name:
|
||||
* type: string
|
||||
* ignoreDuplicates:
|
||||
* type: boolean
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Trail created from GPX
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Trail'
|
||||
* 400:
|
||||
* description: Bad Request - Invalid or empty GPX file
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const data = await event.request.formData();
|
||||
|
||||
@@ -5,6 +5,31 @@ import { Collection, handleError } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
import { ClientResponseError } from 'pocketbase';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/user:
|
||||
* put:
|
||||
* summary: Create user (sign up)
|
||||
* tags:
|
||||
* - Users
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UserCreateInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: User created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/User'
|
||||
* 400:
|
||||
* description: Bad Request - Signup disabled or invalid data
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
if (env.PUBLIC_DISABLE_SIGNUP === "true") {
|
||||
throw new ClientResponseError({ status: 401, response: { messgage: "Forbidden" } })
|
||||
|
||||
@@ -4,6 +4,35 @@ import type { User } from '$lib/models/user';
|
||||
import { Collection, handleError, remove, show } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/user/{id}:
|
||||
* get:
|
||||
* summary: Get user by ID
|
||||
* tags:
|
||||
* - Users
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: User details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/User'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<User>(event, Collection.users)
|
||||
@@ -14,6 +43,40 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/user/{id}:
|
||||
* post:
|
||||
* summary: Update user
|
||||
* description: Updates a user. Handles password changes and email change requests
|
||||
* tags:
|
||||
* - Users
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UserUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: User updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/User'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json()
|
||||
try {
|
||||
@@ -38,6 +101,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/user/{id}:
|
||||
* delete:
|
||||
* summary: Delete user
|
||||
* tags:
|
||||
* - Users
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: User deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.users)
|
||||
|
||||
@@ -2,6 +2,44 @@ import type { User } from "$lib/models/user";
|
||||
import { Collection, upload } from "$lib/util/api_util";
|
||||
import { error, json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/user/{id}/file:
|
||||
* post:
|
||||
* summary: Upload user file
|
||||
* description: Uploads a file (avatar) for a user
|
||||
* tags:
|
||||
* - Users
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File uploaded, user updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/User'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await upload<User>(event, Collection.users);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { UserAnonymous } from '$lib/models/user';
|
||||
import { Collection, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
export async function GET(event: RequestEvent) {
|
||||
let filter = event.url.searchParams.get("filter");
|
||||
|
||||
if (!filter) {
|
||||
filter = "private=false"
|
||||
} else {
|
||||
filter += "&&private=false"
|
||||
}
|
||||
event.url.searchParams.set("filter", filter);
|
||||
|
||||
try {
|
||||
const r = await list<UserAnonymous>(event, Collection.users_anonymous);
|
||||
|
||||
return json(r)
|
||||
} catch (e: any) {
|
||||
return handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import type { UserAnonymous } from "$lib/models/user";
|
||||
import { Collection, handleError, show } from '$lib/util/api_util';
|
||||
import { error, json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<UserAnonymous>(event, Collection.users_anonymous)
|
||||
|
||||
return json(r)
|
||||
} catch (e: any) {
|
||||
return handleError(e);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,32 @@ import { env } from '$env/dynamic/public';
|
||||
import { error, json, type NumericRange, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/valhalla/height:
|
||||
* post:
|
||||
* summary: Get elevation data
|
||||
* description: Queries Valhalla service for elevation data at coordinates
|
||||
* tags:
|
||||
* - Valhalla
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Elevation data from Valhalla
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json()
|
||||
if (!env.PUBLIC_VALHALLA_URL) {
|
||||
|
||||
@@ -2,6 +2,32 @@ import { env } from '$env/dynamic/public';
|
||||
import { error, json, type NumericRange, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/valhalla/route:
|
||||
* post:
|
||||
* summary: Get route data
|
||||
* description: Queries Valhalla service for routing data
|
||||
* tags:
|
||||
* - Valhalla
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Route data from Valhalla
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
const data = await event.request.json()
|
||||
if (!env.PUBLIC_VALHALLA_URL) {
|
||||
|
||||
@@ -3,6 +3,46 @@ import type { Waypoint } from '$lib/models/waypoint';
|
||||
import { Collection, create, handleError, list } from '$lib/util/api_util';
|
||||
import { json, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint:
|
||||
* get:
|
||||
* summary: List waypoints
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: perPage
|
||||
* schema:
|
||||
* type: integer
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: filter
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of waypoints
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ListResult'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await list<Waypoint>(event, Collection.waypoints);
|
||||
@@ -12,6 +52,31 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint:
|
||||
* put:
|
||||
* summary: Create waypoint
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/WaypointInput'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Waypoint created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Waypoint'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function PUT(event: RequestEvent) {
|
||||
try {
|
||||
const r = await create<Waypoint>(event, WaypointCreateSchema, Collection.waypoints)
|
||||
|
||||
@@ -3,6 +3,35 @@ import type { Waypoint } from "$lib/models/waypoint";
|
||||
import { Collection, handleError, remove, show, update } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint/{id}:
|
||||
* get:
|
||||
* summary: Get waypoint
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: query
|
||||
* name: expand
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Waypoint details
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Waypoint'
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function GET(event: RequestEvent) {
|
||||
try {
|
||||
const r = await show<Waypoint>(event, Collection.waypoints)
|
||||
@@ -12,6 +41,39 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint/{id}:
|
||||
* post:
|
||||
* summary: Update waypoint
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/WaypointUpdateInput'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Waypoint updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Waypoint'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Waypoint>(event, WaypointUpdateSchema, Collection.waypoints)
|
||||
@@ -21,6 +83,27 @@ export async function POST(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint/{id}:
|
||||
* delete:
|
||||
* summary: Delete waypoint
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Waypoint deleted
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function DELETE(event: RequestEvent) {
|
||||
try {
|
||||
const r = await remove(event, Collection.waypoints)
|
||||
|
||||
@@ -2,6 +2,44 @@ import type { Waypoint } from "$lib/models/waypoint";
|
||||
import { Collection, handleError, upload } from "$lib/util/api_util";
|
||||
import { json, type RequestEvent } from "@sveltejs/kit";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/waypoint/{id}/file:
|
||||
* post:
|
||||
* summary: Upload waypoint file
|
||||
* description: Uploads a file (photo) for a waypoint
|
||||
* tags:
|
||||
* - Waypoints
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* file:
|
||||
* type: string
|
||||
* format: binary
|
||||
* responses:
|
||||
* 200:
|
||||
* description: File uploaded, waypoint updated
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Waypoint'
|
||||
* 400:
|
||||
* description: Bad Request
|
||||
* 404:
|
||||
* description: Not Found
|
||||
* 500:
|
||||
* description: Internal Server Error
|
||||
*/
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await upload<Waypoint>(event, Collection.waypoints);
|
||||
|
||||
File diff suppressed because one or more lines are too long
6616
web/static/docs/api/wanderer.openapi.json
Normal file
6616
web/static/docs/api/wanderer.openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,22 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import openapiPlugin from 'sveltekit-openapi-generator';
|
||||
import fs from 'fs';
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf-8'));
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), sveltekit()],
|
||||
plugins: [openapiPlugin({
|
||||
info: {
|
||||
title: 'Wanderer API',
|
||||
version: `${packageJson.version}`,
|
||||
description: 'API documentation for wanderer backend',
|
||||
},
|
||||
outputPath: 'static/docs/api/wanderer.openapi.json',
|
||||
include: ['src/routes/api/v1/**/*.{js,ts}'],
|
||||
baseSchemasPath: 'src/lib/models/api/openapi_schemas.ts',
|
||||
}),tailwindcss(), sveltekit()],
|
||||
test: { include: ['src/**/*.{test,spec}.{js,ts}'] },
|
||||
ssr: { noExternal: ['three'] },
|
||||
...(process.env.WANDERER_ENV == "dev" ? {
|
||||
|
||||
Reference in New Issue
Block a user