pocketbase-zod-schema 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cli/index.cjs +449 -50
  3. package/dist/cli/index.cjs.map +1 -1
  4. package/dist/cli/index.d.cts +1 -1
  5. package/dist/cli/index.d.ts +1 -1
  6. package/dist/cli/index.js +449 -50
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/migrate.cjs +455 -53
  9. package/dist/cli/migrate.cjs.map +1 -1
  10. package/dist/cli/migrate.js +455 -53
  11. package/dist/cli/migrate.js.map +1 -1
  12. package/dist/cli/utils/index.cjs +8 -1
  13. package/dist/cli/utils/index.cjs.map +1 -1
  14. package/dist/cli/utils/index.d.cts +1 -1
  15. package/dist/cli/utils/index.d.ts +1 -1
  16. package/dist/cli/utils/index.js +8 -1
  17. package/dist/cli/utils/index.js.map +1 -1
  18. package/dist/index.cjs +90 -1
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +87 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/migration/analyzer.cjs +87 -14
  25. package/dist/migration/analyzer.cjs.map +1 -1
  26. package/dist/migration/analyzer.d.cts +12 -4
  27. package/dist/migration/analyzer.d.ts +12 -4
  28. package/dist/migration/analyzer.js +87 -15
  29. package/dist/migration/analyzer.js.map +1 -1
  30. package/dist/migration/diff.cjs +64 -9
  31. package/dist/migration/diff.cjs.map +1 -1
  32. package/dist/migration/diff.d.cts +12 -2
  33. package/dist/migration/diff.d.ts +12 -2
  34. package/dist/migration/diff.js +64 -10
  35. package/dist/migration/diff.js.map +1 -1
  36. package/dist/migration/generator.cjs +206 -39
  37. package/dist/migration/generator.cjs.map +1 -1
  38. package/dist/migration/generator.d.cts +54 -2
  39. package/dist/migration/generator.d.ts +54 -2
  40. package/dist/migration/generator.js +203 -40
  41. package/dist/migration/generator.js.map +1 -1
  42. package/dist/migration/index.cjs +501 -63
  43. package/dist/migration/index.cjs.map +1 -1
  44. package/dist/migration/index.d.cts +2 -2
  45. package/dist/migration/index.d.ts +2 -2
  46. package/dist/migration/index.js +501 -63
  47. package/dist/migration/index.js.map +1 -1
  48. package/dist/migration/snapshot.cjs +147 -1
  49. package/dist/migration/snapshot.cjs.map +1 -1
  50. package/dist/migration/snapshot.d.cts +3 -1
  51. package/dist/migration/snapshot.d.ts +3 -1
  52. package/dist/migration/snapshot.js +147 -1
  53. package/dist/migration/snapshot.js.map +1 -1
  54. package/dist/migration/utils/index.d.cts +1 -1
  55. package/dist/migration/utils/index.d.ts +1 -1
  56. package/dist/schema.cjs +90 -1
  57. package/dist/schema.cjs.map +1 -1
  58. package/dist/schema.d.cts +128 -2
  59. package/dist/schema.d.ts +128 -2
  60. package/dist/schema.js +87 -2
  61. package/dist/schema.js.map +1 -1
  62. package/dist/server.cjs +545 -65
  63. package/dist/server.cjs.map +1 -1
  64. package/dist/server.d.cts +2 -2
  65. package/dist/server.d.ts +2 -2
  66. package/dist/server.js +542 -66
  67. package/dist/server.js.map +1 -1
  68. package/dist/{types-CWHV6ATd.d.cts → types-CnzfX6JH.d.cts} +20 -2
  69. package/dist/{types-C2nGWHLV.d.ts → types-Do3jyFBm.d.ts} +20 -2
  70. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -451,13 +451,16 @@ function withIndexes(schema, indexes) {
451
451
  return schema.describe(JSON.stringify(metadata));
452
452
  }
453
453
  function defineCollection(config) {
454
- const { collectionName, schema, permissions, indexes, type, ...futureOptions } = config;
454
+ const { collectionName, schema, permissions, indexes, type, viewQuery, ...futureOptions } = config;
455
455
  const metadata = {
456
456
  collectionName
457
457
  };
458
458
  if (type) {
459
459
  metadata.type = type;
460
460
  }
461
+ if (viewQuery !== void 0) {
462
+ metadata.viewQuery = viewQuery;
463
+ }
461
464
  if (permissions) {
462
465
  metadata.permissions = permissions;
463
466
  }
@@ -723,6 +726,88 @@ function GeoPointField() {
723
726
  };
724
727
  return schema.describe(JSON.stringify(metadata));
725
728
  }
729
+ function dedentSql(value) {
730
+ const lines = value.replace(/\r\n/g, "\n").split("\n");
731
+ while (lines.length > 0 && lines[0].trim() === "") {
732
+ lines.shift();
733
+ }
734
+ while (lines.length > 0 && lines[lines.length - 1].trim() === "") {
735
+ lines.pop();
736
+ }
737
+ if (lines.length === 0) {
738
+ return "";
739
+ }
740
+ let minIndent = Infinity;
741
+ for (const line of lines) {
742
+ if (line.trim() === "") continue;
743
+ const indent = line.length - line.trimStart().length;
744
+ if (indent < minIndent) {
745
+ minIndent = indent;
746
+ }
747
+ }
748
+ if (!Number.isFinite(minIndent) || minIndent === 0) {
749
+ return lines.map((line) => line.trimEnd()).join("\n");
750
+ }
751
+ return lines.map((line) => line.slice(minIndent).trimEnd()).join("\n");
752
+ }
753
+ function sql(strings, ...values) {
754
+ let result = "";
755
+ for (let i = 0; i < strings.length; i++) {
756
+ result += strings[i];
757
+ if (i < values.length) {
758
+ result += String(values[i]);
759
+ }
760
+ }
761
+ return dedentSql(result);
762
+ }
763
+ function stripLeadingComments(query) {
764
+ let remaining = query.trim();
765
+ while (remaining.length > 0) {
766
+ if (remaining.startsWith("--")) {
767
+ const newline = remaining.indexOf("\n");
768
+ remaining = newline === -1 ? "" : remaining.slice(newline + 1).trim();
769
+ continue;
770
+ }
771
+ if (remaining.startsWith("/*")) {
772
+ const end = remaining.indexOf("*/");
773
+ remaining = end === -1 ? "" : remaining.slice(end + 2).trim();
774
+ continue;
775
+ }
776
+ break;
777
+ }
778
+ return remaining;
779
+ }
780
+ function validateViewQuery(collectionName, viewQuery) {
781
+ if (typeof viewQuery !== "string" || viewQuery.trim() === "") {
782
+ throw new Error(
783
+ `View collection "${collectionName}" requires a non-empty viewQuery. Provide the SQL SELECT statement backing the view.`
784
+ );
785
+ }
786
+ const body = stripLeadingComments(viewQuery);
787
+ if (!/^(select|with)\b/i.test(body)) {
788
+ throw new Error(
789
+ `View collection "${collectionName}" has an invalid viewQuery: it must start with SELECT or WITH. Received: ${body.slice(0, 40)}${body.length > 40 ? "..." : ""}`
790
+ );
791
+ }
792
+ }
793
+ function defineView(config) {
794
+ const { collectionName, schema, viewQuery, permissions } = config;
795
+ validateViewQuery(collectionName, viewQuery);
796
+ return defineCollection({
797
+ collectionName,
798
+ schema,
799
+ type: "view",
800
+ viewQuery,
801
+ // Write rules are always locked for views - PocketBase rejects anything else
802
+ permissions: {
803
+ listRule: permissions?.listRule ?? null,
804
+ viewRule: permissions?.viewRule ?? null,
805
+ createRule: null,
806
+ updateRule: null,
807
+ deleteRule: null
808
+ }
809
+ });
810
+ }
726
811
 
727
812
  // src/utils/permission-templates.ts
