Files

78 lines
2.1 KiB
TypeScript

import type Pocketbase from "pocketbase";
import type { RecordService } from "pocketbase";
import { z } from "zod";
/******* ENUMS *******/
export const collectionValues = @@_COLLECTION_NAMES_@@ as const;
export const Collection = z.enum(collectionValues);
export type Collection = z.infer<typeof Collection>;
export const COLLECTION = Collection.enum;
@@_ENUMS_@@
/******* BASE *******/
export const BaseModel = z.object({
created: z.string().pipe(z.coerce.date()),
id: z.string(),
updated: z.string().pipe(z.coerce.date()),
});
export type BaseModel = z.infer<typeof BaseModel>;
export const AdminModel = z.object({
...BaseModel.shape,
avatar: z.string(),
email: z.email(),
});
export type AdminModel = z.infer<typeof AdminModel>;
export const RecordModel = z.object({
...BaseModel.shape,
collectionId: z.string(),
collectionName: z.string(),
expand: z.any().optional(),
});
export type RecordModel = z.infer<typeof RecordModel>;
/******* JSON FIELD *******/
export const pbJsonField = (maxSizeInBytes: number = 1048576) => {
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
const jsonSchema: z.ZodType<any> = z.lazy(() =>
z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])
);
const stringTransform = z.string()
.max(maxSizeInBytes, `JSON field cannot exceed ${maxSizeInBytes} bytes`)
.transform((val: string) => {
if (val === "true") return true;
if (val === "false") return false;
if (val === "null") return null;
if ((val.startsWith('[') && val.endsWith(']'))||(val.startsWith('{') && val.endsWith('}')))
try {
return JSON.parse(val);
} catch {
return val;
}
const num = Number(val);
if (!Number.isNaN(num) && Number.isFinite(num) && val.trim() !== '')
return num;
if (val.startsWith('"') && val.endsWith('"'))
return val.slice(1, -1);
return val;
});
return z.union([jsonSchema, stringTransform]);
};
/******* RECORDS *******/
@@_RECORDS_@@
/******* CLIENT *******/
export type TypedPocketbase = Pocketbase & {
@@_SERVICES_@@
};