166 lines
5.5 KiB
TypeScript
166 lines
5.5 KiB
TypeScript
import { error, json, type NumericRange, type RequestEvent } from "@sveltejs/kit";
|
|
import { ClientResponseError, type ListResult } from "pocketbase";
|
|
import { ZodError, type ZodSchema } from "zod";
|
|
import { RecordListOptionsSchema, RecordIdSchema, RecordOptionsSchema } from "$lib/models/api/base_schema";
|
|
|
|
export class APIError extends Error {
|
|
status: number;
|
|
message: string;
|
|
detail: any;
|
|
|
|
constructor(status: number, message: string, detail?: any) {
|
|
super();
|
|
this.status = status;
|
|
this.message = message;
|
|
this.detail = detail
|
|
}
|
|
}
|
|
|
|
|
|
export enum Collection {
|
|
users = "users",
|
|
activitypub_activities = "activitypub_activities",
|
|
activitypub_actors = "activitypub_actors",
|
|
categories = "categories",
|
|
comments = "comments",
|
|
feed = "feed",
|
|
follows = "follows",
|
|
integrations = "integrations",
|
|
list_share = "list_share",
|
|
lists = "lists",
|
|
notifications = "notifications",
|
|
profile_feed = "profile_feed",
|
|
settings = "settings",
|
|
summit_logs = "summit_logs",
|
|
trail_like = "trail_like",
|
|
trail_share = "trail_share",
|
|
trail_link_share = "trail_link_share",
|
|
trails = "trails",
|
|
tags = "tags",
|
|
waypoints = "waypoints",
|
|
trails_bounding_box = "trails_bounding_box",
|
|
trails_filter = "trails_filter",
|
|
users_anonymous = "users_anonymous",
|
|
|
|
}
|
|
|
|
export async function list<T>(event: RequestEvent, collection: Collection) {
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordListOptionsSchema.parse(searchParams);
|
|
|
|
let r: ListResult<T>;
|
|
if ((safeSearchParams.perPage ?? 0) < 0) {
|
|
const activities: T[] = await event.locals.pb.collection(Collection[collection])
|
|
.getFullList<T>(safeSearchParams)
|
|
r = {
|
|
items: activities,
|
|
perPage: -1,
|
|
page: 1,
|
|
totalItems: activities.length,
|
|
totalPages: 1
|
|
}
|
|
} else {
|
|
r = await event.locals.pb.collection(Collection[collection])
|
|
.getList<T>(safeSearchParams.page, safeSearchParams.perPage, { ...safeSearchParams })
|
|
}
|
|
return r
|
|
}
|
|
|
|
export async function show<T>(event: RequestEvent, collection: Collection) {
|
|
const params = event.params
|
|
const safeParams = RecordIdSchema.parse(params);
|
|
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordOptionsSchema.parse(searchParams);
|
|
|
|
const r = await event.locals.pb.collection(collection.toString())
|
|
.getOne<T>(safeParams.id, safeSearchParams)
|
|
|
|
return r
|
|
}
|
|
|
|
export async function create<T>(event: RequestEvent, schema: ZodSchema, collection: Collection) {
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordOptionsSchema.parse(searchParams);
|
|
|
|
const data = await event.request.json();
|
|
const safeData = schema.parse(data);
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).create<T>(safeData, { ...safeSearchParams, requestKey: null })
|
|
|
|
return r
|
|
}
|
|
|
|
export async function update<T>(event: RequestEvent, schema: ZodSchema, collection: Collection) {
|
|
const params = event.params
|
|
const safeParams = RecordIdSchema.parse(params);
|
|
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordOptionsSchema.parse(searchParams);
|
|
|
|
const data = await event.request.json();
|
|
const safeData = schema.parse(data);
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).update<T>(safeParams.id, safeData, safeSearchParams)
|
|
|
|
return r
|
|
}
|
|
|
|
export async function uploadCreate<T>(event: RequestEvent, collection: Collection) {
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordOptionsSchema.parse(searchParams);
|
|
|
|
const data = await event.request.formData();
|
|
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).create<T>(data, safeSearchParams)
|
|
|
|
return r
|
|
}
|
|
|
|
export async function uploadUpdate<T>(event: RequestEvent, collection: Collection) {
|
|
const searchParams = Object.fromEntries(event.url.searchParams);
|
|
const safeSearchParams = RecordOptionsSchema.parse(searchParams);
|
|
|
|
const data = await event.request.formData();
|
|
if (!data.has('id')) {
|
|
throw new Error("data has no id")
|
|
}
|
|
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).update<T>(data.get('id')!.toString(), data, safeSearchParams)
|
|
|
|
return r
|
|
}
|
|
|
|
export async function upload<T>(event: RequestEvent, collection: Collection) {
|
|
const params = event.params
|
|
const safeParams = RecordIdSchema.parse(params);
|
|
|
|
const data = await event.request.formData();
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).update<T>(safeParams.id, data)
|
|
|
|
return r
|
|
}
|
|
|
|
export async function remove(event: RequestEvent, collection: Collection) {
|
|
const params = event.params
|
|
const safeParams = RecordIdSchema.parse(params);
|
|
|
|
const r = await event.locals.pb.collection(Collection[collection]).delete(safeParams.id)
|
|
|
|
return { 'acknowledged': r }
|
|
}
|
|
|
|
export function handleError(e: any) {
|
|
if (e instanceof ZodError) {
|
|
return json({ message: "invalid_params", detail: e.issues }, { status: 400 })
|
|
} else if (e instanceof ClientResponseError && e.status > 0) {
|
|
return json({ ...e.response, message: e.message, detail: e.originalError.data }, { status: e.status })
|
|
} else if (e instanceof SyntaxError) {
|
|
return json({ message: "invalid_json" }, { status: 400 })
|
|
} else {
|
|
return json({ message: e }, { status: 500 })
|
|
}
|
|
} |