728
813
  var PermissionTemplates = {
@@ -969,7 +1054,9 @@ exports.baseImageFileSchema = baseImageFileSchema;
969
1054
  exports.baseSchema = baseSchema;
970
1055
  exports.baseSchemaWithTimestamps = baseSchemaWithTimestamps;
971
1056
  exports.createPermissions = createPermissions;
1057
+ exports.dedentSql = dedentSql;
972
1058
  exports.defineCollection = defineCollection;
1059
+ exports.defineView = defineView;
973
1060
  exports.extractFieldMetadata = extractFieldMetadata;
974
1061
  exports.extractRelationMetadata = extractRelationMetadata;
975
1062
  exports.inputImageFileSchema = inputImageFileSchema;
@@ -978,8 +1065,10 @@ exports.isTemplateConfig = isTemplateConfig;
978
1065
  exports.mergePermissions = mergePermissions;
979
1066
  exports.omitImageFilesSchema = omitImageFilesSchema;
980
1067
  exports.resolveTemplate = resolveTemplate;
1068
+ exports.sql = sql;
981
1069
  exports.validatePermissionConfig = validatePermissionConfig;
982
1070
  exports.validateRuleExpression = validateRuleExpression;
1071
+ exports.validateViewQuery = validateViewQuery;
983
1072
  exports.withIndexes = withIndexes;
984
1073
  exports.withPermissions = withPermissions;
985
1074
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/enums.ts","../src/mutator/baseMutator.ts","../src/schema/base.ts","../src/schema/fields.ts","../src/utils/permission-templates.ts"],"names":["z","baseSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\n\nexport const StatusEnum = z.enum([\n \"draft\", // Initial proposal stage (RequestDraft, ProjectDraft)\n \"active\", // Work in progress\n \"complete\", // Fully completed project\n \"fail\", // Failed project at any stage\n]);\nexport type StatusEnumType = z.infer<typeof StatusEnum>;\n","import PocketBase, {\n RecordService,\n type ListResult,\n type RecordListOptions,\n type RecordModel,\n type RecordOptions,\n type RecordSubscribeOptions,\n type RecordSubscription,\n type UnsubscribeFunc,\n} from \"pocketbase\";\n\nexport interface MutatorOptions {\n expand: string[];\n filter: string[];\n sort: string[];\n}\n\n// Helper to infer the type of the expanded resource\nexport type Expanded<\n T extends RecordModel,\n E extends keyof NonNullable<T[\"expand\"]>\n> = [E] extends [never]\n ? T\n : T & {\n expand: Required<\n Pick<\n NonNullable<T[\"expand\"]>,\n E extends keyof NonNullable<T[\"expand\"]> ? E : never\n >\n >;\n };\n\n// T represents the output model type that extends RecordModel\n// InputType represents the input type for creation operations\nexport abstract class BaseMutator<T extends RecordModel, InputType> {\n protected pb: PocketBase;\n\n // Define a default property that subclasses will override\n protected options: MutatorOptions = {\n expand: [],\n filter: [],\n sort: [],\n };\n\n constructor(pb: PocketBase, options?: Partial<MutatorOptions>) {\n this.pb = pb;\n\n // Initialize with default options first\n this.initializeOptions();\n if (options) {\n this.overrideOptions(options);\n }\n }\n\n private initializeOptions(): void {\n this.options = this.setDefaults();\n }\n /**\n * Initialize options with class-specific defaults\n * Subclasses should override this instead of directly setting options\n */\n protected setDefaults(): MutatorOptions {\n return {\n expand: [],\n filter: [],\n sort: [],\n };\n }\n\n /**\n * Merge provided options with current options\n */\n protected overrideOptions(newOptions: Partial<MutatorOptions>): void {\n if (newOptions.expand !== undefined) {\n this.options.expand = newOptions.expand;\n }\n if (newOptions.filter !== undefined) {\n this.options.filter = newOptions.filter;\n }\n if (newOptions.sort !== undefined) {\n this.options.sort = newOptions.sort;\n }\n }\n\n /**\n * Get the collection instance\n */\n protected abstract getCollection(): RecordService<T>;\n\n toSnakeCase(str: string): string {\n return str\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_|_$/g, \"\");\n }\n\n /**\n * Create a new entity\n */\n async create<E extends keyof NonNullable<T[\"expand\"]> = never>(\n input: InputType,\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n try {\n const data = await this.validateInput(input);\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n\n const record = await this.entityCreate(data, options);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Update an existing entity\n */\n async update<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n input: Partial<T>,\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n try {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n\n const record = await this.entityUpdate(id, input, options);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Create or update entity (upsert)\n */\n async upsert<E extends keyof NonNullable<T[\"expand\"]> = never>(\n input: InputType & { id?: string },\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n if (input?.id) {\n return await this.update(input.id, input as Partial<T>, expand);\n }\n\n // Implementations should override this method if they need\n // more specific upsert logic like checking for existing entities\n return await this.create(input, expand);\n }\n\n /**\n * Get entity by ID\n */\n async getById<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n expand?: E | E[]\n ): Promise<Expanded<T, E> | null> {\n try {\n const record = await this.entityGetById(id, expand as string | string[]);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.handleError(error, { allowNotFound: true });\n }\n }\n\n /**\n * Get first entity by filter\n */\n async getFirstByFilter<E extends keyof NonNullable<T[\"expand\"]> = never>(\n filter: string | string[],\n expand?: E | E[],\n sort?: string\n ): Promise<Expanded<T, E> | null> {\n try {\n const record = await this.entityGetFirstByFilter(\n filter,\n expand as string | string[],\n sort\n );\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.handleError(error, { allowNotFound: true });\n }\n }\n\n /**\n * Get list of entities\n */\n async getList<E extends keyof NonNullable<T[\"expand\"]> = never>(\n page = 1,\n perPage = 100,\n filter?: string | string[],\n sort?: string,\n expand?: E | E[]\n ): Promise<ListResult<Expanded<T, E>>> {\n try {\n const result = await this.entityGetList(\n page,\n perPage,\n filter,\n sort,\n expand as string | string[]\n );\n // processListResult expects ListResult<T>, but we are returning ListResult<Expanded<T, E>>\n // processRecord needs to handle T.\n // We cast the result of processListResult.\n const processed = await this.processListResult(result);\n return processed as unknown as ListResult<Expanded<T, E>>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Delete entity by ID\n */\n async delete(id: string): Promise<boolean> {\n try {\n return await this.entityDelete(id);\n } catch (error) {\n return this.handleError(error, { returnValue: false });\n }\n }\n\n /**\n * Process a single record before returning it\n * Can be overridden to handle special cases like mapped entities\n */\n protected async processRecord(record: T): Promise<T> {\n return record;\n }\n\n /**\n * Process a list result before returning it\n * Can be overridden to handle special cases like mapped entities\n */\n protected async processListResult(result: ListResult<T>): Promise<ListResult<T>> {\n // Process each item in the list\n const processedItems = await Promise.all(\n result.items.map((item) => this.processRecord(item))\n );\n\n return {\n ...result,\n items: processedItems,\n };\n }\n\n /**\n * Prepare expand parameter\n * Combines default expands with provided expands\n */\n protected prepareExpand(expand?: string | string[]): string | undefined {\n // Handle empty defaults case\n if (!this.options.expand.length && !expand) {\n return undefined;\n }\n\n // Convert all inputs to arrays for easy processing\n let expandArray: string[] = [...this.options.expand];\n\n if (expand) {\n // If expand is a string, split it and add the parts\n if (typeof expand === \"string\") {\n expandArray = expandArray.concat(expand.split(\",\").map((e) => e.trim()));\n }\n // If expand is already an array, concatenate\n else {\n expandArray = expandArray.concat(expand);\n }\n }\n\n // Filter out duplicates, empty strings, and undefined values\n const uniqueExpands = [...new Set(expandArray)].filter(\n (e) => e !== \"\" && e !== undefined\n );\n\n // If no valid expands, return undefined\n if (!uniqueExpands.length) {\n return undefined;\n }\n\n // Join with comma and space\n return uniqueExpands.join(\",\");\n }\n\n /**\n * Prepare filter parameter\n * Combines default filters with provided filters\n */\n protected prepareFilter(filter?: string | string[]): string | undefined {\n // Handle empty case\n if (!this.options.filter.length && !filter) {\n return undefined;\n }\n\n // Convert all inputs to arrays for easy processing\n let filterArray: string[] = [...this.options.filter];\n\n if (filter) {\n // If filter is a string, add it as is (it might contain && already)\n if (typeof filter === \"string\") {\n if (filter) filterArray.push(filter);\n }\n // If filter is an array, concatenate\n else {\n filterArray = filterArray.concat(filter);\n }\n }\n\n // Filter out empty strings and undefined values\n const validFilters = filterArray.filter((f) => f !== \"\" && f !== undefined);\n\n // If no valid filters, return undefined\n if (!validFilters.length) {\n return undefined;\n }\n\n // Join with AND operator\n return validFilters.join(\"&&\");\n }\n\n /**\n * Prepare sort parameter\n * Uses provided sort or falls back to default sort\n */\n protected prepareSort(sort?: string): string | undefined {\n // If explicit sort is provided and not empty, use it (overriding defaults)\n if (sort && sort !== \"\") {\n return sort;\n }\n\n // If no explicit sort but we have defaults\n if (this.options.sort.length) {\n // Filter out empty and undefined values\n const validSorts = this.options.sort.filter(\n (s) => s !== \"\" && s !== undefined\n );\n\n // If we have valid sort items after filtering\n if (validSorts.length) {\n return validSorts.join(\",\");\n }\n }\n\n // No sort specified\n return undefined;\n }\n\n /**\n * Perform the actual create operation\n */\n protected async entityCreate(data: InputType, options?: RecordOptions): Promise<T> {\n return await this.getCollection().create(data as Record<string, any>, options);\n }\n\n /**\n * Perform the actual update operation\n */\n protected async entityUpdate(id: string, data: Partial<T>, options?: RecordOptions): Promise<T> {\n return await this.getCollection().update(id, data, options);\n }\n\n /**\n * Perform the actual getById operation\n */\n protected async entityGetById(\n id: string,\n expand?: string | string[]\n ): Promise<T> {\n const finalExpand = this.prepareExpand(expand);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n return await this.getCollection().getOne(id, options);\n }\n\n /**\n * Perform the actual getFirstByFilter operation\n */\n protected async entityGetFirstByFilter(\n filter: string | string[],\n expand?: string | string[],\n sort?: string\n ): Promise<T> {\n const finalFilter = this.prepareFilter(filter);\n const finalExpand = this.prepareExpand(expand);\n const finalSort = this.prepareSort(sort);\n\n const options: RecordListOptions = {};\n if (finalExpand) options.expand = finalExpand;\n if (finalSort) options.sort = finalSort;\n\n return await this.getCollection().getFirstListItem(finalFilter || \"\", options);\n }\n\n /**\n * Perform the actual getList operation\n * Returns a list result with items of type T\n */\n protected async entityGetList(\n page: number,\n perPage: number,\n filter?: string | string[],\n sort?: string,\n expand?: string | string[]\n ): Promise<ListResult<T>> {\n const finalFilter = this.prepareFilter(filter);\n const finalExpand = this.prepareExpand(expand);\n const finalSort = this.prepareSort(sort);\n\n const options: RecordListOptions = {};\n if (finalFilter) options.filter = finalFilter;\n if (finalExpand) options.expand = finalExpand;\n if (finalSort) options.sort = finalSort;\n\n return await this.getCollection().getList(page, perPage, options);\n }\n\n /**\n * Perform the actual delete operation\n */\n protected async entityDelete(id: string): Promise<boolean> {\n await this.getCollection().delete(id);\n return true;\n }\n\n /**\n * Error handler for common errors\n * @param error The error to handle\n * @param options Handler options\n * @returns The value to return if the error is handled, or throws if not handled\n */\n protected handleError<R>(\n error: any,\n options: {\n allowNotFound?: boolean;\n returnValue?: R;\n logError?: boolean;\n } = { logError: true }\n ): R {\n const { allowNotFound = false, returnValue, logError = true } = options;\n\n // Log the error if requested\n if (logError) {\n console.error(`Error in ${this.constructor.name}:`, error);\n }\n\n // Handle 404 errors if allowed\n if (allowNotFound && this.isNotFoundError(error)) {\n return null as R;\n }\n\n // Return specified value or rethrow\n if (returnValue !== undefined) {\n return returnValue;\n }\n\n // Rethrow the error\n throw error;\n }\n\n /**\n * Check if an error is a \"not found\" error\n */\n protected isNotFoundError(error: any): boolean {\n return (\n error instanceof Error &&\n (error.message.includes(\"404\") ||\n error.message.toLowerCase().includes(\"not found\"))\n );\n }\n\n /**\n * Standard error handling wrapper (legacy method, consider using handleError instead)\n */\n protected errorWrapper(error: any): never {\n console.error(`Error in ${this.constructor.name}:`, error);\n throw error;\n }\n\n /**\n * Validate input data before creating/updating\n * Should be implemented by child classes\n */\n protected abstract validateInput(input: InputType): Promise<InputType>;\n\n /**\n * Subscribe to changes on a specific record\n * @param id The ID of the record to subscribe to\n * @param callback Function to call when changes occur\n * @param expand Optional expand parameters\n * @returns Promise that resolves to an unsubscribe function\n */\n async subscribeToRecord<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n callback: (data: RecordSubscription<Expanded<T, E>>) => void,\n expand?: E | E[]\n ): Promise<UnsubscribeFunc> {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordSubscribeOptions = finalExpand\n ? { expand: finalExpand }\n : {};\n\n return this.getCollection().subscribe(id, callback as any, options);\n }\n\n /**\n * Subscribe to changes on the entire collection\n * @param callback Function to call when changes occur\n * @param expand Optional expand parameters\n * @returns Promise that resolves to an unsubscribe function\n */\n async subscribeToCollection<\n E extends keyof NonNullable<T[\"expand\"]> = never\n >(\n callback: (data: RecordSubscription<Expanded<T, E>>) => void,\n expand?: E | E[]\n ): Promise<UnsubscribeFunc> {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordSubscribeOptions = finalExpand\n ? { expand: finalExpand }\n : {};\n\n return this.getCollection().subscribe(\"*\", callback as any, options);\n }\n\n /**\n * Unsubscribe from a specific record's changes\n * @param id The ID of the record to unsubscribe from\n */\n unsubscribeFromRecord(id: string): void {\n this.getCollection().unsubscribe(id);\n }\n\n /**\n * Unsubscribe from collection-wide changes\n */\n unsubscribeFromCollection(): void {\n this.getCollection().unsubscribe(\"*\");\n }\n\n /**\n * Unsubscribe from all subscriptions in this collection\n */\n unsubscribeAll(): void {\n this.getCollection().unsubscribe();\n }\n}\n","import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n id: z.string().describe(\"unique id\"),\n collectionId: z.string().describe(\"collection id\"),\n collectionName: z.string().describe(\"collection name\"),\n expand: z.record(z.string(), z.any()).describe(\"expandable fields\"),\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Extended base schema with timestamp fields\n * Includes created and updated autodate fields\n */\nexport const baseSchemaWithTimestamps = {\n ...baseSchema,\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Base schema for image file collections\n * Extends base schema with thumbnail URL and image files array\n */\nexport const baseImageFileSchema = {\n ...baseSchema,\n thumbnailURL: z.string().optional(),\n imageFiles: z.array(z.string()),\n};\n\n/**\n * Input schema for image file uploads\n * Used in forms where users upload File objects\n * Requires Node.js 20+ or browser environment with File API\n */\nexport const inputImageFileSchema = {\n imageFiles: z.array(z.instanceof(File)),\n};\n\n/**\n * Helper constant for omitting image files from schemas\n * Used with Zod's .omit() method\n */\nexport const omitImageFilesSchema = {\n imageFiles: true,\n} as const;\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n// Note: Field type helpers are now exported from ./fields.ts with PascalCase names\n// (e.g., TextField, EmailField, JSONField, etc.) to ensure consistent naming.\n\n// ============================================================================\n// Relation Field Helpers - Explicit Relationship Definitions\n// ============================================================================\n\n/**\n * Relation field configuration options\n */\nexport interface RelationConfig {\n /**\n * Target collection name (e.g., 'users', 'posts', 'tags')\n * This is the PocketBase collection that the relation points to\n */\n collection: string;\n\n /**\n * Whether to cascade delete related records when this record is deleted\n * @default false\n */\n cascadeDelete?: boolean;\n\n /**\n * Fields to display in the admin UI\n */\n displayFields?: string[] | null;\n}\n\n/**\n * Multiple relation field configuration options\n */\nexport interface RelationsConfig extends RelationConfig {\n /**\n * Minimum number of relations required\n * @default 0\n */\n minSelect?: number;\n\n /**\n * Maximum number of relations allowed\n * @default 999\n */\n maxSelect?: number;\n}\n\n/**\n * Internal marker for relation metadata\n * Used by the analyzer to detect explicit relation definitions\n */\nconst RELATION_METADATA_KEY = \"__pocketbase_relation__\";\n\n/**\n * Creates a single relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect=1\n *\n * This is the recommended way to define relations - it's explicit and doesn't\n * rely on naming conventions.\n *\n * @param config - Relation configuration with target collection\n * @returns Zod string schema with relation metadata\n *\n * @example\n * // Single relation to users collection\n * const PostSchema = z.object({\n * title: z.string(),\n * author: RelationField({ collection: 'users' }),\n * });\n *\n * @example\n * // Relation with cascade delete\n * const CommentSchema = z.object({\n * content: z.string(),\n * post: RelationField({ collection: 'posts', cascadeDelete: true }),\n * });\n */\nexport function RelationField(config: RelationConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"single\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: 1,\n minSelect: 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect>1\n *\n * This is the recommended way to define multi-relations - it's explicit and\n * doesn't rely on naming conventions.\n *\n * @param config - Relations configuration with target collection and limits\n * @returns Zod array of strings schema with relation metadata\n *\n * @example\n * // Multiple relations to tags collection\n * const PostSchema = z.object({\n * title: z.string(),\n * tags: RelationsField({ collection: 'tags' }),\n * });\n *\n * @example\n * // Relations with min/max constraints\n * const ProjectSchema = z.object({\n * title: z.string(),\n * collaborators: RelationsField({\n * collection: 'users',\n * minSelect: 1,\n * maxSelect: 10,\n * }),\n * });\n */\nexport function RelationsField(config: RelationsConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"multiple\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: config.maxSelect ?? 999,\n minSelect: config.minSelect ?? 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n let schema = z.array(z.string());\n\n // Apply array constraints for Zod validation\n if (config.minSelect !== undefined) {\n schema = schema.min(config.minSelect);\n }\n if (config.maxSelect !== undefined) {\n schema = schema.max(config.maxSelect);\n }\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Extracts relation metadata from a Zod type's description\n * Used internally by the analyzer to detect explicit relation definitions\n *\n * @param description - The Zod type's description string\n * @returns Relation metadata if present, null otherwise\n */\nexport function extractRelationMetadata(description: string | undefined): {\n type: \"single\" | \"multiple\";\n collection: string;\n cascadeDelete: boolean;\n maxSelect: number;\n minSelect: number;\n displayFields?: string[] | null;\n} | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[RELATION_METADATA_KEY]) {\n return parsed[RELATION_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n/**\n * Attach permission metadata to a Zod schema\n *\n * This helper function allows you to define PocketBase API rules alongside your\n * entity schema definitions. The permissions are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach permissions to\n * @param config - Either a PermissionTemplateConfig (for template-based permissions)\n * or a PermissionSchema (for custom permissions)\n * @returns The schema with permission metadata attached\n *\n * @example\n * // Using a template\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * { template: 'owner-only', ownerField: 'User' }\n * );\n *\n * @example\n * // Using custom rules\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string() }),\n * { listRule: '@request.auth.id != \"\"', viewRule: '' }\n * );\n *\n * @example\n * // Using template with custom rule overrides\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * {\n * template: 'owner-only',\n * ownerField: 'User',\n * customRules: { listRule: '@request.auth.id != \"\"' }\n * }\n * );\n */\nexport function withPermissions<T extends z.ZodTypeAny>(\n schema: T,\n config: PermissionTemplateConfig | PermissionSchema\n): T {\n // Create metadata object with permissions config directly\n // The PermissionAnalyzer will handle resolving templates vs direct schemas\n const metadata = {\n permissions: config,\n };\n\n // Attach permission metadata to schema using Zod's describe() method\n // The metadata is serialized as JSON and stored in the schema's description\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Attach index definitions to a Zod schema\n *\n * This helper function allows you to define PocketBase indexes alongside your\n * entity schema definitions. The indexes are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach indexes to\n * @param indexes - Array of PocketBase index SQL statements\n * @returns The schema with index metadata attached\n *\n * @example\n * // Define indexes for a user schema\n * const UserSchema = withIndexes(\n * withPermissions(\n * z.object({ name: z.string(), email: z.string().email() }),\n * userPermissions\n * ),\n * [\n * 'CREATE UNIQUE INDEX idx_users_email ON users (email)',\n * 'CREATE INDEX idx_users_name ON users (name)'\n * ]\n * );\n *\n * @example\n * // Single index\n * const ProjectSchema = withIndexes(\n * ProjectDatabaseSchema,\n * ['CREATE INDEX idx_projects_status ON projects (status)']\n * );\n */\nexport function withIndexes<T extends z.ZodTypeAny>(schema: T, indexes: string[]): T {\n // Extract existing metadata if present\n let existingMetadata: any = {};\n\n if (schema.description) {\n try {\n existingMetadata = JSON.parse(schema.description);\n } catch {\n // If description is not JSON, ignore it\n }\n }\n\n // Merge indexes with existing metadata\n const metadata = {\n ...existingMetadata,\n indexes,\n };\n\n // Attach metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Configuration options for defining a collection\n */\nexport interface CollectionConfig {\n /**\n * The name of the PocketBase collection\n * This will be used when generating migrations\n */\n collectionName: string;\n\n /**\n * The Zod schema definition for the collection\n */\n schema: z.ZodObject<any>;\n\n /**\n * Optional permission configuration\n * Can be a template-based config or custom permission rules\n */\n permissions?: PermissionTemplateConfig | PermissionSchema;\n\n /**\n * Optional array of index SQL statements\n * Example: ['CREATE UNIQUE INDEX idx_users_email ON users (email)']\n */\n indexes?: string[];\n\n /**\n * Optional collection type\n * - \"base\": Standard collection (default)\n * - \"auth\": Authentication collection with system auth fields\n *\n * If not specified, the type will be auto-detected based on field presence\n * (collections with both email and password fields are detected as auth)\n */\n type?: \"base\" | \"auth\";\n\n /**\n * Future extensibility - additional options can be added here\n */\n [key: string]: unknown;\n}\n\n/**\n * High-level wrapper for defining a PocketBase collection with all metadata\n *\n * This is the recommended way to define collections as it provides a single\n * entry point for collection name, schema, permissions, indexes, and future features.\n *\n * @param config - Collection configuration object\n * @returns The schema with all metadata attached\n *\n * @example\n * // Recommended: Use default export for clarity\n * const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n * export default PostCollection;\n *\n * @example\n * // Also supported: Named export (backward compatible)\n * export const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n *\n * @example\n * // Collection with permissions and indexes\n * export const UserSchema = defineCollection({\n * collectionName: \"users\",\n * schema: z.object({\n * name: z.string(),\n * email: z.string().email(),\n * }),\n * permissions: {\n * listRule: \"id = @request.auth.id\",\n * viewRule: \"id = @request.auth.id\",\n * createRule: \"\",\n * updateRule: \"id = @request.auth.id\",\n * deleteRule: \"id = @request.auth.id\",\n * },\n * indexes: [\n * \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n * ],\n * });\n *\n * @example\n * // Collection with template and custom rule overrides\n * export const ProjectSchema = defineCollection({\n * collectionName: \"projects\",\n * schema: z.object({\n * title: z.string(),\n * owner: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"owner\",\n * customRules: {\n * listRule: '@request.auth.id != \"\"',\n * },\n * },\n * });\n */\nexport function defineCollection(config: CollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, permissions, indexes, type, ...futureOptions } = config;\n\n // Build metadata object\n const metadata: any = {\n collectionName,\n };\n\n // Add type if provided\n if (type) {\n metadata.type = type;\n }\n\n // Add permissions if provided\n if (permissions) {\n metadata.permissions = permissions;\n }\n\n // Add indexes if provided\n if (indexes) {\n metadata.indexes = indexes;\n }\n\n // Add any future options\n if (Object.keys(futureOptions).length > 0) {\n Object.assign(metadata, futureOptions);\n }\n\n // Attach all metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as z.ZodObject<any>;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Field Metadata System\n// ============================================================================\n\n/**\n * Internal marker for field metadata\n * Used by the migration generator to detect explicit field type definitions\n */\nexport const FIELD_METADATA_KEY = \"__pocketbase_field__\";\n\n/**\n * PocketBase field types\n */\nexport type PocketBaseFieldType =\n | \"text\"\n | \"email\"\n | \"url\"\n | \"editor\"\n | \"number\"\n | \"bool\"\n | \"date\"\n | \"autodate\"\n | \"select\"\n | \"relation\"\n | \"file\"\n | \"json\"\n | \"geoPoint\"\n | \"password\";\n\n/**\n * Field metadata structure embedded in Zod schema descriptions\n */\nexport interface FieldMetadata {\n type: PocketBaseFieldType;\n options?: Record<string, any>;\n}\n\n/**\n * Extracts field metadata from a Zod type's description\n * Used by the migration generator to detect explicit field type definitions\n *\n * @param description - The Zod type's description string\n * @returns Field metadata if present, null otherwise\n *\n * @example\n * const schema = TextField({ min: 1, max: 100 });\n * const metadata = extractFieldMetadata(schema.description);\n * // Returns: { type: \"text\", options: { min: 1, max: 100 } }\n */\nexport function extractFieldMetadata(description: string | undefined): FieldMetadata | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[FIELD_METADATA_KEY]) {\n return parsed[FIELD_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n// ============================================================================\n// Field Options Interfaces\n// ============================================================================\n\n/**\n * Text field configuration options\n */\nexport interface TextFieldOptions {\n /**\n * Minimum length constraint\n */\n min?: number;\n\n /**\n * Maximum length constraint\n */\n max?: number;\n\n /**\n * Pattern constraint (regex)\n */\n pattern?: RegExp | string;\n\n /**\n * Auto-generate pattern for automatic value generation\n * Example: \"[A-Z]{3}-[0-9]{6}\" generates values like \"ABC-123456\"\n */\n autogeneratePattern?: string;\n}\n\n/**\n * Number field configuration options\n */\nexport interface NumberFieldOptions {\n /**\n * Minimum value constraint\n */\n min?: number;\n\n /**\n * Maximum value constraint\n */\n max?: number;\n\n /**\n * Whether to disallow decimal values (integers only)\n */\n noDecimal?: boolean;\n\n /**\n * Whether the field is required\n * @default false\n *\n * Note: In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you want to allow zero values (e.g., for progress: 0-100), keep this as `false`.\n * Set to `true` only if you want to enforce non-zero values.\n */\n required?: boolean;\n}\n\n/**\n * Date field configuration options\n */\nexport interface DateFieldOptions {\n /**\n * Minimum date constraint\n */\n min?: Date | string;\n\n /**\n * Maximum date constraint\n */\n max?: Date | string;\n}\n\n/**\n * Autodate field configuration options\n */\nexport interface AutodateFieldOptions {\n /**\n * Set date automatically on record creation\n * @default false\n */\n onCreate?: boolean;\n\n /**\n * Update date automatically on record update\n * @default false\n */\n onUpdate?: boolean;\n}\n\n/**\n * Select field configuration options\n */\nexport interface SelectFieldOptions {\n /**\n * Maximum number of selections allowed\n * If > 1, enables multiple selection\n * @default 1\n */\n maxSelect?: number;\n}\n\ntype EnumFromArray<T extends readonly [string, ...string[]]> = z.ZodEnum<z.core.util.ToEnum<T[number]>>;\n\n/**\n * Human-friendly byte size input.\n *\n * - Use a number for raw bytes (e.g. `5242880`)\n * - Use a string with unit suffix for kibibytes/mebibytes/gibibytes (e.g. `\"5M\"`, `\"1G\"`)\n *\n * Supported suffixes: `K`, `M`, `G` (case-insensitive).\n */\nexport type ByteSize = number | `${number}${\"K\" | \"M\" | \"G\" | \"k\" | \"m\" | \"g\"}`;\n\n/**\n * File field configuration options\n */\nexport interface FileFieldOptions {\n /**\n * Allowed MIME types\n * Example: [\"image/*\", \"application/pdf\"]\n */\n mimeTypes?: string[];\n\n /**\n * Maximum file size.\n *\n * - Provide a number for raw bytes\n * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n *\n * Max allowed is `8G`.\n *\n * @example\n * maxSize: 5242880\n * maxSize: \"5M\"\n * maxSize: \"1G\"\n */\n maxSize?: ByteSize;\n\n /**\n * Thumbnail sizes to generate\n * Example: [\"100x100\", \"200x200\"]\n * Set to null to explicitly disable thumbnails\n */\n thumbs?: string[];\n\n /**\n * Whether the file is protected (requires auth to access)\n * @default false\n */\n protected?: boolean;\n}\n\n/**\n * Multiple files field configuration options\n */\nexport interface FilesFieldOptions extends FileFieldOptions {\n /**\n * Minimum number of files required\n */\n minSelect?: number;\n\n /**\n * Maximum number of files allowed\n */\n maxSelect?: number;\n}\n\nconst MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024; // 8G\n\nfunction parseByteSizeToBytes(value: ByteSize, context: string): number {\n let bytes: number;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(`${context}: maxSize must be a finite number of bytes`);\n }\n bytes = Math.round(value);\n } else {\n const trimmed = value.trim();\n const match = /^(\\d+(?:\\.\\d+)?)\\s*([KMG])$/i.exec(trimmed);\n if (!match) {\n throw new Error(`${context}: maxSize string must be like \"10K\", \"5M\", or \"1G\" (case-insensitive)`);\n }\n\n const amount = Number(match[1]);\n const unit = match[2].toUpperCase() as \"K\" | \"M\" | \"G\";\n\n if (!Number.isFinite(amount)) {\n throw new Error(`${context}: maxSize must be a valid number`);\n }\n\n const multiplier = unit === \"K\" ? 1024 : unit === \"M\" ? 1024 * 1024 : 1024 * 1024 * 1024;\n bytes = Math.round(amount * multiplier);\n }\n\n if (bytes < 0) {\n throw new Error(`${context}: maxSize must be >= 0`);\n }\n\n if (bytes > MAX_FILE_SIZE_BYTES) {\n throw new Error(`${context}: maxSize cannot exceed 8G (${MAX_FILE_SIZE_BYTES} bytes)`);\n }\n\n return bytes;\n}\n\nfunction normalizeFileFieldOptions(\n options: FileFieldOptions | undefined,\n context: string\n): FileFieldOptions | undefined {\n if (!options) return options;\n if (options.maxSize === undefined) return options;\n\n return {\n ...options,\n // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.\n maxSize: parseByteSizeToBytes(options.maxSize, context),\n };\n}\n\n// ============================================================================\n// Field Helper Functions\n// ============================================================================\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n *\n * @returns Zod boolean schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * active: BoolField(),\n * featured: BoolField().optional(),\n * });\n */\nexport function BoolField(): z.ZodBoolean {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"bool\" as const,\n },\n };\n\n return z.boolean().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a number field schema with optional constraints\n * Maps to PocketBase 'number' field type\n *\n * @param options - Optional constraints for the number field\n * @returns Zod number schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * price: NumberField({ min: 0 }),\n * quantity: NumberField({ min: 0, noDecimal: true }),\n * rating: NumberField({ min: 0, max: 5 }),\n * progress: NumberField({ min: 0, max: 100 }), // required defaults to false, allowing zero\n * score: NumberField({ min: 1, max: 10, required: true }), // requires non-zero value\n * });\n *\n * @remarks\n * By default, number fields are not required (`required: false`), which allows zero values.\n * In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you set `min: 0` and want to allow zero, keep `required: false` (the default).\n */\nexport function NumberField(options?: NumberFieldOptions): z.ZodNumber {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"NumberField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.number();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"number\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a text field schema with optional constraints\n * Maps to PocketBase 'text' field type\n *\n * @param options - Optional constraints for the text field\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * name: TextField({ min: 1, max: 200 }),\n * sku: TextField({ autogeneratePattern: \"[A-Z]{3}-[0-9]{6}\" }),\n * description: TextField({ max: 1000 }),\n * });\n */\nexport function TextField(options?: TextFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"TextField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.string();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n if (options?.pattern !== undefined) {\n const pattern = options.pattern instanceof RegExp ? options.pattern : new RegExp(options.pattern);\n schema = schema.regex(pattern);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"text\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n *\n * @returns Zod string schema with email validation and PocketBase metadata\n *\n * @example\n * const UserSchema = z.object({\n * email: EmailField(),\n * alternateEmail: EmailField().optional(),\n * });\n */\nexport function EmailField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"email\" as const,\n },\n };\n\n return z.string().email().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n *\n * @returns Zod string schema with URL validation and PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * website: URLField(),\n * documentation: URLField().optional(),\n * });\n */\nexport function URLField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"url\" as const,\n },\n };\n\n return z.string().url().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a rich text editor field schema\n * Maps to PocketBase 'editor' field type\n *\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * content: EditorField(),\n * summary: EditorField().optional(),\n * });\n */\nexport function EditorField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"editor\" as const,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a date field schema with optional constraints\n * Maps to PocketBase 'date' field type\n *\n * @param options - Optional date constraints\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const EventSchema = z.object({\n * startDate: DateField(),\n * endDate: DateField({ min: new Date('2024-01-01') }),\n * releaseDate: DateField().optional(),\n * });\n */\nexport function DateField(options?: DateFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n const minDate = typeof options.min === \"string\" ? new Date(options.min) : options.min;\n const maxDate = typeof options.max === \"string\" ? new Date(options.max) : options.max;\n if (minDate > maxDate) {\n throw new Error(\"DateField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"date\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an autodate field schema with automatic timestamp management\n * Maps to PocketBase 'autodate' field type\n *\n * @param options - Optional autodate configuration\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * createdAt: AutodateField({ onCreate: true }),\n * updatedAt: AutodateField({ onUpdate: true }),\n * publishedAt: AutodateField({ onCreate: true, onUpdate: false }),\n * });\n */\nexport function AutodateField(options?: AutodateFieldOptions): z.ZodString {\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"autodate\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod enum or array schema with PocketBase metadata\n *\n * @example\n * // Single select\n * const PostSchema = z.object({\n * status: SelectField([\"draft\", \"published\", \"archived\"]),\n * });\n *\n * @example\n * // Multiple select\n * const ProductSchema = z.object({\n * categories: SelectField([\"electronics\", \"clothing\", \"food\"], { maxSelect: 3 }),\n * });\n */\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): EnumFromArray<T> | z.ZodArray<EnumFromArray<T>> {\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return MultiSelectField(values, options);\n }\n\n return SingleSelectField(values);\n}\n\n/**\n * Creates a single select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect=1\n *\n * @param values - Array of allowed string values\n * @returns Zod enum schema with PocketBase metadata\n */\nexport function SingleSelectField<const T extends readonly [string, ...string[]]>(values: T): EnumFromArray<T> {\n const enumSchema = z.enum(values);\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: 1,\n },\n },\n };\n\n return enumSchema.describe(JSON.stringify(metadata)) as EnumFromArray<T>;\n}\n\n/**\n * Creates a multiple select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect>1\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod array schema with PocketBase metadata\n */\nexport function MultiSelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodArray<EnumFromArray<T>> {\n const enumSchema = z.enum(values);\n const maxSelect = options?.maxSelect ?? 999;\n\n if (maxSelect <= 1) {\n throw new Error(\"MultiSelectField: maxSelect must be greater than 1\");\n }\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect,\n },\n },\n };\n\n return z.array(enumSchema).describe(JSON.stringify(metadata)) as z.ZodArray<EnumFromArray<T>>;\n}\n\n/**\n * Creates a single file field schema\n * Maps to PocketBase 'file' field type with maxSelect=1\n *\n * @param options - Optional file constraints\n * @returns Zod schema that accepts File on input and returns string when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File objects\n * - When reading from PocketBase: returns string (filename)\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<string, File | string> {\n // Accept File for input (when creating/updating) or string (when reading from DB)\n // Output is always string (as returned by PocketBase)\n const schema = z.preprocess((val) => {\n // If it's a File, return its name (or empty string if no name)\n // If it's already a string (from DB), return as-is\n return val instanceof File ? val.name || \"\" : val;\n }, z.string()) as z.ZodType<string, File | string>;\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FileField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple files field schema\n * Maps to PocketBase 'file' field type with maxSelect>1\n *\n * @param options - Optional file constraints\n * @returns Zod array schema that accepts File[] on input and returns string[] when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File[]\n * - When reading from PocketBase: returns string[] (filenames)\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodType<string[], (File | string)[]> {\n // Validate options\n if (options?.minSelect !== undefined && options?.maxSelect !== undefined) {\n if (options.minSelect > options.maxSelect) {\n throw new Error(\"FilesField: minSelect cannot be greater than maxSelect\");\n }\n }\n\n // Accept File[] for input (when creating/updating) or string[] (when reading from DB)\n // Output is always string[] (as returned by PocketBase)\n let baseArraySchema = z.array(z.string());\n\n // Apply Zod validations first\n if (options?.minSelect !== undefined) {\n baseArraySchema = baseArraySchema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n baseArraySchema = baseArraySchema.max(options.maxSelect);\n }\n\n const schema = z.preprocess((val) => {\n // Handle array of Files or strings\n if (Array.isArray(val)) {\n return val.map((item) => (item instanceof File ? item.name || \"\" : item));\n }\n return val;\n }, baseArraySchema);\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FilesField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata)) as z.ZodType<string[], (File | string)[]>;\n}\n\n/**\n * Creates a JSON field schema with optional inner schema validation\n * Maps to PocketBase 'json' field type\n *\n * @param schema - Optional Zod schema for the JSON structure\n * @returns Zod schema with PocketBase metadata\n *\n * @example\n * // Any JSON\n * const ProductSchema = z.object({\n * metadata: JSONField(),\n * });\n *\n * @example\n * // Typed JSON\n * const ProductSchema = z.object({\n * settings: JSONField(z.object({\n * theme: z.string(),\n * notifications: z.boolean(),\n * })),\n * });\n */\nexport function JSONField<T extends z.ZodTypeAny>(schema?: T): T | z.ZodRecord<z.ZodString, z.ZodAny> {\n const baseSchema = schema ?? z.record(z.string(), z.any());\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"json\" as const,\n },\n };\n\n return baseSchema.describe(JSON.stringify(metadata)) as T | z.ZodRecord<z.ZodString, z.ZodAny>;\n}\n\n/**\n * Creates a geographic point field schema\n * Maps to PocketBase 'geoPoint' field type\n *\n * @returns Zod object schema with lon/lat fields and PocketBase metadata\n *\n * @example\n * const LocationSchema = z.object({\n * coordinates: GeoPointField(),\n * homeLocation: GeoPointField().optional(),\n * });\n */\nexport function GeoPointField(): z.ZodObject<{\n lon: z.ZodNumber;\n lat: z.ZodNumber;\n}> {\n const schema = z.object({\n lon: z.number(),\n lat: z.number(),\n });\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"geoPoint\" as const,\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n","import type { PermissionSchema, PermissionTemplateConfig, RuleExpression } from \"../utils/permissions\";\n\n/**\n * Predefined permission templates for common access control patterns\n */\nexport const PermissionTemplates = {\n /**\n * Public access - anyone can perform all operations\n */\n public: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: \"\",\n updateRule: \"\",\n deleteRule: \"\",\n }),\n\n /**\n * Authenticated users only - requires valid authentication for all operations\n */\n authenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Owner-only access - users can only manage their own records\n * @param ownerField - Name of the relation field pointing to user (default: 'User')\n */\n ownerOnly: (ownerField: string = \"User\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n viewRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n createRule: '@request.auth.id != \"\"',\n updateRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n deleteRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n }),\n\n /**\n * Admin/superuser only access\n * Assumes a 'role' field exists with 'admin' value\n * @param roleField - Name of the role field (default: 'role')\n */\n adminOnly: (roleField: string = \"role\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n viewRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n createRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n updateRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n deleteRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n }),\n\n /**\n * Public read, authenticated write\n * Anyone can list/view, but only authenticated users can create/update/delete\n */\n readPublic: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Locked access - only superusers can perform operations\n * All rules are set to null (locked)\n */\n locked: (): PermissionSchema => ({\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n\n /**\n * Read-only authenticated - authenticated users can read, no write access\n */\n readOnlyAuthenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n};\n\n/**\n * Resolve template configuration to concrete permission schema\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema with all rules defined\n */\nexport function resolveTemplate(config: PermissionTemplateConfig): PermissionSchema {\n let baseRules: PermissionSchema;\n\n switch (config.template) {\n case \"public\":\n baseRules = PermissionTemplates.public();\n break;\n case \"authenticated\":\n baseRules = PermissionTemplates.authenticated();\n break;\n case \"owner-only\":\n baseRules = PermissionTemplates.ownerOnly(config.ownerField);\n break;\n case \"admin-only\":\n baseRules = PermissionTemplates.adminOnly(config.roleField);\n break;\n case \"read-public\":\n baseRules = PermissionTemplates.readPublic();\n break;\n case \"custom\":\n baseRules = {};\n break;\n default: {\n // Exhaustive check - TypeScript will error if we miss a template type\n const _exhaustive: never = config.template;\n throw new Error(`Unknown template type: ${_exhaustive}`);\n }\n }\n\n // Merge with custom rules if provided (custom rules override template rules)\n return {\n ...baseRules,\n ...config.customRules,\n };\n}\n\n/**\n * Check if a configuration is a template config or direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a template configuration\n */\nexport function isTemplateConfig(\n config: PermissionTemplateConfig | PermissionSchema\n): config is PermissionTemplateConfig {\n return \"template\" in config;\n}\n\n/**\n * Check if a configuration is a direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a direct permission schema\n */\nexport function isPermissionSchema(config: PermissionTemplateConfig | PermissionSchema): config is PermissionSchema {\n return (\n \"listRule\" in config ||\n \"viewRule\" in config ||\n \"createRule\" in config ||\n \"updateRule\" in config ||\n \"deleteRule\" in config ||\n \"manageRule\" in config\n );\n}\n\n/**\n * Validation result for permission configuration\n */\nexport interface PermissionValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Validate a permission configuration\n * @param config - Permission configuration to validate\n * @param isAuthCollection - Whether this is for an auth collection\n * @returns Validation result\n */\nexport function validatePermissionConfig(\n config: PermissionTemplateConfig | PermissionSchema,\n isAuthCollection: boolean = false\n): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Resolve to permission schema\n let permissions: PermissionSchema;\n if (isTemplateConfig(config)) {\n // Validate template config\n if (config.template === \"owner-only\" && !config.ownerField) {\n result.warnings.push(\"owner-only template without ownerField specified - using default 'User'\");\n }\n if (config.template === \"admin-only\" && !config.roleField) {\n result.warnings.push(\"admin-only template without roleField specified - using default 'role'\");\n }\n permissions = resolveTemplate(config);\n } else {\n permissions = config;\n }\n\n // Validate manageRule usage\n if (permissions.manageRule !== undefined && !isAuthCollection) {\n result.errors.push(\"manageRule is only valid for auth collections\");\n result.valid = false;\n }\n\n // Validate rule expressions\n const ruleTypes: (keyof PermissionSchema)[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\"];\n if (isAuthCollection) {\n ruleTypes.push(\"manageRule\");\n }\n\n for (const ruleType of ruleTypes) {\n const rule = permissions[ruleType];\n if (rule !== undefined && rule !== null && rule !== \"\") {\n const ruleValidation = validateRuleExpression(rule);\n if (!ruleValidation.valid) {\n result.errors.push(`${ruleType}: ${ruleValidation.errors.join(\", \")}`);\n result.valid = false;\n }\n result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));\n }\n }\n\n return result;\n}\n\n/**\n * Validate a single rule expression for basic syntax\n * @param expression - Rule expression to validate\n * @returns Validation result\n */\nexport function validateRuleExpression(expression: RuleExpression): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Null and empty string are always valid\n if (expression === null || expression === \"\") {\n return result;\n }\n\n // Check for balanced parentheses\n let parenCount = 0;\n for (const char of expression) {\n if (char === \"(\") parenCount++;\n if (char === \")\") parenCount--;\n if (parenCount < 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n return result;\n }\n }\n if (parenCount !== 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n }\n\n // Check for common mistakes\n if (expression.includes(\"==\")) {\n result.warnings.push(\"Use '=' instead of '==' for equality comparison\");\n }\n\n // Check for valid @request references\n const requestRefs = expression.match(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];\n for (const ref of requestRefs) {\n const isValid =\n ref.startsWith(\"@request.auth.\") ||\n ref === \"@request.method\" ||\n ref === \"@request.context\" ||\n ref.startsWith(\"@request.body.\") ||\n ref.startsWith(\"@request.query.\") ||\n ref.startsWith(\"@request.headers.\");\n\n if (!isValid) {\n result.errors.push(`Invalid @request reference: '${ref}'`);\n result.valid = false;\n }\n }\n\n return result;\n}\n\n/**\n * Create a custom permission schema with type safety\n * @param permissions - Partial permission schema\n * @returns Complete permission schema with null defaults\n */\nexport function createPermissions(permissions: Partial<PermissionSchema>): PermissionSchema {\n return {\n listRule: permissions.listRule ?? null,\n viewRule: permissions.viewRule ?? null,\n createRule: permissions.createRule ?? null,\n updateRule: permissions.updateRule ?? null,\n deleteRule: permissions.deleteRule ?? null,\n manageRule: permissions.manageRule ?? null,\n };\n}\n\n/**\n * Merge multiple permission schemas, with later schemas taking precedence\n * @param schemas - Permission schemas to merge\n * @returns Merged permission schema\n */\nexport function mergePermissions(...schemas: Partial<PermissionSchema>[]): PermissionSchema {\n const merged: PermissionSchema = {\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n manageRule: null,\n };\n\n for (const schema of schemas) {\n if (schema.listRule !== undefined) merged.listRule = schema.listRule;\n if (schema.viewRule !== undefined) merged.viewRule = schema.viewRule;\n if (schema.createRule !== undefined) merged.createRule = schema.createRule;\n if (schema.updateRule !== undefined) merged.updateRule = schema.updateRule;\n if (schema.deleteRule !== undefined) merged.deleteRule = schema.deleteRule;\n if (schema.manageRule !== undefined) merged.manageRule = schema.manageRule;\n }\n\n return merged;\n}\n"]}
1
+ {"version":3,"sources":["../src/enums.ts","../src/mutator/baseMutator.ts","../src/schema/base.ts","../src/schema/fields.ts","../src/schema/view.ts","../src/utils/permission-templates.ts"],"names":["z","baseSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\n\nexport const StatusEnum = z.enum([\n \"draft\", // Initial proposal stage (RequestDraft, ProjectDraft)\n \"active\", // Work in progress\n \"complete\", // Fully completed project\n \"fail\", // Failed project at any stage\n]);\nexport type StatusEnumType = z.infer<typeof StatusEnum>;\n","import PocketBase, {\n RecordService,\n type ListResult,\n type RecordListOptions,\n type RecordModel,\n type RecordOptions,\n type RecordSubscribeOptions,\n type RecordSubscription,\n type UnsubscribeFunc,\n} from \"pocketbase\";\n\nexport interface MutatorOptions {\n expand: string[];\n filter: string[];\n sort: string[];\n}\n\n// Helper to infer the type of the expanded resource\nexport type Expanded<\n T extends RecordModel,\n E extends keyof NonNullable<T[\"expand\"]>\n> = [E] extends [never]\n ? T\n : T & {\n expand: Required<\n Pick<\n NonNullable<T[\"expand\"]>,\n E extends keyof NonNullable<T[\"expand\"]> ? E : never\n >\n >;\n };\n\n// T represents the output model type that extends RecordModel\n// InputType represents the input type for creation operations\nexport abstract class BaseMutator<T extends RecordModel, InputType> {\n protected pb: PocketBase;\n\n // Define a default property that subclasses will override\n protected options: MutatorOptions = {\n expand: [],\n filter: [],\n sort: [],\n };\n\n constructor(pb: PocketBase, options?: Partial<MutatorOptions>) {\n this.pb = pb;\n\n // Initialize with default options first\n this.initializeOptions();\n if (options) {\n this.overrideOptions(options);\n }\n }\n\n private initializeOptions(): void {\n this.options = this.setDefaults();\n }\n /**\n * Initialize options with class-specific defaults\n * Subclasses should override this instead of directly setting options\n */\n protected setDefaults(): MutatorOptions {\n return {\n expand: [],\n filter: [],\n sort: [],\n };\n }\n\n /**\n * Merge provided options with current options\n */\n protected overrideOptions(newOptions: Partial<MutatorOptions>): void {\n if (newOptions.expand !== undefined) {\n this.options.expand = newOptions.expand;\n }\n if (newOptions.filter !== undefined) {\n this.options.filter = newOptions.filter;\n }\n if (newOptions.sort !== undefined) {\n this.options.sort = newOptions.sort;\n }\n }\n\n /**\n * Get the collection instance\n */\n protected abstract getCollection(): RecordService<T>;\n\n toSnakeCase(str: string): string {\n return str\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_|_$/g, \"\");\n }\n\n /**\n * Create a new entity\n */\n async create<E extends keyof NonNullable<T[\"expand\"]> = never>(\n input: InputType,\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n try {\n const data = await this.validateInput(input);\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n\n const record = await this.entityCreate(data, options);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Update an existing entity\n */\n async update<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n input: Partial<T>,\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n try {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n\n const record = await this.entityUpdate(id, input, options);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Create or update entity (upsert)\n */\n async upsert<E extends keyof NonNullable<T[\"expand\"]> = never>(\n input: InputType & { id?: string },\n expand?: E | E[]\n ): Promise<Expanded<T, E>> {\n if (input?.id) {\n return await this.update(input.id, input as Partial<T>, expand);\n }\n\n // Implementations should override this method if they need\n // more specific upsert logic like checking for existing entities\n return await this.create(input, expand);\n }\n\n /**\n * Get entity by ID\n */\n async getById<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n expand?: E | E[]\n ): Promise<Expanded<T, E> | null> {\n try {\n const record = await this.entityGetById(id, expand as string | string[]);\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.handleError(error, { allowNotFound: true });\n }\n }\n\n /**\n * Get first entity by filter\n */\n async getFirstByFilter<E extends keyof NonNullable<T[\"expand\"]> = never>(\n filter: string | string[],\n expand?: E | E[],\n sort?: string\n ): Promise<Expanded<T, E> | null> {\n try {\n const record = await this.entityGetFirstByFilter(\n filter,\n expand as string | string[],\n sort\n );\n return (await this.processRecord(record)) as Expanded<T, E>;\n } catch (error) {\n return this.handleError(error, { allowNotFound: true });\n }\n }\n\n /**\n * Get list of entities\n */\n async getList<E extends keyof NonNullable<T[\"expand\"]> = never>(\n page = 1,\n perPage = 100,\n filter?: string | string[],\n sort?: string,\n expand?: E | E[]\n ): Promise<ListResult<Expanded<T, E>>> {\n try {\n const result = await this.entityGetList(\n page,\n perPage,\n filter,\n sort,\n expand as string | string[]\n );\n // processListResult expects ListResult<T>, but we are returning ListResult<Expanded<T, E>>\n // processRecord needs to handle T.\n // We cast the result of processListResult.\n const processed = await this.processListResult(result);\n return processed as unknown as ListResult<Expanded<T, E>>;\n } catch (error) {\n return this.errorWrapper(error);\n }\n }\n\n /**\n * Delete entity by ID\n */\n async delete(id: string): Promise<boolean> {\n try {\n return await this.entityDelete(id);\n } catch (error) {\n return this.handleError(error, { returnValue: false });\n }\n }\n\n /**\n * Process a single record before returning it\n * Can be overridden to handle special cases like mapped entities\n */\n protected async processRecord(record: T): Promise<T> {\n return record;\n }\n\n /**\n * Process a list result before returning it\n * Can be overridden to handle special cases like mapped entities\n */\n protected async processListResult(result: ListResult<T>): Promise<ListResult<T>> {\n // Process each item in the list\n const processedItems = await Promise.all(\n result.items.map((item) => this.processRecord(item))\n );\n\n return {\n ...result,\n items: processedItems,\n };\n }\n\n /**\n * Prepare expand parameter\n * Combines default expands with provided expands\n */\n protected prepareExpand(expand?: string | string[]): string | undefined {\n // Handle empty defaults case\n if (!this.options.expand.length && !expand) {\n return undefined;\n }\n\n // Convert all inputs to arrays for easy processing\n let expandArray: string[] = [...this.options.expand];\n\n if (expand) {\n // If expand is a string, split it and add the parts\n if (typeof expand === \"string\") {\n expandArray = expandArray.concat(expand.split(\",\").map((e) => e.trim()));\n }\n // If expand is already an array, concatenate\n else {\n expandArray = expandArray.concat(expand);\n }\n }\n\n // Filter out duplicates, empty strings, and undefined values\n const uniqueExpands = [...new Set(expandArray)].filter(\n (e) => e !== \"\" && e !== undefined\n );\n\n // If no valid expands, return undefined\n if (!uniqueExpands.length) {\n return undefined;\n }\n\n // Join with comma and space\n return uniqueExpands.join(\",\");\n }\n\n /**\n * Prepare filter parameter\n * Combines default filters with provided filters\n */\n protected prepareFilter(filter?: string | string[]): string | undefined {\n // Handle empty case\n if (!this.options.filter.length && !filter) {\n return undefined;\n }\n\n // Convert all inputs to arrays for easy processing\n let filterArray: string[] = [...this.options.filter];\n\n if (filter) {\n // If filter is a string, add it as is (it might contain && already)\n if (typeof filter === \"string\") {\n if (filter) filterArray.push(filter);\n }\n // If filter is an array, concatenate\n else {\n filterArray = filterArray.concat(filter);\n }\n }\n\n // Filter out empty strings and undefined values\n const validFilters = filterArray.filter((f) => f !== \"\" && f !== undefined);\n\n // If no valid filters, return undefined\n if (!validFilters.length) {\n return undefined;\n }\n\n // Join with AND operator\n return validFilters.join(\"&&\");\n }\n\n /**\n * Prepare sort parameter\n * Uses provided sort or falls back to default sort\n */\n protected prepareSort(sort?: string): string | undefined {\n // If explicit sort is provided and not empty, use it (overriding defaults)\n if (sort && sort !== \"\") {\n return sort;\n }\n\n // If no explicit sort but we have defaults\n if (this.options.sort.length) {\n // Filter out empty and undefined values\n const validSorts = this.options.sort.filter(\n (s) => s !== \"\" && s !== undefined\n );\n\n // If we have valid sort items after filtering\n if (validSorts.length) {\n return validSorts.join(\",\");\n }\n }\n\n // No sort specified\n return undefined;\n }\n\n /**\n * Perform the actual create operation\n */\n protected async entityCreate(data: InputType, options?: RecordOptions): Promise<T> {\n return await this.getCollection().create(data as Record<string, any>, options);\n }\n\n /**\n * Perform the actual update operation\n */\n protected async entityUpdate(id: string, data: Partial<T>, options?: RecordOptions): Promise<T> {\n return await this.getCollection().update(id, data, options);\n }\n\n /**\n * Perform the actual getById operation\n */\n protected async entityGetById(\n id: string,\n expand?: string | string[]\n ): Promise<T> {\n const finalExpand = this.prepareExpand(expand);\n const options: RecordOptions = finalExpand ? { expand: finalExpand } : {};\n return await this.getCollection().getOne(id, options);\n }\n\n /**\n * Perform the actual getFirstByFilter operation\n */\n protected async entityGetFirstByFilter(\n filter: string | string[],\n expand?: string | string[],\n sort?: string\n ): Promise<T> {\n const finalFilter = this.prepareFilter(filter);\n const finalExpand = this.prepareExpand(expand);\n const finalSort = this.prepareSort(sort);\n\n const options: RecordListOptions = {};\n if (finalExpand) options.expand = finalExpand;\n if (finalSort) options.sort = finalSort;\n\n return await this.getCollection().getFirstListItem(finalFilter || \"\", options);\n }\n\n /**\n * Perform the actual getList operation\n * Returns a list result with items of type T\n */\n protected async entityGetList(\n page: number,\n perPage: number,\n filter?: string | string[],\n sort?: string,\n expand?: string | string[]\n ): Promise<ListResult<T>> {\n const finalFilter = this.prepareFilter(filter);\n const finalExpand = this.prepareExpand(expand);\n const finalSort = this.prepareSort(sort);\n\n const options: RecordListOptions = {};\n if (finalFilter) options.filter = finalFilter;\n if (finalExpand) options.expand = finalExpand;\n if (finalSort) options.sort = finalSort;\n\n return await this.getCollection().getList(page, perPage, options);\n }\n\n /**\n * Perform the actual delete operation\n */\n protected async entityDelete(id: string): Promise<boolean> {\n await this.getCollection().delete(id);\n return true;\n }\n\n /**\n * Error handler for common errors\n * @param error The error to handle\n * @param options Handler options\n * @returns The value to return if the error is handled, or throws if not handled\n */\n protected handleError<R>(\n error: any,\n options: {\n allowNotFound?: boolean;\n returnValue?: R;\n logError?: boolean;\n } = { logError: true }\n ): R {\n const { allowNotFound = false, returnValue, logError = true } = options;\n\n // Log the error if requested\n if (logError) {\n console.error(`Error in ${this.constructor.name}:`, error);\n }\n\n // Handle 404 errors if allowed\n if (allowNotFound && this.isNotFoundError(error)) {\n return null as R;\n }\n\n // Return specified value or rethrow\n if (returnValue !== undefined) {\n return returnValue;\n }\n\n // Rethrow the error\n throw error;\n }\n\n /**\n * Check if an error is a \"not found\" error\n */\n protected isNotFoundError(error: any): boolean {\n return (\n error instanceof Error &&\n (error.message.includes(\"404\") ||\n error.message.toLowerCase().includes(\"not found\"))\n );\n }\n\n /**\n * Standard error handling wrapper (legacy method, consider using handleError instead)\n */\n protected errorWrapper(error: any): never {\n console.error(`Error in ${this.constructor.name}:`, error);\n throw error;\n }\n\n /**\n * Validate input data before creating/updating\n * Should be implemented by child classes\n */\n protected abstract validateInput(input: InputType): Promise<InputType>;\n\n /**\n * Subscribe to changes on a specific record\n * @param id The ID of the record to subscribe to\n * @param callback Function to call when changes occur\n * @param expand Optional expand parameters\n * @returns Promise that resolves to an unsubscribe function\n */\n async subscribeToRecord<E extends keyof NonNullable<T[\"expand\"]> = never>(\n id: string,\n callback: (data: RecordSubscription<Expanded<T, E>>) => void,\n expand?: E | E[]\n ): Promise<UnsubscribeFunc> {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordSubscribeOptions = finalExpand\n ? { expand: finalExpand }\n : {};\n\n return this.getCollection().subscribe(id, callback as any, options);\n }\n\n /**\n * Subscribe to changes on the entire collection\n * @param callback Function to call when changes occur\n * @param expand Optional expand parameters\n * @returns Promise that resolves to an unsubscribe function\n */\n async subscribeToCollection<\n E extends keyof NonNullable<T[\"expand\"]> = never\n >(\n callback: (data: RecordSubscription<Expanded<T, E>>) => void,\n expand?: E | E[]\n ): Promise<UnsubscribeFunc> {\n const finalExpand = this.prepareExpand(expand as string | string[]);\n const options: RecordSubscribeOptions = finalExpand\n ? { expand: finalExpand }\n : {};\n\n return this.getCollection().subscribe(\"*\", callback as any, options);\n }\n\n /**\n * Unsubscribe from a specific record's changes\n * @param id The ID of the record to unsubscribe from\n */\n unsubscribeFromRecord(id: string): void {\n this.getCollection().unsubscribe(id);\n }\n\n /**\n * Unsubscribe from collection-wide changes\n */\n unsubscribeFromCollection(): void {\n this.getCollection().unsubscribe(\"*\");\n }\n\n /**\n * Unsubscribe from all subscriptions in this collection\n */\n unsubscribeAll(): void {\n this.getCollection().unsubscribe();\n }\n}\n","import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n id: z.string().describe(\"unique id\"),\n collectionId: z.string().describe(\"collection id\"),\n collectionName: z.string().describe(\"collection name\"),\n expand: z.record(z.string(), z.any()).describe(\"expandable fields\"),\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Extended base schema with timestamp fields\n * Includes created and updated autodate fields\n */\nexport const baseSchemaWithTimestamps = {\n ...baseSchema,\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Base schema for image file collections\n * Extends base schema with thumbnail URL and image files array\n */\nexport const baseImageFileSchema = {\n ...baseSchema,\n thumbnailURL: z.string().optional(),\n imageFiles: z.array(z.string()),\n};\n\n/**\n * Input schema for image file uploads\n * Used in forms where users upload File objects\n * Requires Node.js 20+ or browser environment with File API\n */\nexport const inputImageFileSchema = {\n imageFiles: z.array(z.instanceof(File)),\n};\n\n/**\n * Helper constant for omitting image files from schemas\n * Used with Zod's .omit() method\n */\nexport const omitImageFilesSchema = {\n imageFiles: true,\n} as const;\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n// Note: Field type helpers are now exported from ./fields.ts with PascalCase names\n// (e.g., TextField, EmailField, JSONField, etc.) to ensure consistent naming.\n\n// ============================================================================\n// Relation Field Helpers - Explicit Relationship Definitions\n// ============================================================================\n\n/**\n * Relation field configuration options\n */\nexport interface RelationConfig {\n /**\n * Target collection name (e.g., 'users', 'posts', 'tags')\n * This is the PocketBase collection that the relation points to\n */\n collection: string;\n\n /**\n * Whether to cascade delete related records when this record is deleted\n * @default false\n */\n cascadeDelete?: boolean;\n\n /**\n * Fields to display in the admin UI\n */\n displayFields?: string[] | null;\n}\n\n/**\n * Multiple relation field configuration options\n */\nexport interface RelationsConfig extends RelationConfig {\n /**\n * Minimum number of relations required\n * @default 0\n */\n minSelect?: number;\n\n /**\n * Maximum number of relations allowed\n * @default 999\n */\n maxSelect?: number;\n}\n\n/**\n * Internal marker for relation metadata\n * Used by the analyzer to detect explicit relation definitions\n */\nconst RELATION_METADATA_KEY = \"__pocketbase_relation__\";\n\n/**\n * Creates a single relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect=1\n *\n * This is the recommended way to define relations - it's explicit and doesn't\n * rely on naming conventions.\n *\n * @param config - Relation configuration with target collection\n * @returns Zod string schema with relation metadata\n *\n * @example\n * // Single relation to users collection\n * const PostSchema = z.object({\n * title: z.string(),\n * author: RelationField({ collection: 'users' }),\n * });\n *\n * @example\n * // Relation with cascade delete\n * const CommentSchema = z.object({\n * content: z.string(),\n * post: RelationField({ collection: 'posts', cascadeDelete: true }),\n * });\n */\nexport function RelationField(config: RelationConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"single\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: 1,\n minSelect: 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect>1\n *\n * This is the recommended way to define multi-relations - it's explicit and\n * doesn't rely on naming conventions.\n *\n * @param config - Relations configuration with target collection and limits\n * @returns Zod array of strings schema with relation metadata\n *\n * @example\n * // Multiple relations to tags collection\n * const PostSchema = z.object({\n * title: z.string(),\n * tags: RelationsField({ collection: 'tags' }),\n * });\n *\n * @example\n * // Relations with min/max constraints\n * const ProjectSchema = z.object({\n * title: z.string(),\n * collaborators: RelationsField({\n * collection: 'users',\n * minSelect: 1,\n * maxSelect: 10,\n * }),\n * });\n */\nexport function RelationsField(config: RelationsConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"multiple\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: config.maxSelect ?? 999,\n minSelect: config.minSelect ?? 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n let schema = z.array(z.string());\n\n // Apply array constraints for Zod validation\n if (config.minSelect !== undefined) {\n schema = schema.min(config.minSelect);\n }\n if (config.maxSelect !== undefined) {\n schema = schema.max(config.maxSelect);\n }\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Extracts relation metadata from a Zod type's description\n * Used internally by the analyzer to detect explicit relation definitions\n *\n * @param description - The Zod type's description string\n * @returns Relation metadata if present, null otherwise\n */\nexport function extractRelationMetadata(description: string | undefined): {\n type: \"single\" | \"multiple\";\n collection: string;\n cascadeDelete: boolean;\n maxSelect: number;\n minSelect: number;\n displayFields?: string[] | null;\n} | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[RELATION_METADATA_KEY]) {\n return parsed[RELATION_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n/**\n * Attach permission metadata to a Zod schema\n *\n * This helper function allows you to define PocketBase API rules alongside your\n * entity schema definitions. The permissions are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach permissions to\n * @param config - Either a PermissionTemplateConfig (for template-based permissions)\n * or a PermissionSchema (for custom permissions)\n * @returns The schema with permission metadata attached\n *\n * @example\n * // Using a template\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * { template: 'owner-only', ownerField: 'User' }\n * );\n *\n * @example\n * // Using custom rules\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string() }),\n * { listRule: '@request.auth.id != \"\"', viewRule: '' }\n * );\n *\n * @example\n * // Using template with custom rule overrides\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * {\n * template: 'owner-only',\n * ownerField: 'User',\n * customRules: { listRule: '@request.auth.id != \"\"' }\n * }\n * );\n */\nexport function withPermissions<T extends z.ZodTypeAny>(\n schema: T,\n config: PermissionTemplateConfig | PermissionSchema\n): T {\n // Create metadata object with permissions config directly\n // The PermissionAnalyzer will handle resolving templates vs direct schemas\n const metadata = {\n permissions: config,\n };\n\n // Attach permission metadata to schema using Zod's describe() method\n // The metadata is serialized as JSON and stored in the schema's description\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Attach index definitions to a Zod schema\n *\n * This helper function allows you to define PocketBase indexes alongside your\n * entity schema definitions. The indexes are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach indexes to\n * @param indexes - Array of PocketBase index SQL statements\n * @returns The schema with index metadata attached\n *\n * @example\n * // Define indexes for a user schema\n * const UserSchema = withIndexes(\n * withPermissions(\n * z.object({ name: z.string(), email: z.string().email() }),\n * userPermissions\n * ),\n * [\n * 'CREATE UNIQUE INDEX idx_users_email ON users (email)',\n * 'CREATE INDEX idx_users_name ON users (name)'\n * ]\n * );\n *\n * @example\n * // Single index\n * const ProjectSchema = withIndexes(\n * ProjectDatabaseSchema,\n * ['CREATE INDEX idx_projects_status ON projects (status)']\n * );\n */\nexport function withIndexes<T extends z.ZodTypeAny>(schema: T, indexes: string[]): T {\n // Extract existing metadata if present\n let existingMetadata: any = {};\n\n if (schema.description) {\n try {\n existingMetadata = JSON.parse(schema.description);\n } catch {\n // If description is not JSON, ignore it\n }\n }\n\n // Merge indexes with existing metadata\n const metadata = {\n ...existingMetadata,\n indexes,\n };\n\n // Attach metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Configuration options for defining a collection\n */\nexport interface CollectionConfig {\n /**\n * The name of the PocketBase collection\n * This will be used when generating migrations\n */\n collectionName: string;\n\n /**\n * The Zod schema definition for the collection\n */\n schema: z.ZodObject<any>;\n\n /**\n * Optional permission configuration\n * Can be a template-based config or custom permission rules\n */\n permissions?: PermissionTemplateConfig | PermissionSchema;\n\n /**\n * Optional array of index SQL statements\n * Example: ['CREATE UNIQUE INDEX idx_users_email ON users (email)']\n */\n indexes?: string[];\n\n /**\n * Optional collection type\n * - \"base\": Standard collection (default)\n * - \"auth\": Authentication collection with system auth fields\n * - \"view\": Read-only collection backed by a SQL query (requires viewQuery)\n *\n * If not specified, the type will be auto-detected based on field presence\n * (collections with both email and password fields are detected as auth)\n *\n * Prefer defineView() over type: \"view\" - it enforces the constraints\n * PocketBase places on view collections at compile time.\n */\n type?: \"base\" | \"auth\" | \"view\";\n\n /**\n * SQL SELECT statement backing a view collection\n *\n * Only valid when type is \"view\", where it is required. PocketBase derives\n * the collection's fields by running this query, so the Zod schema is used\n * for TypeScript types only.\n */\n viewQuery?: string;\n\n /**\n * Future extensibility - additional options can be added here\n */\n [key: string]: unknown;\n}\n\n/**\n * High-level wrapper for defining a PocketBase collection with all metadata\n *\n * This is the recommended way to define collections as it provides a single\n * entry point for collection name, schema, permissions, indexes, and future features.\n *\n * @param config - Collection configuration object\n * @returns The schema with all metadata attached\n *\n * @example\n * // Recommended: Use default export for clarity\n * const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n * export default PostCollection;\n *\n * @example\n * // Also supported: Named export (backward compatible)\n * export const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n *\n * @example\n * // Collection with permissions and indexes\n * export const UserSchema = defineCollection({\n * collectionName: \"users\",\n * schema: z.object({\n * name: z.string(),\n * email: z.string().email(),\n * }),\n * permissions: {\n * listRule: \"id = @request.auth.id\",\n * viewRule: \"id = @request.auth.id\",\n * createRule: \"\",\n * updateRule: \"id = @request.auth.id\",\n * deleteRule: \"id = @request.auth.id\",\n * },\n * indexes: [\n * \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n * ],\n * });\n *\n * @example\n * // Collection with template and custom rule overrides\n * export const ProjectSchema = defineCollection({\n * collectionName: \"projects\",\n * schema: z.object({\n * title: z.string(),\n * owner: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"owner\",\n * customRules: {\n * listRule: '@request.auth.id != \"\"',\n * },\n * },\n * });\n */\nexport function defineCollection(config: CollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, permissions, indexes, type, viewQuery, ...futureOptions } = config;\n\n // Build metadata object\n const metadata: any = {\n collectionName,\n };\n\n // Add type if provided\n if (type) {\n metadata.type = type;\n }\n\n // Add the SQL query backing a view collection\n if (viewQuery !== undefined) {\n metadata.viewQuery = viewQuery;\n }\n\n // Add permissions if provided\n if (permissions) {\n metadata.permissions = permissions;\n }\n\n // Add indexes if provided\n if (indexes) {\n metadata.indexes = indexes;\n }\n\n // Add any future options\n if (Object.keys(futureOptions).length > 0) {\n Object.assign(metadata, futureOptions);\n }\n\n // Attach all metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as z.ZodObject<any>;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Field Metadata System\n// ============================================================================\n\n/**\n * Internal marker for field metadata\n * Used by the migration generator to detect explicit field type definitions\n */\nexport const FIELD_METADATA_KEY = \"__pocketbase_field__\";\n\n/**\n * PocketBase field types\n */\nexport type PocketBaseFieldType =\n | \"text\"\n | \"email\"\n | \"url\"\n | \"editor\"\n | \"number\"\n | \"bool\"\n | \"date\"\n | \"autodate\"\n | \"select\"\n | \"relation\"\n | \"file\"\n | \"json\"\n | \"geoPoint\"\n | \"password\";\n\n/**\n * Field metadata structure embedded in Zod schema descriptions\n */\nexport interface FieldMetadata {\n type: PocketBaseFieldType;\n options?: Record<string, any>;\n}\n\n/**\n * Extracts field metadata from a Zod type's description\n * Used by the migration generator to detect explicit field type definitions\n *\n * @param description - The Zod type's description string\n * @returns Field metadata if present, null otherwise\n *\n * @example\n * const schema = TextField({ min: 1, max: 100 });\n * const metadata = extractFieldMetadata(schema.description);\n * // Returns: { type: \"text\", options: { min: 1, max: 100 } }\n */\nexport function extractFieldMetadata(description: string | undefined): FieldMetadata | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[FIELD_METADATA_KEY]) {\n return parsed[FIELD_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n// ============================================================================\n// Field Options Interfaces\n// ============================================================================\n\n/**\n * Text field configuration options\n */\nexport interface TextFieldOptions {\n /**\n * Minimum length constraint\n */\n min?: number;\n\n /**\n * Maximum length constraint\n */\n max?: number;\n\n /**\n * Pattern constraint (regex)\n */\n pattern?: RegExp | string;\n\n /**\n * Auto-generate pattern for automatic value generation\n * Example: \"[A-Z]{3}-[0-9]{6}\" generates values like \"ABC-123456\"\n */\n autogeneratePattern?: string;\n}\n\n/**\n * Number field configuration options\n */\nexport interface NumberFieldOptions {\n /**\n * Minimum value constraint\n */\n min?: number;\n\n /**\n * Maximum value constraint\n */\n max?: number;\n\n /**\n * Whether to disallow decimal values (integers only)\n */\n noDecimal?: boolean;\n\n /**\n * Whether the field is required\n * @default false\n *\n * Note: In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you want to allow zero values (e.g., for progress: 0-100), keep this as `false`.\n * Set to `true` only if you want to enforce non-zero values.\n */\n required?: boolean;\n}\n\n/**\n * Date field configuration options\n */\nexport interface DateFieldOptions {\n /**\n * Minimum date constraint\n */\n min?: Date | string;\n\n /**\n * Maximum date constraint\n */\n max?: Date | string;\n}\n\n/**\n * Autodate field configuration options\n */\nexport interface AutodateFieldOptions {\n /**\n * Set date automatically on record creation\n * @default false\n */\n onCreate?: boolean;\n\n /**\n * Update date automatically on record update\n * @default false\n */\n onUpdate?: boolean;\n}\n\n/**\n * Select field configuration options\n */\nexport interface SelectFieldOptions {\n /**\n * Maximum number of selections allowed\n * If > 1, enables multiple selection\n * @default 1\n */\n maxSelect?: number;\n}\n\ntype EnumFromArray<T extends readonly [string, ...string[]]> = z.ZodEnum<z.core.util.ToEnum<T[number]>>;\n\n/**\n * Human-friendly byte size input.\n *\n * - Use a number for raw bytes (e.g. `5242880`)\n * - Use a string with unit suffix for kibibytes/mebibytes/gibibytes (e.g. `\"5M\"`, `\"1G\"`)\n *\n * Supported suffixes: `K`, `M`, `G` (case-insensitive).\n */\nexport type ByteSize = number | `${number}${\"K\" | \"M\" | \"G\" | \"k\" | \"m\" | \"g\"}`;\n\n/**\n * File field configuration options\n */\nexport interface FileFieldOptions {\n /**\n * Allowed MIME types\n * Example: [\"image/*\", \"application/pdf\"]\n */\n mimeTypes?: string[];\n\n /**\n * Maximum file size.\n *\n * - Provide a number for raw bytes\n * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n *\n * Max allowed is `8G`.\n *\n * @example\n * maxSize: 5242880\n * maxSize: \"5M\"\n * maxSize: \"1G\"\n */\n maxSize?: ByteSize;\n\n /**\n * Thumbnail sizes to generate\n * Example: [\"100x100\", \"200x200\"]\n * Set to null to explicitly disable thumbnails\n */\n thumbs?: string[];\n\n /**\n * Whether the file is protected (requires auth to access)\n * @default false\n */\n protected?: boolean;\n}\n\n/**\n * Multiple files field configuration options\n */\nexport interface FilesFieldOptions extends FileFieldOptions {\n /**\n * Minimum number of files required\n */\n minSelect?: number;\n\n /**\n * Maximum number of files allowed\n */\n maxSelect?: number;\n}\n\nconst MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024; // 8G\n\nfunction parseByteSizeToBytes(value: ByteSize, context: string): number {\n let bytes: number;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(`${context}: maxSize must be a finite number of bytes`);\n }\n bytes = Math.round(value);\n } else {\n const trimmed = value.trim();\n const match = /^(\\d+(?:\\.\\d+)?)\\s*([KMG])$/i.exec(trimmed);\n if (!match) {\n throw new Error(`${context}: maxSize string must be like \"10K\", \"5M\", or \"1G\" (case-insensitive)`);\n }\n\n const amount = Number(match[1]);\n const unit = match[2].toUpperCase() as \"K\" | \"M\" | \"G\";\n\n if (!Number.isFinite(amount)) {\n throw new Error(`${context}: maxSize must be a valid number`);\n }\n\n const multiplier = unit === \"K\" ? 1024 : unit === \"M\" ? 1024 * 1024 : 1024 * 1024 * 1024;\n bytes = Math.round(amount * multiplier);\n }\n\n if (bytes < 0) {\n throw new Error(`${context}: maxSize must be >= 0`);\n }\n\n if (bytes > MAX_FILE_SIZE_BYTES) {\n throw new Error(`${context}: maxSize cannot exceed 8G (${MAX_FILE_SIZE_BYTES} bytes)`);\n }\n\n return bytes;\n}\n\nfunction normalizeFileFieldOptions(\n options: FileFieldOptions | undefined,\n context: string\n): FileFieldOptions | undefined {\n if (!options) return options;\n if (options.maxSize === undefined) return options;\n\n return {\n ...options,\n // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.\n maxSize: parseByteSizeToBytes(options.maxSize, context),\n };\n}\n\n// ============================================================================\n// Field Helper Functions\n// ============================================================================\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n *\n * @returns Zod boolean schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * active: BoolField(),\n * featured: BoolField().optional(),\n * });\n */\nexport function BoolField(): z.ZodBoolean {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"bool\" as const,\n },\n };\n\n return z.boolean().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a number field schema with optional constraints\n * Maps to PocketBase 'number' field type\n *\n * @param options - Optional constraints for the number field\n * @returns Zod number schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * price: NumberField({ min: 0 }),\n * quantity: NumberField({ min: 0, noDecimal: true }),\n * rating: NumberField({ min: 0, max: 5 }),\n * progress: NumberField({ min: 0, max: 100 }), // required defaults to false, allowing zero\n * score: NumberField({ min: 1, max: 10, required: true }), // requires non-zero value\n * });\n *\n * @remarks\n * By default, number fields are not required (`required: false`), which allows zero values.\n * In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you set `min: 0` and want to allow zero, keep `required: false` (the default).\n */\nexport function NumberField(options?: NumberFieldOptions): z.ZodNumber {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"NumberField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.number();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"number\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a text field schema with optional constraints\n * Maps to PocketBase 'text' field type\n *\n * @param options - Optional constraints for the text field\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * name: TextField({ min: 1, max: 200 }),\n * sku: TextField({ autogeneratePattern: \"[A-Z]{3}-[0-9]{6}\" }),\n * description: TextField({ max: 1000 }),\n * });\n */\nexport function TextField(options?: TextFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"TextField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.string();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n if (options?.pattern !== undefined) {\n const pattern = options.pattern instanceof RegExp ? options.pattern : new RegExp(options.pattern);\n schema = schema.regex(pattern);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"text\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n *\n * @returns Zod string schema with email validation and PocketBase metadata\n *\n * @example\n * const UserSchema = z.object({\n * email: EmailField(),\n * alternateEmail: EmailField().optional(),\n * });\n */\nexport function EmailField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"email\" as const,\n },\n };\n\n return z.string().email().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n *\n * @returns Zod string schema with URL validation and PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * website: URLField(),\n * documentation: URLField().optional(),\n * });\n */\nexport function URLField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"url\" as const,\n },\n };\n\n return z.string().url().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a rich text editor field schema\n * Maps to PocketBase 'editor' field type\n *\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * content: EditorField(),\n * summary: EditorField().optional(),\n * });\n */\nexport function EditorField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"editor\" as const,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a date field schema with optional constraints\n * Maps to PocketBase 'date' field type\n *\n * @param options - Optional date constraints\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const EventSchema = z.object({\n * startDate: DateField(),\n * endDate: DateField({ min: new Date('2024-01-01') }),\n * releaseDate: DateField().optional(),\n * });\n */\nexport function DateField(options?: DateFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n const minDate = typeof options.min === \"string\" ? new Date(options.min) : options.min;\n const maxDate = typeof options.max === \"string\" ? new Date(options.max) : options.max;\n if (minDate > maxDate) {\n throw new Error(\"DateField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"date\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an autodate field schema with automatic timestamp management\n * Maps to PocketBase 'autodate' field type\n *\n * @param options - Optional autodate configuration\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * createdAt: AutodateField({ onCreate: true }),\n * updatedAt: AutodateField({ onUpdate: true }),\n * publishedAt: AutodateField({ onCreate: true, onUpdate: false }),\n * });\n */\nexport function AutodateField(options?: AutodateFieldOptions): z.ZodString {\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"autodate\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod enum or array schema with PocketBase metadata\n *\n * @example\n * // Single select\n * const PostSchema = z.object({\n * status: SelectField([\"draft\", \"published\", \"archived\"]),\n * });\n *\n * @example\n * // Multiple select\n * const ProductSchema = z.object({\n * categories: SelectField([\"electronics\", \"clothing\", \"food\"], { maxSelect: 3 }),\n * });\n */\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): EnumFromArray<T> | z.ZodArray<EnumFromArray<T>> {\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return MultiSelectField(values, options);\n }\n\n return SingleSelectField(values);\n}\n\n/**\n * Creates a single select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect=1\n *\n * @param values - Array of allowed string values\n * @returns Zod enum schema with PocketBase metadata\n */\nexport function SingleSelectField<const T extends readonly [string, ...string[]]>(values: T): EnumFromArray<T> {\n const enumSchema = z.enum(values);\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: 1,\n },\n },\n };\n\n return enumSchema.describe(JSON.stringify(metadata)) as EnumFromArray<T>;\n}\n\n/**\n * Creates a multiple select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect>1\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod array schema with PocketBase metadata\n */\nexport function MultiSelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodArray<EnumFromArray<T>> {\n const enumSchema = z.enum(values);\n const maxSelect = options?.maxSelect ?? 999;\n\n if (maxSelect <= 1) {\n throw new Error(\"MultiSelectField: maxSelect must be greater than 1\");\n }\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect,\n },\n },\n };\n\n return z.array(enumSchema).describe(JSON.stringify(metadata)) as z.ZodArray<EnumFromArray<T>>;\n}\n\n/**\n * Creates a single file field schema\n * Maps to PocketBase 'file' field type with maxSelect=1\n *\n * @param options - Optional file constraints\n * @returns Zod schema that accepts File on input and returns string when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File objects\n * - When reading from PocketBase: returns string (filename)\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<string, File | string> {\n // Accept File for input (when creating/updating) or string (when reading from DB)\n // Output is always string (as returned by PocketBase)\n const schema = z.preprocess((val) => {\n // If it's a File, return its name (or empty string if no name)\n // If it's already a string (from DB), return as-is\n return val instanceof File ? val.name || \"\" : val;\n }, z.string()) as z.ZodType<string, File | string>;\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FileField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple files field schema\n * Maps to PocketBase 'file' field type with maxSelect>1\n *\n * @param options - Optional file constraints\n * @returns Zod array schema that accepts File[] on input and returns string[] when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File[]\n * - When reading from PocketBase: returns string[] (filenames)\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodType<string[], (File | string)[]> {\n // Validate options\n if (options?.minSelect !== undefined && options?.maxSelect !== undefined) {\n if (options.minSelect > options.maxSelect) {\n throw new Error(\"FilesField: minSelect cannot be greater than maxSelect\");\n }\n }\n\n // Accept File[] for input (when creating/updating) or string[] (when reading from DB)\n // Output is always string[] (as returned by PocketBase)\n let baseArraySchema = z.array(z.string());\n\n // Apply Zod validations first\n if (options?.minSelect !== undefined) {\n baseArraySchema = baseArraySchema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n baseArraySchema = baseArraySchema.max(options.maxSelect);\n }\n\n const schema = z.preprocess((val) => {\n // Handle array of Files or strings\n if (Array.isArray(val)) {\n return val.map((item) => (item instanceof File ? item.name || \"\" : item));\n }\n return val;\n }, baseArraySchema);\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FilesField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata)) as z.ZodType<string[], (File | string)[]>;\n}\n\n/**\n * Creates a JSON field schema with optional inner schema validation\n * Maps to PocketBase 'json' field type\n *\n * @param schema - Optional Zod schema for the JSON structure\n * @returns Zod schema with PocketBase metadata\n *\n * @example\n * // Any JSON\n * const ProductSchema = z.object({\n * metadata: JSONField(),\n * });\n *\n * @example\n * // Typed JSON\n * const ProductSchema = z.object({\n * settings: JSONField(z.object({\n * theme: z.string(),\n * notifications: z.boolean(),\n * })),\n * });\n */\nexport function JSONField<T extends z.ZodTypeAny>(schema?: T): T | z.ZodRecord<z.ZodString, z.ZodAny> {\n const baseSchema = schema ?? z.record(z.string(), z.any());\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"json\" as const,\n },\n };\n\n return baseSchema.describe(JSON.stringify(metadata)) as T | z.ZodRecord<z.ZodString, z.ZodAny>;\n}\n\n/**\n * Creates a geographic point field schema\n * Maps to PocketBase 'geoPoint' field type\n *\n * @returns Zod object schema with lon/lat fields and PocketBase metadata\n *\n * @example\n * const LocationSchema = z.object({\n * coordinates: GeoPointField(),\n * homeLocation: GeoPointField().optional(),\n * });\n */\nexport function GeoPointField(): z.ZodObject<{\n lon: z.ZodNumber;\n lat: z.ZodNumber;\n}> {\n const schema = z.object({\n lon: z.number(),\n lat: z.number(),\n });\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"geoPoint\" as const,\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n","import { z } from \"zod\";\nimport type { RuleExpression } from \"../utils/permissions\";\nimport { defineCollection } from \"./base\";\n\n/**\n * Permission rules that apply to a view collection\n *\n * View collections are read-only: PocketBase rejects createRule, updateRule,\n * deleteRule and manageRule on them, so only the two read rules are accepted.\n */\nexport interface ViewPermissionSchema {\n /** Controls who can list/query the view's rows */\n listRule?: RuleExpression;\n\n /** Controls who can view an individual row */\n viewRule?: RuleExpression;\n}\n\n/**\n * Configuration options for defining a view collection\n */\nexport interface ViewCollectionConfig {\n /**\n * The name of the PocketBase collection\n */\n collectionName: string;\n\n /**\n * The Zod schema describing the shape of a row\n *\n * For views this is used for TypeScript type generation and application-side\n * parsing only - PocketBase derives the collection's actual fields from the\n * SQL query when the collection is saved.\n */\n schema: z.ZodObject<any>;\n\n /**\n * The SQL SELECT statement backing the view\n *\n * Use the `sql` tagged template for consistent formatting.\n */\n viewQuery: string;\n\n /**\n * Optional read permissions (listRule / viewRule)\n */\n permissions?: ViewPermissionSchema;\n}\n\n/**\n * Removes the common leading indentation from a multi-line string and trims\n * blank leading/trailing lines\n *\n * Keeps generated migrations stable when a query is re-indented in the source\n * file, since only the relative indentation is preserved. Also used when\n * reading a query back out of a migration file, where the generator has\n * indented it to fit the surrounding code.\n *\n * @param value - Raw multi-line string\n * @returns Dedented string\n */\nexport function dedentSql(value: string): string {\n const lines = value.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\n // Drop leading and trailing blank lines\n while (lines.length > 0 && lines[0].trim() === \"\") {\n lines.shift();\n }\n while (lines.length > 0 && lines[lines.length - 1].trim() === \"\") {\n lines.pop();\n }\n\n if (lines.length === 0) {\n return \"\";\n }\n\n // Find the smallest indentation across all non-blank lines\n let minIndent = Infinity;\n for (const line of lines) {\n if (line.trim() === \"\") continue;\n const indent = line.length - line.trimStart().length;\n if (indent < minIndent) {\n minIndent = indent;\n }\n }\n\n if (!Number.isFinite(minIndent) || minIndent === 0) {\n return lines.map((line) => line.trimEnd()).join(\"\\n\");\n }\n\n return lines.map((line) => line.slice(minIndent).trimEnd()).join(\"\\n\");\n}\n\n/**\n * Tagged template for SQL view queries\n *\n * Interpolates values, strips the common leading indentation and trims blank\n * leading/trailing lines. Returns a plain string, so a regular string literal\n * works anywhere `sql` does.\n *\n * @example\n * const query = sql`\n * SELECT p.id AS id, p.title AS title\n * FROM Projects p\n * `;\n * // \"SELECT p.id AS id, p.title AS title\\n FROM Projects p\"\n */\nexport function sql(strings: TemplateStringsArray, ...values: Array<string | number>): string {\n let result = \"\";\n\n for (let i = 0; i < strings.length; i++) {\n result += strings[i];\n if (i < values.length) {\n result += String(values[i]);\n }\n }\n\n return dedentSql(result);\n}\n\n/**\n * Strips SQL comments and leading whitespace so the first real token can be checked\n *\n * @param query - The SQL query\n * @returns The query with leading comments and whitespace removed\n */\nfunction stripLeadingComments(query: string): string {\n let remaining = query.trim();\n\n // Repeatedly strip line comments (-- ...) and block comments (/* ... */)\n while (remaining.length > 0) {\n if (remaining.startsWith(\"--\")) {\n const newline = remaining.indexOf(\"\\n\");\n remaining = newline === -1 ? \"\" : remaining.slice(newline + 1).trim();\n continue;\n }\n\n if (remaining.startsWith(\"/*\")) {\n const end = remaining.indexOf(\"*/\");\n remaining = end === -1 ? \"\" : remaining.slice(end + 2).trim();\n continue;\n }\n\n break;\n }\n\n return remaining;\n}\n\n/**\n * Validates a view query, throwing with an actionable message when it can't work\n *\n * @param collectionName - Collection name, used in error messages\n * @param viewQuery - The SQL query to validate\n */\nexport function validateViewQuery(collectionName: string, viewQuery: unknown): asserts viewQuery is string {\n if (typeof viewQuery !== \"string\" || viewQuery.trim() === \"\") {\n throw new Error(\n `View collection \"${collectionName}\" requires a non-empty viewQuery. ` +\n `Provide the SQL SELECT statement backing the view.`\n );\n }\n\n const body = stripLeadingComments(viewQuery);\n if (!/^(select|with)\\b/i.test(body)) {\n throw new Error(\n `View collection \"${collectionName}\" has an invalid viewQuery: it must start with SELECT or WITH. ` +\n `Received: ${body.slice(0, 40)}${body.length > 40 ? \"...\" : \"\"}`\n );\n }\n}\n\n/**\n * Defines a read-only PocketBase view collection backed by a SQL query\n *\n * PocketBase derives the collection's fields by running the query, so the Zod\n * schema only describes the shape for TypeScript types and application-side\n * parsing. Views cannot have indexes and only support listRule / viewRule.\n *\n * The generated migration creates the collection with `type: \"view\"` and the\n * query; changing the SQL later produces an in-place `viewQuery` update, which\n * keeps the collection id stable.\n *\n * @param config - View collection configuration\n * @returns The schema with view metadata attached\n *\n * @example\n * export default defineView({\n * collectionName: \"ProjectStats\",\n * schema: ProjectStatsSchema,\n * viewQuery: sql`\n * SELECT p.OwnerUser AS id,\n * p.OwnerUser AS OwnerUser,\n * COUNT(*) AS projectCount\n * FROM Projects p\n * GROUP BY p.OwnerUser\n * `,\n * permissions: {\n * listRule: \"OwnerUser = @request.auth.id\",\n * viewRule: \"OwnerUser = @request.auth.id\",\n * },\n * });\n *\n * @example\n * // Requirements PocketBase places on the query:\n * // - the outermost SELECT must expose an `id` column\n * // - a relation column must be selected bare (e.g. `p.OwnerUser AS OwnerUser`)\n * // from the outer table for PocketBase to infer it as a relation field\n * // - no top-level UNION (wrap unions in a subquery)\n */\nexport function defineView(config: ViewCollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, viewQuery, permissions } = config;\n\n validateViewQuery(collectionName, viewQuery);\n\n return defineCollection({\n collectionName,\n schema,\n type: \"view\",\n viewQuery,\n // Write rules are always locked for views - PocketBase rejects anything else\n permissions: {\n listRule: permissions?.listRule ?? null,\n viewRule: permissions?.viewRule ?? null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n },\n });\n}\n","import type { PermissionSchema, PermissionTemplateConfig, RuleExpression } from \"../utils/permissions\";\n\n/**\n * Predefined permission templates for common access control patterns\n */\nexport const PermissionTemplates = {\n /**\n * Public access - anyone can perform all operations\n */\n public: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: \"\",\n updateRule: \"\",\n deleteRule: \"\",\n }),\n\n /**\n * Authenticated users only - requires valid authentication for all operations\n */\n authenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Owner-only access - users can only manage their own records\n * @param ownerField - Name of the relation field pointing to user (default: 'User')\n */\n ownerOnly: (ownerField: string = \"User\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n viewRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n createRule: '@request.auth.id != \"\"',\n updateRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n deleteRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n }),\n\n /**\n * Admin/superuser only access\n * Assumes a 'role' field exists with 'admin' value\n * @param roleField - Name of the role field (default: 'role')\n */\n adminOnly: (roleField: string = \"role\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n viewRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n createRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n updateRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n deleteRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n }),\n\n /**\n * Public read, authenticated write\n * Anyone can list/view, but only authenticated users can create/update/delete\n */\n readPublic: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Locked access - only superusers can perform operations\n * All rules are set to null (locked)\n */\n locked: (): PermissionSchema => ({\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n\n /**\n * Read-only authenticated - authenticated users can read, no write access\n */\n readOnlyAuthenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n};\n\n/**\n * Resolve template configuration to concrete permission schema\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema with all rules defined\n */\nexport function resolveTemplate(config: PermissionTemplateConfig): PermissionSchema {\n let baseRules: PermissionSchema;\n\n switch (config.template) {\n case \"public\":\n baseRules = PermissionTemplates.public();\n break;\n case \"authenticated\":\n baseRules = PermissionTemplates.authenticated();\n break;\n case \"owner-only\":\n baseRules = PermissionTemplates.ownerOnly(config.ownerField);\n break;\n case \"admin-only\":\n baseRules = PermissionTemplates.adminOnly(config.roleField);\n break;\n case \"read-public\":\n baseRules = PermissionTemplates.readPublic();\n break;\n case \"custom\":\n baseRules = {};\n break;\n default: {\n // Exhaustive check - TypeScript will error if we miss a template type\n const _exhaustive: never = config.template;\n throw new Error(`Unknown template type: ${_exhaustive}`);\n }\n }\n\n // Merge with custom rules if provided (custom rules override template rules)\n return {\n ...baseRules,\n ...config.customRules,\n };\n}\n\n/**\n * Check if a configuration is a template config or direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a template configuration\n */\nexport function isTemplateConfig(\n config: PermissionTemplateConfig | PermissionSchema\n): config is PermissionTemplateConfig {\n return \"template\" in config;\n}\n\n/**\n * Check if a configuration is a direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a direct permission schema\n */\nexport function isPermissionSchema(config: PermissionTemplateConfig | PermissionSchema): config is PermissionSchema {\n return (\n \"listRule\" in config ||\n \"viewRule\" in config ||\n \"createRule\" in config ||\n \"updateRule\" in config ||\n \"deleteRule\" in config ||\n \"manageRule\" in config\n );\n}\n\n/**\n * Validation result for permission configuration\n */\nexport interface PermissionValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Validate a permission configuration\n * @param config - Permission configuration to validate\n * @param isAuthCollection - Whether this is for an auth collection\n * @returns Validation result\n */\nexport function validatePermissionConfig(\n config: PermissionTemplateConfig | PermissionSchema,\n isAuthCollection: boolean = false\n): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Resolve to permission schema\n let permissions: PermissionSchema;\n if (isTemplateConfig(config)) {\n // Validate template config\n if (config.template === \"owner-only\" && !config.ownerField) {\n result.warnings.push(\"owner-only template without ownerField specified - using default 'User'\");\n }\n if (config.template === \"admin-only\" && !config.roleField) {\n result.warnings.push(\"admin-only template without roleField specified - using default 'role'\");\n }\n permissions = resolveTemplate(config);\n } else {\n permissions = config;\n }\n\n // Validate manageRule usage\n if (permissions.manageRule !== undefined && !isAuthCollection) {\n result.errors.push(\"manageRule is only valid for auth collections\");\n result.valid = false;\n }\n\n // Validate rule expressions\n const ruleTypes: (keyof PermissionSchema)[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\"];\n if (isAuthCollection) {\n ruleTypes.push(\"manageRule\");\n }\n\n for (const ruleType of ruleTypes) {\n const rule = permissions[ruleType];\n if (rule !== undefined && rule !== null && rule !== \"\") {\n const ruleValidation = validateRuleExpression(rule);\n if (!ruleValidation.valid) {\n result.errors.push(`${ruleType}: ${ruleValidation.errors.join(\", \")}`);\n result.valid = false;\n }\n result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));\n }\n }\n\n return result;\n}\n\n/**\n * Validate a single rule expression for basic syntax\n * @param expression - Rule expression to validate\n * @returns Validation result\n */\nexport function validateRuleExpression(expression: RuleExpression): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Null and empty string are always valid\n if (expression === null || expression === \"\") {\n return result;\n }\n\n // Check for balanced parentheses\n let parenCount = 0;\n for (const char of expression) {\n if (char === \"(\") parenCount++;\n if (char === \")\") parenCount--;\n if (parenCount < 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n return result;\n }\n }\n if (parenCount !== 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n }\n\n // Check for common mistakes\n if (expression.includes(\"==\")) {\n result.warnings.push(\"Use '=' instead of '==' for equality comparison\");\n }\n\n // Check for valid @request references\n const requestRefs = expression.match(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];\n for (const ref of requestRefs) {\n const isValid =\n ref.startsWith(\"@request.auth.\") ||\n ref === \"@request.method\" ||\n ref === \"@request.context\" ||\n ref.startsWith(\"@request.body.\") ||\n ref.startsWith(\"@request.query.\") ||\n ref.startsWith(\"@request.headers.\");\n\n if (!isValid) {\n result.errors.push(`Invalid @request reference: '${ref}'`);\n result.valid = false;\n }\n }\n\n return result;\n}\n\n/**\n * Create a custom permission schema with type safety\n * @param permissions - Partial permission schema\n * @returns Complete permission schema with null defaults\n */\nexport function createPermissions(permissions: Partial<PermissionSchema>): PermissionSchema {\n return {\n listRule: permissions.listRule ?? null,\n viewRule: permissions.viewRule ?? null,\n createRule: permissions.createRule ?? null,\n updateRule: permissions.updateRule ?? null,\n deleteRule: permissions.deleteRule ?? null,\n manageRule: permissions.manageRule ?? null,\n };\n}\n\n/**\n * Merge multiple permission schemas, with later schemas taking precedence\n * @param schemas - Permission schemas to merge\n * @returns Merged permission schema\n */\nexport function mergePermissions(...schemas: Partial<PermissionSchema>[]): PermissionSchema {\n const merged: PermissionSchema = {\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n manageRule: null,\n };\n\n for (const schema of schemas) {\n if (schema.listRule !== undefined) merged.listRule = schema.listRule;\n if (schema.viewRule !== undefined) merged.viewRule = schema.viewRule;\n if (schema.createRule !== undefined) merged.createRule = schema.createRule;\n if (schema.updateRule !== undefined) merged.updateRule = schema.updateRule;\n if (schema.deleteRule !== undefined) merged.deleteRule = schema.deleteRule;\n if (schema.manageRule !== undefined) merged.manageRule = schema.manageRule;\n }\n\n return merged;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { StatusEnum, StatusEnumType } from './enums.cjs';
2
2
  export { BaseMutator, Expanded, MutatorOptions } from './mutator.cjs';
3
- export { CollectionConfig, PermissionTemplates, PermissionValidationResult, RelationConfig, RelationField, RelationsConfig, RelationsField, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, createPermissions, defineCollection, extractRelationMetadata, inputImageFileSchema, isPermissionSchema, isTemplateConfig, mergePermissions, omitImageFilesSchema, resolveTemplate, validatePermissionConfig, validateRuleExpression, withIndexes, withPermissions } from './schema.cjs';
3
+ export { CollectionConfig, PermissionTemplates, PermissionValidationResult, RelationConfig, RelationField, RelationsConfig, RelationsField, ViewCollectionConfig, ViewPermissionSchema, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, createPermissions, dedentSql, defineCollection, defineView, extractRelationMetadata, inputImageFileSchema, isPermissionSchema, isTemplateConfig, mergePermissions, omitImageFilesSchema, resolveTemplate, sql, validatePermissionConfig, validateRuleExpression, validateViewQuery, withIndexes, withPermissions } from './schema.cjs';
4
4
  export { o as APIRuleType, j as AutodateField, A as AutodateFieldOptions, d as BoolField, B as ByteSize, i as DateField, D as DateFieldOptions, h as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, m as FileField, b as FileFieldOptions, n as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, M as MultiSelectField, f as NumberField, N as NumberFieldOptions, p as PermissionSchema, q as PermissionTemplate, r as PermissionTemplateConfig, P as PocketBaseFieldType, R as RuleExpression, k as SelectField, S as SelectFieldOptions, l as SingleSelectField, g as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-B96iGprI.cjs';
5
5
  import 'zod';
6
6
  import 'pocketbase';