pocketbase-zod-schema 0.2.5 → 0.3.1

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 (68) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cli/index.cjs +497 -298
  3. package/dist/cli/index.cjs.map +1 -1
  4. package/dist/cli/index.d.cts +2 -2
  5. package/dist/cli/index.d.ts +2 -2
  6. package/dist/cli/index.js +497 -298
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/migrate.cjs +497 -298
  9. package/dist/cli/migrate.cjs.map +1 -1
  10. package/dist/cli/migrate.js +497 -298
  11. package/dist/cli/migrate.js.map +1 -1
  12. package/dist/cli/utils/index.d.cts +2 -2
  13. package/dist/cli/utils/index.d.ts +2 -2
  14. package/dist/{fields-YjcpBXVp.d.cts → fields-RVj26U-O.d.cts} +17 -0
  15. package/dist/{fields-YjcpBXVp.d.ts → fields-RVj26U-O.d.ts} +17 -0
  16. package/dist/index.cjs +575 -155
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +4 -4
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +576 -144
  21. package/dist/index.js.map +1 -1
  22. package/dist/migration/analyzer.cjs +12 -2
  23. package/dist/migration/analyzer.cjs.map +1 -1
  24. package/dist/migration/analyzer.d.cts +2 -2
  25. package/dist/migration/analyzer.d.ts +2 -2
  26. package/dist/migration/analyzer.js +12 -2
  27. package/dist/migration/analyzer.js.map +1 -1
  28. package/dist/migration/diff.cjs +150 -24
  29. package/dist/migration/diff.cjs.map +1 -1
  30. package/dist/migration/diff.d.cts +4 -4
  31. package/dist/migration/diff.d.ts +4 -4
  32. package/dist/migration/diff.js +150 -24
  33. package/dist/migration/diff.js.map +1 -1
  34. package/dist/migration/generator.cjs +360 -46
  35. package/dist/migration/generator.cjs.map +1 -1
  36. package/dist/migration/generator.d.cts +59 -12
  37. package/dist/migration/generator.d.ts +59 -12
  38. package/dist/migration/generator.js +356 -47
  39. package/dist/migration/generator.js.map +1 -1
  40. package/dist/migration/index.cjs +561 -90
  41. package/dist/migration/index.cjs.map +1 -1
  42. package/dist/migration/index.d.cts +3 -3
  43. package/dist/migration/index.d.ts +3 -3
  44. package/dist/migration/index.js +561 -90
  45. package/dist/migration/index.js.map +1 -1
  46. package/dist/migration/snapshot.cjs +51 -18
  47. package/dist/migration/snapshot.cjs.map +1 -1
  48. package/dist/migration/snapshot.d.cts +2 -2
  49. package/dist/migration/snapshot.d.ts +2 -2
  50. package/dist/migration/snapshot.js +51 -18
  51. package/dist/migration/snapshot.js.map +1 -1
  52. package/dist/migration/utils/index.cjs +66 -0
  53. package/dist/migration/utils/index.cjs.map +1 -1
  54. package/dist/migration/utils/index.d.cts +39 -202
  55. package/dist/migration/utils/index.d.ts +39 -202
  56. package/dist/migration/utils/index.js +65 -1
  57. package/dist/migration/utils/index.js.map +1 -1
  58. package/dist/schema.cjs +0 -61
  59. package/dist/schema.cjs.map +1 -1
  60. package/dist/schema.d.cts +2 -86
  61. package/dist/schema.d.ts +2 -86
  62. package/dist/schema.js +1 -50
  63. package/dist/schema.js.map +1 -1
  64. package/dist/type-mapper-CZzVeDj7.d.ts +208 -0
  65. package/dist/type-mapper-DaBe-1ph.d.cts +208 -0
  66. package/dist/{types-LFBGHl9Y.d.ts → types-CUVzgZ9k.d.ts} +33 -2
  67. package/dist/{types-mhQXWNi3.d.cts → types-D-Fsdn_O.d.cts} +33 -2
  68. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema/base.ts","../src/schema/fields.ts","../src/utils/permission-templates.ts"],"names":["z","baseSchema"],"mappings":"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","file":"schema.js","sourcesContent":["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.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\n/**\n * Creates a text field schema with optional constraints\n * @param options - Optional constraints for the text field\n */\nexport function textField(options?: { min?: number; max?: number; pattern?: RegExp }) {\n let schema = z.string();\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n if (options?.pattern !== undefined) schema = schema.regex(options.pattern);\n return schema;\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n */\nexport function emailField() {\n return z.string().email();\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n */\nexport function urlField() {\n return z.string().url();\n}\n\n/**\n * Creates a number field schema with optional constraints\n * @param options - Optional constraints for the number field\n */\nexport function numberField(options?: { min?: number; max?: number }) {\n let schema = z.number();\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n return schema;\n}\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n */\nexport function boolField() {\n return z.boolean();\n}\n\n/**\n * Creates a date field schema\n * Maps to PocketBase 'date' field type\n */\nexport function dateField() {\n return z.date();\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n * @param values - Array of allowed string values\n */\nexport function selectField<T extends [string, ...string[]]>(values: T) {\n return z.enum(values);\n}\n\n/**\n * Creates a JSON field schema\n * Maps to PocketBase 'json' field type\n * @param schema - Optional Zod schema for the JSON structure\n */\nexport function jsonField<T extends z.ZodTypeAny>(schema?: T) {\n return schema ?? z.record(z.any());\n}\n\n/**\n * Creates a single file field schema for form input\n * Maps to PocketBase 'file' field type with maxSelect=1\n * Requires Node.js 20+ or browser environment with File API\n */\nexport function fileField() {\n return z.instanceof(File);\n}\n\n/**\n * Creates a multiple file field schema for form input\n * Maps to PocketBase 'file' field type with maxSelect>1\n * Requires Node.js 20+ or browser environment with File API\n * @param options - Optional constraints for the file field\n */\nexport function filesField(options?: { min?: number; max?: number }) {\n let schema = z.array(z.instanceof(File));\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n return schema;\n}\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/**\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 },\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 },\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} | 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 * Creates an editor field schema (rich text)\n * Maps to PocketBase 'editor' field type\n */\nexport function editorField() {\n return z.string();\n}\n\n/**\n * Creates a geo point field schema\n * Maps to PocketBase 'geoPoint' field type\n */\nexport function geoPointField() {\n return z.object({\n lon: z.number(),\n lat: z.number(),\n });\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\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/**\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\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 in bytes\n */\n maxSize?: number;\n\n /**\n * Thumbnail sizes to generate\n * Example: [\"100x100\", \"200x200\"]\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\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 * });\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<T extends [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodEnum<T> | z.ZodArray<z.ZodEnum<T>> {\n const enumSchema = z.enum(values);\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: options?.maxSelect ?? 1,\n },\n },\n };\n\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return z.array(enumSchema).describe(JSON.stringify(metadata));\n }\n\n return enumSchema.describe(JSON.stringify(metadata));\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 File schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<File> {\n const schema = z.instanceof(File);\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: options || {},\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 of File schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodArray<z.ZodType<File>> {\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 let schema = z.array(z.instanceof(File));\n\n // Apply Zod validations\n if (options?.minSelect !== undefined) {\n schema = schema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n schema = schema.max(options.maxSelect);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\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/schema/base.ts","../src/schema/fields.ts","../src/utils/permission-templates.ts"],"names":["z","baseSchema"],"mappings":"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","file":"schema.js","sourcesContent":["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.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/**\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 },\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 },\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} | 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\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\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 in bytes\n */\n maxSize?: number;\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\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<T extends [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodEnum<T> | z.ZodArray<z.ZodEnum<T>> {\n const enumSchema = z.enum(values);\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: options?.maxSelect ?? 1,\n },\n },\n };\n\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return z.array(enumSchema).describe(JSON.stringify(metadata));\n }\n\n return enumSchema.describe(JSON.stringify(metadata));\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 File schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<File> {\n const schema = z.instanceof(File);\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: options || {},\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 of File schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodArray<z.ZodType<File>> {\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 let schema = z.array(z.instanceof(File));\n\n // Apply Zod validations\n if (options?.minSelect !== undefined) {\n schema = schema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n schema = schema.max(options.maxSelect);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\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"]}
@@ -0,0 +1,208 @@
1
+ import { z } from 'zod';
2
+ import { P as PocketBaseFieldType } from './fields-RVj26U-O.js';
3
+
4
+ /**
5
+ * Collection name pluralization utilities
6
+ */
7
+ /**
8
+ * Pluralizes a singular noun to its plural form
9
+ * Handles special cases and common English pluralization rules
10
+ *
11
+ * @param singular - The singular form of the noun
12
+ * @returns The plural form of the noun
13
+ */
14
+ declare function pluralize(singular: string): string;
15
+ /**
16
+ * Converts a singular entity name to a collection name
17
+ * This is an alias for pluralize for better semantic clarity
18
+ *
19
+ * @param entityName - The singular entity name (e.g., "User", "Project")
20
+ * @returns The collection name (e.g., "Users", "Projects")
21
+ */
22
+ declare function toCollectionName(entityName: string): string;
23
+ /**
24
+ * Attempts to singularize a plural noun (reverse of pluralize)
25
+ * Note: This is a best-effort implementation and may not handle all edge cases
26
+ *
27
+ * @param plural - The plural form of the noun
28
+ * @returns The singular form of the noun
29
+ */
30
+ declare function singularize(plural: string): string;
31
+
32
+ /**
33
+ * Relation field detection utilities
34
+ */
35
+
36
+ /**
37
+ * Detects if a field is a single relation based on naming convention
38
+ * Single relation: field name matches a collection name (e.g., "User" -> "Users" collection)
39
+ */
40
+ declare function isSingleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean;
41
+ /**
42
+ * Detects if a field is a multiple relation based on naming convention
43
+ * Multiple relation: field name is an array of strings ending with entity name
44
+ * (e.g., "SubscriberUsers" -> "Users" collection)
45
+ */
46
+ declare function isMultipleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean;
47
+ /**
48
+ * Resolves the target collection name from a relation field name
49
+ * Examples:
50
+ * - "User" -> "Users"
51
+ * - "SubscriberUsers" -> "Users"
52
+ * - "Author" -> "Authors"
53
+ * - "Category" -> "Categories"
54
+ */
55
+ declare function resolveTargetCollection(fieldName: string): string;
56
+ /**
57
+ * Detects if a field is any type of relation (single or multiple)
58
+ */
59
+ declare function isRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean;
60
+ /**
61
+ * Gets the maximum number of relations allowed for a relation field
62
+ * Returns 1 for single relations, or the max constraint for multiple relations
63
+ */
64
+ declare function getMaxSelect(fieldName: string, zodType: z.ZodTypeAny): number;
65
+ /**
66
+ * Gets the minimum number of relations required for a relation field
67
+ * Returns 0 as default for all relation fields (single or multiple)
68
+ * PocketBase always expects minSelect to be defined for relation fields
69
+ */
70
+ declare function getMinSelect(fieldName: string, zodType: z.ZodTypeAny): number;
71
+
72
+ /**
73
+ * Zod to PocketBase type mapping utilities
74
+ *
75
+ * This module provides comprehensive mapping between Zod schema types
76
+ * and PocketBase field types, including support for all PocketBase field types:
77
+ * - text, email, url, editor
78
+ * - number, bool
79
+ * - date, autodate
80
+ * - select (single/multiple)
81
+ * - relation (single/multiple)
82
+ * - file (single/multiple)
83
+ * - json
84
+ * - geoPoint
85
+ */
86
+
87
+ /**
88
+ * All supported PocketBase field types
89
+ */
90
+ declare const POCKETBASE_FIELD_TYPES: readonly PocketBaseFieldType[];
91
+ /**
92
+ * Field type metadata for documentation and validation
93
+ */
94
+ interface FieldTypeInfo {
95
+ type: PocketBaseFieldType;
96
+ description: string;
97
+ zodTypes: string[];
98
+ supportsMultiple: boolean;
99
+ }
100
+ /**
101
+ * Metadata about each PocketBase field type
102
+ */
103
+ declare const FIELD_TYPE_INFO: Record<PocketBaseFieldType, FieldTypeInfo>;
104
+ /**
105
+ * Maps Zod string types to PocketBase field types
106
+ */
107
+ declare function mapZodStringType(zodType: z.ZodString): PocketBaseFieldType;
108
+ /**
109
+ * Maps Zod number types to PocketBase number type
110
+ */
111
+ declare function mapZodNumberType(_zodType: z.ZodNumber): PocketBaseFieldType;
112
+ /**
113
+ * Maps Zod boolean types to PocketBase bool type
114
+ */
115
+ declare function mapZodBooleanType(_zodType: z.ZodBoolean): PocketBaseFieldType;
116
+ /**
117
+ * Maps Zod enum types to PocketBase select type
118
+ */
119
+ declare function mapZodEnumType(_zodType: z.ZodEnum<any>): PocketBaseFieldType;
120
+ /**
121
+ * Maps Zod array types to appropriate PocketBase types
122
+ * Arrays of strings could be relations or file fields depending on context
123
+ */
124
+ declare function mapZodArrayType(zodType: z.ZodArray<any>, _fieldName: string): PocketBaseFieldType;
125
+ /**
126
+ * Maps Zod date types to PocketBase date type
127
+ */
128
+ declare function mapZodDateType(_zodType: z.ZodDate): PocketBaseFieldType;
129
+ /**
130
+ * Maps Zod record/object types to PocketBase JSON type
131
+ */
132
+ declare function mapZodRecordType(_zodType: z.ZodRecord | z.ZodObject<any>): PocketBaseFieldType;
133
+ /**
134
+ * Main type mapping function that determines PocketBase field type from Zod type
135
+ */
136
+ declare function mapZodTypeToPocketBase(zodType: z.ZodTypeAny, fieldName: string): PocketBaseFieldType;
137
+ /**
138
+ * Extracts field options from Zod type (min, max, pattern, etc.)
139
+ */
140
+ declare function extractFieldOptions(zodType: z.ZodTypeAny): Record<string, any>;
141
+ /**
142
+ * Determines if a Zod field is required (not optional)
143
+ */
144
+ declare function isFieldRequired(zodType: z.ZodTypeAny): boolean;
145
+ /**
146
+ * Unwraps a Zod type to get the inner type
147
+ * Handles optional, nullable, and default wrappers
148
+ */
149
+ declare function unwrapZodType(zodType: z.ZodTypeAny): z.ZodTypeAny;
150
+ /**
151
+ * Gets the default value from a Zod type if it has one
152
+ */
153
+ declare function getDefaultValue(zodType: z.ZodTypeAny): any;
154
+ /**
155
+ * Checks if a Zod type is an array type
156
+ */
157
+ declare function isArrayType(zodType: z.ZodTypeAny): boolean;
158
+ /**
159
+ * Gets the element type of an array Zod type
160
+ */
161
+ declare function getArrayElementType(zodType: z.ZodTypeAny): z.ZodTypeAny | null;
162
+ /**
163
+ * Checks if a Zod type represents a geo point (object with lon/lat)
164
+ */
165
+ declare function isGeoPointType(zodType: z.ZodTypeAny): boolean;
166
+ /**
167
+ * Complete field options extracted from a Zod type
168
+ */
169
+ interface ExtractedFieldOptions {
170
+ min?: number;
171
+ max?: number;
172
+ pattern?: string;
173
+ values?: string[];
174
+ minSelect?: number;
175
+ maxSelect?: number;
176
+ mimeTypes?: string[];
177
+ maxSize?: number;
178
+ thumbs?: string[];
179
+ }
180
+ /**
181
+ * Extracts comprehensive field options from Zod type
182
+ * Includes all constraints that can be mapped to PocketBase field options
183
+ */
184
+ declare function extractComprehensiveFieldOptions(zodType: z.ZodTypeAny): ExtractedFieldOptions;
185
+ /**
186
+ * Determines if a field should be treated as an editor field
187
+ * based on field name conventions
188
+ */
189
+ declare function isEditorField(fieldName: string): boolean;
190
+ /**
191
+ * Determines if a field should be treated as a file field
192
+ * based on field name conventions
193
+ */
194
+ declare function isFileFieldByName(fieldName: string): boolean;
195
+ /**
196
+ * Gets the PocketBase field type with additional context
197
+ */
198
+ interface FieldTypeResult {
199
+ type: PocketBaseFieldType;
200
+ isMultiple: boolean;
201
+ options: ExtractedFieldOptions;
202
+ }
203
+ /**
204
+ * Comprehensive type mapping that returns full field information
205
+ */
206
+ declare function getFieldTypeInfo(zodType: z.ZodTypeAny, fieldName: string): FieldTypeResult;
207
+
208
+ export { isEditorField as A, isFileFieldByName as B, type FieldTypeResult as C, getFieldTypeInfo as D, type ExtractedFieldOptions as E, type FieldTypeInfo as F, POCKETBASE_FIELD_TYPES as P, isMultipleRelationField as a, isRelationField as b, getMinSelect as c, FIELD_TYPE_INFO as d, mapZodNumberType as e, mapZodBooleanType as f, getMaxSelect as g, mapZodEnumType as h, isSingleRelationField as i, mapZodArrayType as j, mapZodDateType as k, mapZodRecordType as l, mapZodStringType as m, mapZodTypeToPocketBase as n, extractFieldOptions as o, pluralize as p, isFieldRequired as q, resolveTargetCollection as r, singularize as s, toCollectionName as t, unwrapZodType as u, getDefaultValue as v, isArrayType as w, getArrayElementType as x, isGeoPointType as y, extractComprehensiveFieldOptions as z };