adds zod API validation

This commit is contained in:
Christian Beutel
2024-12-27 01:56:35 +01:00
parent 1f81779a64
commit 75c94a3ce4
80 changed files with 847 additions and 559 deletions

View File

@@ -0,0 +1,115 @@
import { error, type NumericRange, type RequestEvent } from "@sveltejs/kit";
import { ClientResponseError, type ListResult } from "pocketbase";
import { pb } from "$lib/pocketbase";
import { ZodError, type ZodSchema } from "zod";
import { RecordListOptionsSchema, RecordIdSchema, RecordOptionsSchema } from "$lib/models/api/base_schema";
export enum Collection {
users = "users",
categories = "categories",
comments = "comments",
follows = "follows",
list_share = "list_share",
lists = "lists",
notifications = "notifications",
settings = "settings",
summit_logs = "summit_logs",
trail_share = "trail_share",
trails = "trails",
waypoints = "waypoints",
activities = "activities",
follow_counts = "follow_counts",
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 pb.collection(Collection[collection])
.getFullList<T>(safeSearchParams)
r = {
items: activities,
perPage: -1,
page: 1,
totalItems: activities.length,
totalPages: 1
}
} else {
r = await 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 pb.collection(collection.toString())
.getOne<T>(safeParams.id, safeSearchParams)
return r
}
export async function create<T>(event: RequestEvent, schema: ZodSchema, collection: Collection) {
const data = await event.request.json();
const safeData = schema.parse(data);
const r = await pb.collection(Collection[collection]).create<T>(safeData)
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 pb.collection(Collection[collection]).update<T>(safeParams.id, safeData, 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 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 pb.collection(Collection[collection]).delete(safeParams.id)
return { 'acknowledged': r }
}
export function handleError(e: any) {
if (e instanceof ZodError) {
return error(400, e.message)
} else if (e instanceof ClientResponseError && e.status > 0) {
return error(e.status as NumericRange<400, 599>, e.message)
} else {
return e
}
}