pocketbase-zod-schema 0.7.2 → 1.0.0
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.
- package/CHANGELOG.md +25 -0
- package/README.md +198 -25
- package/dist/cli/index.cjs +3740 -1233
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +3737 -1232
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +3815 -1201
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +3811 -1199
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.cjs +52 -13
- package/dist/cli/utils/index.cjs.map +1 -1
- package/dist/cli/utils/index.d.cts +46 -1
- package/dist/cli/utils/index.d.ts +46 -1
- package/dist/cli/utils/index.js +51 -13
- package/dist/cli/utils/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +123 -42
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.js +123 -42
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +13 -0
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.js +13 -0
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/engine.cjs +3263 -0
- package/dist/migration/engine.cjs.map +1 -0
- package/dist/migration/engine.d.cts +105 -0
- package/dist/migration/engine.d.ts +105 -0
- package/dist/migration/engine.js +3173 -0
- package/dist/migration/engine.js.map +1 -0
- package/dist/migration/generator.cjs +40 -18
- package/dist/migration/generator.cjs.map +1 -1
- package/dist/migration/generator.d.cts +45 -2
- package/dist/migration/generator.d.ts +45 -2
- package/dist/migration/generator.js +39 -19
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +3479 -1145
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +21 -4
- package/dist/migration/index.d.ts +21 -4
- package/dist/migration/index.js +3433 -1142
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs +2200 -804
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +24 -66
- package/dist/migration/snapshot.d.ts +24 -66
- package/dist/migration/snapshot.js +2198 -801
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +51 -9
- package/dist/migration/utils/index.cjs.map +1 -1
- package/dist/migration/utils/index.d.cts +1 -1
- package/dist/migration/utils/index.d.ts +1 -1
- package/dist/migration/utils/index.js +50 -10
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/server.cjs +3837 -1248
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -4
- package/dist/server.d.ts +6 -4
- package/dist/server.js +3791 -1245
- package/dist/server.js.map +1 -1
- package/dist/{type-mapper-Bu9qjCdd.d.cts → type-mapper-BSPTj8t5.d.cts} +23 -1
- package/dist/{type-mapper-JBaVuKE2.d.ts → type-mapper-D31WYDee.d.ts} +23 -1
- package/dist/types-B_MLb1Ob.d.ts +475 -0
- package/dist/types-upZBVMfb.d.cts +475 -0
- package/dist/verify-BF72n2df.d.ts +402 -0
- package/dist/verify-DTzYpiXX.d.cts +402 -0
- package/package.json +7 -1
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/migration/errors.ts","../../src/migration/analyzer/config.ts","../../src/schema/base.ts","../../src/schema/fields.ts","../../src/utils/permission-templates.ts","../../src/migration/utils/collection-id-generator.ts","../../src/migration/rule-validator.ts","../../src/migration/permission-analyzer.ts","../../src/migration/utils/pluralize.ts","../../src/migration/utils/relation-detector.ts","../../src/migration/utils/type-mapper.ts","../../src/schema/view.ts","../../src/migration/analyzer/extractors.ts","../../src/migration/analyzer/converter.ts","../../src/migration/analyzer/loader.ts","../../src/migration/analyzer/index.ts","../../src/migration/pocketbase-converter.ts","../../src/migration/migration-parser.ts","../../src/migration/snapshot.ts","../../src/migration/diff/config.ts","../../src/migration/diff/utils.ts","../../src/migration/diff/fields.ts","../../src/migration/diff/indexes.ts","../../src/migration/diff/rules.ts","../../src/migration/diff/collections.ts","../../src/migration/diff/summary.ts","../../src/migration/diff/filter.ts","../../src/migration/diff/index.ts","../../src/migration/generator/config.ts","../../src/migration/generator/file-writer.ts","../../src/migration/generator/utils.ts","../../src/migration/generator/fields.ts","../../src/migration/generator/indexes.ts","../../src/migration/generator/rules.ts","../../src/migration/generator/collections.ts","../../src/migration/generator/migrator.ts","../../src/migration/utils/dependency-sorter.ts","../../src/migration/generator/operations.ts","../../src/migration/generator/index.ts","../../src/migration/validation.ts","../../src/cli/utils/config.ts","../../src/cli/utils/logger.ts","../../src/cli/commands/generate.ts","../../src/cli/commands/status.ts"],"names":["path","isAuthCollection","z","getChecks","getJsonSchema","path2","required","options","fieldDef","relationMetadata","fs","path3","fs2","extractFieldOptions","fs3","path4","match","fs4","path5","migrationContent","DEFAULT_CONFIG","mergeConfig","path6","fs5","hasChanges","fs6","path7","path9","hasDestructiveChanges","chalk"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Custom error classes for migration tool\n * Provides specific error types for better error handling and user feedback\n */\n\n/**\n * Base error class for all migration-related errors\n */\nexport class MigrationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MigrationError\";\n Object.setPrototypeOf(this, MigrationError.prototype);\n }\n}\n\n/**\n * Error thrown when schema parsing fails\n * Used when Zod schemas cannot be parsed or are invalid\n */\nexport class SchemaParsingError extends MigrationError {\n public readonly filePath?: string;\n public readonly originalError?: Error;\n\n constructor(message: string, filePath?: string, originalError?: Error) {\n super(message);\n this.name = \"SchemaParsingError\";\n this.filePath = filePath;\n this.originalError = originalError;\n Object.setPrototypeOf(this, SchemaParsingError.prototype);\n }\n\n /**\n * Creates a formatted error message with file path and original error details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.filePath) {\n parts.push(`\\nFile: ${this.filePath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when snapshot operations fail\n * Used for snapshot file read/write/parse errors\n */\nexport class SnapshotError extends MigrationError {\n public readonly snapshotPath?: string;\n public readonly operation?: \"read\" | \"write\" | \"parse\" | \"validate\";\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n snapshotPath?: string,\n operation?: \"read\" | \"write\" | \"parse\" | \"validate\",\n originalError?: Error\n ) {\n super(message);\n this.name = \"SnapshotError\";\n this.snapshotPath = snapshotPath;\n this.operation = operation;\n this.originalError = originalError;\n Object.setPrototypeOf(this, SnapshotError.prototype);\n }\n\n /**\n * Creates a formatted error message with snapshot path and operation details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.operation) {\n parts.push(`\\nOperation: ${this.operation}`);\n }\n\n if (this.snapshotPath) {\n parts.push(`\\nSnapshot: ${this.snapshotPath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when migration file generation fails\n * Used when migration files cannot be created or written\n */\nexport class MigrationGenerationError extends MigrationError {\n public readonly migrationPath?: string;\n public readonly originalError?: Error;\n\n constructor(message: string, migrationPath?: string, originalError?: Error) {\n super(message);\n this.name = \"MigrationGenerationError\";\n this.migrationPath = migrationPath;\n this.originalError = originalError;\n Object.setPrototypeOf(this, MigrationGenerationError.prototype);\n }\n\n /**\n * Creates a formatted error message with migration path and original error details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.migrationPath) {\n parts.push(`\\nMigration: ${this.migrationPath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when file system operations fail\n * Used for directory creation, file permissions, disk space issues\n */\nexport class FileSystemError extends MigrationError {\n public readonly path?: string;\n public readonly operation?: \"read\" | \"write\" | \"create\" | \"delete\" | \"access\";\n public readonly code?: string;\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n path?: string,\n operation?: \"read\" | \"write\" | \"create\" | \"delete\" | \"access\",\n code?: string,\n originalError?: Error\n ) {\n super(message);\n this.name = \"FileSystemError\";\n this.path = path;\n this.operation = operation;\n this.code = code;\n this.originalError = originalError;\n Object.setPrototypeOf(this, FileSystemError.prototype);\n }\n\n /**\n * Creates a formatted error message with path, operation, and error code details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.operation) {\n parts.push(`\\nOperation: ${this.operation}`);\n }\n\n if (this.path) {\n parts.push(`\\nPath: ${this.path}`);\n }\n\n if (this.code) {\n parts.push(`\\nError Code: ${this.code}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when configuration is invalid\n * Used for configuration file parsing, validation, and path resolution errors\n */\nexport class ConfigurationError extends MigrationError {\n public readonly configPath?: string;\n public readonly invalidFields?: string[];\n public readonly originalError?: Error;\n\n constructor(message: string, configPath?: string, invalidFields?: string[], originalError?: Error) {\n super(message);\n this.name = \"ConfigurationError\";\n this.configPath = configPath;\n this.invalidFields = invalidFields;\n this.originalError = originalError;\n Object.setPrototypeOf(this, ConfigurationError.prototype);\n }\n\n /**\n * Creates a formatted error message with configuration details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.configPath) {\n parts.push(`\\nConfiguration File: ${this.configPath}`);\n }\n\n if (this.invalidFields && this.invalidFields.length > 0) {\n parts.push(`\\nInvalid Fields: ${this.invalidFields.join(\", \")}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when CLI command usage is incorrect\n * Used for invalid arguments, missing required options, etc.\n */\nexport class CLIUsageError extends MigrationError {\n public readonly command?: string;\n public readonly suggestion?: string;\n\n constructor(message: string, command?: string, suggestion?: string) {\n super(message);\n this.name = \"CLIUsageError\";\n this.command = command;\n this.suggestion = suggestion;\n Object.setPrototypeOf(this, CLIUsageError.prototype);\n }\n\n /**\n * Creates a formatted error message with usage suggestions\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.command) {\n parts.push(`\\nCommand: ${this.command}`);\n }\n\n if (this.suggestion) {\n parts.push(`\\nSuggestion: ${this.suggestion}`);\n }\n\n return parts.join(\"\");\n }\n}\n","import * as path from \"path\";\n\n/**\n * Configuration options for schema discovery and parsing\n */\nexport interface SchemaAnalyzerConfig {\n /**\n * Directory containing schema files (source or compiled)\n * Can be absolute or relative to workspaceRoot\n */\n schemaDir: string;\n\n /**\n * Workspace root directory for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * File patterns to exclude from schema discovery\n * Defaults to ['base.ts', 'index.ts', 'permissions.ts', 'permission-templates.ts']\n */\n excludePatterns?: string[];\n\n /**\n * File extensions to include in schema discovery\n * Defaults to ['.ts', '.js']\n */\n includeExtensions?: string[];\n\n /**\n * Schema export name patterns to look for\n * Defaults to ['Schema', 'InputSchema']\n */\n schemaPatterns?: string[];\n\n /**\n * Whether to use compiled JavaScript files instead of TypeScript source\n * When true, looks for .js files; when false, looks for .ts files\n * Defaults to true (use compiled files for dynamic import)\n */\n useCompiledFiles?: boolean;\n\n /**\n * Custom path transformation function for converting source paths to import paths\n * Useful for monorepo setups where source and dist directories differ\n * If not provided, uses the schemaDir directly\n */\n pathTransformer?: (sourcePath: string) => string;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<Omit<SchemaAnalyzerConfig, \"schemaDir\" | \"pathTransformer\">> = {\n workspaceRoot: process.cwd(),\n excludePatterns: [\n \"base.ts\",\n \"index.ts\",\n \"permissions.ts\",\n \"permission-templates.ts\",\n \"base.js\",\n \"index.js\",\n \"permissions.js\",\n \"permission-templates.js\",\n ],\n includeExtensions: [\".ts\", \".js\"],\n schemaPatterns: [\"Schema\", \"InputSchema\", \"Collection\"],\n useCompiledFiles: true,\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(\n config: SchemaAnalyzerConfig\n): Required<Omit<SchemaAnalyzerConfig, \"pathTransformer\">> & { pathTransformer?: (sourcePath: string) => string } {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n excludePatterns: config.excludePatterns || DEFAULT_CONFIG.excludePatterns,\n includeExtensions: config.includeExtensions || DEFAULT_CONFIG.includeExtensions,\n schemaPatterns: config.schemaPatterns || DEFAULT_CONFIG.schemaPatterns,\n };\n}\n\n/**\n * Resolves the schema directory path\n */\nexport function resolveSchemaDir(config: SchemaAnalyzerConfig): string {\n const workspaceRoot = config.workspaceRoot || process.cwd();\n\n if (path.isAbsolute(config.schemaDir)) {\n return config.schemaDir;\n }\n\n return path.join(workspaceRoot, config.schemaDir);\n}\n","import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n id: z.string().describe(\"unique id\"),\n collectionId: z.string().describe(\"collection id\"),\n collectionName: z.string().describe(\"collection name\"),\n expand: z.record(z.string(), z.any()).describe(\"expandable fields\"),\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Extended base schema with timestamp fields\n * Includes created and updated autodate fields\n */\nexport const baseSchemaWithTimestamps = {\n ...baseSchema,\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Base schema for image file collections\n * Extends base schema with thumbnail URL and image files array\n */\nexport const baseImageFileSchema = {\n ...baseSchema,\n thumbnailURL: z.string().optional(),\n imageFiles: z.array(z.string()),\n};\n\n/**\n * Input schema for image file uploads\n * Used in forms where users upload File objects\n * Requires Node.js 20+ or browser environment with File API\n */\nexport const inputImageFileSchema = {\n imageFiles: z.array(z.instanceof(File)),\n};\n\n/**\n * Helper constant for omitting image files from schemas\n * Used with Zod's .omit() method\n */\nexport const omitImageFilesSchema = {\n imageFiles: true,\n} as const;\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n// Note: Field type helpers are now exported from ./fields.ts with PascalCase names\n// (e.g., TextField, EmailField, JSONField, etc.) to ensure consistent naming.\n\n// ============================================================================\n// Relation Field Helpers - Explicit Relationship Definitions\n// ============================================================================\n\n/**\n * Relation field configuration options\n */\nexport interface RelationConfig {\n /**\n * Target collection name (e.g., 'users', 'posts', 'tags')\n * This is the PocketBase collection that the relation points to\n */\n collection: string;\n\n /**\n * Whether to cascade delete related records when this record is deleted\n * @default false\n */\n cascadeDelete?: boolean;\n\n /**\n * Fields to display in the admin UI\n */\n displayFields?: string[] | null;\n}\n\n/**\n * Multiple relation field configuration options\n */\nexport interface RelationsConfig extends RelationConfig {\n /**\n * Minimum number of relations required\n * @default 0\n */\n minSelect?: number;\n\n /**\n * Maximum number of relations allowed\n * @default 999\n */\n maxSelect?: number;\n}\n\n/**\n * Internal marker for relation metadata\n * Used by the analyzer to detect explicit relation definitions\n */\nconst RELATION_METADATA_KEY = \"__pocketbase_relation__\";\n\n/**\n * Creates a single relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect=1\n *\n * This is the recommended way to define relations - it's explicit and doesn't\n * rely on naming conventions.\n *\n * @param config - Relation configuration with target collection\n * @returns Zod string schema with relation metadata\n *\n * @example\n * // Single relation to users collection\n * const PostSchema = z.object({\n * title: z.string(),\n * author: RelationField({ collection: 'users' }),\n * });\n *\n * @example\n * // Relation with cascade delete\n * const CommentSchema = z.object({\n * content: z.string(),\n * post: RelationField({ collection: 'posts', cascadeDelete: true }),\n * });\n */\nexport function RelationField(config: RelationConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"single\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: 1,\n minSelect: 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect>1\n *\n * This is the recommended way to define multi-relations - it's explicit and\n * doesn't rely on naming conventions.\n *\n * @param config - Relations configuration with target collection and limits\n * @returns Zod array of strings schema with relation metadata\n *\n * @example\n * // Multiple relations to tags collection\n * const PostSchema = z.object({\n * title: z.string(),\n * tags: RelationsField({ collection: 'tags' }),\n * });\n *\n * @example\n * // Relations with min/max constraints\n * const ProjectSchema = z.object({\n * title: z.string(),\n * collaborators: RelationsField({\n * collection: 'users',\n * minSelect: 1,\n * maxSelect: 10,\n * }),\n * });\n */\nexport function RelationsField(config: RelationsConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"multiple\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: config.maxSelect ?? 999,\n minSelect: config.minSelect ?? 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n let schema = z.array(z.string());\n\n // Apply array constraints for Zod validation\n if (config.minSelect !== undefined) {\n schema = schema.min(config.minSelect);\n }\n if (config.maxSelect !== undefined) {\n schema = schema.max(config.maxSelect);\n }\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Extracts relation metadata from a Zod type's description\n * Used internally by the analyzer to detect explicit relation definitions\n *\n * @param description - The Zod type's description string\n * @returns Relation metadata if present, null otherwise\n */\nexport function extractRelationMetadata(description: string | undefined): {\n type: \"single\" | \"multiple\";\n collection: string;\n cascadeDelete: boolean;\n maxSelect: number;\n minSelect: number;\n displayFields?: string[] | null;\n} | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[RELATION_METADATA_KEY]) {\n return parsed[RELATION_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n/**\n * Attach permission metadata to a Zod schema\n *\n * This helper function allows you to define PocketBase API rules alongside your\n * entity schema definitions. The permissions are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach permissions to\n * @param config - Either a PermissionTemplateConfig (for template-based permissions)\n * or a PermissionSchema (for custom permissions)\n * @returns The schema with permission metadata attached\n *\n * @example\n * // Using a template\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * { template: 'owner-only', ownerField: 'User' }\n * );\n *\n * @example\n * // Using custom rules\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string() }),\n * { listRule: '@request.auth.id != \"\"', viewRule: '' }\n * );\n *\n * @example\n * // Using template with custom rule overrides\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * {\n * template: 'owner-only',\n * ownerField: 'User',\n * customRules: { listRule: '@request.auth.id != \"\"' }\n * }\n * );\n */\nexport function withPermissions<T extends z.ZodTypeAny>(\n schema: T,\n config: PermissionTemplateConfig | PermissionSchema\n): T {\n // Create metadata object with permissions config directly\n // The PermissionAnalyzer will handle resolving templates vs direct schemas\n const metadata = {\n permissions: config,\n };\n\n // Attach permission metadata to schema using Zod's describe() method\n // The metadata is serialized as JSON and stored in the schema's description\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Attach index definitions to a Zod schema\n *\n * This helper function allows you to define PocketBase indexes alongside your\n * entity schema definitions. The indexes are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach indexes to\n * @param indexes - Array of PocketBase index SQL statements\n * @returns The schema with index metadata attached\n *\n * @example\n * // Define indexes for a user schema\n * const UserSchema = withIndexes(\n * withPermissions(\n * z.object({ name: z.string(), email: z.string().email() }),\n * userPermissions\n * ),\n * [\n * 'CREATE UNIQUE INDEX idx_users_email ON users (email)',\n * 'CREATE INDEX idx_users_name ON users (name)'\n * ]\n * );\n *\n * @example\n * // Single index\n * const ProjectSchema = withIndexes(\n * ProjectDatabaseSchema,\n * ['CREATE INDEX idx_projects_status ON projects (status)']\n * );\n */\nexport function withIndexes<T extends z.ZodTypeAny>(schema: T, indexes: string[]): T {\n // Extract existing metadata if present\n let existingMetadata: any = {};\n\n if (schema.description) {\n try {\n existingMetadata = JSON.parse(schema.description);\n } catch {\n // If description is not JSON, ignore it\n }\n }\n\n // Merge indexes with existing metadata\n const metadata = {\n ...existingMetadata,\n indexes,\n };\n\n // Attach metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Configuration options for defining a collection\n */\nexport interface CollectionConfig {\n /**\n * The name of the PocketBase collection\n * This will be used when generating migrations\n */\n collectionName: string;\n\n /**\n * The Zod schema definition for the collection\n */\n schema: z.ZodObject<any>;\n\n /**\n * Optional permission configuration\n * Can be a template-based config or custom permission rules\n */\n permissions?: PermissionTemplateConfig | PermissionSchema;\n\n /**\n * Optional array of index SQL statements\n * Example: ['CREATE UNIQUE INDEX idx_users_email ON users (email)']\n */\n indexes?: string[];\n\n /**\n * Optional collection type\n * - \"base\": Standard collection (default)\n * - \"auth\": Authentication collection with system auth fields\n * - \"view\": Read-only collection backed by a SQL query (requires viewQuery)\n *\n * If not specified, the type will be auto-detected based on field presence\n * (collections with both email and password fields are detected as auth)\n *\n * Prefer defineView() over type: \"view\" - it enforces the constraints\n * PocketBase places on view collections at compile time.\n */\n type?: \"base\" | \"auth\" | \"view\";\n\n /**\n * SQL SELECT statement backing a view collection\n *\n * Only valid when type is \"view\", where it is required. PocketBase derives\n * the collection's fields by running this query, so the Zod schema is used\n * for TypeScript types only.\n */\n viewQuery?: string;\n\n /**\n * Future extensibility - additional options can be added here\n */\n [key: string]: unknown;\n}\n\n/**\n * High-level wrapper for defining a PocketBase collection with all metadata\n *\n * This is the recommended way to define collections as it provides a single\n * entry point for collection name, schema, permissions, indexes, and future features.\n *\n * @param config - Collection configuration object\n * @returns The schema with all metadata attached\n *\n * @example\n * // Recommended: Use default export for clarity\n * const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n * export default PostCollection;\n *\n * @example\n * // Also supported: Named export (backward compatible)\n * export const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n *\n * @example\n * // Collection with permissions and indexes\n * export const UserSchema = defineCollection({\n * collectionName: \"users\",\n * schema: z.object({\n * name: z.string(),\n * email: z.string().email(),\n * }),\n * permissions: {\n * listRule: \"id = @request.auth.id\",\n * viewRule: \"id = @request.auth.id\",\n * createRule: \"\",\n * updateRule: \"id = @request.auth.id\",\n * deleteRule: \"id = @request.auth.id\",\n * },\n * indexes: [\n * \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n * ],\n * });\n *\n * @example\n * // Collection with template and custom rule overrides\n * export const ProjectSchema = defineCollection({\n * collectionName: \"projects\",\n * schema: z.object({\n * title: z.string(),\n * owner: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"owner\",\n * customRules: {\n * listRule: '@request.auth.id != \"\"',\n * },\n * },\n * });\n */\nexport function defineCollection(config: CollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, permissions, indexes, type, viewQuery, ...futureOptions } = config;\n\n // Build metadata object\n const metadata: any = {\n collectionName,\n };\n\n // Add type if provided\n if (type) {\n metadata.type = type;\n }\n\n // Add the SQL query backing a view collection\n if (viewQuery !== undefined) {\n metadata.viewQuery = viewQuery;\n }\n\n // Add permissions if provided\n if (permissions) {\n metadata.permissions = permissions;\n }\n\n // Add indexes if provided\n if (indexes) {\n metadata.indexes = indexes;\n }\n\n // Add any future options\n if (Object.keys(futureOptions).length > 0) {\n Object.assign(metadata, futureOptions);\n }\n\n // Attach all metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as z.ZodObject<any>;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Field Metadata System\n// ============================================================================\n\n/**\n * Internal marker for field metadata\n * Used by the migration generator to detect explicit field type definitions\n */\nexport const FIELD_METADATA_KEY = \"__pocketbase_field__\";\n\n/**\n * PocketBase field types\n */\nexport type PocketBaseFieldType =\n | \"text\"\n | \"email\"\n | \"url\"\n | \"editor\"\n | \"number\"\n | \"bool\"\n | \"date\"\n | \"autodate\"\n | \"select\"\n | \"relation\"\n | \"file\"\n | \"json\"\n | \"geoPoint\"\n | \"password\";\n\n/**\n * Field metadata structure embedded in Zod schema descriptions\n */\nexport interface FieldMetadata {\n type: PocketBaseFieldType;\n options?: Record<string, any>;\n}\n\n/**\n * Extracts field metadata from a Zod type's description\n * Used by the migration generator to detect explicit field type definitions\n *\n * @param description - The Zod type's description string\n * @returns Field metadata if present, null otherwise\n *\n * @example\n * const schema = TextField({ min: 1, max: 100 });\n * const metadata = extractFieldMetadata(schema.description);\n * // Returns: { type: \"text\", options: { min: 1, max: 100 } }\n */\nexport function extractFieldMetadata(description: string | undefined): FieldMetadata | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[FIELD_METADATA_KEY]) {\n return parsed[FIELD_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n// ============================================================================\n// Field Options Interfaces\n// ============================================================================\n\n/**\n * Text field configuration options\n */\nexport interface TextFieldOptions {\n /**\n * Minimum length constraint\n */\n min?: number;\n\n /**\n * Maximum length constraint\n */\n max?: number;\n\n /**\n * Pattern constraint (regex)\n */\n pattern?: RegExp | string;\n\n /**\n * Auto-generate pattern for automatic value generation\n * Example: \"[A-Z]{3}-[0-9]{6}\" generates values like \"ABC-123456\"\n */\n autogeneratePattern?: string;\n}\n\n/**\n * Number field configuration options\n */\nexport interface NumberFieldOptions {\n /**\n * Minimum value constraint\n */\n min?: number;\n\n /**\n * Maximum value constraint\n */\n max?: number;\n\n /**\n * Whether to disallow decimal values (integers only)\n */\n noDecimal?: boolean;\n\n /**\n * Whether the field is required\n * @default false\n *\n * Note: In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you want to allow zero values (e.g., for progress: 0-100), keep this as `false`.\n * Set to `true` only if you want to enforce non-zero values.\n */\n required?: boolean;\n}\n\n/**\n * Date field configuration options\n */\nexport interface DateFieldOptions {\n /**\n * Minimum date constraint\n */\n min?: Date | string;\n\n /**\n * Maximum date constraint\n */\n max?: Date | string;\n}\n\n/**\n * Autodate field configuration options\n */\nexport interface AutodateFieldOptions {\n /**\n * Set date automatically on record creation\n * @default false\n */\n onCreate?: boolean;\n\n /**\n * Update date automatically on record update\n * @default false\n */\n onUpdate?: boolean;\n}\n\n/**\n * Select field configuration options\n */\nexport interface SelectFieldOptions {\n /**\n * Maximum number of selections allowed\n * If > 1, enables multiple selection\n * @default 1\n */\n maxSelect?: number;\n}\n\ntype EnumFromArray<T extends readonly [string, ...string[]]> = z.ZodEnum<z.core.util.ToEnum<T[number]>>;\n\n/**\n * Human-friendly byte size input.\n *\n * - Use a number for raw bytes (e.g. `5242880`)\n * - Use a string with unit suffix for kibibytes/mebibytes/gibibytes (e.g. `\"5M\"`, `\"1G\"`)\n *\n * Supported suffixes: `K`, `M`, `G` (case-insensitive).\n */\nexport type ByteSize = number | `${number}${\"K\" | \"M\" | \"G\" | \"k\" | \"m\" | \"g\"}`;\n\n/**\n * File field configuration options\n */\nexport interface FileFieldOptions {\n /**\n * Allowed MIME types\n * Example: [\"image/*\", \"application/pdf\"]\n */\n mimeTypes?: string[];\n\n /**\n * Maximum file size.\n *\n * - Provide a number for raw bytes\n * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n *\n * Max allowed is `8G`.\n *\n * @example\n * maxSize: 5242880\n * maxSize: \"5M\"\n * maxSize: \"1G\"\n */\n maxSize?: ByteSize;\n\n /**\n * Thumbnail sizes to generate\n * Example: [\"100x100\", \"200x200\"]\n * Set to null to explicitly disable thumbnails\n */\n thumbs?: string[];\n\n /**\n * Whether the file is protected (requires auth to access)\n * @default false\n */\n protected?: boolean;\n}\n\n/**\n * Multiple files field configuration options\n */\nexport interface FilesFieldOptions extends FileFieldOptions {\n /**\n * Minimum number of files required\n */\n minSelect?: number;\n\n /**\n * Maximum number of files allowed\n */\n maxSelect?: number;\n}\n\nconst MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024; // 8G\n\nfunction parseByteSizeToBytes(value: ByteSize, context: string): number {\n let bytes: number;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(`${context}: maxSize must be a finite number of bytes`);\n }\n bytes = Math.round(value);\n } else {\n const trimmed = value.trim();\n const match = /^(\\d+(?:\\.\\d+)?)\\s*([KMG])$/i.exec(trimmed);\n if (!match) {\n throw new Error(`${context}: maxSize string must be like \"10K\", \"5M\", or \"1G\" (case-insensitive)`);\n }\n\n const amount = Number(match[1]);\n const unit = match[2].toUpperCase() as \"K\" | \"M\" | \"G\";\n\n if (!Number.isFinite(amount)) {\n throw new Error(`${context}: maxSize must be a valid number`);\n }\n\n const multiplier = unit === \"K\" ? 1024 : unit === \"M\" ? 1024 * 1024 : 1024 * 1024 * 1024;\n bytes = Math.round(amount * multiplier);\n }\n\n if (bytes < 0) {\n throw new Error(`${context}: maxSize must be >= 0`);\n }\n\n if (bytes > MAX_FILE_SIZE_BYTES) {\n throw new Error(`${context}: maxSize cannot exceed 8G (${MAX_FILE_SIZE_BYTES} bytes)`);\n }\n\n return bytes;\n}\n\nfunction normalizeFileFieldOptions(\n options: FileFieldOptions | undefined,\n context: string\n): FileFieldOptions | undefined {\n if (!options) return options;\n if (options.maxSize === undefined) return options;\n\n return {\n ...options,\n // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.\n maxSize: parseByteSizeToBytes(options.maxSize, context),\n };\n}\n\n// ============================================================================\n// Field Helper Functions\n// ============================================================================\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n *\n * @returns Zod boolean schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * active: BoolField(),\n * featured: BoolField().optional(),\n * });\n */\nexport function BoolField(): z.ZodBoolean {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"bool\" as const,\n },\n };\n\n return z.boolean().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a number field schema with optional constraints\n * Maps to PocketBase 'number' field type\n *\n * @param options - Optional constraints for the number field\n * @returns Zod number schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * price: NumberField({ min: 0 }),\n * quantity: NumberField({ min: 0, noDecimal: true }),\n * rating: NumberField({ min: 0, max: 5 }),\n * progress: NumberField({ min: 0, max: 100 }), // required defaults to false, allowing zero\n * score: NumberField({ min: 1, max: 10, required: true }), // requires non-zero value\n * });\n *\n * @remarks\n * By default, number fields are not required (`required: false`), which allows zero values.\n * In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you set `min: 0` and want to allow zero, keep `required: false` (the default).\n */\nexport function NumberField(options?: NumberFieldOptions): z.ZodNumber {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"NumberField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.number();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"number\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a text field schema with optional constraints\n * Maps to PocketBase 'text' field type\n *\n * @param options - Optional constraints for the text field\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * name: TextField({ min: 1, max: 200 }),\n * sku: TextField({ autogeneratePattern: \"[A-Z]{3}-[0-9]{6}\" }),\n * description: TextField({ max: 1000 }),\n * });\n */\nexport function TextField(options?: TextFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"TextField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.string();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n if (options?.pattern !== undefined) {\n const pattern = options.pattern instanceof RegExp ? options.pattern : new RegExp(options.pattern);\n schema = schema.regex(pattern);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"text\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n *\n * @returns Zod string schema with email validation and PocketBase metadata\n *\n * @example\n * const UserSchema = z.object({\n * email: EmailField(),\n * alternateEmail: EmailField().optional(),\n * });\n */\nexport function EmailField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"email\" as const,\n },\n };\n\n return z.string().email().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n *\n * @returns Zod string schema with URL validation and PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * website: URLField(),\n * documentation: URLField().optional(),\n * });\n */\nexport function URLField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"url\" as const,\n },\n };\n\n return z.string().url().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a rich text editor field schema\n * Maps to PocketBase 'editor' field type\n *\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * content: EditorField(),\n * summary: EditorField().optional(),\n * });\n */\nexport function EditorField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"editor\" as const,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a date field schema with optional constraints\n * Maps to PocketBase 'date' field type\n *\n * @param options - Optional date constraints\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const EventSchema = z.object({\n * startDate: DateField(),\n * endDate: DateField({ min: new Date('2024-01-01') }),\n * releaseDate: DateField().optional(),\n * });\n */\nexport function DateField(options?: DateFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n const minDate = typeof options.min === \"string\" ? new Date(options.min) : options.min;\n const maxDate = typeof options.max === \"string\" ? new Date(options.max) : options.max;\n if (minDate > maxDate) {\n throw new Error(\"DateField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"date\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an autodate field schema with automatic timestamp management\n * Maps to PocketBase 'autodate' field type\n *\n * @param options - Optional autodate configuration\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * createdAt: AutodateField({ onCreate: true }),\n * updatedAt: AutodateField({ onUpdate: true }),\n * publishedAt: AutodateField({ onCreate: true, onUpdate: false }),\n * });\n */\nexport function AutodateField(options?: AutodateFieldOptions): z.ZodString {\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"autodate\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod enum or array schema with PocketBase metadata\n *\n * @example\n * // Single select\n * const PostSchema = z.object({\n * status: SelectField([\"draft\", \"published\", \"archived\"]),\n * });\n *\n * @example\n * // Multiple select\n * const ProductSchema = z.object({\n * categories: SelectField([\"electronics\", \"clothing\", \"food\"], { maxSelect: 3 }),\n * });\n */\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): EnumFromArray<T> | z.ZodArray<EnumFromArray<T>> {\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return MultiSelectField(values, options);\n }\n\n return SingleSelectField(values);\n}\n\n/**\n * Creates a single select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect=1\n *\n * @param values - Array of allowed string values\n * @returns Zod enum schema with PocketBase metadata\n */\nexport function SingleSelectField<const T extends readonly [string, ...string[]]>(values: T): EnumFromArray<T> {\n const enumSchema = z.enum(values);\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: 1,\n },\n },\n };\n\n return enumSchema.describe(JSON.stringify(metadata)) as EnumFromArray<T>;\n}\n\n/**\n * Creates a multiple select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect>1\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod array schema with PocketBase metadata\n */\nexport function MultiSelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodArray<EnumFromArray<T>> {\n const enumSchema = z.enum(values);\n const maxSelect = options?.maxSelect ?? 999;\n\n if (maxSelect <= 1) {\n throw new Error(\"MultiSelectField: maxSelect must be greater than 1\");\n }\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect,\n },\n },\n };\n\n return z.array(enumSchema).describe(JSON.stringify(metadata)) as z.ZodArray<EnumFromArray<T>>;\n}\n\n/**\n * Creates a single file field schema\n * Maps to PocketBase 'file' field type with maxSelect=1\n *\n * @param options - Optional file constraints\n * @returns Zod schema that accepts File on input and returns string when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File objects\n * - When reading from PocketBase: returns string (filename)\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<string, File | string> {\n // Accept File for input (when creating/updating) or string (when reading from DB)\n // Output is always string (as returned by PocketBase)\n const schema = z.preprocess((val) => {\n // If it's a File, return its name (or empty string if no name)\n // If it's already a string (from DB), return as-is\n return val instanceof File ? val.name || \"\" : val;\n }, z.string()) as z.ZodType<string, File | string>;\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FileField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple files field schema\n * Maps to PocketBase 'file' field type with maxSelect>1\n *\n * @param options - Optional file constraints\n * @returns Zod array schema that accepts File[] on input and returns string[] when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File[]\n * - When reading from PocketBase: returns string[] (filenames)\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodType<string[], (File | string)[]> {\n // Validate options\n if (options?.minSelect !== undefined && options?.maxSelect !== undefined) {\n if (options.minSelect > options.maxSelect) {\n throw new Error(\"FilesField: minSelect cannot be greater than maxSelect\");\n }\n }\n\n // Accept File[] for input (when creating/updating) or string[] (when reading from DB)\n // Output is always string[] (as returned by PocketBase)\n let baseArraySchema = z.array(z.string());\n\n // Apply Zod validations first\n if (options?.minSelect !== undefined) {\n baseArraySchema = baseArraySchema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n baseArraySchema = baseArraySchema.max(options.maxSelect);\n }\n\n const schema = z.preprocess((val) => {\n // Handle array of Files or strings\n if (Array.isArray(val)) {\n return val.map((item) => (item instanceof File ? item.name || \"\" : item));\n }\n return val;\n }, baseArraySchema);\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FilesField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata)) as z.ZodType<string[], (File | string)[]>;\n}\n\n/**\n * Creates a JSON field schema with optional inner schema validation\n * Maps to PocketBase 'json' field type\n *\n * @param schema - Optional Zod schema for the JSON structure\n * @returns Zod schema with PocketBase metadata\n *\n * @example\n * // Any JSON\n * const ProductSchema = z.object({\n * metadata: JSONField(),\n * });\n *\n * @example\n * // Typed JSON\n * const ProductSchema = z.object({\n * settings: JSONField(z.object({\n * theme: z.string(),\n * notifications: z.boolean(),\n * })),\n * });\n */\nexport function JSONField<T extends z.ZodTypeAny>(schema?: T): T | z.ZodRecord<z.ZodString, z.ZodAny> {\n const baseSchema = schema ?? z.record(z.string(), z.any());\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"json\" as const,\n },\n };\n\n return baseSchema.describe(JSON.stringify(metadata)) as T | z.ZodRecord<z.ZodString, z.ZodAny>;\n}\n\n/**\n * Creates a geographic point field schema\n * Maps to PocketBase 'geoPoint' field type\n *\n * @returns Zod object schema with lon/lat fields and PocketBase metadata\n *\n * @example\n * const LocationSchema = z.object({\n * coordinates: GeoPointField(),\n * homeLocation: GeoPointField().optional(),\n * });\n */\nexport function GeoPointField(): z.ZodObject<{\n lon: z.ZodNumber;\n lat: z.ZodNumber;\n}> {\n const schema = z.object({\n lon: z.number(),\n lat: z.number(),\n });\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"geoPoint\" as const,\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n","import 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","/**\n * Collection ID generation utilities for PocketBase migrations\n */\n\nimport { createHash, randomBytes } from \"crypto\";\n\n/**\n * Generates a unique collection ID in PocketBase format\n * Format: pb_ followed by 15 alphanumeric lowercase characters\n *\n * @returns A unique collection ID string (e.g., \"pb_a1b2c3d4e5f6g7h\")\n */\nexport function generateCollectionId(): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const idLength = 15;\n\n // Generate cryptographically secure random bytes\n const bytes = randomBytes(idLength);\n\n // Convert bytes to alphanumeric characters\n let id = \"pb_\";\n for (let i = 0; i < idLength; i++) {\n const index = bytes[i] % chars.length;\n id += chars[index];\n }\n\n return id;\n}\n\n/**\n * Generates a unique field ID based on type and name\n * Format: type followed by 10 alphanumeric lowercase characters\n * If name is provided, the ID is deterministic\n *\n * @param type - PocketBase field type\n * @param name - Optional field name for deterministic ID\n * @returns A unique field ID string\n */\nexport function generateFieldId(type: string, name?: string): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const idLength = 10;\n\n let bytes: Buffer | Uint8Array;\n if (name) {\n // Deterministic based on name to ensure stability across runs\n bytes = createHash(\"sha256\").update(name).digest();\n } else {\n // Random\n bytes = randomBytes(idLength);\n }\n\n // Convert bytes to alphanumeric characters\n let suffix = \"\";\n for (let i = 0; i < idLength; i++) {\n const index = bytes[i] % chars.length;\n suffix += chars[index];\n }\n\n return `${type}${suffix}`;\n}\n\n/**\n * Registry to track generated collection IDs and ensure uniqueness within a migration batch\n */\nexport class CollectionIdRegistry {\n private ids: Set<string>;\n\n constructor() {\n this.ids = new Set<string>();\n }\n\n /**\n * Generates a unique collection ID for a given collection name\n * Retries up to 10 times if collision occurs (extremely rare)\n * Special case: returns \"_pb_users_auth_\" for users collection\n *\n * @param collectionName - The name of the collection (optional)\n * @returns A unique collection ID\n * @throws Error if unable to generate unique ID after max attempts\n */\n generate(collectionName?: string): string {\n // Special case: users collection always uses the constant\n if (collectionName && collectionName.toLowerCase() === \"users\") {\n const usersId = \"_pb_users_auth_\";\n if (!this.has(usersId)) {\n this.register(usersId);\n }\n return usersId;\n }\n\n const maxAttempts = 10;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const id = generateCollectionId();\n\n if (!this.has(id)) {\n this.register(id);\n return id;\n }\n }\n\n throw new Error(\"Failed to generate unique collection ID after maximum attempts\");\n }\n\n /**\n * Checks if an ID has already been registered\n *\n * @param id - The collection ID to check\n * @returns True if the ID exists in the registry\n */\n has(id: string): boolean {\n return this.ids.has(id);\n }\n\n /**\n * Registers a collection ID in the registry\n *\n * @param id - The collection ID to register\n */\n register(id: string): void {\n this.ids.add(id);\n }\n}\n","/**\n * Rule validator for PocketBase API rule expressions\n *\n * Validates permission rule expressions against PocketBase syntax rules,\n * including field references, @request references, and basic syntax validation.\n */\n\nimport type { APIRuleType, RuleExpression } from \"../utils/permissions\";\nimport type { FieldDefinition } from \"./types\";\nimport { generateFieldId } from \"./utils/collection-id-generator.js\";\n\n/**\n * Validation result for rule expressions\n */\nexport interface RuleValidationResult {\n /** Whether the rule expression is valid */\n valid: boolean;\n\n /** List of validation errors */\n errors: string[];\n\n /** List of validation warnings */\n warnings: string[];\n\n /** List of field references found in the expression */\n fieldReferences: string[];\n}\n\n/**\n * Rule expression validator\n *\n * Validates PocketBase API rule expressions for:\n * - Field reference existence and validity\n * - @request reference syntax\n * - Basic expression syntax (parentheses, operators)\n * - Auth collection specific rules (manageRule)\n */\nexport class RuleValidator {\n private fields: Map<string, FieldDefinition>;\n private collectionName: string;\n private isAuthCollection: boolean;\n\n constructor(collectionName: string, fields: FieldDefinition[], isAuthCollection: boolean = false) {\n this.collectionName = collectionName;\n this.fields = new Map(fields.map((f) => [f.name, f]));\n this.isAuthCollection = isAuthCollection;\n\n // Add system fields that are always available in PocketBase\n this.addSystemFields();\n }\n\n /**\n * Add system fields that are always available in PocketBase collections\n * These fields are automatically added by PocketBase and can be referenced in rules\n */\n private addSystemFields(): void {\n // Base system fields available in all collections\n const systemFields: FieldDefinition[] = [\n { name: \"id\", id: generateFieldId(\"text\", \"id\"), type: \"text\", required: true, options: {} },\n { name: \"created\", id: generateFieldId(\"date\", \"created\"), type: \"date\", required: true, options: {} },\n { name: \"updated\", id: generateFieldId(\"date\", \"updated\"), type: \"date\", required: true, options: {} },\n { name: \"collectionId\", id: generateFieldId(\"text\", \"collectionId\"), type: \"text\", required: true, options: {} },\n { name: \"collectionName\", id: generateFieldId(\"text\", \"collectionName\"), type: \"text\", required: true, options: {} },\n ];\n\n // Auth collection specific system fields\n if (this.isAuthCollection) {\n systemFields.push(\n { name: \"email\", id: generateFieldId(\"email\", \"email\"), type: \"email\", required: true, options: {} },\n { name: \"emailVisibility\", id: generateFieldId(\"bool\", \"emailVisibility\"), type: \"bool\", required: false, options: {} },\n { name: \"verified\", id: generateFieldId(\"bool\", \"verified\"), type: \"bool\", required: false, options: {} },\n { name: \"tokenKey\", id: generateFieldId(\"text\", \"tokenKey\"), type: \"text\", required: true, options: {} },\n { name: \"password\", id: generateFieldId(\"text\", \"password\"), type: \"text\", required: true, options: {} }\n );\n }\n\n // Add system fields to the fields map (don't overwrite user-defined fields)\n for (const field of systemFields) {\n if (!this.fields.has(field.name)) {\n this.fields.set(field.name, field);\n }\n }\n }\n\n /**\n * Validate a rule expression\n *\n * @param ruleType - The type of rule being validated\n * @param expression - The rule expression to validate\n * @returns Validation result with errors, warnings, and field references\n */\n validate(ruleType: APIRuleType, expression: RuleExpression): RuleValidationResult {\n const result: RuleValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n fieldReferences: [],\n };\n\n // Null means locked (superuser only) - always valid\n if (expression === null) {\n return result;\n }\n\n // Empty string means public - always valid but warn\n if (expression === \"\") {\n result.warnings.push(`${ruleType} is public - anyone can perform this operation`);\n return result;\n }\n\n // Validate manageRule only for auth collections\n if (ruleType === \"manageRule\" && !this.isAuthCollection) {\n result.valid = false;\n result.errors.push(\"manageRule is only valid for auth collections\");\n return result;\n }\n\n // Extract and validate field references\n const fieldRefs = this.extractFieldReferences(expression);\n result.fieldReferences = fieldRefs;\n\n for (const fieldRef of fieldRefs) {\n this.validateFieldReference(fieldRef, result);\n }\n\n // Validate @request references\n this.validateRequestReferences(expression, result);\n\n // Validate syntax patterns\n this.validateSyntax(expression, result);\n\n return result;\n }\n\n /**\n * Extract field references from expression\n *\n * Matches field names that are not @request references.\n * Handles dot notation for relations: user.email, post.author.name\n *\n * @param expression - The rule expression\n * @returns Array of unique field references\n */\n private extractFieldReferences(expression: string): string[] {\n const refs: string[] = [];\n\n // First, remove string literals and @request references to avoid matching them\n let cleaned = expression.replace(/\"[^\"]*\"/g, '\"\"').replace(/'[^']*'/g, \"''\");\n cleaned = cleaned.replace(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g, \"\");\n\n // Match field names (not starting with @)\n // Handles dot notation for relations: user.email, post.author.name\n const fieldPattern = /(?:^|[^@\\w])([a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*)(?=[^a-zA-Z0-9_.]|$)/g;\n\n let match;\n while ((match = fieldPattern.exec(cleaned)) !== null) {\n const ref = match[1];\n // Exclude PocketBase keywords and operators\n if (!this.isKeyword(ref)) {\n refs.push(ref);\n }\n }\n\n return [...new Set(refs)]; // Remove duplicates\n }\n\n /**\n * Check if a word is a PocketBase keyword\n *\n * @param word - The word to check\n * @returns True if the word is a keyword\n */\n private isKeyword(word: string): boolean {\n const keywords = [\"true\", \"false\", \"null\", \"AND\", \"OR\", \"NOT\", \"LIKE\", \"IN\"];\n return keywords.includes(word.toUpperCase());\n }\n\n /**\n * Validate a field reference exists in schema\n *\n * Checks if the root field exists and validates relation chains.\n * For nested references, warns about potential issues since we can't\n * validate across collections without loading related schemas.\n *\n * @param fieldRef - The field reference to validate (e.g., \"user\" or \"user.email\")\n * @param result - The validation result to update\n */\n private validateFieldReference(fieldRef: string, result: RuleValidationResult): void {\n const parts = fieldRef.split(\".\");\n const rootField = parts[0];\n\n if (!this.fields.has(rootField)) {\n result.errors.push(`Field '${rootField}' does not exist in collection '${this.collectionName}'`);\n result.valid = false;\n return;\n }\n\n // For nested references, validate relation chain\n if (parts.length > 1) {\n const field = this.fields.get(rootField)!;\n if (field.type !== \"relation\") {\n result.errors.push(`Field '${rootField}' is not a relation field, cannot access nested property '${parts[1]}'`);\n result.valid = false;\n } else {\n // Note: We can't validate nested fields without loading related schemas\n // This would require cross-schema validation\n result.warnings.push(\n `Nested field reference '${fieldRef}' - ensure target collection has field '${parts.slice(1).join(\".\")}'`\n );\n }\n }\n }\n\n /**\n * Validate @request references\n *\n * Checks that @request references follow valid PocketBase patterns:\n * - @request.auth.* - authenticated user data\n * - @request.body.* - request body fields\n * - @request.query.* - query parameters\n * - @request.headers.* - request headers\n * - @request.method - HTTP method\n * - @request.context - execution context\n *\n * @param expression - The rule expression\n * @param result - The validation result to update\n */\n private validateRequestReferences(expression: string, result: RuleValidationResult): void {\n // Find all @request references\n const requestRefs = expression.match(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];\n\n for (const ref of requestRefs) {\n // Check if the reference starts with a valid pattern\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\n /**\n * Validate basic syntax patterns\n *\n * Checks for:\n * - Balanced parentheses\n * - Common operator mistakes (== instead of =)\n *\n * @param expression - The rule expression\n * @param result - The validation result to update\n */\n private validateSyntax(expression: string, result: RuleValidationResult): void {\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 in expression\");\n result.valid = false;\n return;\n }\n }\n if (parenCount !== 0) {\n result.errors.push(\"Unbalanced parentheses in expression\");\n result.valid = false;\n }\n\n // Warn about common mistakes\n if (expression.includes(\"==\")) {\n result.warnings.push(\"Use '=' instead of '==' for equality comparison in PocketBase rules\");\n }\n }\n}\n","/**\n * Permission analyzer for extracting and validating permissions from Zod schemas\n *\n * This module provides utilities to:\n * - Extract permission metadata from Zod schema descriptions\n * - Resolve template configurations to concrete permission schemas\n * - Validate permission rules against collection fields\n * - Merge permissions with default values\n */\n\nimport { resolveTemplate } from \"../utils/permission-templates\";\nimport type { APIRuleType, PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\nimport type { RuleValidationResult } from \"./rule-validator\";\nimport { RuleValidator } from \"./rule-validator\";\nimport type { FieldDefinition } from \"./types\";\n\n/**\n * Extract and analyze permissions from schema\n *\n * The PermissionAnalyzer class provides methods to work with permission\n * definitions attached to Zod schemas, including extraction, resolution,\n * validation, and normalization.\n */\nexport class PermissionAnalyzer {\n /**\n * Extract permission metadata from Zod schema description\n *\n * Zod schemas can have permission metadata attached via the describe() method.\n * This method parses the description and extracts the permission configuration.\n *\n * @param schemaDescription - The Zod schema description string\n * @returns Permission schema if found, null otherwise\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const permissions = analyzer.extractPermissions(schema.description);\n * ```\n */\n extractPermissions(schemaDescription: string | undefined): PermissionSchema | null {\n if (!schemaDescription) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(schemaDescription);\n if (metadata.permissions) {\n return metadata.permissions;\n }\n } catch {\n // Not JSON or no permissions - this is expected for schemas without permissions\n return null;\n }\n\n return null;\n }\n\n /**\n * Resolve template configuration to concrete rules\n *\n * Takes either a template configuration or a direct permission schema\n * and returns a fully resolved permission schema with all rules defined.\n *\n * If the input is already a permission schema (has rule properties),\n * it's returned as-is. Otherwise, the template is resolved using the\n * template resolver.\n *\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n *\n * // Resolve from template\n * const permissions = analyzer.resolvePermissions({\n * template: 'owner-only',\n * ownerField: 'User'\n * });\n *\n * // Or pass direct schema\n * const permissions = analyzer.resolvePermissions({\n * listRule: '@request.auth.id != \"\"',\n * viewRule: '@request.auth.id != \"\"'\n * });\n * ```\n */\n resolvePermissions(config: PermissionTemplateConfig | PermissionSchema): PermissionSchema {\n // If it's already a permission schema (has rule properties), return as-is\n if (\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 return config as PermissionSchema;\n }\n\n // Otherwise resolve template\n return resolveTemplate(config as PermissionTemplateConfig);\n }\n\n /**\n * Validate all rules in a permission schema\n *\n * Validates each rule in the permission schema against the collection's\n * field definitions. Returns a map of validation results keyed by rule type.\n *\n * Only validates rules that are defined (not undefined). Undefined rules\n * are treated as null (locked) by default.\n *\n * @param collectionName - Name of the collection being validated\n * @param permissions - Permission schema to validate\n * @param fields - Collection field definitions\n * @param isAuthCollection - Whether this is an auth collection (allows manageRule)\n * @returns Map of validation results by rule type\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const results = analyzer.validatePermissions(\n * 'posts',\n * { listRule: '@request.auth.id != \"\"', viewRule: 'author = @request.auth.id' },\n * fields,\n * false\n * );\n *\n * for (const [ruleType, result] of results) {\n * if (!result.valid) {\n * console.error(`${ruleType} validation failed:`, result.errors);\n * }\n * }\n * ```\n */\n validatePermissions(\n collectionName: string,\n permissions: PermissionSchema,\n fields: FieldDefinition[],\n isAuthCollection: boolean = false\n ): Map<APIRuleType, RuleValidationResult> {\n const validator = new RuleValidator(collectionName, fields, isAuthCollection);\n const results = new Map<APIRuleType, RuleValidationResult>();\n\n // Define all possible rule types\n const ruleTypes: APIRuleType[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\"];\n\n // Add manageRule for auth collections\n if (isAuthCollection) {\n ruleTypes.push(\"manageRule\");\n }\n\n // Validate each defined rule\n for (const ruleType of ruleTypes) {\n const expression = permissions[ruleType];\n if (expression !== undefined) {\n results.set(ruleType, validator.validate(ruleType, expression));\n }\n }\n\n return results;\n }\n\n /**\n * Merge permissions with defaults\n *\n * Ensures all rule types have a defined value. Undefined rules are set\n * to null (locked to superusers only), which is the PocketBase default.\n *\n * This is useful when generating migrations to ensure all rules are\n * explicitly set in the collection configuration.\n *\n * @param permissions - Permission schema (may have undefined rules)\n * @returns Permission schema with all rules defined (null if not specified)\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const merged = analyzer.mergeWithDefaults({\n * listRule: '@request.auth.id != \"\"'\n * // other rules undefined\n * });\n *\n * // Result:\n * // {\n * // listRule: '@request.auth.id != \"\"',\n * // viewRule: null,\n * // createRule: null,\n * // updateRule: null,\n * // deleteRule: null,\n * // manageRule: null\n * // }\n * ```\n */\n mergeWithDefaults(permissions: 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 * Collection name pluralization utilities\n */\n\n/**\n * Special case pluralization rules\n * Maps singular forms to their plural forms\n */\nconst SPECIAL_CASES: Record<string, string> = {\n // Common irregular plurals\n person: \"people\",\n Person: \"People\",\n child: \"children\",\n Child: \"Children\",\n man: \"men\",\n Man: \"Men\",\n woman: \"women\",\n Woman: \"Women\",\n tooth: \"teeth\",\n Tooth: \"Teeth\",\n foot: \"feet\",\n Foot: \"Feet\",\n mouse: \"mice\",\n Mouse: \"Mice\",\n goose: \"geese\",\n Goose: \"Geese\",\n\n // Words ending in -y\n category: \"categories\",\n Category: \"Categories\",\n company: \"companies\",\n Company: \"Companies\",\n city: \"cities\",\n City: \"Cities\",\n country: \"countries\",\n Country: \"Countries\",\n story: \"stories\",\n Story: \"Stories\",\n party: \"parties\",\n Party: \"Parties\",\n family: \"families\",\n Family: \"Families\",\n activity: \"activities\",\n Activity: \"Activities\",\n priority: \"priorities\",\n Priority: \"Priorities\",\n\n // Words ending in -f or -fe\n life: \"lives\",\n Life: \"Lives\",\n wife: \"wives\",\n Wife: \"Wives\",\n knife: \"knives\",\n Knife: \"Knives\",\n leaf: \"leaves\",\n Leaf: \"Leaves\",\n shelf: \"shelves\",\n Shelf: \"Shelves\",\n half: \"halves\",\n Half: \"Halves\",\n\n // Words ending in -is\n analysis: \"analyses\",\n Analysis: \"Analyses\",\n basis: \"bases\",\n Basis: \"Bases\",\n crisis: \"crises\",\n Crisis: \"Crises\",\n thesis: \"theses\",\n Thesis: \"Theses\",\n\n // Words ending in -us\n cactus: \"cacti\",\n Cactus: \"Cacti\",\n focus: \"foci\",\n Focus: \"Foci\",\n fungus: \"fungi\",\n Fungus: \"Fungi\",\n nucleus: \"nuclei\",\n Nucleus: \"Nuclei\",\n radius: \"radii\",\n Radius: \"Radii\",\n\n // Words ending in -on\n phenomenon: \"phenomena\",\n Phenomenon: \"Phenomena\",\n criterion: \"criteria\",\n Criterion: \"Criteria\",\n\n // Words ending in -um\n datum: \"data\",\n Datum: \"Data\",\n medium: \"media\",\n Medium: \"Media\",\n curriculum: \"curricula\",\n Curriculum: \"Curricula\",\n\n // Unchanged plurals\n sheep: \"sheep\",\n Sheep: \"Sheep\",\n deer: \"deer\",\n Deer: \"Deer\",\n fish: \"fish\",\n Fish: \"Fish\",\n species: \"species\",\n Species: \"Species\",\n series: \"series\",\n Series: \"Series\",\n};\n\n/**\n * Pluralizes a singular noun to its plural form\n * Handles special cases and common English pluralization rules\n *\n * @param singular - The singular form of the noun\n * @returns The plural form of the noun\n */\nexport function pluralize(singular: string): string {\n // Check special cases first (before checking if already plural)\n if (SPECIAL_CASES[singular]) {\n return SPECIAL_CASES[singular];\n }\n\n // Check if it's already plural (ends with 's' and is longer than 3 chars)\n if (singular.length > 3 && singular.endsWith(\"s\") && !singular.endsWith(\"ss\")) {\n // Could already be plural, return as-is\n return singular;\n }\n\n // Preserve case for the transformation\n const lowerSingular = singular.toLowerCase();\n\n let plural: string;\n\n // Rule 1: Words ending in -s, -ss, -sh, -ch, -x, -z -> add -es\n if (/(?:s|ss|sh|ch|x|z)$/.test(lowerSingular)) {\n plural = singular + \"es\";\n }\n // Rule 2: Words ending in consonant + y -> change y to ies\n else if (/[^aeiou]y$/.test(lowerSingular)) {\n plural = singular.slice(0, -1) + \"ies\";\n }\n // Rule 3: Words ending in consonant + o -> add -es\n else if (/[^aeiou]o$/.test(lowerSingular)) {\n plural = singular + \"es\";\n }\n // Rule 4: Words ending in -f or -fe -> change to -ves\n else if (/fe?$/.test(lowerSingular)) {\n if (lowerSingular.endsWith(\"fe\")) {\n plural = singular.slice(0, -2) + \"ves\";\n } else {\n plural = singular.slice(0, -1) + \"ves\";\n }\n }\n // Rule 5: Default -> add -s\n else {\n plural = singular + \"s\";\n }\n\n return plural;\n}\n\n/**\n * Converts a singular entity name to a collection name\n * This is an alias for pluralize for better semantic clarity\n *\n * @param entityName - The singular entity name (e.g., \"User\", \"Project\")\n * @returns The collection name (e.g., \"Users\", \"Projects\")\n */\nexport function toCollectionName(entityName: string): string {\n return pluralize(entityName);\n}\n\n/**\n * Attempts to singularize a plural noun (reverse of pluralize)\n * Note: This is a best-effort implementation and may not handle all edge cases\n *\n * @param plural - The plural form of the noun\n * @returns The singular form of the noun\n */\nexport function singularize(plural: string): string {\n // Check reverse special cases\n for (const [singular, pluralForm] of Object.entries(SPECIAL_CASES)) {\n if (pluralForm === plural) {\n return singular;\n }\n }\n\n const lower = plural.toLowerCase();\n\n // Rule 1: Words ending in -ies -> change to -y\n if (lower.endsWith(\"ies\") && plural.length > 3) {\n return plural.slice(0, -3) + \"y\";\n }\n\n // Rule 2: Words ending in -ves -> change to -f or -fe\n if (lower.endsWith(\"ves\")) {\n // Try -fe first (more common)\n return plural.slice(0, -3) + \"fe\";\n }\n\n // Rule 3: Words ending in -ses, -shes, -ches, -xes, -zes -> remove -es\n if (/(?:ses|shes|ches|xes|zes)$/.test(lower)) {\n return plural.slice(0, -2);\n }\n\n // Rule 4: Words ending in -s -> remove -s\n if (lower.endsWith(\"s\") && plural.length > 1) {\n return plural.slice(0, -1);\n }\n\n // Default: return as-is\n return plural;\n}\n","/**\n * Relation field detection utilities\n */\n\nimport { z } from \"zod\";\nimport { pluralize } from \"./pluralize\";\n\n/**\n * Detects if a field is a single relation based on naming convention\n * Single relation: field name matches a collection name (e.g., \"User\" -> \"Users\" collection)\n */\nfunction unwrapType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let unwrappedType = zodType;\n\n if (unwrappedType instanceof z.ZodOptional) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n if (unwrappedType instanceof z.ZodNullable) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n if (unwrappedType instanceof z.ZodDefault) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n\n return unwrappedType;\n}\n\nfunction getChecks(zodType: z.ZodTypeAny): any[] {\n const def = (zodType as any).def ?? (zodType as any)._def;\n return (def?.checks ?? []) as any[];\n}\n\nfunction getJsonSchema(zodType: z.ZodTypeAny): any | null {\n try {\n const toJSONSchema = (zodType as any).toJSONSchema;\n return typeof toJSONSchema === \"function\" ? toJSONSchema.call(zodType) : null;\n } catch {\n return null;\n }\n}\n\nexport function isSingleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n const unwrappedType = unwrapType(zodType);\n\n // Must be a string type\n if (!(unwrappedType instanceof z.ZodString)) {\n return false;\n }\n\n // Field name should start with uppercase (convention for entity references)\n // and not be a common string field name\n const startsWithUppercase = /^[A-Z]/.test(fieldName);\n\n // Exclude common string fields that start with uppercase\n const commonStringFields = [\"Title\", \"Name\", \"Description\", \"Content\", \"Summary\", \"Status\", \"Type\"];\n const isCommonField = commonStringFields.includes(fieldName);\n\n return startsWithUppercase && !isCommonField;\n}\n\n/**\n * Detects if a field is a multiple relation based on naming convention\n * Multiple relation: field name is an array of strings ending with entity name\n * (e.g., \"SubscriberUsers\" -> \"Users\" collection)\n */\nexport function isMultipleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n const unwrappedType = unwrapType(zodType);\n\n // Must be an array type\n if (!(unwrappedType instanceof z.ZodArray)) {\n return false;\n }\n\n // Element type must be string\n const elementType = unwrappedType.element;\n if (!(elementType instanceof z.ZodString)) {\n return false;\n }\n\n // Field name should contain an uppercase letter (entity reference pattern)\n const hasUppercase = /[A-Z]/.test(fieldName);\n\n return hasUppercase;\n}\n\n/**\n * Resolves the target collection name from a relation field name\n * Examples:\n * - \"User\" -> \"Users\"\n * - \"SubscriberUsers\" -> \"Users\"\n * - \"Author\" -> \"Authors\"\n * - \"Category\" -> \"Categories\"\n */\nexport function resolveTargetCollection(fieldName: string): string {\n // For single relations, the field name is typically the entity name\n // For multiple relations, extract the entity name from the end\n\n // Check if field name ends with a known plural entity name\n // Common patterns: \"SubscriberUsers\", \"RelatedPosts\", \"Tags\"\n\n // Try to find the entity name by looking for uppercase letters\n const matches = fieldName.match(/[A-Z][a-z]+/g);\n\n if (!matches || matches.length === 0) {\n // Fallback: pluralize the entire field name\n return pluralize(fieldName);\n }\n\n // Take the last matched entity name (e.g., \"Users\" from \"SubscriberUsers\")\n const entityName = matches[matches.length - 1];\n\n // Pluralize the entity name to get collection name\n return pluralize(entityName);\n}\n\n/**\n * Detects if a field is any type of relation (single or multiple)\n */\nexport function isRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n return isSingleRelationField(fieldName, zodType) || isMultipleRelationField(fieldName, zodType);\n}\n\n/**\n * Gets the maximum number of relations allowed for a relation field\n * Returns 1 for single relations, or the max constraint for multiple relations\n */\nexport function getMaxSelect(fieldName: string, zodType: z.ZodTypeAny): number {\n if (isSingleRelationField(fieldName, zodType)) {\n return 1;\n }\n\n if (isMultipleRelationField(fieldName, zodType)) {\n const unwrappedType = unwrapType(zodType);\n if (unwrappedType instanceof z.ZodArray) {\n const checks = getChecks(unwrappedType);\n const maxCheck = checks.find((check) => check.kind === \"max\");\n if (maxCheck) {\n return maxCheck.value;\n }\n const schema = getJsonSchema(unwrappedType);\n if (schema && typeof schema.maxItems === \"number\") {\n return schema.maxItems;\n }\n // Default to 999 for multiple relations without explicit max\n return 999;\n }\n }\n\n return 1;\n}\n\n/**\n * Gets the minimum number of relations required for a relation field\n * Returns 0 as default for all relation fields (single or multiple)\n * PocketBase always expects minSelect to be defined for relation fields\n */\nexport function getMinSelect(fieldName: string, zodType: z.ZodTypeAny): number {\n // For single relations, always return 0\n if (isSingleRelationField(fieldName, zodType)) {\n return 0;\n }\n\n // For multiple relations, check for explicit min constraint\n if (isMultipleRelationField(fieldName, zodType)) {\n const unwrappedType = unwrapType(zodType);\n if (unwrappedType instanceof z.ZodArray) {\n const checks = getChecks(unwrappedType);\n const minCheck = checks.find((check) => check.kind === \"min\");\n if (minCheck) {\n return minCheck.value;\n }\n const schema = getJsonSchema(unwrappedType);\n if (schema && typeof schema.minItems === \"number\") {\n return schema.minItems;\n }\n }\n }\n\n // Default to 0 for all relation fields\n return 0;\n}\n","/**\n * Zod to PocketBase type mapping utilities\n *\n * This module provides comprehensive mapping between Zod schema types\n * and PocketBase field types, including support for all PocketBase field types:\n * - text, email, url, editor\n * - number, bool\n * - date, autodate\n * - select (single/multiple)\n * - relation (single/multiple)\n * - file (single/multiple)\n * - json\n * - geoPoint\n */\n\nimport { z } from \"zod\";\nimport type { PocketBaseFieldType } from \"../types\";\nimport { extractFieldMetadata, FIELD_METADATA_KEY } from \"../../schema/fields\";\n\n// Re-export extractFieldMetadata from fields.ts for backward compatibility\nexport { extractFieldMetadata, FIELD_METADATA_KEY };\nexport type { FieldMetadata } from \"../../schema/fields\";\n\n/**\n * All supported PocketBase field types\n */\nexport const POCKETBASE_FIELD_TYPES: readonly PocketBaseFieldType[] = [\n \"text\",\n \"email\",\n \"url\",\n \"number\",\n \"bool\",\n \"date\",\n \"select\",\n \"relation\",\n \"file\",\n \"json\",\n \"editor\",\n \"geoPoint\",\n \"autodate\",\n \"password\",\n] as const;\n\n/**\n * Field type metadata for documentation and validation\n */\nexport interface FieldTypeInfo {\n type: PocketBaseFieldType;\n description: string;\n zodTypes: string[];\n supportsMultiple: boolean;\n}\n\n/**\n * Metadata about each PocketBase field type\n */\nexport const FIELD_TYPE_INFO: Record<PocketBaseFieldType, FieldTypeInfo> = {\n text: {\n type: \"text\",\n description: \"Plain text field\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n password: {\n type: \"password\",\n description: \"Password field (system)\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n email: {\n type: \"email\",\n description: \"Email address field with validation\",\n zodTypes: [\"ZodString with email()\"],\n supportsMultiple: false,\n },\n url: {\n type: \"url\",\n description: \"URL field with validation\",\n zodTypes: [\"ZodString with url()\"],\n supportsMultiple: false,\n },\n editor: {\n type: \"editor\",\n description: \"Rich text editor field\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n number: {\n type: \"number\",\n description: \"Numeric field (integer or float)\",\n zodTypes: [\"ZodNumber\"],\n supportsMultiple: false,\n },\n bool: {\n type: \"bool\",\n description: \"Boolean field\",\n zodTypes: [\"ZodBoolean\"],\n supportsMultiple: false,\n },\n date: {\n type: \"date\",\n description: \"Date/datetime field\",\n zodTypes: [\"ZodDate\", \"ZodString with datetime format\"],\n supportsMultiple: false,\n },\n autodate: {\n type: \"autodate\",\n description: \"Auto-managed date field (created/updated)\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n select: {\n type: \"select\",\n description: \"Single or multiple select from predefined values\",\n zodTypes: [\"ZodEnum\", \"ZodArray<ZodEnum>\"],\n supportsMultiple: true,\n },\n relation: {\n type: \"relation\",\n description: \"Reference to another collection\",\n zodTypes: [\"ZodString\", \"ZodArray<ZodString>\"],\n supportsMultiple: true,\n },\n file: {\n type: \"file\",\n description: \"File upload field\",\n zodTypes: [\"File\", \"ZodArray<File>\"],\n supportsMultiple: true,\n },\n json: {\n type: \"json\",\n description: \"JSON data field\",\n zodTypes: [\"ZodRecord\", \"ZodObject\", \"ZodArray\"],\n supportsMultiple: false,\n },\n geoPoint: {\n type: \"geoPoint\",\n description: \"Geographic coordinates (lon, lat)\",\n zodTypes: [\"ZodObject with lon/lat\"],\n supportsMultiple: false,\n },\n};\n\nfunction getChecks(zodType: z.ZodTypeAny): any[] {\n const def = (zodType as any).def ?? (zodType as any)._def;\n return (def?.checks ?? []) as any[];\n}\n\nfunction getJsonSchema(zodType: z.ZodTypeAny): any | null {\n try {\n const toJSONSchema = (zodType as any).toJSONSchema;\n return typeof toJSONSchema === \"function\" ? toJSONSchema.call(zodType) : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Maps Zod string types to PocketBase field types\n */\nexport function mapZodStringType(zodType: z.ZodString): PocketBaseFieldType {\n const checks = getChecks(zodType);\n\n // Check for email validation\n const hasEmail = checks.some((check: any) => check.kind === \"email\" || check.def?.format === \"email\");\n if (hasEmail) {\n return \"email\";\n }\n\n // Check for URL validation\n const hasUrl = checks.some((check: any) => check.kind === \"url\" || check.def?.format === \"url\");\n if (hasUrl) {\n return \"url\";\n }\n\n // Check for datetime validation (could be date field)\n const hasDatetime = checks.some(\n (check: any) => check.kind === \"datetime\" || check.def?.format === \"datetime\" || check.def?.format === \"date-time\"\n );\n if (hasDatetime) {\n return \"date\";\n }\n\n // Default to text\n return \"text\";\n}\n\n/**\n * Maps Zod number types to PocketBase number type\n */\nexport function mapZodNumberType(_zodType: z.ZodNumber): PocketBaseFieldType {\n return \"number\";\n}\n\n/**\n * Maps Zod boolean types to PocketBase bool type\n */\nexport function mapZodBooleanType(_zodType: z.ZodBoolean): PocketBaseFieldType {\n return \"bool\";\n}\n\n/**\n * Maps Zod enum types to PocketBase select type\n */\nexport function mapZodEnumType(_zodType: z.ZodEnum<any>): PocketBaseFieldType {\n return \"select\";\n}\n\n/**\n * Maps Zod array types to appropriate PocketBase types\n * Arrays of strings could be relations or file fields depending on context\n */\nexport function mapZodArrayType(zodType: z.ZodArray<any>, _fieldName: string): PocketBaseFieldType {\n const elementType = zodType.element as z.ZodTypeAny;\n\n if (elementType instanceof z.ZodFile) {\n return \"file\";\n }\n\n // Array of strings - could be relation (will be determined by relation detector)\n if (elementType instanceof z.ZodString) {\n return \"relation\";\n }\n\n // Default to JSON for other array types\n return \"json\";\n}\n\n/**\n * Maps Zod date types to PocketBase date type\n */\nexport function mapZodDateType(_zodType: z.ZodDate): PocketBaseFieldType {\n return \"date\";\n}\n\n/**\n * Maps Zod record/object types to PocketBase JSON type\n */\nexport function mapZodRecordType(_zodType: z.ZodRecord | z.ZodObject<any>): PocketBaseFieldType {\n return \"json\";\n}\n\n/**\n * Main type mapping function that determines PocketBase field type from Zod type\n */\nexport function mapZodTypeToPocketBase(zodType: z.ZodTypeAny, fieldName: string): PocketBaseFieldType {\n const unwrappedType = unwrapZodType(zodType);\n\n // Check for metadata first (explicit type overrides)\n const metadata = extractFieldMetadata(unwrappedType.description);\n if (metadata && metadata.type) {\n return metadata.type;\n }\n\n if (unwrappedType instanceof z.ZodFile) {\n return \"file\";\n }\n\n // Map based on Zod type\n let type: PocketBaseFieldType = \"text\";\n\n if (unwrappedType instanceof z.ZodString) {\n type = mapZodStringType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodNumber) {\n type = mapZodNumberType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodBoolean) {\n type = mapZodBooleanType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodEnum) {\n type = mapZodEnumType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodArray) {\n type = mapZodArrayType(unwrappedType, fieldName);\n } else if (unwrappedType instanceof z.ZodDate) {\n type = mapZodDateType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodRecord || unwrappedType instanceof z.ZodObject) {\n type = mapZodRecordType(unwrappedType);\n }\n\n return type;\n}\n\n/**\n * Extracts field options from Zod type (min, max, pattern, etc.)\n */\nexport function extractFieldOptions(zodType: z.ZodTypeAny): Record<string, any> {\n const options: Record<string, any> = {};\n\n const unwrappedType = unwrapZodType(zodType);\n const checks = getChecks(unwrappedType);\n\n // Extract string constraints\n if (unwrappedType instanceof z.ZodString) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n if (check.kind === \"regex\") {\n options.pattern = check.regex.source;\n }\n }\n\n if (options.min === undefined || options.max === undefined || options.pattern === undefined) {\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.min === undefined && typeof schema.minLength === \"number\") {\n options.min = schema.minLength;\n }\n if (options.max === undefined && typeof schema.maxLength === \"number\") {\n options.max = schema.maxLength;\n }\n if (options.pattern === undefined && typeof schema.pattern === \"string\") {\n options.pattern = schema.pattern;\n }\n }\n }\n }\n\n // Extract number constraints\n if (unwrappedType instanceof z.ZodNumber) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n }\n\n if (options.min === undefined || options.max === undefined) {\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.min === undefined && typeof schema.minimum === \"number\") {\n options.min = schema.minimum;\n }\n if (options.max === undefined && typeof schema.maximum === \"number\") {\n options.max = schema.maximum;\n }\n }\n }\n }\n\n // Extract enum values\n if (unwrappedType instanceof z.ZodEnum) {\n options.values = unwrappedType.options.map(String);\n }\n\n // Extract array constraints\n if (unwrappedType instanceof z.ZodArray) {\n const arrayChecks = getChecks(unwrappedType);\n for (const check of arrayChecks) {\n if (check.kind === \"min\") {\n options.minSelect = check.value;\n }\n if (check.kind === \"max\") {\n options.maxSelect = check.value;\n }\n }\n\n if (options.minSelect === undefined || options.maxSelect === undefined) {\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.minSelect === undefined && typeof schema.minItems === \"number\") {\n options.minSelect = schema.minItems;\n }\n if (options.maxSelect === undefined && typeof schema.maxItems === \"number\") {\n options.maxSelect = schema.maxItems;\n }\n }\n }\n }\n\n return options;\n}\n\n/**\n * Determines if a Zod field is required (not optional)\n */\nexport function isFieldRequired(zodType: z.ZodTypeAny): boolean {\n // Check if it's optional\n if (zodType instanceof z.ZodOptional) {\n return false;\n }\n\n // Check if it has a default value (makes it optional)\n if (zodType instanceof z.ZodDefault) {\n return false;\n }\n\n // Check for nullable (in PocketBase context, nullable means optional)\n if (zodType instanceof z.ZodNullable) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Unwraps a Zod type to get the inner type\n * Handles optional, nullable, and default wrappers\n */\nexport function unwrapZodType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let unwrapped = zodType;\n let previous = null;\n\n while (unwrapped !== previous) {\n previous = unwrapped;\n if (unwrapped instanceof z.ZodOptional) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n } else if (unwrapped instanceof z.ZodNullable) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n } else if (unwrapped instanceof z.ZodDefault) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n }\n }\n\n return unwrapped;\n}\n\n/**\n * Gets the default value from a Zod type if it has one\n */\nexport function getDefaultValue(zodType: z.ZodTypeAny): any {\n if (zodType instanceof z.ZodDefault) {\n return zodType.def.defaultValue;\n }\n return undefined;\n}\n\n/**\n * Checks if a Zod type is an array type\n */\nexport function isArrayType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapZodType(zodType);\n return unwrapped instanceof z.ZodArray;\n}\n\n/**\n * Gets the element type of an array Zod type\n */\nexport function getArrayElementType(zodType: z.ZodTypeAny): z.ZodTypeAny | null {\n const unwrapped = unwrapZodType(zodType);\n if (unwrapped instanceof z.ZodArray) {\n return unwrapped.element as z.ZodTypeAny;\n }\n return null;\n}\n\n/**\n * Checks if a Zod type represents a geo point (object with lon/lat)\n */\nexport function isGeoPointType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapZodType(zodType);\n if (!(unwrapped instanceof z.ZodObject)) {\n return false;\n }\n\n const shape = unwrapped.shape;\n const hasLon = \"lon\" in shape && shape.lon instanceof z.ZodNumber;\n const hasLat = \"lat\" in shape && shape.lat instanceof z.ZodNumber;\n\n return hasLon && hasLat;\n}\n\n/**\n * Complete field options extracted from a Zod type\n */\nexport interface ExtractedFieldOptions {\n min?: number;\n max?: number;\n pattern?: string;\n values?: string[];\n minSelect?: number;\n maxSelect?: number;\n mimeTypes?: string[];\n maxSize?: number;\n thumbs?: string[];\n}\n\n/**\n * Extracts comprehensive field options from Zod type\n * Includes all constraints that can be mapped to PocketBase field options\n */\nexport function extractComprehensiveFieldOptions(zodType: z.ZodTypeAny): ExtractedFieldOptions {\n const options: ExtractedFieldOptions = {};\n const unwrapped = unwrapZodType(zodType);\n const checks = getChecks(unwrapped);\n\n // Extract string constraints\n if (unwrapped instanceof z.ZodString) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n if (check.kind === \"regex\") {\n options.pattern = check.regex.source;\n }\n }\n\n if (options.min === undefined || options.max === undefined || options.pattern === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.min === undefined && typeof schema.minLength === \"number\") {\n options.min = schema.minLength;\n }\n if (options.max === undefined && typeof schema.maxLength === \"number\") {\n options.max = schema.maxLength;\n }\n if (options.pattern === undefined && typeof schema.pattern === \"string\") {\n options.pattern = schema.pattern;\n }\n }\n }\n }\n\n // Extract number constraints\n if (unwrapped instanceof z.ZodNumber) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n }\n\n if (options.min === undefined || options.max === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.min === undefined && typeof schema.minimum === \"number\") {\n options.min = schema.minimum;\n }\n if (options.max === undefined && typeof schema.maximum === \"number\") {\n options.max = schema.maximum;\n }\n }\n }\n }\n\n // Extract enum values\n if (unwrapped instanceof z.ZodEnum) {\n options.values = unwrapped.options.map(String);\n }\n\n // Extract array constraints\n if (unwrapped instanceof z.ZodArray) {\n const arrayChecks = getChecks(unwrapped);\n for (const check of arrayChecks) {\n if (check.kind === \"min\") {\n options.minSelect = check.value;\n }\n if (check.kind === \"max\") {\n options.maxSelect = check.value;\n }\n }\n\n if (options.minSelect === undefined || options.maxSelect === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.minSelect === undefined && typeof schema.minItems === \"number\") {\n options.minSelect = schema.minItems;\n }\n if (options.maxSelect === undefined && typeof schema.maxItems === \"number\") {\n options.maxSelect = schema.maxItems;\n }\n }\n }\n\n // Check for enum element type\n const elementType = unwrapped.element as z.ZodTypeAny;\n if (elementType instanceof z.ZodEnum) {\n options.values = elementType.options.map(String);\n }\n }\n\n return options;\n}\n\n\n\n/**\n * Gets the PocketBase field type with additional context\n */\nexport interface FieldTypeResult {\n type: PocketBaseFieldType;\n isMultiple: boolean;\n options: ExtractedFieldOptions;\n}\n\n/**\n * Comprehensive type mapping that returns full field information\n */\nexport function getFieldTypeInfo(zodType: z.ZodTypeAny, fieldName: string): FieldTypeResult {\n const type = mapZodTypeToPocketBase(zodType, fieldName);\n const isMultiple = isArrayType(zodType);\n const options = extractComprehensiveFieldOptions(zodType);\n\n return {\n type,\n isMultiple,\n options,\n };\n}\n","import { z } from \"zod\";\nimport type { RuleExpression } from \"../utils/permissions\";\nimport { defineCollection } from \"./base\";\n\n/**\n * Permission rules that apply to a view collection\n *\n * View collections are read-only: PocketBase rejects createRule, updateRule,\n * deleteRule and manageRule on them, so only the two read rules are accepted.\n */\nexport interface ViewPermissionSchema {\n /** Controls who can list/query the view's rows */\n listRule?: RuleExpression;\n\n /** Controls who can view an individual row */\n viewRule?: RuleExpression;\n}\n\n/**\n * Configuration options for defining a view collection\n */\nexport interface ViewCollectionConfig {\n /**\n * The name of the PocketBase collection\n */\n collectionName: string;\n\n /**\n * The Zod schema describing the shape of a row\n *\n * For views this is used for TypeScript type generation and application-side\n * parsing only - PocketBase derives the collection's actual fields from the\n * SQL query when the collection is saved.\n */\n schema: z.ZodObject<any>;\n\n /**\n * The SQL SELECT statement backing the view\n *\n * Use the `sql` tagged template for consistent formatting.\n */\n viewQuery: string;\n\n /**\n * Optional read permissions (listRule / viewRule)\n */\n permissions?: ViewPermissionSchema;\n}\n\n/**\n * Removes the common leading indentation from a multi-line string and trims\n * blank leading/trailing lines\n *\n * Keeps generated migrations stable when a query is re-indented in the source\n * file, since only the relative indentation is preserved. Also used when\n * reading a query back out of a migration file, where the generator has\n * indented it to fit the surrounding code.\n *\n * @param value - Raw multi-line string\n * @returns Dedented string\n */\nexport function dedentSql(value: string): string {\n const lines = value.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\n // Drop leading and trailing blank lines\n while (lines.length > 0 && lines[0].trim() === \"\") {\n lines.shift();\n }\n while (lines.length > 0 && lines[lines.length - 1].trim() === \"\") {\n lines.pop();\n }\n\n if (lines.length === 0) {\n return \"\";\n }\n\n // Find the smallest indentation across all non-blank lines\n let minIndent = Infinity;\n for (const line of lines) {\n if (line.trim() === \"\") continue;\n const indent = line.length - line.trimStart().length;\n if (indent < minIndent) {\n minIndent = indent;\n }\n }\n\n if (!Number.isFinite(minIndent) || minIndent === 0) {\n return lines.map((line) => line.trimEnd()).join(\"\\n\");\n }\n\n return lines.map((line) => line.slice(minIndent).trimEnd()).join(\"\\n\");\n}\n\n/**\n * Tagged template for SQL view queries\n *\n * Interpolates values, strips the common leading indentation and trims blank\n * leading/trailing lines. Returns a plain string, so a regular string literal\n * works anywhere `sql` does.\n *\n * @example\n * const query = sql`\n * SELECT p.id AS id, p.title AS title\n * FROM Projects p\n * `;\n * // \"SELECT p.id AS id, p.title AS title\\n FROM Projects p\"\n */\nexport function sql(strings: TemplateStringsArray, ...values: Array<string | number>): string {\n let result = \"\";\n\n for (let i = 0; i < strings.length; i++) {\n result += strings[i];\n if (i < values.length) {\n result += String(values[i]);\n }\n }\n\n return dedentSql(result);\n}\n\n/**\n * Strips SQL comments and leading whitespace so the first real token can be checked\n *\n * @param query - The SQL query\n * @returns The query with leading comments and whitespace removed\n */\nfunction stripLeadingComments(query: string): string {\n let remaining = query.trim();\n\n // Repeatedly strip line comments (-- ...) and block comments (/* ... */)\n while (remaining.length > 0) {\n if (remaining.startsWith(\"--\")) {\n const newline = remaining.indexOf(\"\\n\");\n remaining = newline === -1 ? \"\" : remaining.slice(newline + 1).trim();\n continue;\n }\n\n if (remaining.startsWith(\"/*\")) {\n const end = remaining.indexOf(\"*/\");\n remaining = end === -1 ? \"\" : remaining.slice(end + 2).trim();\n continue;\n }\n\n break;\n }\n\n return remaining;\n}\n\n/**\n * Validates a view query, throwing with an actionable message when it can't work\n *\n * @param collectionName - Collection name, used in error messages\n * @param viewQuery - The SQL query to validate\n */\nexport function validateViewQuery(collectionName: string, viewQuery: unknown): asserts viewQuery is string {\n if (typeof viewQuery !== \"string\" || viewQuery.trim() === \"\") {\n throw new Error(\n `View collection \"${collectionName}\" requires a non-empty viewQuery. ` +\n `Provide the SQL SELECT statement backing the view.`\n );\n }\n\n const body = stripLeadingComments(viewQuery);\n if (!/^(select|with)\\b/i.test(body)) {\n throw new Error(\n `View collection \"${collectionName}\" has an invalid viewQuery: it must start with SELECT or WITH. ` +\n `Received: ${body.slice(0, 40)}${body.length > 40 ? \"...\" : \"\"}`\n );\n }\n}\n\n/**\n * Defines a read-only PocketBase view collection backed by a SQL query\n *\n * PocketBase derives the collection's fields by running the query, so the Zod\n * schema only describes the shape for TypeScript types and application-side\n * parsing. Views cannot have indexes and only support listRule / viewRule.\n *\n * The generated migration creates the collection with `type: \"view\"` and the\n * query; changing the SQL later produces an in-place `viewQuery` update, which\n * keeps the collection id stable.\n *\n * @param config - View collection configuration\n * @returns The schema with view metadata attached\n *\n * @example\n * export default defineView({\n * collectionName: \"ProjectStats\",\n * schema: ProjectStatsSchema,\n * viewQuery: sql`\n * SELECT p.OwnerUser AS id,\n * p.OwnerUser AS OwnerUser,\n * COUNT(*) AS projectCount\n * FROM Projects p\n * GROUP BY p.OwnerUser\n * `,\n * permissions: {\n * listRule: \"OwnerUser = @request.auth.id\",\n * viewRule: \"OwnerUser = @request.auth.id\",\n * },\n * });\n *\n * @example\n * // Requirements PocketBase places on the query:\n * // - the outermost SELECT must expose an `id` column\n * // - a relation column must be selected bare (e.g. `p.OwnerUser AS OwnerUser`)\n * // from the outer table for PocketBase to infer it as a relation field\n * // - no top-level UNION (wrap unions in a subquery)\n */\nexport function defineView(config: ViewCollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, viewQuery, permissions } = config;\n\n validateViewQuery(collectionName, viewQuery);\n\n return defineCollection({\n collectionName,\n schema,\n type: \"view\",\n viewQuery,\n // Write rules are always locked for views - PocketBase rejects anything else\n permissions: {\n listRule: permissions?.listRule ?? null,\n viewRule: permissions?.viewRule ?? null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n },\n });\n}\n","import * as path from \"path\";\nimport { z } from \"zod\";\nimport { toCollectionName } from \"../utils/pluralize\";\n\n/**\n * Gets the collection name from a schema file path\n * Converts the filename (without extension) to a pluralized collection name\n *\n * @param filePath - Path to the schema file (with or without extension)\n * @returns The collection name\n */\nexport function getCollectionNameFromFile(filePath: string): string {\n // Remove both .ts and .js extensions if present\n const filename = path.basename(filePath).replace(/\\.(ts|js)$/, \"\");\n return toCollectionName(filename);\n}\n\n/**\n * Extracts the collection name from a Zod schema's metadata\n * Checks if the schema was created with defineCollection() which stores\n * the collection name in the schema description\n *\n * @param zodSchema - The Zod schema to extract collection name from\n * @returns The collection name if found in metadata, null otherwise\n */\nexport function extractCollectionNameFromSchema(zodSchema: z.ZodTypeAny): string | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (metadata.collectionName && typeof metadata.collectionName === \"string\") {\n return metadata.collectionName;\n }\n } catch {\n // Not JSON or no collectionName - this is expected for schemas without defineCollection\n }\n\n return null;\n}\n\n/**\n * Extracts the collection type from a Zod schema's metadata\n * Checks if the schema was created with defineCollection() which stores\n * the collection type in the schema description\n *\n * @param zodSchema - The Zod schema to extract collection type from\n * @returns The collection type (\"base\" | \"auth\" | \"view\") if found in metadata, null otherwise\n */\nexport function extractCollectionTypeFromSchema(zodSchema: z.ZodTypeAny): \"base\" | \"auth\" | \"view\" | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (metadata.type === \"base\" || metadata.type === \"auth\" || metadata.type === \"view\") {\n return metadata.type;\n }\n } catch {\n // Not JSON or no type - this is expected for schemas without explicit type\n }\n\n return null;\n}\n\n/**\n * Extracts the SQL query backing a view collection from a Zod schema's metadata\n * Set by defineView() (or defineCollection with type: \"view\")\n *\n * @param zodSchema - The Zod schema to extract the view query from\n * @returns The SQL query if found in metadata, null otherwise\n */\nexport function extractViewQueryFromSchema(zodSchema: z.ZodTypeAny): string | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (typeof metadata.viewQuery === \"string\") {\n return metadata.viewQuery;\n }\n } catch {\n // Not JSON or no viewQuery - expected for non-view collections\n }\n\n return null;\n}\n\n/**\n * Extracts Zod schema definitions from a module\n *\n * Detection priority (highest to lowest):\n * 1. Default export - recommended pattern for clarity and explicitness\n * 2. Named exports ending with \"Collection\" - contains metadata (indexes, permissions)\n * 3. Named exports ending with \"Schema\" - basic schema definitions\n * 4. Named exports ending with \"InputSchema\" - form input schemas\n *\n * @param module - The imported schema module\n * @param patterns - Schema name patterns to look for (default: ['Schema', 'InputSchema', 'Collection'])\n * @returns Object containing found schemas\n *\n * @example\n * // Recommended: Use default export\n * const UserCollection = defineCollection({ ... });\n * export default UserCollection;\n *\n * @example\n * // Also supported: Named export with pattern\n * export const UserCollection = defineCollection({ ... });\n */\nexport function extractSchemaDefinitions(\n module: any,\n patterns: string[] = [\"Schema\", \"InputSchema\", \"Collection\"]\n): { inputSchema?: z.ZodObject<any>; schema?: z.ZodObject<any> } {\n const result: { inputSchema?: z.ZodObject<any>; schema?: z.ZodObject<any> } = {};\n\n // Priority 1: Check for default export (highest priority, most explicit)\n // This allows each file to have one clear schema definition\n if (module.default instanceof z.ZodObject) {\n // Default export is always the primary schema\n result.schema = module.default as z.ZodObject<any>;\n // If we have a default export, we can return early as it takes precedence\n // But we still check for InputSchema for backward compatibility\n }\n\n // Priority 2: Look for named exports matching patterns (for backward compatibility)\n for (const [key, value] of Object.entries(module)) {\n // Skip default export as we already handled it\n if (key === \"default\") continue;\n\n // Check if it's a Zod schema\n if (value instanceof z.ZodObject) {\n // Check for InputSchema pattern (used for form validation)\n if (patterns.includes(\"InputSchema\") && key.endsWith(\"InputSchema\")) {\n result.inputSchema = value as z.ZodObject<any>;\n } else if (!result.schema) {\n // Only set schema if we haven't found one via default export\n if (patterns.includes(\"Collection\") && key.endsWith(\"Collection\")) {\n // Prefer Collection over Schema as it has metadata (indexes, permissions)\n result.schema = value as z.ZodObject<any>;\n } else if (patterns.includes(\"Schema\") && key.endsWith(\"Schema\") && !key.endsWith(\"InputSchema\")) {\n result.schema = value as z.ZodObject<any>;\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Identifies whether to use InputSchema or Schema pattern\n * Prefers Schema over InputSchema as it includes base fields\n *\n * @param schemas - Object containing inputSchema and/or schema\n * @returns The schema to use for collection definition\n */\nexport function selectSchemaForCollection(schemas: {\n inputSchema?: z.ZodObject<any>;\n schema?: z.ZodObject<any>;\n}): z.ZodObject<any> | null {\n // Prefer the full Schema over InputSchema as it includes base fields\n if (schemas.schema) {\n return schemas.schema;\n }\n\n if (schemas.inputSchema) {\n return schemas.inputSchema;\n }\n\n return null;\n}\n\n/**\n * Extracts field definitions from a Zod object schema\n * Filters out base schema fields (id, collectionId, created, updated, expand)\n *\n * @param zodSchema - The Zod object schema\n * @param excludeFields - Additional fields to exclude (default: base schema fields)\n * @returns Array of field names and their Zod types\n */\nexport function extractFieldDefinitions(\n zodSchema: z.ZodObject<any>,\n excludeFields?: string[]\n): Array<{ name: string; zodType: z.ZodTypeAny }> {\n const shape = zodSchema.shape;\n const fields: Array<{ name: string; zodType: z.ZodTypeAny }> = [];\n\n // Base schema fields to exclude (these are system fields in PocketBase)\n const baseFields = [\"id\", \"collectionId\", \"collectionName\", \"created\", \"updated\", \"expand\"];\n\n // Additional fields to exclude (image file handling fields)\n const defaultExcludeFields = [\"thumbnailURL\", \"imageFiles\"];\n\n // Combine all exclusions\n const allExclusions = new Set([...baseFields, ...defaultExcludeFields, ...(excludeFields || [])]);\n\n for (const [fieldName, zodType] of Object.entries(shape)) {\n // Skip excluded fields\n if (!allExclusions.has(fieldName)) {\n fields.push({ name: fieldName, zodType: zodType as z.ZodTypeAny });\n }\n }\n\n return fields;\n}\n\n/**\n * Extracts index definitions from a Zod schema\n * Parses the schema description metadata to find index definitions\n *\n * @param schema - Zod schema with index metadata\n * @returns Array of index SQL statements or undefined\n */\nexport function extractIndexes(schema: z.ZodTypeAny): string[] | undefined {\n // Try to extract indexes from schema description\n const schemaDescription = schema.description;\n\n if (!schemaDescription) {\n return undefined;\n }\n\n try {\n const metadata = JSON.parse(schemaDescription);\n\n // Check if indexes are present in metadata\n if (metadata.indexes && Array.isArray(metadata.indexes)) {\n return metadata.indexes;\n }\n } catch {\n // If description is not valid JSON, return undefined\n }\n\n return undefined;\n}\n","import { z } from \"zod\";\nimport { extractRelationMetadata } from \"../../schema/base\";\nimport { extractFieldMetadata } from \"../../schema/fields\";\nimport type { PermissionSchema } from \"../../utils/permissions\";\nimport { PermissionAnalyzer } from \"../permission-analyzer\";\nimport type { CollectionSchema, FieldDefinition } from \"../types\";\nimport { getMaxSelect, getMinSelect, isRelationField, resolveTargetCollection } from \"../utils/relation-detector\";\nimport { extractFieldOptions, isFieldRequired, mapZodTypeToPocketBase, unwrapZodType } from \"../utils/type-mapper\";\nimport { validateViewQuery } from \"../../schema/view\";\nimport {\n extractCollectionTypeFromSchema,\n extractFieldDefinitions,\n extractIndexes,\n extractViewQueryFromSchema,\n} from \"./extractors\";\nimport { generateFieldId } from \"../utils/collection-id-generator.js\";\n\n/**\n * Detects if a collection is an auth collection\n * Auth collections have email and password fields\n *\n * @param fields - Array of field definitions\n * @returns True if the collection is an auth collection\n */\nexport function isAuthCollection(fields: Array<{ name: string; zodType: z.ZodTypeAny }>): boolean {\n const fieldNames = fields.map((f) => f.name.toLowerCase());\n\n // Auth collections must have both email and password fields\n const hasEmail = fieldNames.includes(\"email\");\n const hasPassword = fieldNames.includes(\"password\");\n\n return hasEmail && hasPassword;\n}\n\n/**\n * Extracts validation constraints from Zod type\n * Includes min, max, required, unique, and other options\n *\n * @param fieldName - The field name\n * @param zodType - The Zod type\n * @returns Field definition with constraints\n */\nexport function buildFieldDefinition(fieldName: string, zodType: z.ZodTypeAny): FieldDefinition {\n // Check for explicit field metadata first (from field helper functions)\n const unwrappedType = unwrapZodType(zodType);\n const fieldMetadata = extractFieldMetadata(unwrappedType.description ?? zodType.description);\n\n if (fieldMetadata) {\n // Use explicit metadata from field helpers\n // For number fields, default to required: false unless explicitly set\n // (because required: true in PocketBase means non-zero, which is often not desired)\n let required: boolean;\n if (fieldMetadata.type === \"number\") {\n // Check if required is explicitly set in options\n if (fieldMetadata.options?.required !== undefined) {\n required = fieldMetadata.options.required;\n } else {\n // Default to false for number fields to allow zero values\n // This allows zero values (e.g., progress: 0-100) unless explicitly set to required: true\n required = false;\n }\n } else {\n // For other field types, use standard logic\n required = isFieldRequired(zodType);\n }\n\n // Remove 'required' from options if present (it's a top-level property, not an option)\n const { required: _required, ...options } = fieldMetadata.options || {};\n\n const fieldDef: FieldDefinition = {\n name: fieldName,\n id: generateFieldId(fieldMetadata.type, fieldName),\n type: fieldMetadata.type,\n required,\n options: Object.keys(options).length > 0 ? options : undefined,\n zodType: zodType,\n };\n\n // If it's a relation type from metadata, we still need to extract relation config\n if (fieldMetadata.type === \"relation\") {\n const relationMetadata = extractRelationMetadata(unwrappedType.description ?? zodType.description);\n if (relationMetadata) {\n fieldDef.relation = {\n collection: relationMetadata.collection,\n maxSelect: relationMetadata.maxSelect,\n minSelect: relationMetadata.minSelect,\n cascadeDelete: relationMetadata.cascadeDelete,\n displayFields: relationMetadata.displayFields,\n };\n }\n }\n\n return fieldDef;\n }\n\n // Fall back to existing type inference logic\n const fieldType = mapZodTypeToPocketBase(zodType, fieldName);\n const required = isFieldRequired(zodType);\n const options = extractFieldOptions(zodType);\n\n const fieldDef: FieldDefinition = {\n name: fieldName,\n id: generateFieldId(fieldType, fieldName),\n type: fieldType,\n required,\n options,\n zodType: zodType,\n };\n\n // Check for explicit relation metadata first (from relation() or relations() helpers)\n const relationMetadata = extractRelationMetadata(unwrappedType.description ?? zodType.description);\n\n if (relationMetadata) {\n // Explicit relation definition found\n fieldDef.type = \"relation\";\n fieldDef.relation = {\n collection: relationMetadata.collection,\n maxSelect: relationMetadata.maxSelect,\n minSelect: relationMetadata.minSelect,\n cascadeDelete: relationMetadata.cascadeDelete,\n displayFields: relationMetadata.displayFields,\n };\n\n // Clear out string-specific options that don't apply to relation fields\n fieldDef.options = undefined;\n }\n // Fall back to naming convention detection for backward compatibility\n else if (isRelationField(fieldName, zodType)) {\n // Override type to 'relation' for relation fields\n fieldDef.type = \"relation\";\n\n const targetCollection = resolveTargetCollection(fieldName);\n const maxSelect = getMaxSelect(fieldName, zodType);\n const minSelect = getMinSelect(fieldName, zodType);\n\n fieldDef.relation = {\n collection: targetCollection,\n maxSelect,\n minSelect,\n cascadeDelete: false, // Default to false, can be configured later\n displayFields: null,\n };\n\n // Clear out string-specific options that don't apply to relation fields\n // Options like 'min', 'max', 'pattern' are from string validation and don't apply to relations\n if (fieldDef.options) {\n const { min: _min, max: _max, pattern: _pattern, ...relationSafeOptions } = fieldDef.options;\n fieldDef.options = Object.keys(relationSafeOptions).length ? relationSafeOptions : undefined;\n }\n }\n\n // Special handling for autodate fields\n if (fieldDef.type === \"autodate\") {\n // Autodate fields shouldn't have pattern or other string options\n // and should have onCreate/onUpdate set by default\n fieldDef.options = {\n onCreate: true,\n onUpdate: true,\n ...(fieldDef.options || {}),\n };\n // Remove options that don't apply to autodate\n delete fieldDef.options.pattern;\n delete fieldDef.options.min;\n delete fieldDef.options.max;\n }\n\n return fieldDef;\n}\n\n/**\n * Converts a Zod schema to a CollectionSchema interface\n *\n * @param collectionName - The name of the collection\n * @param zodSchema - The Zod object schema\n * @returns CollectionSchema definition\n */\nexport function convertZodSchemaToCollectionSchema(\n collectionName: string,\n zodSchema: z.ZodObject<any>\n): CollectionSchema {\n // Extract field definitions from Zod schema\n const rawFields = extractFieldDefinitions(zodSchema);\n\n // Determine collection type (auth, view or base)\n // Prefer explicit type from metadata, fall back to field detection\n const explicitType = extractCollectionTypeFromSchema(zodSchema);\n const collectionType = explicitType ?? (isAuthCollection(rawFields) ? \"auth\" : \"base\");\n const isView = collectionType === \"view\";\n\n // View collections are backed by SQL - the query is required\n const viewQuery = extractViewQueryFromSchema(zodSchema);\n if (isView) {\n validateViewQuery(collectionName, viewQuery);\n } else if (viewQuery !== null) {\n console.warn(\n `[${collectionName}] viewQuery is only used by view collections and will be ignored. ` +\n `Use defineView() or set type: \"view\" to define a view collection.`\n );\n }\n\n // Build field definitions with constraints\n const fields: FieldDefinition[] = rawFields\n // Explicitly filter out system fields that might have slipped through\n // This can happen if the schema was constructed manually without base schema\n .filter((f) => ![\"created\", \"updated\"].includes(f.name))\n .map(({ name, zodType }) => buildFieldDefinition(name, zodType));\n\n // Ensure auth system fields exist for auth collections\n if (collectionType === \"auth\") {\n // These fields are required for auth collections and should match the native CLI output\n // Options are set to match PocketBase defaults found in snapshots\n const authSystemFields = [\n {\n name: \"password\",\n type: \"password\",\n required: true,\n options: { min: 8, max: 0, pattern: \"\" },\n },\n {\n name: \"email\",\n type: \"email\",\n required: true,\n options: { exceptDomains: null, onlyDomains: null },\n },\n {\n name: \"emailVisibility\",\n type: \"bool\",\n required: false,\n options: {},\n },\n {\n name: \"verified\",\n type: \"bool\",\n required: false,\n options: {},\n },\n {\n name: \"tokenKey\",\n type: \"text\",\n required: true,\n options: { min: 30, max: 60, pattern: \"\" },\n },\n ] as const;\n\n // Add or update auth fields\n for (const authField of authSystemFields) {\n const existingFieldIndex = fields.findIndex((f) => f.name === authField.name);\n\n if (existingFieldIndex !== -1) {\n // Update existing field to ensure correct type and required status\n const existingField = fields[existingFieldIndex];\n\n // Merge options: defaults -> existing -> forced overrides (none currently)\n // We want to ensure specific options like min/max match defaults if not set\n const mergedOptions = { ...authField.options, ...existingField.options };\n\n fields[existingFieldIndex] = {\n ...existingField,\n type: authField.type, // Force correct type (e.g. 'text' -> 'password')\n required: authField.required, // Force correct required status\n options: mergedOptions,\n };\n } else {\n // Add missing field\n fields.push({\n name: authField.name,\n id: generateFieldId(authField.type, authField.name),\n type: authField.type,\n required: authField.required,\n options: authField.options,\n });\n }\n }\n }\n\n // Extract indexes from schema\n // View collections cannot have indexes - PocketBase rejects them\n const indexes = extractIndexes(zodSchema) || [];\n if (isView && indexes.length > 0) {\n throw new Error(\n `View collection \"${collectionName}\" cannot declare indexes. ` +\n `PocketBase view collections are backed by a SQL query and do not support indexes.`\n );\n }\n\n // Extract and validate permissions from schema\n const permissionAnalyzer = new PermissionAnalyzer();\n let permissions: PermissionSchema | undefined = undefined;\n\n // Try to extract permissions from schema description\n const schemaDescription = zodSchema.description;\n const extractedPermissions = permissionAnalyzer.extractPermissions(schemaDescription);\n\n if (extractedPermissions) {\n // Resolve template configurations to concrete rules\n const resolvedPermissions = permissionAnalyzer.resolvePermissions(extractedPermissions);\n\n // View collections are read-only - warn and drop any write rules\n if (isView) {\n for (const ruleType of [\"createRule\", \"updateRule\", \"deleteRule\", \"manageRule\"] as const) {\n if (resolvedPermissions[ruleType]) {\n console.warn(\n `[${collectionName}] ${ruleType} is not supported on view collections and will be set to null.`\n );\n }\n resolvedPermissions[ruleType] = null;\n }\n }\n\n // Validate permissions against collection fields\n // Skipped for views: their real fields come from the SQL query, so field\n // references in the rules can't be checked against the Zod shape\n if (!isView) {\n const validationResults = permissionAnalyzer.validatePermissions(\n collectionName,\n resolvedPermissions,\n fields,\n collectionType === \"auth\"\n );\n\n // Log validation errors and warnings\n for (const [ruleType, result] of validationResults) {\n if (!result.valid) {\n console.error(`[${collectionName}] Permission validation failed for ${ruleType}:`);\n result.errors.forEach((error) => console.error(` - ${error}`));\n }\n\n if (result.warnings.length > 0) {\n console.warn(`[${collectionName}] Permission warnings for ${ruleType}:`);\n result.warnings.forEach((warning) => console.warn(` - ${warning}`));\n }\n }\n }\n\n // Merge with defaults to ensure all rules are defined\n permissions = permissionAnalyzer.mergeWithDefaults(resolvedPermissions);\n }\n\n // Build collection schema\n // Use extracted permissions for rules, falling back to nulls\n const collectionSchema: CollectionSchema = {\n name: collectionName,\n type: collectionType,\n fields,\n indexes,\n rules: {\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 // Omit manageRule for base collections to match native CLI behavior\n manageRule: collectionType === \"auth\" ? (permissions?.manageRule ?? null) : undefined,\n },\n permissions,\n };\n\n if (isView) {\n collectionSchema.viewQuery = viewQuery as string;\n }\n\n return collectionSchema;\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, SchemaParsingError } from \"../errors\";\nimport { mergeConfig, resolveSchemaDir, type SchemaAnalyzerConfig } from \"./config\";\n\n// Register tsx loader for TypeScript file support\n// This allows dynamic imports of .ts files to work\nlet tsxLoaderRegistered = false;\nasync function ensureTsxLoader(): Promise<void> {\n if (tsxLoaderRegistered) return;\n\n try {\n // Import tsx/esm to register the TypeScript loader hooks\n // This enables dynamic imports of .ts files in Node.js ESM\n await import(\"tsx/esm\");\n tsxLoaderRegistered = true;\n } catch {\n // tsx is not available - will handle in importSchemaModule\n tsxLoaderRegistered = false;\n }\n}\n\n/**\n * Discovers schema files in the specified directory\n * Filters based on configuration patterns\n *\n * @param config - Schema analyzer configuration\n * @returns Array of schema file paths (without extension)\n */\nexport function discoverSchemaFiles(config: SchemaAnalyzerConfig | string): string[] {\n // Support legacy string-only parameter\n const normalizedConfig: SchemaAnalyzerConfig = typeof config === \"string\" ? { schemaDir: config } : config;\n\n const mergedConfig = mergeConfig(normalizedConfig);\n const schemaDir = resolveSchemaDir(normalizedConfig);\n\n try {\n if (!fs.existsSync(schemaDir)) {\n throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, \"access\", \"ENOENT\");\n }\n\n const files = fs.readdirSync(schemaDir);\n\n // Pre-compile exclusion patterns to regexes for performance\n const excludeMatchers = mergedConfig.excludePatterns.map((pattern) => {\n if (pattern.includes(\"*\")) {\n return new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n }\n return pattern; // For exact match\n });\n\n // Filter files based on configuration\n const schemaFiles = files.filter((file) => {\n // Check extension\n const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));\n if (!hasValidExtension) return false;\n\n // Check exclusion patterns\n const isExcluded = excludeMatchers.some((matcher) => {\n if (typeof matcher === \"string\") {\n return file === matcher;\n }\n return matcher.test(file); // It's a regex\n });\n if (isExcluded) return false;\n\n return true;\n });\n\n // Create a single regex to remove any of the valid extensions, escaping special characters\n const extensionRemovalRegex = new RegExp(\n `(${mergedConfig.includeExtensions.map((ext) => ext.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\"|\")})$`\n );\n\n // Return full paths without extension (for dynamic import)\n return schemaFiles.map((file) => {\n return path.join(schemaDir, file.replace(extensionRemovalRegex, \"\"));\n });\n } catch (error) {\n if (error instanceof FileSystemError) {\n throw error;\n }\n\n const fsError = error as NodeJS.ErrnoException;\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied reading schema directory: ${schemaDir}`,\n schemaDir,\n \"read\",\n fsError.code,\n error as Error\n );\n }\n\n throw new FileSystemError(\n `Failed to read schema directory: ${schemaDir}`,\n schemaDir,\n \"read\",\n fsError.code,\n error as Error\n );\n }\n}\n\n/**\n * Dynamically imports a schema module\n * Supports both JavaScript and TypeScript files using tsx\n *\n * @param filePath - Path to the schema file (without extension)\n * @param config - Optional configuration for path transformation\n * @returns The imported module\n */\nexport async function importSchemaModule(filePath: string, config?: SchemaAnalyzerConfig): Promise<any> {\n try {\n let importPath = filePath;\n\n // Apply path transformation if provided\n if (config?.pathTransformer) {\n importPath = config.pathTransformer(filePath);\n }\n\n // Determine the file extension to use\n // Try .js first (for compiled files), then .ts (for source files)\n let resolvedPath: string | null = null;\n const jsPath = `${importPath}.js`;\n const tsPath = `${importPath}.ts`;\n\n if (fs.existsSync(jsPath)) {\n resolvedPath = jsPath;\n } else if (fs.existsSync(tsPath)) {\n resolvedPath = tsPath;\n } else {\n // Default to .js extension for ESM import\n resolvedPath = jsPath;\n }\n\n // If it's a TypeScript file, ensure tsx loader is registered\n if (resolvedPath.endsWith(\".ts\")) {\n await ensureTsxLoader();\n\n // Check if tsx was successfully registered\n if (!tsxLoaderRegistered) {\n throw new SchemaParsingError(\n `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.\\n` +\n `Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)\\n` +\n `Alternatively, compile your schema files to JavaScript first.`,\n filePath\n );\n }\n }\n\n // Convert to file URL for proper ESM import\n const fileUrl = new URL(`file://${path.resolve(resolvedPath)}`);\n\n // Use dynamic import to load the module\n // tsx/esm will handle TypeScript files automatically if registered\n const module = await import(fileUrl.href);\n return module;\n } catch (error) {\n // Check if we're trying to import a TypeScript file\n const tsPath = `${filePath}.ts`;\n const isTypeScriptFile = fs.existsSync(tsPath);\n\n if (isTypeScriptFile && error instanceof SchemaParsingError) {\n // Re-throw SchemaParsingError as-is (already has helpful message)\n throw error;\n }\n\n if (isTypeScriptFile) {\n throw new SchemaParsingError(\n `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.\\n` +\n `Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)\\n` +\n `Alternatively, compile your schema files to JavaScript first.`,\n filePath,\n error as Error\n );\n }\n\n throw new SchemaParsingError(\n `Failed to import schema module. Make sure the schema files exist and are valid.`,\n filePath,\n error as Error\n );\n }\n}\n","/**\n * Schema Analyzer - Parses Zod schemas and extracts field definitions\n *\n * This module provides a standalone, configurable schema analyzer that can be used\n * by consumer projects to parse Zod schemas and convert them to PocketBase collection schemas.\n */\n\nimport * as fs from \"fs\";\nimport { z } from \"zod\";\nimport { SchemaParsingError } from \"../errors\";\nimport type { CollectionSchema, SchemaDefinition } from \"../types\";\nimport { mergeConfig, resolveSchemaDir, type SchemaAnalyzerConfig } from \"./config\";\nimport { convertZodSchemaToCollectionSchema } from \"./converter\";\nimport {\n extractCollectionNameFromSchema,\n extractSchemaDefinitions,\n getCollectionNameFromFile,\n selectSchemaForCollection,\n} from \"./extractors\";\nimport { discoverSchemaFiles, importSchemaModule } from \"./loader\";\n\n// Export everything from submodules\nexport * from \"./config\";\nexport * from \"./converter\";\nexport * from \"./extractors\";\nexport * from \"./loader\";\n\n/**\n * Builds a complete SchemaDefinition from schema files\n * Main entry point for the Schema Analyzer\n *\n * @param config - Schema analyzer configuration or path to schema directory\n * @returns Complete SchemaDefinition with all collections\n */\nexport async function buildSchemaDefinition(config: SchemaAnalyzerConfig | string): Promise<SchemaDefinition> {\n // Support legacy string-only parameter\n const normalizedConfig: SchemaAnalyzerConfig = typeof config === \"string\" ? { schemaDir: config } : config;\n\n const mergedConfig = mergeConfig(normalizedConfig);\n const collections = new Map<string, CollectionSchema>();\n\n // Discover schema files\n const schemaFiles = discoverSchemaFiles(normalizedConfig);\n\n if (schemaFiles.length === 0) {\n const schemaDir = resolveSchemaDir(normalizedConfig);\n throw new SchemaParsingError(\n `No schema files found in ${schemaDir}. Make sure you have schema files in the directory.`,\n schemaDir\n );\n }\n\n // Process each schema file\n for (const filePath of schemaFiles) {\n try {\n let importPath = filePath;\n\n // Apply path transformation if provided (for monorepo setups)\n if (normalizedConfig.pathTransformer) {\n importPath = normalizedConfig.pathTransformer(filePath);\n } else if (mergedConfig.useCompiledFiles) {\n // Default transformation: convert /src/ to /dist/ for compiled files\n // This is a common pattern but can be overridden with pathTransformer\n const distPath = filePath.replace(/\\/src\\//, \"/dist/\");\n // Only use dist path if it actually exists (i.e., files are compiled)\n // Otherwise, fall back to source path for TypeScript files\n if (fs.existsSync(`${distPath}.js`) || fs.existsSync(`${distPath}.mjs`)) {\n importPath = distPath;\n } else {\n // Files aren't compiled, use source path\n importPath = filePath;\n }\n }\n\n // Import the module\n const module = await importSchemaModule(importPath, normalizedConfig);\n\n // Extract schema definitions\n const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);\n\n // Select the appropriate schema\n const zodSchema = selectSchemaForCollection(schemas);\n\n if (!zodSchema) {\n console.warn(`No valid schema found in ${filePath}, skipping...`);\n continue;\n }\n\n // Get collection name - prefer metadata from defineCollection(), fall back to filename\n const collectionNameFromSchema = extractCollectionNameFromSchema(zodSchema);\n const collectionName = collectionNameFromSchema ?? getCollectionNameFromFile(filePath);\n\n // Convert to CollectionSchema\n const collectionSchema = convertZodSchemaToCollectionSchema(collectionName, zodSchema);\n\n // Add to collections map\n collections.set(collectionName, collectionSchema);\n } catch (error) {\n // If it's already a SchemaParsingError, re-throw it\n if (error instanceof SchemaParsingError) {\n throw error;\n }\n\n // Otherwise, wrap it in a SchemaParsingError\n throw new SchemaParsingError(\n `Error processing schema file: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error as Error\n );\n }\n }\n\n return { collections };\n}\n\n/**\n * Parses schema files and returns SchemaDefinition\n * Alias for buildSchemaDefinition for better semantic clarity\n *\n * @param config - Schema analyzer configuration or path to schema directory\n * @returns Complete SchemaDefinition with all collections\n */\nexport async function parseSchemaFiles(config: SchemaAnalyzerConfig | string): Promise<SchemaDefinition> {\n return buildSchemaDefinition(config);\n}\n\n/**\n * Creates a SchemaAnalyzer instance with the given configuration\n * Provides an object-oriented interface for schema analysis\n */\nexport class SchemaAnalyzer {\n private config: Required<Omit<SchemaAnalyzerConfig, \"pathTransformer\">> & {\n pathTransformer?: (sourcePath: string) => string;\n };\n\n constructor(config: SchemaAnalyzerConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Discovers schema files in the configured directory\n */\n discoverSchemaFiles(): string[] {\n return discoverSchemaFiles(this.config);\n }\n\n /**\n * Parses all schema files and returns a SchemaDefinition\n */\n async parseSchemaFiles(): Promise<SchemaDefinition> {\n return buildSchemaDefinition(this.config);\n }\n\n /**\n * Converts a single Zod schema to a CollectionSchema\n */\n convertZodSchemaToCollectionSchema(name: string, schema: z.ZodObject<any>): CollectionSchema {\n return convertZodSchemaToCollectionSchema(name, schema);\n }\n}\n","/**\n * PocketBase Format Converter\n * Converts PocketBase collection objects to our internal CollectionSchema format\n *\n * This module handles conversion between PocketBase's native collection format\n * (as found in migration files and snapshots) and our internal schema representation.\n */\n\nimport { dedentSql } from \"../schema/view\";\nimport { SnapshotError } from \"./errors\";\nimport type { CollectionSchema, FieldDefinition, SchemaSnapshot } from \"./types\";\n\nconst SNAPSHOT_VERSION = \"1.0.0\";\n\n/**\n * Resolves a collection ID to a collection name\n * Uses known constants and parses migration expressions to resolve IDs\n *\n * @param collectionId - The collection ID to resolve\n * @returns The collection name, or the original ID if it can't be resolved\n */\nexport function resolveCollectionIdToName(collectionId: string): string {\n // Special case: _pb_users_auth_ is the constant for users collection\n if (collectionId === \"_pb_users_auth_\") {\n return \"users\";\n }\n\n // Try to extract collection name from expressions like app.findCollectionByNameOrId(\"Name\").id\n const nameMatch = collectionId.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (nameMatch) {\n return nameMatch[1];\n }\n\n // If we can't resolve it, return the original ID\n // This will cause a comparison issue, but it's better than failing\n return collectionId;\n}\n\n/**\n * Extracts field options from a PocketBase field object\n * Options can be placed directly on the field or in a nested options object\n * Direct properties take precedence over nested options\n *\n * @param pbField - PocketBase field object\n * @returns Merged options object\n */\nfunction extractFieldOptions(pbField: any): Record<string, any> {\n const options: Record<string, any> = {};\n\n // Start with nested options if present\n if (pbField.options && typeof pbField.options === \"object\") {\n Object.assign(options, pbField.options);\n }\n\n // Extract common field options from direct properties\n // These take precedence over nested options\n const directOptionKeys = [\n \"min\",\n \"max\",\n \"pattern\",\n \"noDecimal\", // text/number fields (legacy, PocketBase uses onlyInt)\n \"onlyInt\", // number fields (PocketBase uses this instead of noDecimal)\n \"values\",\n \"maxSelect\", // select fields\n \"mimeTypes\",\n \"maxSize\",\n \"thumbs\",\n \"protected\", // file fields\n \"onCreate\",\n \"onUpdate\", // autodate fields\n \"exceptDomains\",\n \"onlyDomains\", // email/url fields\n ];\n\n for (const key of directOptionKeys) {\n if (pbField[key] !== undefined) {\n options[key] = pbField[key];\n }\n }\n\n return options;\n}\n\n/**\n * Converts a PocketBase field object to FieldDefinition format\n *\n * @param pbField - PocketBase field object\n * @returns FieldDefinition object\n */\nexport function convertPocketBaseField(pbField: any): FieldDefinition {\n const field: any = {\n name: pbField.name,\n id: pbField.id,\n type: pbField.type,\n required: pbField.required || false,\n };\n\n // Extract options from both direct properties and nested options object\n field.options = extractFieldOptions(pbField);\n\n // Convert onlyInt to noDecimal for number fields (PocketBase uses onlyInt, but our schema uses noDecimal)\n if (pbField.type === \"number\" && field.options.onlyInt !== undefined) {\n field.options.noDecimal = field.options.onlyInt;\n delete field.options.onlyInt;\n }\n\n // Handle relation fields\n if (pbField.type === \"relation\") {\n // Support both formats: collectionId directly on field or in options\n const collectionId = pbField.collectionId || pbField.options?.collectionId || \"\";\n // Resolve collectionId to collection name\n // collectionId is a system field (like _pb_users_auth_), not the collection name\n // We need to resolve it to the actual collection name for comparison\n const collectionName = resolveCollectionIdToName(collectionId || \"\");\n field.relation = {\n collection: collectionName,\n cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,\n maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,\n minSelect: pbField.minSelect ?? pbField.options?.minSelect,\n displayFields: pbField.displayFields ?? pbField.options?.displayFields ?? null,\n };\n\n // Remove relation-specific properties from options\n // These belong in the relation object, not options\n delete field.options.maxSelect;\n delete field.options.minSelect;\n delete field.options.cascadeDelete;\n delete field.options.displayFields;\n }\n\n // Clean up empty options object, but preserve values for select fields\n // If options only contains values for a select field, keep it\n const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== undefined;\n if (Object.keys(field.options).length === 0) {\n delete field.options;\n } else if (pbField.type === \"select\" && hasOnlyValues) {\n // Keep options object if it only contains values for a select field\n // This ensures values are preserved for comparison\n }\n\n return field as FieldDefinition;\n}\n\n/**\n * Converts a PocketBase collection object to CollectionSchema format\n *\n * @param pbCollection - PocketBase collection object from migration file\n * @returns CollectionSchema object\n */\nexport function convertPocketBaseCollection(pbCollection: any): CollectionSchema {\n const fields: any[] = [];\n const isView = pbCollection.type === \"view\";\n\n // System field names that should always be excluded\n const systemFieldNames = [\"id\", \"created\", \"updated\", \"collectionId\", \"collectionName\", \"expand\"];\n\n // View collections have no stored fields - PocketBase derives them from the\n // view query, so anything present here is generated output, not schema\n // Convert PocketBase fields to our FieldDefinition format\n if (!isView && pbCollection.fields && Array.isArray(pbCollection.fields)) {\n for (const pbField of pbCollection.fields) {\n // Skip system fields by checking both the system flag and field name\n // Some PocketBase exports mark created/updated as system: false\n if (pbField.system || systemFieldNames.includes(pbField.name)) {\n // For auth collections, we want to keep the system fields (email, password, etc.)\n // These are marked as system: true in PocketBase, but we need them in our schema\n // to match the CLI behavior which includes them in the fields array\n const isAuthSystemField =\n pbCollection.type === \"auth\" &&\n [\"email\", \"emailVisibility\", \"verified\", \"password\", \"tokenKey\"].includes(pbField.name);\n\n if (!isAuthSystemField) {\n continue;\n }\n }\n\n const field = convertPocketBaseField(pbField);\n fields.push(field);\n }\n }\n\n const schema: CollectionSchema = {\n name: pbCollection.name,\n type: pbCollection.type || \"base\",\n fields,\n };\n\n // Preserve collection ID if present (needed for relation resolution)\n if (pbCollection.id) {\n schema.id = pbCollection.id;\n }\n\n // Preserve the SQL query backing a view collection\n // Dedented so a query indented to fit the migration file compares equal to\n // the one declared in the schema\n if (typeof pbCollection.viewQuery === \"string\") {\n schema.viewQuery = dedentSql(pbCollection.viewQuery);\n }\n\n // Add indexes if present\n if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {\n schema.indexes = pbCollection.indexes;\n }\n\n // Add rules/permissions\n // Check if any rule properties exist on the collection object\n const hasAnyRule =\n pbCollection.listRule !== undefined ||\n pbCollection.viewRule !== undefined ||\n pbCollection.createRule !== undefined ||\n pbCollection.updateRule !== undefined ||\n pbCollection.deleteRule !== undefined ||\n pbCollection.manageRule !== undefined;\n\n if (hasAnyRule) {\n const rules: any = {};\n // Include rules even if they're null (null is a valid value)\n if (pbCollection.listRule !== undefined) rules.listRule = pbCollection.listRule;\n if (pbCollection.viewRule !== undefined) rules.viewRule = pbCollection.viewRule;\n if (pbCollection.createRule !== undefined) rules.createRule = pbCollection.createRule;\n if (pbCollection.updateRule !== undefined) rules.updateRule = pbCollection.updateRule;\n if (pbCollection.deleteRule !== undefined) rules.deleteRule = pbCollection.deleteRule;\n if (pbCollection.manageRule !== undefined) rules.manageRule = pbCollection.manageRule;\n\n schema.rules = rules;\n // Also set permissions to match rules (they're the same thing)\n schema.permissions = { ...rules };\n }\n\n return schema;\n}\n\n/**\n * Converts PocketBase migration format to SchemaSnapshot\n * Extracts the snapshot array from the migration file content\n *\n * @param migrationContent - Raw migration file content\n * @returns SchemaSnapshot with collections map\n */\nexport function convertPocketBaseMigration(migrationContent: string): SchemaSnapshot {\n try {\n // Extract the snapshot array from the migration file\n // The format is: migrate((app) => { const snapshot = [...]; ... })\n const snapshotMatch = migrationContent.match(/const\\s+snapshot\\s*=\\s*(\\[[\\s\\S]*?\\]);/);\n\n if (!snapshotMatch) {\n throw new Error(\"Could not find snapshot array in migration file\");\n }\n\n // Parse the snapshot array as JSON\n // We need to evaluate it as JavaScript since it's not pure JSON\n const snapshotArrayStr = snapshotMatch[1];\n let snapshotArray: any[];\n\n try {\n // Use Function constructor to safely evaluate the array\n // This is safer than eval() and works for our use case\n snapshotArray = new Function(`return ${snapshotArrayStr}`)();\n } catch (parseError) {\n throw new Error(`Failed to parse snapshot array: ${parseError}`);\n }\n\n if (!Array.isArray(snapshotArray)) {\n throw new Error(\"Snapshot is not an array\");\n }\n\n // Convert each collection to our format\n const collections = new Map<string, CollectionSchema>();\n\n for (const pbCollection of snapshotArray) {\n if (!pbCollection.name) {\n console.warn(\"Skipping collection without name\");\n continue;\n }\n\n const schema = convertPocketBaseCollection(pbCollection);\n collections.set(pbCollection.name, schema);\n }\n\n return {\n version: SNAPSHOT_VERSION,\n timestamp: new Date().toISOString(),\n collections,\n };\n } catch (error) {\n throw new SnapshotError(\n `Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,\n undefined,\n \"parse\",\n error instanceof Error ? error : undefined\n );\n }\n}\n","/**\n * Migration File Parser\n * Parses PocketBase migration files to extract collection operations\n *\n * This module handles parsing migration files to extract:\n * - Collection creations (new Collection(...))\n * - Collection deletions (app.delete(...))\n * - Field modifications (field.property = value)\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { dedentSql } from \"../schema/view\";\nimport { convertPocketBaseCollection, convertPocketBaseField } from \"./pocketbase-converter\";\nimport type { CollectionSchema, FieldDefinition } from \"./types\";\n\nexport interface ParsedCollectionUpdate {\n collectionName: string;\n fieldsToAdd: FieldDefinition[];\n fieldsToRemove: string[]; // names\n fieldsToUpdate: {\n fieldName: string;\n changes: Record<string, any>; // property -> value\n }[];\n indexesToAdd: string[];\n indexesToRemove: string[];\n rulesToUpdate: Record<string, string | null>;\n /** New SQL query for a view collection, when the migration updates one */\n viewQuery?: string;\n}\n\n/**\n * Extracts timestamp from migration filename\n * Migration files are named: [timestamp]_[description].js\n *\n * @param filename - Migration filename\n * @returns Timestamp as number or null if not found\n */\nexport function extractTimestampFromFilename(filename: string): number | null {\n const match = filename.match(/^(\\d+)_/);\n if (match) {\n return parseInt(match[1], 10);\n }\n return null;\n}\n\n/**\n * Finds all migration files after a given snapshot timestamp\n * Excludes snapshot files themselves\n *\n * @param migrationsPath - Path to migrations directory\n * @param snapshotTimestamp - Timestamp of the snapshot file\n * @returns Array of migration file paths sorted by timestamp\n */\nexport function findMigrationsAfterSnapshot(migrationsPath: string, snapshotTimestamp: number): string[] {\n try {\n if (!fs.existsSync(migrationsPath)) {\n return [];\n }\n\n const files = fs.readdirSync(migrationsPath);\n const migrationFiles: { path: string; timestamp: number }[] = [];\n const timestampsSeen = new Set<number>();\n // const duplicates: string[] = [];\n\n for (const file of files) {\n // Skip snapshot files\n if (file.endsWith(\"_collections_snapshot.js\") || file.endsWith(\"_snapshot.js\")) {\n continue;\n }\n\n // Skip non-JS files\n if (!file.endsWith(\".js\")) {\n continue;\n }\n\n const timestamp = extractTimestampFromFilename(file);\n if (timestamp) {\n if (timestampsSeen.has(timestamp)) {\n console.warn(`Duplicate migration timestamp detected: ${timestamp} in file ${file}`);\n }\n timestampsSeen.add(timestamp);\n\n if (timestamp > snapshotTimestamp) {\n migrationFiles.push({\n path: path.join(migrationsPath, file),\n timestamp,\n });\n }\n }\n }\n\n // Sort by timestamp (ascending order)\n migrationFiles.sort((a, b) => a.timestamp - b.timestamp);\n\n return migrationFiles.map((f) => f.path);\n } catch (error) {\n console.warn(`Error finding migrations after snapshot: ${error}`);\n return [];\n }\n}\n\n/**\n * Skips over a template literal starting at the given backtick\n *\n * View queries are emitted as backtick templates and routinely contain braces,\n * double quotes and apostrophes (in SQL comments), all of which would otherwise\n * desynchronize the object scanner.\n *\n * @param content - Full migration content\n * @param start - Index of the opening backtick\n * @returns Index just past the closing backtick (or end of content)\n */\nfunction skipTemplateLiteral(content: string, start: number): number {\n let i = start + 1;\n\n while (i < content.length) {\n const char = content[i];\n\n if (char === \"\\\\\") {\n // Skip the escaped character\n i += 2;\n continue;\n }\n\n if (char === \"`\") {\n return i + 1;\n }\n\n i++;\n }\n\n return i;\n}\n\n/**\n * Reverses the escaping applied when a value is emitted as a template literal\n *\n * @param raw - Template literal body (without the surrounding backticks)\n * @returns The original string\n */\nfunction unescapeTemplateLiteral(raw: string): string {\n return raw.replace(/\\\\(`|\\$\\{|\\\\)/g, \"$1\");\n}\n\n/**\n * Helper function to parse collection operations from migration content\n *\n * @param content - Migration content (should be just the UP migration)\n * @returns Object with collections to create and collections to delete\n */\nfunction parseMigrationOperationsFromContent(content: string): {\n collectionsToCreate: CollectionSchema[];\n collectionsToDelete: string[];\n collectionsToUpdate: ParsedCollectionUpdate[];\n} {\n const collectionsToCreate: CollectionSchema[] = [];\n const collectionsToDelete: string[] = [];\n const collectionsToUpdate: ParsedCollectionUpdate[] = [];\n\n // Mock app object for eval\n const mockApp = {\n findCollectionByNameOrId: (name: string) => ({ id: name, name }),\n };\n\n // Helper to get or create update object\n const getUpdate = (name: string) => {\n let update = collectionsToUpdate.find((u) => u.collectionName === name);\n if (!update) {\n update = {\n collectionName: name,\n fieldsToAdd: [],\n fieldsToRemove: [],\n fieldsToUpdate: [],\n indexesToAdd: [],\n indexesToRemove: [],\n rulesToUpdate: {},\n };\n collectionsToUpdate.push(update);\n }\n return update;\n };\n\n try {\n // 1. Parse Creations: new Collection({...})\n let searchIndex = 0;\n while (true) {\n const collectionStart = content.indexOf(\"new Collection(\", searchIndex);\n if (collectionStart === -1) {\n break;\n }\n\n const openParen = collectionStart + \"new Collection(\".length;\n let objectContent = \"\";\n let i = openParen;\n\n // Extract object literal\n let braceCount = 0;\n let parenCount = 1;\n let inString = false;\n let stringChar = null;\n let objectStart = -1;\n\n // Skip whitespace to find the opening brace\n while (i < content.length && /\\s/.test(content[i])) {\n i++;\n }\n\n if (content[i] === \"{\") {\n objectStart = i;\n braceCount = 1;\n i++;\n\n while (i < content.length && (braceCount > 0 || parenCount > 0)) {\n const char = content[i];\n const prevChar = i > 0 ? content[i - 1] : \"\";\n\n if (!inString && (char === '\"' || char === \"'\")) {\n inString = true;\n stringChar = char;\n } else if (inString && char === stringChar && prevChar !== \"\\\\\") {\n inString = false;\n stringChar = null;\n }\n\n if (!inString) {\n if (char === \"{\") braceCount++;\n if (char === \"}\") braceCount--;\n if (char === \"(\") parenCount++;\n if (char === \")\") parenCount--;\n }\n i++;\n }\n\n if (braceCount === 0) {\n objectContent = content.substring(objectStart, i - (parenCount === 0 ? 1 : 0));\n // Correctly substring: if we broke loop because braceCount is 0, i is at char AFTER '}'\n // But if parenCount also went to 0, we might be further.\n // Actually my logic above: i increments at end of loop.\n // If braceCount becomes 0, loop continues if parenCount > 0 (which it is, started at 1)\n // Wait, new Collection({...})\n // { ... } is inside ( ... )\n // So braceCount goes 1 -> ... -> 0.\n // parenCount stays 1.\n // Loop continues until parenCount 0? No, usually `new Collection({...})`\n // The loop condition is `braceCount > 0 || parenCount > 0`.\n // When '}' matches, braceCount becomes 0. parenCount is 1. Loop continues.\n // Next char is ')'. parenCount becomes 0. Loop stops.\n }\n } else {\n // No object literal?\n searchIndex = i + 1;\n continue;\n }\n\n if (objectContent) {\n // We need to extract just the object part, which ended when braceCount hit 0.\n // My loop logic is a bit combined.\n // Let's rely on the previous simpler logic but refined.\n // Actually, let's use the object content extraction from the previous implementation but wrapped in this loop\n }\n\n // Re-implementing the object extraction carefully\n i = openParen;\n // Skip whitespace\n while (i < content.length && /\\s/.test(content[i])) {\n i++;\n }\n\n if (content[i] !== \"{\") {\n searchIndex = i + 1;\n continue;\n }\n\n const startObj = i;\n let bCount = 1;\n i++;\n let inStr = false;\n let strChar = null;\n\n while (i < content.length && bCount > 0) {\n const char = content[i];\n const prev = i > 0 ? content[i - 1] : \"\";\n\n // Template literals (used for view queries) can contain braces, quotes\n // and apostrophes, so skip over them wholesale\n if (!inStr && char === \"`\") {\n i = skipTemplateLiteral(content, i);\n continue;\n }\n\n if (!inStr && (char === '\"' || char === \"'\")) {\n inStr = true;\n strChar = char;\n } else if (inStr && char === strChar && prev !== \"\\\\\") {\n inStr = false;\n strChar = null;\n }\n\n if (!inStr) {\n if (char === \"{\") bCount++;\n if (char === \"}\") bCount--;\n }\n i++;\n }\n\n if (bCount === 0) {\n const objStr = content.substring(startObj, i);\n try {\n // Pass mockApp as 'app' to the function\n const collectionObj = new Function(\"app\", `return ${objStr}`)(mockApp);\n if (collectionObj && collectionObj.name) {\n const schema = convertPocketBaseCollection(collectionObj);\n collectionsToCreate.push(schema);\n }\n } catch (e) {\n console.warn(\"Failed to parse collection object:\", e);\n }\n }\n searchIndex = i;\n }\n\n // 2. Parse Deletions\n const deleteMatches = content.matchAll(\n /app\\.delete\\s*\\(\\s*(?:collection_\\w+|app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\))\\s*\\)/g\n );\n for (const match of deleteMatches) {\n if (match[1]) {\n collectionsToDelete.push(match[1]);\n } else {\n // Variable lookup logic (simplified for now, assuming standard variable naming)\n // Assuming collection variables are tracked if I were parsing sequentially.\n // But here I'm using regex.\n // Let's try to extract name from variable name if it follows `collection_NAME`\n const varMatch = match[0].match(/collection_(\\w+)/);\n if (varMatch) {\n // Try to infer name (may not be accurate if variable name != collection name)\n // But usually generator uses `collection_NAME`\n // Can I look up the definition?\n // Not easily without full scan.\n // I'll stick to what was there: try to find definition.\n const varName = `collection_${varMatch[1]}`;\n const defRegex = new RegExp(\n `const\\\\s+${varName}\\\\s*=\\\\s*app\\\\.findCollectionByNameOrId\\\\([\"']([^\"']+)[\"']\\\\)(?:\\\\s*//\\\\s*([^\\\\n\\\\r;]+))?`\n );\n const defMatch = content.match(defRegex);\n if (defMatch) {\n const name = defMatch[2] ? defMatch[2].trim() : defMatch[1];\n collectionsToDelete.push(name);\n } else {\n // Try new Collection assignment\n // const newColRegex = new RegExp(\n // `const\\\\s+${varName}\\\\s*=\\\\s*new\\\\s+Collection\\\\(\\\\s*\\\\{([\\\\s\\\\S]*?)\\\\}\\\\s*\\\\)`\n // );\n // This is hard.\n }\n }\n }\n }\n\n // Also direct delete of variable\n // Check assignments: const col = app.findCollectionByNameOrId(\"name\"); app.delete(col);\n const varAssignments = new Map<string, string>();\n const assignmentMatches = content.matchAll(\n /const\\s+(\\w+)\\s*=\\s*app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)(?:[ \\t]*\\/\\/\\s*([^\\n\\r;]+))?/g\n );\n for (const match of assignmentMatches) {\n const name = match[3] ? match[3].trim() : match[2];\n varAssignments.set(match[1], name);\n }\n\n const varDeleteMatches = content.matchAll(/app\\.delete\\s*\\(\\s*(\\w+)\\s*\\)/g);\n for (const match of varDeleteMatches) {\n if (varAssignments.has(match[1])) {\n const name = varAssignments.get(match[1])!;\n if (!collectionsToDelete.includes(name)) {\n collectionsToDelete.push(name);\n }\n }\n }\n\n // 3. Parse Updates\n\n // Map of variable name -> { collectionName, type: 'collection' | 'field' | 'index', parentVar? }\n const variables = new Map<string, { type: \"collection\" | \"field\"; name: string; parentCollection?: string }>();\n\n // Initialize variables from assignments\n for (const [varName, colName] of varAssignments) {\n variables.set(varName, { type: \"collection\", name: colName });\n }\n\n // Find field variables: const field = col.fields.getByName(\"name\")\n const fieldAssignmentMatches = content.matchAll(\n /const\\s+(\\w+)\\s*=\\s*(\\w+)\\.fields\\.getByName\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g\n );\n for (const match of fieldAssignmentMatches) {\n const [_, fieldVar, colVar, fieldName] = match;\n const colInfo = variables.get(colVar);\n if (colInfo && colInfo.type === \"collection\") {\n variables.set(fieldVar, {\n type: \"field\",\n name: fieldName,\n parentCollection: colInfo.name,\n });\n }\n }\n\n // 3a. fields.add and fields.addAt\n // Pattern: colVar.fields.add(new TypeField({...})) OR colVar.fields.addAt(index, new TypeField({...}))\n const addFieldMatches = content.matchAll(\n /(\\w+)\\.fields\\.(?:add|addAt)\\s*\\((?:\\s*\\d+\\s*,)?\\s*new\\s+\\w*Field\\s*\\(/g\n );\n for (const match of addFieldMatches) {\n const [fullMatch, colVar] = match;\n const colInfo = variables.get(colVar);\n if (colInfo && colInfo.type === \"collection\") {\n // Extract the field definition object\n const startIdx = match.index! + fullMatch.length;\n // We need to find the object inside (...)\n // It usually looks like: new TextField({ ... })\n // So we are at start of `{` hopefully?\n // Actually `new TextField(` -> next char might be whitespace then `{`\n\n let j = startIdx;\n while (j < content.length && /\\s/.test(content[j])) j++;\n\n if (content[j] === \"{\") {\n // Extract object\n const objStart = j;\n let bCount = 1;\n j++;\n let inStr = false;\n let sChar = null;\n\n while (j < content.length && bCount > 0) {\n const char = content[j];\n const prev = j > 0 ? content[j - 1] : \"\";\n if (!inStr && (char === '\"' || char === \"'\")) {\n inStr = true;\n sChar = char;\n } else if (inStr && char === sChar && prev !== \"\\\\\") {\n inStr = false;\n sChar = null;\n }\n if (!inStr) {\n if (char === \"{\") bCount++;\n if (char === \"}\") bCount--;\n }\n j++;\n }\n\n if (bCount === 0) {\n const objStr = content.substring(objStart, j);\n // We also need the type. Regex `new (\\w+)Field`\n const typeMatch = fullMatch.match(/new\\s+(\\w*)Field/);\n // const fieldTypeStr = typeMatch ? typeMatch[1].toLowerCase() : \"text\"; // Default/Fallback\n\n try {\n // We need to inject the type into the object if it's not there,\n // or rely on convertPocketBaseField.\n // convertPocketBaseField expects `type` property.\n // But `new TextField({...})` usually doesn't have `type: 'text'` inside.\n // It's inferred from constructor.\n\n const rawObj = new Function(\"app\", `return ${objStr}`)(mockApp);\n\n // Map constructor name to type string if needed\n // Valid types: text, number, bool, email, url, date, select, json, file, relation\n const typeMap: Record<string, string> = {\n Text: \"text\",\n Number: \"number\",\n Bool: \"bool\",\n Email: \"email\",\n URL: \"url\",\n Date: \"date\",\n Select: \"select\",\n JSON: \"json\",\n File: \"file\",\n Relation: \"relation\",\n };\n const typePrefix = typeMatch ? typeMatch[1] : \"Text\";\n const inferredType = typeMap[typePrefix] || typePrefix.toLowerCase();\n\n if (!rawObj.type) rawObj.type = inferredType;\n\n const fieldDef = convertPocketBaseField(rawObj);\n getUpdate(colInfo.name).fieldsToAdd.push(fieldDef);\n } catch (e) {\n console.warn(\"Failed to parse field object:\", e);\n }\n }\n }\n }\n }\n\n // 3b. fields.removeByName\n const removeFieldMatches = content.matchAll(/(\\w+)\\.fields\\.removeByName\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g);\n for (const match of removeFieldMatches) {\n const [_, colVar, fieldName] = match;\n const colInfo = variables.get(colVar);\n if (colInfo && colInfo.type === \"collection\") {\n getUpdate(colInfo.name).fieldsToRemove.push(fieldName);\n }\n }\n\n // 3c. Field updates: fieldVar.prop = value\n // We iterate over lines/statements or just generic assignment regex?\n // Assignment: `var.prop = value;`\n // Regex: `(\\w+)\\.(\\w+)\\s*=\\s*(.+?);`\n // Be careful with newlines and semicolons.\n const assignmentRegex = RegExp(`(\\\\w+)\\\\.([\\\\w.]+)\\\\s*=\\\\s*([^;]+);`, \"g\");\n const assignments = content.matchAll(assignmentRegex);\n for (const match of assignments) {\n const [_, varName, propPath, valueStr] = match;\n const varInfo = variables.get(varName);\n\n if (varInfo) {\n if (varInfo.type === \"field\") {\n // Update to a field\n const colName = varInfo.parentCollection!;\n const fieldName = varInfo.name;\n const update = getUpdate(colName);\n\n let fieldUpdate = update.fieldsToUpdate.find((f) => f.fieldName === fieldName);\n if (!fieldUpdate) {\n fieldUpdate = { fieldName, changes: {} };\n update.fieldsToUpdate.push(fieldUpdate);\n }\n\n try {\n // Parse value\n const value = new Function(\"app\", `return ${valueStr}`)(mockApp);\n fieldUpdate.changes[propPath] = value;\n } catch {\n // console.warn(\"Failed to parse value:\", valueStr);\n // Use string if eval fails?\n fieldUpdate.changes[propPath] = valueStr.trim();\n }\n } else if (varInfo.type === \"collection\") {\n // Update to collection (rules, indexes)\n const colName = varInfo.name;\n const update = getUpdate(colName);\n\n if (propPath === \"indexes\") {\n // ignore direct assignment to indexes for now, usually it's push/splice\n } else if (propPath.endsWith(\"Rule\")) {\n try {\n const value = new Function(\"app\", `return ${valueStr}`)(mockApp);\n update.rulesToUpdate[propPath] = value;\n } catch {\n update.rulesToUpdate[propPath] = valueStr.trim();\n }\n }\n }\n }\n }\n\n // 3c-2. View query updates: `collectionVar.viewQuery = `...`;`\n // Handled separately from the generic assignment regex above because the\n // SQL is a multi-line template literal that may contain semicolons\n const viewQueryRegex = /(\\w+)\\.viewQuery\\s*=\\s*/g;\n let viewQueryMatch;\n while ((viewQueryMatch = viewQueryRegex.exec(content)) !== null) {\n const varInfo = variables.get(viewQueryMatch[1]);\n if (!varInfo || varInfo.type !== \"collection\") continue;\n\n const valueStart = viewQueryMatch.index + viewQueryMatch[0].length;\n\n if (content[valueStart] === \"`\") {\n const end = skipTemplateLiteral(content, valueStart);\n const raw = content.substring(valueStart + 1, end - 1);\n // Undo the indentation the generator applied to fit the query into the code\n getUpdate(varInfo.name).viewQuery = dedentSql(unescapeTemplateLiteral(raw));\n viewQueryRegex.lastIndex = end;\n } else {\n // Plain string literal\n const terminator = content.indexOf(\";\", valueStart);\n const valueStr = content.substring(valueStart, terminator === -1 ? content.length : terminator);\n try {\n getUpdate(varInfo.name).viewQuery = dedentSql(new Function(\"app\", `return ${valueStr}`)(mockApp));\n } catch {\n getUpdate(varInfo.name).viewQuery = dedentSql(valueStr.trim());\n }\n }\n }\n\n // 3d. unmarshal({...}, collectionVar) — PocketBase-native grouped rule/permission updates\n const unmarshalRegex = /unmarshal\\s*\\(/g;\n let unmarshalMatch;\n while ((unmarshalMatch = unmarshalRegex.exec(content)) !== null) {\n let i = unmarshalMatch.index + unmarshalMatch[0].length;\n\n // Skip whitespace\n while (i < content.length && /\\s/.test(content[i])) i++;\n\n // Expect opening brace\n if (content[i] !== \"{\") continue;\n\n // Extract object literal using brace matching\n const objStart = i;\n let braceCount = 1;\n let inStr = false;\n let strChar: string | null = null;\n i++;\n while (i < content.length && braceCount > 0) {\n const ch = content[i];\n const prev = i > 0 ? content[i - 1] : \"\";\n // Template literals (view queries) can contain braces and apostrophes\n if (!inStr && ch === \"`\") { i = skipTemplateLiteral(content, i); continue; }\n if (!inStr && (ch === '\"' || ch === \"'\")) { inStr = true; strChar = ch; }\n else if (inStr && ch === strChar && prev !== \"\\\\\") { inStr = false; strChar = null; }\n if (!inStr) {\n if (ch === \"{\") braceCount++;\n if (ch === \"}\") braceCount--;\n }\n i++;\n }\n if (braceCount !== 0) continue;\n\n const objStr = content.substring(objStart, i);\n\n // Skip comma and whitespace, then read the collection variable name\n while (i < content.length && /[\\s,]/.test(content[i])) i++;\n const varStart = i;\n while (i < content.length && /\\w/.test(content[i])) i++;\n const colVarName = content.substring(varStart, i);\n\n const colInfo = variables.get(colVarName);\n if (!colInfo || colInfo.type !== \"collection\") continue;\n\n // Parse the object for *Rule keys\n const keyValRegex = /\"(\\w+Rule)\"\\s*:\\s*([^,}\\n]+)/g;\n let kvMatch;\n while ((kvMatch = keyValRegex.exec(objStr)) !== null) {\n const ruleKey = kvMatch[1];\n const valStr = kvMatch[2].trim();\n try {\n const value = new Function(\"app\", `return ${valStr}`)(mockApp);\n getUpdate(colInfo.name).rulesToUpdate[ruleKey] = value;\n } catch {\n getUpdate(colInfo.name).rulesToUpdate[ruleKey] = valStr;\n }\n }\n\n // Parse a viewQuery key, whose value is a multi-line template literal\n const viewQueryKey = objStr.match(/\"viewQuery\"\\s*:\\s*/);\n if (viewQueryKey) {\n const valueStart = viewQueryKey.index! + viewQueryKey[0].length;\n if (objStr[valueStart] === \"`\") {\n const end = skipTemplateLiteral(objStr, valueStart);\n const raw = objStr.substring(valueStart + 1, end - 1);\n getUpdate(colInfo.name).viewQuery = dedentSql(unescapeTemplateLiteral(raw));\n } else {\n const valStr = objStr.substring(valueStart).replace(/[,}\\s]+$/, \"\");\n try {\n getUpdate(colInfo.name).viewQuery = dedentSql(new Function(\"app\", `return ${valStr}`)(mockApp));\n } catch {\n getUpdate(colInfo.name).viewQuery = dedentSql(valStr);\n }\n }\n }\n }\n\n // 3e. Indexes push/splice\n // col.indexes.push(\"...\")\n const idxPushRegex = /(\\w+)\\.indexes\\.push\\s*\\(/g;\n let match;\n while ((match = idxPushRegex.exec(content)) !== null) {\n const colVar = match[1];\n const colInfo = variables.get(colVar);\n if (colInfo && colInfo.type === \"collection\") {\n // Parse forward to find matching closing parenthesis\n let i = match.index + match[0].length;\n let parenCount = 1;\n let inString = false;\n let stringChar: string | null = null;\n const start = i;\n\n while (i < content.length && parenCount > 0) {\n const char = content[i];\n const prevChar = i > 0 ? content[i - 1] : \"\";\n\n if (!inString && (char === '\"' || char === \"'\")) {\n inString = true;\n stringChar = char;\n } else if (inString && char === stringChar && prevChar !== \"\\\\\") {\n inString = false;\n stringChar = null;\n }\n\n if (!inString) {\n if (char === \"(\") parenCount++;\n if (char === \")\") parenCount--;\n }\n i++;\n }\n\n if (parenCount === 0) {\n const valStr = content.substring(start, i - 1).trim();\n try {\n const val = new Function(`return ${valStr}`)();\n getUpdate(colInfo.name).indexesToAdd.push(val);\n } catch {\n console.warn(`Failed to parse index value: ${valStr}`);\n }\n }\n }\n }\n\n // col.indexes.splice(idx, 1) - this is hard because we need to know what index corresponds to.\n // The generator produces:\n // const idxVar = col.indexes.findIndex(idx => idx === \"...\");\n // if (idxVar !== -1) col.indexes.splice(idxVar, 1);\n // So we should look for the findIndex call to identify the index string being removed.\n const idxFindMatches = content.matchAll(\n /const\\s+(\\w+)\\s*=\\s*(\\w+)\\.indexes\\.findIndex\\s*\\(\\s*idx\\s*=>\\s*idx\\s*===\\s*\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\)/g\n );\n for (const match of idxFindMatches) {\n const [_, idxVar, colVar, idxStr] = match;\n const colInfo = variables.get(colVar);\n if (colInfo && colInfo.type === \"collection\") {\n try {\n // idxStr contains the JavaScript string value (escape sequences already processed)\n getUpdate(colInfo.name).indexesToRemove.push(idxStr);\n } catch {\n console.warn(`Failed to parse index value: ${idxStr} ${idxVar} ${colVar}`);\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to parse migration operations from content: ${error}`);\n }\n\n return { collectionsToCreate, collectionsToDelete, collectionsToUpdate };\n}\n\n/**\n * Parses a migration file to extract collection operations\n * Extracts collections created with `new Collection(...)` and collections deleted with `app.delete(...)`\n * Only parses the UP migration (first function), not the down migration\n *\n * @param migrationContent - Raw migration file content\n * @returns Object with collections to create and collections to delete\n */\nexport function parseMigrationOperations(migrationContent: string): {\n collectionsToCreate: CollectionSchema[];\n collectionsToDelete: string[];\n collectionsToUpdate: ParsedCollectionUpdate[];\n} {\n try {\n // Extract only the UP migration (first function argument to migrate())\n // Find the migrate call and extract the first function body\n const migrateMatch = migrationContent.match(/migrate\\s*\\(\\s*/);\n if (!migrateMatch) {\n // If we can't find the migrate pattern, try to parse the whole file\n return parseMigrationOperationsFromContent(migrationContent);\n }\n\n const startIndex = migrateMatch.index! + migrateMatch[0].length;\n\n // Find the opening paren of the first function\n let i = startIndex;\n let parenCount = 0;\n let foundFirstParen = false;\n\n while (i < migrationContent.length) {\n const char = migrationContent[i];\n if (char === \"(\") {\n parenCount++;\n foundFirstParen = true;\n i++;\n break;\n }\n i++;\n }\n\n if (!foundFirstParen) {\n return parseMigrationOperationsFromContent(migrationContent);\n }\n\n // Skip the function parameters: (app) => {\n let inString = false;\n let stringChar = null;\n let foundBrace = false;\n let braceStart = -1;\n\n while (i < migrationContent.length && !foundBrace) {\n const char = migrationContent[i];\n const prevChar = i > 0 ? migrationContent[i - 1] : \"\";\n\n if (!inString && (char === '\"' || char === \"'\")) {\n inString = true;\n stringChar = char;\n } else if (inString && char === stringChar && prevChar !== \"\\\\\") {\n inString = false;\n stringChar = null;\n }\n\n if (!inString) {\n if (char === \"(\") parenCount++;\n if (char === \")\") {\n parenCount--;\n if (parenCount === 0) {\n // Found end of function parameters, look for =>\n i++;\n while (i < migrationContent.length && /\\s/.test(migrationContent[i])) {\n i++;\n }\n if (i < migrationContent.length - 1 && migrationContent[i] === \"=\" && migrationContent[i + 1] === \">\") {\n i += 2;\n while (i < migrationContent.length && /\\s/.test(migrationContent[i])) {\n i++;\n }\n if (i < migrationContent.length && migrationContent[i] === \"{\") {\n foundBrace = true;\n braceStart = i + 1;\n break;\n }\n }\n }\n }\n }\n i++;\n }\n\n if (!foundBrace || braceStart === -1) {\n return parseMigrationOperationsFromContent(migrationContent);\n }\n\n // Find the matching closing brace\n let braceCount = 1;\n i = braceStart;\n inString = false;\n stringChar = null;\n\n while (i < migrationContent.length && braceCount > 0) {\n const char = migrationContent[i];\n const prevChar = i > 0 ? migrationContent[i - 1] : \"\";\n\n // Template literals (view queries) can contain braces and apostrophes\n if (!inString && char === \"`\") {\n i = skipTemplateLiteral(migrationContent, i);\n continue;\n }\n\n if (!inString && (char === '\"' || char === \"'\")) {\n inString = true;\n stringChar = char;\n } else if (inString && char === stringChar && prevChar !== \"\\\\\") {\n inString = false;\n stringChar = null;\n }\n\n if (!inString) {\n if (char === \"{\") braceCount++;\n if (char === \"}\") braceCount--;\n }\n\n i++;\n }\n\n if (braceCount === 0) {\n const upMigrationContent = migrationContent.substring(braceStart, i - 1);\n return parseMigrationOperationsFromContent(upMigrationContent);\n }\n\n // Fallback: parse the whole file\n return parseMigrationOperationsFromContent(migrationContent);\n } catch (error) {\n console.warn(`Failed to parse migration operations: ${error}`);\n return { collectionsToCreate: [], collectionsToDelete: [], collectionsToUpdate: [] };\n }\n}\n","/**\n * Snapshot Manager\n * Handles saving and loading schema snapshots from JSON files\n *\n * This module provides a standalone, configurable snapshot manager that can be used\n * by consumer projects to manage schema snapshots. It focuses on JSON snapshot file\n * management, delegating migration file parsing and PocketBase format conversion\n * to specialized modules.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, SnapshotError } from \"./errors\";\nimport {\n extractTimestampFromFilename,\n findMigrationsAfterSnapshot,\n parseMigrationOperations,\n type ParsedCollectionUpdate,\n} from \"./migration-parser\";\nimport { convertPocketBaseMigration } from \"./pocketbase-converter\";\nimport type { CollectionSchema, SchemaDefinition, SchemaSnapshot } from \"./types\";\n\nconst SNAPSHOT_VERSION = \"1.0.0\";\nconst DEFAULT_SNAPSHOT_FILENAME = \".migration-snapshot.json\";\n\n/**\n * Configuration for snapshot operations\n */\nexport interface SnapshotConfig {\n /**\n * Path to the snapshot file\n * Can be absolute or relative to workspaceRoot\n */\n snapshotPath?: string;\n\n /**\n * Workspace root directory for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * Path to the migrations directory for finding PocketBase snapshots\n */\n migrationsPath?: string;\n\n /**\n * Whether to auto-migrate old snapshot formats\n * Defaults to true\n */\n autoMigrate?: boolean;\n\n /**\n * Custom snapshot version for testing\n */\n version?: string;\n}\n\n/**\n * Snapshot format versions and their migration functions\n */\ninterface SnapshotMigration {\n fromVersion: string;\n toVersion: string;\n migrate: (data: any) => any;\n}\n\n/**\n * Registry of snapshot format migrations\n */\nconst SNAPSHOT_MIGRATIONS: SnapshotMigration[] = [\n // Add migrations here as the format evolves\n // Example:\n // {\n // fromVersion: '0.9.0',\n // toVersion: '1.0.0',\n // migrate: (data) => ({ ...data, newField: 'default' })\n // }\n];\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: Omit<Required<SnapshotConfig>, \"migrationsPath\"> & { migrationsPath?: string } = {\n snapshotPath: DEFAULT_SNAPSHOT_FILENAME,\n workspaceRoot: process.cwd(),\n autoMigrate: true,\n version: SNAPSHOT_VERSION,\n};\n\n/**\n * Merges user config with defaults\n */\nfunction mergeConfig(config: SnapshotConfig = {}): typeof DEFAULT_CONFIG {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n };\n}\n\n/**\n * Gets the snapshot file path from configuration\n *\n * @param config - Snapshot configuration\n * @returns Absolute path to the snapshot file\n */\nexport function getSnapshotPath(config: SnapshotConfig = {}): string {\n const mergedConfig = mergeConfig(config);\n const workspaceRoot = mergedConfig.workspaceRoot;\n const snapshotFilename = mergedConfig.snapshotPath;\n\n // If snapshotPath is absolute, use it directly\n if (path.isAbsolute(snapshotFilename)) {\n return snapshotFilename;\n }\n\n // Otherwise, resolve relative to workspaceRoot\n return path.join(workspaceRoot, snapshotFilename);\n}\n\n/**\n * Checks if snapshot file exists\n *\n * @param config - Snapshot configuration\n * @returns True if snapshot file exists\n */\nexport function snapshotExists(config: SnapshotConfig = {}): boolean {\n try {\n const snapshotPath = getSnapshotPath(config);\n return fs.existsSync(snapshotPath);\n } catch {\n // If there's any error checking existence, treat as non-existent\n return false;\n }\n}\n\n/**\n * Handles file system errors with descriptive messages\n *\n * @param error - The error object\n * @param operation - The operation being performed\n * @param filePath - The file path involved\n * @throws SnapshotError or FileSystemError with descriptive message\n */\nfunction handleFileSystemError(error: any, operation: \"read\" | \"write\", filePath: string): never {\n const fsError = error as NodeJS.ErrnoException;\n\n if (fsError.code === \"ENOENT\") {\n throw new SnapshotError(`Snapshot file not found: ${filePath}`, filePath, operation, error);\n } else if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied ${operation === \"read\" ? \"reading\" : \"writing\"} snapshot file. Check file permissions.`,\n filePath,\n operation,\n fsError.code,\n error\n );\n } else if (fsError.code === \"ENOSPC\") {\n throw new FileSystemError(\n `No space left on device when ${operation === \"read\" ? \"reading\" : \"writing\"} snapshot file.`,\n filePath,\n operation,\n fsError.code,\n error\n );\n } else {\n throw new SnapshotError(`Failed to ${operation} snapshot file: ${error.message}`, filePath, operation, error);\n }\n}\n\n/**\n * Serializes a Map to a plain object for JSON serialization\n *\n * @param map - Map to serialize\n * @returns Plain object representation\n */\nfunction serializeMap<K extends string, V>(map: Map<K, V>): Record<K, V> {\n const obj: Record<string, V> = {};\n for (const [key, value] of map.entries()) {\n obj[key] = value;\n }\n return obj as Record<K, V>;\n}\n\n/**\n * Deserializes a plain object to a Map\n *\n * @param obj - Plain object to deserialize\n * @returns Map representation\n */\nfunction deserializeMap<K extends string, V>(obj: Record<K, V>): Map<K, V> {\n const map = new Map<K, V>();\n for (const [key, value] of Object.entries(obj)) {\n map.set(key as K, value as V);\n }\n return map;\n}\n\n/**\n * Serializes SchemaDefinition to JSON format\n * Converts Map to plain object for JSON compatibility\n *\n * @param schema - Schema definition to serialize\n * @returns JSON-serializable object\n */\nfunction serializeSchemaDefinition(schema: SchemaDefinition): any {\n return {\n collections: serializeMap(schema.collections),\n };\n}\n\n/**\n * Adds version and timestamp metadata to snapshot\n *\n * @param schema - Schema definition\n * @param config - Optional configuration with custom version\n * @returns Snapshot with metadata\n */\nfunction addSnapshotMetadata(schema: SchemaDefinition, config?: SnapshotConfig): any {\n const mergedConfig = mergeConfig(config);\n return {\n version: mergedConfig.version,\n timestamp: new Date().toISOString(),\n ...serializeSchemaDefinition(schema),\n };\n}\n\n/**\n * Saves schema snapshot to file\n * Serializes SchemaDefinition to JSON with version and timestamp metadata\n * Writes with pretty printing for readability\n *\n * @param schema - Schema definition to save\n * @param config - Snapshot configuration\n */\nexport function saveSnapshot(schema: SchemaDefinition, config: SnapshotConfig = {}): void {\n const snapshotPath = getSnapshotPath(config);\n\n try {\n // Ensure directory exists\n const snapshotDir = path.dirname(snapshotPath);\n if (!fs.existsSync(snapshotDir)) {\n fs.mkdirSync(snapshotDir, { recursive: true });\n }\n\n // Add metadata and serialize\n const snapshotData = addSnapshotMetadata(schema, config);\n\n // Write with pretty printing (2 spaces indentation)\n const jsonContent = JSON.stringify(snapshotData, null, 2);\n fs.writeFileSync(snapshotPath, jsonContent, \"utf-8\");\n } catch (error) {\n handleFileSystemError(error, \"write\", snapshotPath);\n }\n}\n\n/**\n * Parses JSON and validates snapshot format\n *\n * @param jsonContent - Raw JSON content\n * @param snapshotPath - Path to snapshot file (for error messages)\n * @returns Parsed snapshot data\n */\nfunction parseAndValidateSnapshot(jsonContent: string, snapshotPath: string): any {\n try {\n const data = JSON.parse(jsonContent);\n\n // Validate required fields\n if (!data.version) {\n throw new SnapshotError(\n \"Snapshot file is missing version field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n if (!data.timestamp) {\n throw new SnapshotError(\n \"Snapshot file is missing timestamp field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n if (!data.collections) {\n throw new SnapshotError(\n \"Snapshot file is missing collections field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n return data;\n } catch (error) {\n if (error instanceof SnapshotError) {\n throw error;\n }\n\n if (error instanceof SyntaxError) {\n throw new SnapshotError(\n `Invalid JSON in snapshot file. The file may be corrupted or manually edited incorrectly.`,\n snapshotPath,\n \"parse\",\n error\n );\n }\n throw error;\n }\n}\n\n/**\n * Compares two version strings\n * Returns -1 if a < b, 0 if a == b, 1 if a > b\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const numA = partsA[i] || 0;\n const numB = partsB[i] || 0;\n\n if (numA < numB) return -1;\n if (numA > numB) return 1;\n }\n\n return 0;\n}\n\n/**\n * Migrates old snapshot formats to current version\n * Applies migrations in sequence from old version to current\n *\n * @param data - Parsed snapshot data\n * @param config - Optional configuration\n * @returns Migrated snapshot data\n */\nfunction migrateSnapshotFormat(data: any, config?: SnapshotConfig): any {\n const mergedConfig = mergeConfig(config);\n const currentVersion = data.version;\n const targetVersion = mergedConfig.version;\n\n // If versions match, no migration needed\n if (currentVersion === targetVersion) {\n return data;\n }\n\n // If auto-migrate is disabled, just return the data with a warning\n if (!mergedConfig.autoMigrate) {\n console.warn(\n `Snapshot version ${currentVersion} differs from current ${targetVersion}, but auto-migrate is disabled.`\n );\n return data;\n }\n\n // Find and apply migrations in sequence\n let migratedData = { ...data };\n let currentMigrationVersion = currentVersion;\n\n // Sort migrations by fromVersion\n const sortedMigrations = [...SNAPSHOT_MIGRATIONS].sort((a, b) => compareVersions(a.fromVersion, b.fromVersion));\n\n for (const migration of sortedMigrations) {\n if (compareVersions(currentMigrationVersion, migration.fromVersion) === 0) {\n console.log(`Migrating snapshot from ${migration.fromVersion} to ${migration.toVersion}...`);\n migratedData = migration.migrate(migratedData);\n migratedData.version = migration.toVersion;\n currentMigrationVersion = migration.toVersion;\n }\n }\n\n // If we couldn't migrate to the target version, log a warning\n if (compareVersions(currentMigrationVersion, targetVersion) !== 0) {\n console.warn(`Unknown snapshot version ${currentVersion}, attempting to load anyway...`);\n }\n\n return migratedData;\n}\n\n/**\n * Deserializes snapshot data to SchemaSnapshot\n *\n * @param data - Parsed and validated snapshot data\n * @returns SchemaSnapshot object\n */\nfunction deserializeSnapshot(data: any): SchemaSnapshot {\n return {\n version: data.version,\n timestamp: data.timestamp,\n collections: deserializeMap<string, CollectionSchema>(data.collections),\n };\n}\n\n/**\n * Loads schema snapshot from file\n * Reads snapshot file, parses JSON, validates format, and handles migrations\n *\n * @param config - Snapshot configuration\n * @returns SchemaSnapshot object\n * @throws Error if snapshot file doesn't exist or is invalid\n */\nexport function loadSnapshot(config: SnapshotConfig = {}): SchemaSnapshot {\n const snapshotPath = getSnapshotPath(config);\n\n try {\n // Read file\n const jsonContent = fs.readFileSync(snapshotPath, \"utf-8\");\n\n // Parse and validate\n const data = parseAndValidateSnapshot(jsonContent, snapshotPath);\n\n // Migrate format if needed\n const migratedData = migrateSnapshotFormat(data, config);\n\n // Deserialize to SchemaSnapshot\n return deserializeSnapshot(migratedData);\n } catch (error) {\n // If it's already a SnapshotError or FileSystemError, re-throw it\n if (error instanceof SnapshotError || error instanceof FileSystemError) {\n throw error;\n }\n\n // If file doesn't exist, throw specific error\n if ((error as any).code === \"ENOENT\") {\n throw new SnapshotError(\n `Snapshot file not found. This may be the first migration run.`,\n snapshotPath,\n \"read\",\n error as Error\n );\n }\n\n // Handle other file system errors\n handleFileSystemError(error, \"read\", snapshotPath);\n }\n}\n\n/**\n * Merges base schema with custom snapshot\n * Base schema collections are preserved, custom collections are added\n * Custom collections override base collections if they have the same name\n *\n * @param baseSnapshot - PocketBase base schema\n * @param customSnapshot - User's custom schema snapshot (may be null)\n * @returns Merged SchemaSnapshot\n */\nexport function mergeSnapshots(baseSnapshot: SchemaSnapshot, customSnapshot: SchemaSnapshot | null): SchemaSnapshot {\n // If no custom snapshot, return base snapshot\n if (!customSnapshot) {\n return baseSnapshot;\n }\n\n // Create a new collections map starting with base collections\n const mergedCollections = new Map<string, CollectionSchema>(baseSnapshot.collections);\n\n // Add or override with custom collections\n for (const [name, schema] of customSnapshot.collections.entries()) {\n mergedCollections.set(name, schema);\n }\n\n return {\n version: customSnapshot.version || baseSnapshot.version,\n timestamp: customSnapshot.timestamp || baseSnapshot.timestamp,\n collections: mergedCollections,\n };\n}\n\n/**\n * Finds the most recent snapshot file in the migrations directory\n * Identifies snapshot files by naming pattern (e.g., *_collections_snapshot.js)\n *\n * @param migrationsPath - Path to pb_migrations directory\n * @returns Path to most recent snapshot file or null if none exist\n */\nexport function findLatestSnapshot(migrationsPath: string): string | null {\n try {\n // Check if migrations directory exists\n if (!fs.existsSync(migrationsPath)) {\n return null;\n }\n\n // Read all files in migrations directory\n const files = fs.readdirSync(migrationsPath);\n\n // Filter for snapshot files (files ending with _collections_snapshot.js or _snapshot.js)\n const snapshotFiles = files.filter(\n (file) => file.endsWith(\"_collections_snapshot.js\") || file.endsWith(\"_snapshot.js\")\n );\n\n if (snapshotFiles.length === 0) {\n return null;\n }\n\n // Sort by filename (timestamp prefix) to get most recent\n // Snapshot files are named with timestamp prefix: [timestamp]_collections_snapshot.js\n snapshotFiles.sort().reverse();\n\n // Return full path to most recent snapshot\n const latestSnapshot = snapshotFiles[0];\n if (!latestSnapshot) {\n return null;\n }\n return path.join(migrationsPath, latestSnapshot);\n } catch (error) {\n // If there's any error reading directory, return null\n console.warn(`Error finding latest snapshot: ${error}`);\n return null;\n }\n}\n\n/**\n * Applies migration operations to a snapshot state\n * Creates new collections and deletes collections as specified\n *\n * @param snapshot - Base snapshot state\n * @param operations - Migration operations to apply\n * @returns Updated snapshot with operations applied\n */\nexport function applyMigrationOperations(\n snapshot: SchemaSnapshot,\n operations: {\n collectionsToCreate: CollectionSchema[];\n collectionsToDelete: string[];\n collectionsToUpdate: ParsedCollectionUpdate[];\n }\n): SchemaSnapshot {\n const updatedCollections = new Map(snapshot.collections);\n\n // Apply deletions first\n for (const collectionName of operations.collectionsToDelete) {\n updatedCollections.delete(collectionName);\n }\n\n // Apply creations\n for (const collection of operations.collectionsToCreate) {\n updatedCollections.set(collection.name, collection);\n }\n\n // Apply updates\n for (const update of operations.collectionsToUpdate) {\n const collection = updatedCollections.get(update.collectionName);\n if (collection) {\n // Add fields\n if (update.fieldsToAdd.length > 0) {\n for (const newField of update.fieldsToAdd) {\n // Check if field with same ID already exists (update/replace)\n const existingIndex = collection.fields.findIndex((f) => f.id === newField.id);\n if (newField.id && existingIndex !== -1) {\n collection.fields[existingIndex] = newField;\n } else {\n collection.fields.push(newField);\n }\n }\n }\n\n // Remove fields\n if (update.fieldsToRemove.length > 0) {\n collection.fields = collection.fields.filter((f) => !update.fieldsToRemove.includes(f.name));\n }\n\n // Update fields\n for (const fieldUpdate of update.fieldsToUpdate) {\n const field = collection.fields.find((f) => f.name === fieldUpdate.fieldName);\n if (field) {\n const topLevelFieldProps = [\"name\", \"type\", \"required\", \"unique\", \"system\", \"id\", \"presentable\"];\n\n for (const [key, value] of Object.entries(fieldUpdate.changes)) {\n if (key.startsWith(\"options.\")) {\n const optionKey = key.replace(\"options.\", \"\");\n if (!field.options) field.options = {};\n field.options[optionKey] = value;\n } else if (key.startsWith(\"relation.\")) {\n const relationKey = key.replace(\"relation.\", \"\");\n if (!field.relation && field.type === \"relation\") {\n // Should initialize relation object if missing but type is relation\n field.relation = { collection: \"\" };\n }\n if (field.relation) {\n (field.relation as any)[relationKey] = value;\n }\n } else if (topLevelFieldProps.includes(key)) {\n (field as any)[key] = value;\n } else {\n // It's likely an option (e.g. 'values', 'min', 'max') being set directly\n // as produced by the generator or PocketBase SDK\n if (!field.options) field.options = {};\n field.options[key] = value;\n }\n }\n }\n }\n\n // Indexes\n if (update.indexesToAdd.length > 0) {\n if (!collection.indexes) collection.indexes = [];\n collection.indexes.push(...update.indexesToAdd);\n }\n\n if (update.indexesToRemove.length > 0) {\n if (collection.indexes) {\n collection.indexes = collection.indexes.filter((idx) => !update.indexesToRemove.includes(idx));\n }\n }\n\n // View query (view collections only)\n if (update.viewQuery !== undefined) {\n collection.viewQuery = update.viewQuery;\n }\n\n // Rules\n if (Object.keys(update.rulesToUpdate).length > 0) {\n if (!collection.rules) collection.rules = {};\n if (!collection.permissions) collection.permissions = {};\n\n for (const [key, value] of Object.entries(update.rulesToUpdate)) {\n // key is like 'listRule'\n // TS constraint: key must be one of the known rule types.\n // Since ParsedCollectionUpdate uses string key, we cast or check.\n (collection.rules as any)[key] = value;\n (collection.permissions as any)[key] = value;\n }\n }\n } else {\n console.warn(`Attempted to update non-existent collection: ${update.collectionName}`);\n }\n }\n\n return {\n ...snapshot,\n collections: updatedCollections,\n };\n}\n\n/**\n * Loads snapshot and applies all migrations that come after it\n * This gives us the current state of the database schema\n *\n * @param config - Snapshot configuration (must include migrationsPath)\n * @returns SchemaSnapshot object representing current state or null if snapshot doesn't exist\n */\nexport function loadSnapshotWithMigrations(config: SnapshotConfig = {}): SchemaSnapshot | null {\n const migrationsPath = config.migrationsPath;\n\n if (!migrationsPath) {\n return null;\n }\n\n // Check if migrationsPath is actually a file (for backward compatibility with tests)\n if (fs.existsSync(migrationsPath) && fs.statSync(migrationsPath).isFile()) {\n try {\n const migrationContent = fs.readFileSync(migrationsPath, \"utf-8\");\n return convertPocketBaseMigration(migrationContent);\n } catch (error) {\n console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);\n return null;\n }\n }\n\n // It's a directory, find the latest snapshot\n const latestSnapshotPath = findLatestSnapshot(migrationsPath);\n\n if (!latestSnapshotPath) {\n // No snapshot found - return null (empty database)\n return null;\n }\n\n try {\n // Read and convert the PocketBase snapshot file\n const migrationContent = fs.readFileSync(latestSnapshotPath, \"utf-8\");\n let snapshot = convertPocketBaseMigration(migrationContent);\n\n // Extract timestamp from snapshot filename\n const snapshotFilename = path.basename(latestSnapshotPath);\n const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);\n\n if (snapshotTimestamp) {\n // Find all migration files after the snapshot\n const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);\n\n // Apply each migration in order\n for (const migrationFile of migrationFiles) {\n try {\n const migrationContent = fs.readFileSync(migrationFile, \"utf-8\");\n const operations = parseMigrationOperations(migrationContent);\n snapshot = applyMigrationOperations(snapshot, operations);\n } catch (error) {\n console.warn(`Failed to apply migration ${migrationFile}: ${error}`);\n // Continue with other migrations even if one fails\n }\n }\n }\n\n return snapshot;\n } catch (error) {\n console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);\n return null;\n }\n}\n\n/**\n * Loads snapshot if it exists, returns null for first run\n * Convenience method that handles missing snapshot gracefully\n * Finds the most recent snapshot file from migrations directory\n * NOTE: This function only loads the snapshot, not migrations after it.\n * Use loadSnapshotWithMigrations() if you need the current state including migrations.\n *\n * @param config - Snapshot configuration (must include migrationsPath)\n * @returns SchemaSnapshot object or null if snapshot doesn't exist\n */\nexport function loadSnapshotIfExists(config: SnapshotConfig = {}): SchemaSnapshot | null {\n const migrationsPath = config.migrationsPath;\n\n if (!migrationsPath) {\n // No migrations path provided - return null\n return null;\n }\n\n // Check if migrationsPath is actually a file (for backward compatibility with tests)\n // If it's a file, treat it as a direct snapshot file path\n if (fs.existsSync(migrationsPath) && fs.statSync(migrationsPath).isFile()) {\n try {\n const migrationContent = fs.readFileSync(migrationsPath, \"utf-8\");\n return convertPocketBaseMigration(migrationContent);\n } catch (error) {\n console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);\n return null;\n }\n }\n\n // It's a directory, find the latest snapshot\n const latestSnapshotPath = findLatestSnapshot(migrationsPath);\n\n if (latestSnapshotPath) {\n try {\n // Read and convert the PocketBase snapshot file\n const migrationContent = fs.readFileSync(latestSnapshotPath, \"utf-8\");\n return convertPocketBaseMigration(migrationContent);\n } catch (error) {\n console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);\n return null;\n }\n }\n\n // No snapshot found - return null (empty database)\n return null;\n}\n\n/**\n * Loads the base PocketBase schema from the initial migration file\n *\n * @param migrationPath - Path to pocketbase/pb_migrations/000000000_collections_snapshot.js\n * @returns SchemaSnapshot representing PocketBase's initial state\n * @throws SnapshotError if file not found or invalid format\n */\nexport function loadBaseMigration(migrationPath: string): SchemaSnapshot {\n try {\n // Check if file exists\n if (!fs.existsSync(migrationPath)) {\n throw new SnapshotError(\n `Base migration file not found: ${migrationPath}\\n\\n` +\n `This file should contain PocketBase's initial schema.\\n` +\n `Please ensure PocketBase is properly set up by running 'yarn setup'.\\n` +\n `If the file exists in a different location, update the configuration.`,\n migrationPath,\n \"read\"\n );\n }\n\n // Read the migration file\n const migrationContent = fs.readFileSync(migrationPath, \"utf-8\");\n\n // Convert to SchemaSnapshot\n const snapshot = convertPocketBaseMigration(migrationContent);\n\n return snapshot;\n } catch (error) {\n // If it's already a SnapshotError, re-throw it\n if (error instanceof SnapshotError) {\n throw error;\n }\n\n // Handle file system errors\n if ((error as any).code === \"ENOENT\") {\n throw new SnapshotError(\n `Base migration file not found: ${migrationPath}\\n\\n` +\n `This file should contain PocketBase's initial schema.\\n` +\n `Please ensure PocketBase is properly set up by running 'yarn setup'.`,\n migrationPath,\n \"read\",\n error as Error\n );\n }\n\n if ((error as any).code === \"EACCES\" || (error as any).code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied reading base migration file. Check file permissions.`,\n migrationPath,\n \"read\",\n (error as any).code,\n error as Error\n );\n }\n\n // Other errors\n throw new SnapshotError(\n `Failed to load base migration: ${error instanceof Error ? error.message : String(error)}`,\n migrationPath,\n \"read\",\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Gets the current snapshot version\n */\nexport function getSnapshotVersion(): string {\n return SNAPSHOT_VERSION;\n}\n\n/**\n * Validates a snapshot against the current version\n * Returns validation result with any issues found\n */\nexport function validateSnapshot(snapshot: SchemaSnapshot): { valid: boolean; issues: string[] } {\n const issues: string[] = [];\n\n // Check version\n if (!snapshot.version) {\n issues.push(\"Missing version field\");\n } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION) > 0) {\n issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`);\n }\n\n // Check timestamp\n if (!snapshot.timestamp) {\n issues.push(\"Missing timestamp field\");\n }\n\n // Check collections\n if (!snapshot.collections) {\n issues.push(\"Missing collections field\");\n } else if (!(snapshot.collections instanceof Map)) {\n issues.push(\"Collections field is not a Map\");\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n\n/**\n * Re-exports convertPocketBaseMigration for backward compatibility\n */\nexport { convertPocketBaseMigration } from \"./pocketbase-converter\";\n\n/**\n * SnapshotManager class for object-oriented usage\n * Provides a stateful interface for snapshot management\n */\nexport class SnapshotManager {\n private config: SnapshotConfig;\n\n constructor(config: SnapshotConfig = {}) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Loads the current snapshot\n */\n loadSnapshot(): SchemaSnapshot {\n return loadSnapshot(this.config);\n }\n\n /**\n * Saves a schema as a snapshot\n */\n saveSnapshot(schema: SchemaDefinition): void {\n saveSnapshot(schema, this.config);\n }\n\n /**\n * Loads snapshot if it exists, returns null otherwise\n */\n loadSnapshotIfExists(): SchemaSnapshot | null {\n return loadSnapshotIfExists(this.config);\n }\n\n /**\n * Checks if a snapshot exists\n */\n snapshotExists(): boolean {\n return snapshotExists(this.config);\n }\n\n /**\n * Converts a PocketBase migration to a snapshot\n */\n convertPocketBaseMigration(content: string): SchemaSnapshot {\n return convertPocketBaseMigration(content);\n }\n\n /**\n * Gets the snapshot file path\n */\n getSnapshotPath(): string {\n return getSnapshotPath(this.config);\n }\n\n /**\n * Validates a snapshot\n */\n validateSnapshot(snapshot: SchemaSnapshot): { valid: boolean; issues: string[] } {\n return validateSnapshot(snapshot);\n }\n}\n","/**\n * Configuration options for the diff engine\n */\nexport interface DiffEngineConfig {\n /**\n * Whether to warn on collection deletions\n * Defaults to true\n */\n warnOnDelete?: boolean;\n\n /**\n * Whether to require --force flag for destructive changes\n * Defaults to true\n */\n requireForceForDestructive?: boolean;\n\n /**\n * Severity threshold for requiring force flag\n * 'high' = only collection/field deletions and type changes\n * 'medium' = includes making fields required\n * 'low' = includes any constraint changes\n * Defaults to 'high'\n */\n severityThreshold?: \"high\" | \"medium\" | \"low\";\n\n /**\n * Custom system collections to exclude from diff\n * These collections will not be created or deleted\n */\n systemCollections?: string[];\n\n /**\n * Custom system fields to exclude from user collection diffs\n * These fields will not be included in fieldsToAdd for the users collection\n */\n usersSystemFields?: string[];\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<DiffEngineConfig> = {\n warnOnDelete: true,\n requireForceForDestructive: true,\n severityThreshold: \"high\",\n systemCollections: [\"_mfas\", \"_otps\", \"_externalAuths\", \"_authOrigins\", \"_superusers\"],\n usersSystemFields: [\"id\", \"password\", \"tokenKey\", \"email\", \"emailVisibility\", \"verified\", \"created\", \"updated\"],\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(config?: DiffEngineConfig): Required<DiffEngineConfig> {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n };\n}\n","import { mergeConfig, type DiffEngineConfig } from \"./config\";\n\n/**\n * Checks if a collection is a PocketBase system collection\n * System collections are internal to PocketBase and should not be created or deleted\n *\n * @param collectionName - Name of the collection to check\n * @param config - Optional configuration with custom system collections\n * @returns True if the collection is a system collection\n */\nexport function isSystemCollection(collectionName: string, config?: DiffEngineConfig): boolean {\n const mergedConfig = mergeConfig(config);\n return mergedConfig.systemCollections.includes(collectionName);\n}\n\n/**\n * Returns the list of system field names for the users collection\n * These fields are automatically provided by PocketBase for auth collections\n * and should not be included when generating migrations for users collection extensions\n *\n * @param config - Optional configuration with custom system fields\n * @returns Set of system field names\n */\nexport function getUsersSystemFields(config?: DiffEngineConfig): Set<string> {\n const mergedConfig = mergeConfig(config);\n return new Set(mergedConfig.usersSystemFields);\n}\n\n/**\n * Compares two values for equality, handling deep object comparison\n *\n * @param a - First value\n * @param b - Second value\n * @returns True if values are equal\n */\nexport function areValuesEqual(a: any, b: any): boolean {\n // Handle null/undefined\n if (a === b) return true;\n if (a == null || b == null) return false;\n\n // Handle arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((val, idx) => areValuesEqual(val, b[idx]));\n }\n\n // Handle objects\n if (typeof a === \"object\" && typeof b === \"object\") {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) => areValuesEqual(a[key], b[key]));\n }\n\n // Primitive comparison\n return a === b;\n}\n\n/**\n * Normalizes a field option value to account for PocketBase defaults\n * Returns the normalized value, treating default values as equivalent to undefined\n *\n * @param key - Option key name\n * @param value - Option value\n * @param fieldType - Field type\n * @returns Normalized value (undefined if it's a default value)\n */\nexport function normalizeOptionValue(key: string, value: any, fieldType: string): any {\n // maxSelect: 1 is the default for select and file fields\n if (key === \"maxSelect\" && value === 1 && (fieldType === \"select\" || fieldType === \"file\")) {\n return undefined; // Treat as undefined to match missing default\n }\n\n // maxSize: 0 is default for file fields\n if (key === \"maxSize\" && value === 0 && fieldType === \"file\") {\n return undefined;\n }\n\n // min: 1 can be a default for some PocketBase versions/number fields\n if (key === \"min\" && value === 1 && fieldType === \"number\") {\n return undefined;\n }\n\n // Empty arrays are defaults for file fields\n if (fieldType === \"file\") {\n if (key === \"mimeTypes\" && Array.isArray(value) && value.length === 0) {\n return undefined;\n }\n if (key === \"thumbs\" && Array.isArray(value) && value.length === 0) {\n return undefined;\n }\n if (key === \"protected\" && value === false) {\n return undefined;\n }\n }\n\n // Autodate defaults\n if (fieldType === \"autodate\") {\n if (key === \"onCreate\" && value === true) {\n return undefined;\n }\n if (key === \"onUpdate\" && value === false) {\n return undefined;\n }\n }\n\n return value;\n}\n","import type { FieldChange, FieldDefinition } from \"../types\";\nimport { areValuesEqual, normalizeOptionValue } from \"./utils\";\n\n/**\n * Identifies new fields in current collection that don't exist in previous\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of new fields\n */\nexport function findNewFields(currentFields: FieldDefinition[], previousFields: FieldDefinition[]): FieldDefinition[] {\n const newFields: FieldDefinition[] = [];\n const previousFieldNames = new Set(previousFields.map((f) => f.name));\n\n for (const currentField of currentFields) {\n if (!previousFieldNames.has(currentField.name)) {\n newFields.push(currentField);\n }\n }\n\n return newFields;\n}\n\n/**\n * Identifies fields removed from current collection (exist in previous but not in current)\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of removed fields\n */\nexport function findRemovedFields(\n currentFields: FieldDefinition[],\n previousFields: FieldDefinition[]\n): FieldDefinition[] {\n const removedFields: FieldDefinition[] = [];\n const currentFieldNames = new Set(currentFields.map((f) => f.name));\n\n for (const previousField of previousFields) {\n if (!currentFieldNames.has(previousField.name)) {\n removedFields.push(previousField);\n }\n }\n\n return removedFields;\n}\n\n/**\n * Matches fields by name between current and previous collections\n * Returns pairs of [current, previous] for fields that exist in both\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of matched field pairs\n */\nexport function matchFieldsByName(\n currentFields: FieldDefinition[],\n previousFields: FieldDefinition[]\n): Array<[FieldDefinition, FieldDefinition]> {\n const matches: Array<[FieldDefinition, FieldDefinition]> = [];\n\n // Create a map of previous fields by name for efficient lookup\n const previousFieldMap = new Map<string, FieldDefinition>();\n for (const previousField of previousFields) {\n previousFieldMap.set(previousField.name, previousField);\n }\n\n // Find matching fields\n for (const currentField of currentFields) {\n const previousField = previousFieldMap.get(currentField.name);\n\n if (previousField) {\n matches.push([currentField, previousField]);\n }\n }\n\n return matches;\n}\n\n/**\n * Compares field types between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns FieldChange if types differ, null otherwise\n */\nexport function compareFieldTypes(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange | null {\n if (currentField.type !== previousField.type) {\n return {\n property: \"type\",\n oldValue: previousField.type,\n newValue: currentField.type,\n };\n }\n\n return null;\n}\n\n/**\n * Compares field constraints (required, unique) between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for constraint differences\n */\nexport function compareFieldConstraints(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange[] {\n const changes: FieldChange[] = [];\n\n // Compare required constraint\n if (currentField.required !== previousField.required) {\n changes.push({\n property: \"required\",\n oldValue: previousField.required,\n newValue: currentField.required,\n });\n }\n\n // Compare unique constraint\n if (currentField.unique !== previousField.unique) {\n changes.push({\n property: \"unique\",\n oldValue: previousField.unique,\n newValue: currentField.unique,\n });\n }\n\n return changes;\n}\n\n/**\n * Compares field options (min, max, pattern, etc.) between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for option differences\n */\nexport function compareFieldOptions(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange[] {\n const changes: FieldChange[] = [];\n\n const currentOptions = currentField.options || {};\n const previousOptions = previousField.options || {};\n\n // Get all unique option keys\n const allKeys = new Set([...Object.keys(currentOptions), ...Object.keys(previousOptions)]);\n\n // Compare each option\n // Use currentField.type for normalization since types should match at this point\n // (type changes are handled separately in compareFieldTypes)\n const fieldType = currentField.type;\n\n for (const key of allKeys) {\n const currentValue = currentOptions[key];\n const previousValue = previousOptions[key];\n\n // Normalize values to account for default values\n // This ensures that maxSelect: 1 (default) is treated the same as undefined (missing default)\n const normalizedCurrent = normalizeOptionValue(key, currentValue, fieldType);\n const normalizedPrevious = normalizeOptionValue(key, previousValue, fieldType);\n\n // Handle undefined values - if both are undefined (or normalized to undefined), that's not a change\n if (normalizedCurrent === undefined && normalizedPrevious === undefined) {\n continue;\n }\n\n if (!areValuesEqual(normalizedCurrent, normalizedPrevious)) {\n changes.push({\n property: `options.${key}`,\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Compares relation configurations between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for relation differences\n */\nexport function compareRelationConfigurations(\n currentField: FieldDefinition,\n previousField: FieldDefinition,\n collectionIdToName?: Map<string, string>\n): FieldChange[] {\n const changes: FieldChange[] = [];\n\n const currentRelation = currentField.relation;\n const previousRelation = previousField.relation;\n\n // If one has relation and other doesn't, that's not a config change (handled elsewhere, likely type or structure)\n // But here we assume types match (both relation) or structure implies relation\n if (!currentRelation && !previousRelation) {\n return changes;\n }\n\n if (!currentRelation || !previousRelation) {\n // This shouldn't happen if types match and both are 'relation', but handle gracefully\n return changes;\n }\n\n // Compare relation properties\n // Note: collectionId should already be resolved to collection name during parsing\n // This normalization is just a safety net for edge cases\n const normalizeCollection = (collection: string): string => {\n if (!collection) return collection;\n\n // Resolve ID to name if possible\n if (collectionIdToName && collectionIdToName.has(collection)) {\n return collectionIdToName.get(collection)!;\n }\n\n // Handle expressions that might not have been parsed correctly\n const nameMatch = collection.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (nameMatch) {\n return nameMatch[1];\n }\n return collection;\n };\n\n const normalizedCurrent = normalizeCollection(currentRelation.collection);\n // We resolve the ID from the previous relation (snapshot) to its name if available\n const normalizedPrevious = normalizeCollection(previousRelation.collection);\n\n // Only report a change if the normalized values differ\n // Use case-insensitive comparison for collection names\n if (normalizedCurrent.toLowerCase() !== normalizedPrevious.toLowerCase()) {\n changes.push({\n property: \"relation.collection\",\n oldValue: previousRelation.collection,\n newValue: currentRelation.collection,\n });\n }\n\n if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {\n changes.push({\n property: \"relation.cascadeDelete\",\n oldValue: previousRelation.cascadeDelete,\n newValue: currentRelation.cascadeDelete,\n });\n }\n\n // Normalize maxSelect: 1 to undefined/null as it's often the default or treated as such\n const normalizeMax = (val: number | null | undefined) => (val === 1 ? null : val);\n const currentMax = normalizeMax(currentRelation.maxSelect);\n const previousMax = normalizeMax(previousRelation.maxSelect);\n\n // Use loose equality to handle null vs undefined\n if (currentMax != previousMax) {\n changes.push({\n property: \"relation.maxSelect\",\n oldValue: previousRelation.maxSelect,\n newValue: currentRelation.maxSelect,\n });\n }\n\n // Normalize minSelect: 0 to undefined/null\n const normalizeMin = (val: number | null | undefined) => (val === 0 ? null : val);\n const currentMin = normalizeMin(currentRelation.minSelect);\n const previousMin = normalizeMin(previousRelation.minSelect);\n\n if (currentMin != previousMin) {\n changes.push({\n property: \"relation.minSelect\",\n oldValue: previousRelation.minSelect,\n newValue: currentRelation.minSelect,\n });\n }\n\n return changes;\n}\n\n/**\n * Detects all changes between two field definitions\n * Combines type, constraint, option, and relation changes\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of all detected changes\n */\nexport function detectFieldChanges(\n currentField: FieldDefinition,\n previousField: FieldDefinition,\n collectionIdToName?: Map<string, string>\n): FieldChange[] {\n const changes: FieldChange[] = [];\n\n // Compare types\n const typeChange = compareFieldTypes(currentField, previousField);\n if (typeChange) {\n changes.push(typeChange);\n }\n\n // Compare constraints\n changes.push(...compareFieldConstraints(currentField, previousField));\n\n // Compare options\n changes.push(...compareFieldOptions(currentField, previousField));\n\n // Compare relation configurations (if applicable)\n if (currentField.type === \"relation\" && previousField.type === \"relation\") {\n changes.push(...compareRelationConfigurations(currentField, previousField, collectionIdToName));\n }\n\n return changes;\n}\n","/**\n * Compares indexes between current and previous collections\n *\n * @param currentIndexes - Current collection indexes\n * @param previousIndexes - Previous collection indexes\n * @returns Object with indexes to add and remove\n */\nexport function compareIndexes(\n currentIndexes: string[] = [],\n previousIndexes: string[] = []\n): { indexesToAdd: string[]; indexesToRemove: string[] } {\n const currentSet = new Set(currentIndexes);\n const previousSet = new Set(previousIndexes);\n\n const indexesToAdd = currentIndexes.filter((idx) => !previousSet.has(idx));\n const indexesToRemove = previousIndexes.filter((idx) => !currentSet.has(idx));\n\n return { indexesToAdd, indexesToRemove };\n}\n","import type { APIRuleType, CollectionSchema, PermissionChange, RuleUpdate } from \"../types\";\n\n/**\n * Compares API rules between current and previous collections\n *\n * @param currentRules - Current collection rules\n * @param previousRules - Previous collection rules\n * @returns Array of rule updates\n */\nexport function compareRules(\n currentRules: CollectionSchema[\"rules\"],\n previousRules: CollectionSchema[\"rules\"],\n currentPermissions?: CollectionSchema[\"permissions\"],\n previousPermissions?: CollectionSchema[\"permissions\"]\n): RuleUpdate[] {\n const updates: RuleUpdate[] = [];\n\n const ruleTypes: Array<keyof NonNullable<CollectionSchema[\"rules\"]>> = [\n \"listRule\",\n \"viewRule\",\n \"createRule\",\n \"updateRule\",\n \"deleteRule\",\n \"manageRule\",\n ];\n\n for (const ruleType of ruleTypes) {\n // Use rules if available, otherwise fall back to permissions (they're the same thing)\n const currentValue = currentRules?.[ruleType] ?? currentPermissions?.[ruleType] ?? null;\n const previousValue = previousRules?.[ruleType] ?? previousPermissions?.[ruleType] ?? null;\n\n if (currentValue !== previousValue) {\n updates.push({\n ruleType: ruleType as RuleUpdate[\"ruleType\"],\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return updates;\n}\n\n/**\n * Compares permissions between current and previous collections\n * Detects changes in permission rules defined in schema\n *\n * @param currentPermissions - Current collection permissions\n * @param previousPermissions - Previous collection permissions\n * @returns Array of permission changes\n */\nexport function comparePermissions(\n currentPermissions: CollectionSchema[\"permissions\"],\n previousPermissions: CollectionSchema[\"permissions\"]\n): PermissionChange[] {\n const changes: PermissionChange[] = [];\n\n const ruleTypes: APIRuleType[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\", \"manageRule\"];\n\n for (const ruleType of ruleTypes) {\n const currentValue = currentPermissions?.[ruleType] ?? null;\n const previousValue = previousPermissions?.[ruleType] ?? null;\n\n // Compare permission values\n if (currentValue !== previousValue) {\n changes.push({\n ruleType,\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return changes;\n}\n","import type {\n CollectionModification,\n CollectionSchema,\n FieldDefinition,\n FieldModification,\n SchemaDefinition,\n SchemaSnapshot,\n ViewQueryUpdate,\n} from \"../types\";\nimport { type DiffEngineConfig } from \"./config\";\nimport { detectFieldChanges, findNewFields, findRemovedFields, matchFieldsByName } from \"./fields\";\nimport { compareIndexes } from \"./indexes\";\nimport { comparePermissions, compareRules } from \"./rules\";\nimport { getUsersSystemFields, isSystemCollection } from \"./utils\";\n\n/**\n * Filters system collections from a schema definition\n * Returns a new SchemaDefinition with only custom (non-system) collections\n *\n * @param schema - Schema definition to filter\n * @param config - Optional configuration\n * @returns Filtered SchemaDefinition without system collections\n */\nexport function filterSystemCollections(schema: SchemaDefinition, config?: DiffEngineConfig): SchemaDefinition {\n const filteredCollections = new Map<string, CollectionSchema>();\n\n for (const [collectionName, collectionSchema] of schema.collections) {\n if (!isSystemCollection(collectionName, config)) {\n filteredCollections.set(collectionName, collectionSchema);\n }\n }\n\n return {\n collections: filteredCollections,\n };\n}\n\n/**\n * Identifies new collections in schema that don't exist in snapshot\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of new collections\n */\nexport function findNewCollections(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): CollectionSchema[] {\n const newCollections: CollectionSchema[] = [];\n\n // If no previous snapshot, all collections are new\n if (!previousSnapshot) {\n return Array.from(currentSchema.collections.values());\n }\n\n // Find collections in current schema that don't exist in snapshot\n for (const [collectionName, collectionSchema] of currentSchema.collections) {\n if (!previousSnapshot.collections.has(collectionName)) {\n newCollections.push(collectionSchema);\n }\n }\n\n return newCollections;\n}\n\n/**\n * Identifies collections removed from schema (exist in snapshot but not in current schema)\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of removed collections\n */\nexport function findRemovedCollections(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): CollectionSchema[] {\n const removedCollections: CollectionSchema[] = [];\n\n // If no previous snapshot, nothing can be removed\n if (!previousSnapshot) {\n return removedCollections;\n }\n\n // Find collections in snapshot that don't exist in current schema\n for (const [collectionName, collectionSchema] of previousSnapshot.collections) {\n if (!currentSchema.collections.has(collectionName)) {\n removedCollections.push(collectionSchema);\n }\n }\n\n return removedCollections;\n}\n\n/**\n * Matches collections by name between current schema and snapshot\n * Returns pairs of [current, previous] for collections that exist in both\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of matched collection pairs\n */\nexport function matchCollectionsByName(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): Array<[CollectionSchema, CollectionSchema]> {\n const matches: Array<[CollectionSchema, CollectionSchema]> = [];\n\n // If no previous snapshot, no matches possible\n if (!previousSnapshot) {\n return matches;\n }\n\n // Create a case-insensitive lookup map for previous collections\n const previousCollectionsLower = new Map<string, [string, CollectionSchema]>();\n for (const [name, collection] of previousSnapshot.collections) {\n previousCollectionsLower.set(name.toLowerCase(), [name, collection]);\n }\n\n // Find collections that exist in both current and previous (case-insensitive)\n for (const [collectionName, currentCollection] of currentSchema.collections) {\n const previousEntry = previousCollectionsLower.get(collectionName.toLowerCase());\n\n if (previousEntry) {\n const [, previousCollection] = previousEntry;\n matches.push([currentCollection, previousCollection]);\n }\n }\n\n return matches;\n}\n\n/**\n * Compares fields between current and previous collections\n * Identifies new, removed, and modified fields\n * For the users collection, filters out system fields from fieldsToAdd\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @param config - Optional configuration\n * @returns Object with field changes\n */\nfunction compareCollectionFields(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema,\n config?: DiffEngineConfig,\n collectionIdToName?: Map<string, string>\n): {\n fieldsToAdd: FieldDefinition[];\n fieldsToRemove: FieldDefinition[];\n fieldsToModify: FieldModification[];\n} {\n let fieldsToAdd = findNewFields(currentCollection.fields, previousCollection.fields);\n let fieldsToRemove = findRemovedFields(currentCollection.fields, previousCollection.fields);\n const fieldsToModify: FieldModification[] = [];\n\n // For users collection, filter out system fields from fieldsToAdd\n // System fields are automatically provided by PocketBase and should not be in migrations\n if (currentCollection.name === \"users\") {\n const systemFields = getUsersSystemFields(config);\n fieldsToAdd = fieldsToAdd.filter((field) => !systemFields.has(field.name));\n }\n\n // Check for modified fields\n const matchedFields = matchFieldsByName(currentCollection.fields, previousCollection.fields);\n\n for (const [currentField, previousField] of matchedFields) {\n const changes = detectFieldChanges(currentField, previousField, collectionIdToName);\n\n if (changes.length > 0) {\n fieldsToModify.push({\n fieldName: currentField.name,\n currentDefinition: previousField,\n newDefinition: currentField,\n changes,\n });\n }\n }\n\n // Detect Renames (Heuristic)\n // If we have single removed and added fields of the same type, consider it a rename\n const processedAddIndices = new Set<number>();\n const processedRemoveIndices = new Set<number>();\n\n // Helper to resolve collection name from ID/expression\n const resolveCollectionName = (val: string): string => {\n if (!val) return val;\n if (collectionIdToName && collectionIdToName.has(val)) return collectionIdToName.get(val)!;\n const match = val.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n return match ? match[1] : val;\n };\n\n // Group fields by type\n const addedByType = new Map<string, number[]>();\n fieldsToAdd.forEach((field, index) => {\n const type = field.type;\n if (!addedByType.has(type)) addedByType.set(type, []);\n addedByType.get(type)!.push(index);\n });\n\n const removedByType = new Map<string, number[]>();\n fieldsToRemove.forEach((field, index) => {\n const type = field.type;\n if (!removedByType.has(type)) removedByType.set(type, []);\n removedByType.get(type)!.push(index);\n });\n\n // Check each type for potential renames\n for (const [type, removedIndices] of removedByType) {\n const addedIndices = addedByType.get(type);\n\n // Heuristic: Only rename if exactly one field of this type was removed and one added\n if (addedIndices && addedIndices.length === 1 && removedIndices.length === 1) {\n const addedIndex = addedIndices[0];\n const removedIndex = removedIndices[0];\n const addedField = fieldsToAdd[addedIndex];\n const removedField = fieldsToRemove[removedIndex];\n\n // For relations, ensure target collection matches\n let isMatch = true;\n if (type === \"relation\") {\n const addedTarget = resolveCollectionName(addedField.relation?.collection || \"\");\n const removedTarget = resolveCollectionName(removedField.relation?.collection || \"\");\n if (addedTarget.toLowerCase() !== removedTarget.toLowerCase()) {\n isMatch = false;\n }\n }\n\n if (isMatch) {\n // It's a rename!\n processedAddIndices.add(addedIndex);\n processedRemoveIndices.add(removedIndex);\n\n // Calculate changes (including name change)\n const changes = detectFieldChanges(addedField, removedField, collectionIdToName);\n changes.push({\n property: \"name\",\n oldValue: removedField.name,\n newValue: addedField.name,\n });\n\n fieldsToModify.push({\n fieldName: removedField.name, // Use OLD name so generator can find it\n currentDefinition: removedField, // OLD definition\n newDefinition: addedField, // NEW definition\n changes,\n });\n }\n }\n }\n\n // Filter out processed fields\n fieldsToAdd = fieldsToAdd.filter((_, index) => !processedAddIndices.has(index));\n fieldsToRemove = fieldsToRemove.filter((_, index) => !processedRemoveIndices.has(index));\n\n return { fieldsToAdd, fieldsToRemove, fieldsToModify };\n}\n\n/**\n * Normalizes a SQL view query for comparison\n * Collapses whitespace so re-indenting or re-wrapping a query does not produce\n * a migration\n *\n * @param query - The SQL query\n * @returns Normalized query text\n */\nexport function normalizeSql(query: string | null | undefined): string {\n if (!query) {\n return \"\";\n }\n\n return query\n .split(\"\\n\")\n .map((line) => line.trim())\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Compares the SQL query of two view collections\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @returns A ViewQueryUpdate when the query changed, undefined otherwise\n */\nfunction compareViewQuery(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema\n): ViewQueryUpdate | undefined {\n const newValue = currentCollection.viewQuery;\n\n if (typeof newValue !== \"string\") {\n return undefined;\n }\n\n if (normalizeSql(newValue) === normalizeSql(previousCollection.viewQuery)) {\n return undefined;\n }\n\n return {\n oldValue: previousCollection.viewQuery ?? null,\n newValue,\n };\n}\n\n/**\n * Builds a CollectionModification for a matched collection pair\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @param config - Optional configuration\n * @returns CollectionModification object\n */\nexport function buildCollectionModification(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema,\n config?: DiffEngineConfig,\n collectionIdToName?: Map<string, string>\n): CollectionModification {\n // View collections are defined entirely by their SQL query: PocketBase\n // derives the fields from it and views cannot have indexes, so only the\n // query and the read rules are diffed\n const isView = currentCollection.type === \"view\" || previousCollection.type === \"view\";\n\n if (isView) {\n return {\n collection: currentCollection.name,\n fieldsToAdd: [],\n fieldsToRemove: [],\n fieldsToModify: [],\n indexesToAdd: [],\n indexesToRemove: [],\n rulesToUpdate: compareRules(\n currentCollection.rules,\n previousCollection.rules,\n currentCollection.permissions,\n previousCollection.permissions\n ),\n permissionsToUpdate: comparePermissions(currentCollection.permissions, previousCollection.permissions),\n viewQueryUpdate: compareViewQuery(currentCollection, previousCollection),\n };\n }\n\n // Compare fields\n const { fieldsToAdd, fieldsToRemove, fieldsToModify } = compareCollectionFields(\n currentCollection,\n previousCollection,\n config,\n collectionIdToName\n );\n\n // Compare indexes\n const { indexesToAdd, indexesToRemove } = compareIndexes(currentCollection.indexes, previousCollection.indexes);\n\n // Compare rules (also check permissions as fallback since they're the same thing)\n const rulesToUpdate = compareRules(\n currentCollection.rules,\n previousCollection.rules,\n currentCollection.permissions,\n previousCollection.permissions\n );\n\n // Compare permissions\n const permissionsToUpdate = comparePermissions(currentCollection.permissions, previousCollection.permissions);\n\n return {\n collection: currentCollection.name,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexesToAdd,\n indexesToRemove,\n rulesToUpdate,\n permissionsToUpdate,\n };\n}\n","import type { SchemaDiff } from \"../types\";\nimport { type DiffEngineConfig } from \"./config\";\nimport { detectDestructiveChanges, type DestructiveChange } from \"./destructiveness\";\n\n/**\n * Change summary for status reporting\n */\nexport interface ChangeSummary {\n totalChanges: number;\n collectionsToCreate: number;\n collectionsToDelete: number;\n collectionsToModify: number;\n fieldsToAdd: number;\n fieldsToRemove: number;\n fieldsToModify: number;\n indexChanges: number;\n ruleChanges: number;\n permissionChanges: number;\n viewQueryChanges: number;\n destructiveChanges: DestructiveChange[];\n nonDestructiveChanges: string[];\n}\n\n/**\n * Categorizes changes by severity\n * Returns object with destructive and non-destructive changes\n *\n * @param diff - Schema diff to categorize\n * @param config - Optional configuration\n * @returns Object with categorized changes\n */\nexport function categorizeChangesBySeverity(\n diff: SchemaDiff,\n _config?: DiffEngineConfig\n): {\n destructive: string[];\n nonDestructive: string[];\n} {\n const destructive: string[] = [];\n const nonDestructive: string[] = [];\n\n // Collection deletions are destructive, except for views which hold no data\n for (const collection of diff.collectionsToDelete) {\n if (collection.type === \"view\") {\n nonDestructive.push(`Delete view collection: ${collection.name}`);\n } else {\n destructive.push(`Delete collection: ${collection.name}`);\n }\n }\n\n // Collection creations are non-destructive\n for (const collection of diff.collectionsToCreate) {\n nonDestructive.push(`Create collection: ${collection.name}`);\n }\n\n // Analyze modifications\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Field deletions are destructive\n for (const field of modification.fieldsToRemove) {\n destructive.push(`Delete field: ${collectionName}.${field.name}`);\n }\n\n // Field additions are non-destructive\n for (const field of modification.fieldsToAdd) {\n nonDestructive.push(`Add field: ${collectionName}.${field.name}`);\n }\n\n // Field modifications can be destructive or non-destructive\n for (const fieldMod of modification.fieldsToModify) {\n const hasTypeChange = fieldMod.changes.some((c) => c.property === \"type\");\n const hasRequiredChange = fieldMod.changes.some((c) => c.property === \"required\" && c.newValue === true);\n\n if (hasTypeChange) {\n destructive.push(\n `Change field type: ${collectionName}.${fieldMod.fieldName} (${fieldMod.changes.find((c) => c.property === \"type\")?.oldValue} → ${fieldMod.changes.find((c) => c.property === \"type\")?.newValue})`\n );\n } else if (hasRequiredChange) {\n destructive.push(`Make field required: ${collectionName}.${fieldMod.fieldName}`);\n } else {\n nonDestructive.push(`Modify field: ${collectionName}.${fieldMod.fieldName}`);\n }\n }\n\n // Index changes are generally non-destructive\n for (const _index of modification.indexesToAdd) {\n nonDestructive.push(`Add index: ${collectionName}`);\n }\n\n for (const _index of modification.indexesToRemove) {\n nonDestructive.push(`Remove index: ${collectionName}`);\n }\n\n // Rule changes are non-destructive\n for (const rule of modification.rulesToUpdate) {\n nonDestructive.push(`Update rule: ${collectionName}.${rule.ruleType}`);\n }\n\n // View query changes are non-destructive - a view stores no data\n if (modification.viewQueryUpdate) {\n nonDestructive.push(`Update view query: ${collectionName}`);\n }\n }\n\n return { destructive, nonDestructive };\n}\n\n/**\n * Generates a summary of all changes in a diff\n * Useful for status reporting and user feedback\n *\n * @param diff - Schema diff to summarize\n * @param config - Optional configuration\n * @returns Change summary with counts and details\n */\nexport function generateChangeSummary(diff: SchemaDiff, config?: DiffEngineConfig): ChangeSummary {\n const destructiveChanges = detectDestructiveChanges(diff, config);\n const { nonDestructive } = categorizeChangesBySeverity(diff, config);\n\n let fieldsToAdd = 0;\n let fieldsToRemove = 0;\n let fieldsToModify = 0;\n let indexChanges = 0;\n let ruleChanges = 0;\n let permissionChanges = 0;\n let viewQueryChanges = 0;\n\n for (const modification of diff.collectionsToModify) {\n fieldsToAdd += modification.fieldsToAdd.length;\n fieldsToRemove += modification.fieldsToRemove.length;\n fieldsToModify += modification.fieldsToModify.length;\n indexChanges += modification.indexesToAdd.length + modification.indexesToRemove.length;\n ruleChanges += modification.rulesToUpdate.length;\n permissionChanges += modification.permissionsToUpdate.length;\n if (modification.viewQueryUpdate) {\n viewQueryChanges += 1;\n }\n }\n\n return {\n totalChanges: diff.collectionsToCreate.length + diff.collectionsToDelete.length + diff.collectionsToModify.length,\n collectionsToCreate: diff.collectionsToCreate.length,\n collectionsToDelete: diff.collectionsToDelete.length,\n collectionsToModify: diff.collectionsToModify.length,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexChanges,\n ruleChanges,\n permissionChanges,\n viewQueryChanges,\n destructiveChanges,\n nonDestructiveChanges: nonDestructive,\n };\n}\n","import type { SchemaDiff, FieldModification } from \"../types\";\n\nexport interface FilterOptions {\n patterns?: string[];\n skipDestructive?: boolean;\n}\n\nfunction matchesPattern(text: string, patterns: string[]): boolean {\n if (!patterns || patterns.length === 0) return true;\n return patterns.some(pattern => {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return text.includes(pattern);\n }\n });\n}\n\nfunction isDestructiveFieldModification(mod: FieldModification): boolean {\n const typeChange = mod.changes.find(c => c.property === \"type\");\n const requiredChange = mod.changes.find(c => c.property === \"required\" && c.newValue === true);\n return !!(typeChange || requiredChange);\n}\n\nexport function filterDiff(diff: SchemaDiff, options: FilterOptions): SchemaDiff {\n const { patterns = [], skipDestructive = false } = options;\n\n // 1. Filter Collections to Create\n const collectionsToCreate = diff.collectionsToCreate.filter(col => {\n return matchesPattern(col.name, patterns);\n });\n\n // 2. Filter Collections to Delete\n // View collections are kept even when skipping destructive changes: they\n // store no data, so dropping one loses nothing\n let collectionsToDelete = diff.collectionsToDelete;\n if (skipDestructive) {\n collectionsToDelete = collectionsToDelete.filter(col => col.type === \"view\");\n }\n collectionsToDelete = collectionsToDelete.filter(col => {\n return matchesPattern(col.name, patterns);\n });\n\n // 3. Filter Collections to Modify\n const collectionsToModify = diff.collectionsToModify.map(mod => {\n // Check if collection name itself matches\n const collectionMatches = matchesPattern(mod.collection, patterns);\n\n // Filter fields to add\n const fieldsToAdd = mod.fieldsToAdd.filter(field => {\n return collectionMatches || matchesPattern(`${mod.collection}.${field.name}`, patterns);\n });\n\n // Filter fields to remove\n let fieldsToRemove = mod.fieldsToRemove;\n if (skipDestructive) {\n fieldsToRemove = [];\n } else {\n fieldsToRemove = fieldsToRemove.filter(field => {\n return collectionMatches || matchesPattern(`${mod.collection}.${field.name}`, patterns);\n });\n }\n\n // Filter fields to modify\n let fieldsToModify = mod.fieldsToModify;\n if (skipDestructive) {\n fieldsToModify = fieldsToModify.filter(f => !isDestructiveFieldModification(f));\n }\n fieldsToModify = fieldsToModify.filter(f => {\n return collectionMatches || matchesPattern(`${mod.collection}.${f.fieldName}`, patterns);\n });\n\n // Filter collection-level changes (indexes, rules, permissions)\n // Only include them if the collection name itself matches the pattern.\n // If user targets specific fields (e.g. \"User.name\"), collectionMatches is false, so these are skipped.\n const indexesToAdd = collectionMatches ? mod.indexesToAdd : [];\n const indexesToRemove = collectionMatches ? mod.indexesToRemove : [];\n const rulesToUpdate = collectionMatches ? mod.rulesToUpdate : [];\n const permissionsToUpdate = collectionMatches ? mod.permissionsToUpdate : [];\n const viewQueryUpdate = collectionMatches ? mod.viewQueryUpdate : undefined;\n\n return {\n ...mod,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexesToAdd,\n indexesToRemove,\n rulesToUpdate,\n permissionsToUpdate,\n viewQueryUpdate\n };\n }).filter(mod => {\n // Keep modification object only if there is something left to modify\n return mod.fieldsToAdd.length > 0 ||\n mod.fieldsToRemove.length > 0 ||\n mod.fieldsToModify.length > 0 ||\n mod.indexesToAdd.length > 0 ||\n mod.indexesToRemove.length > 0 ||\n mod.rulesToUpdate.length > 0 ||\n mod.permissionsToUpdate.length > 0 ||\n mod.viewQueryUpdate !== undefined;\n });\n\n return {\n ...diff,\n collectionsToCreate,\n collectionsToDelete,\n collectionsToModify\n };\n}\n","/**\n * Diff Engine component\n * Compares current schema with previous snapshot and identifies changes\n *\n * This module provides a standalone, configurable diff engine that can be used\n * by consumer projects to compare schema definitions and detect changes.\n */\n\nimport type { CollectionModification, SchemaDefinition, SchemaDiff, SchemaSnapshot } from \"../types\";\nimport { CollectionIdRegistry } from \"../utils/collection-id-generator\";\nimport {\n buildCollectionModification,\n findNewCollections,\n findRemovedCollections,\n matchCollectionsByName,\n} from \"./collections\";\nimport { mergeConfig, type DiffEngineConfig } from \"./config\";\nimport {\n categorizeChangesBySeverity,\n generateChangeSummary,\n type ChangeSummary,\n} from \"./summary\";\nimport { isSystemCollection } from \"./utils\";\nimport { detectDestructiveChanges, type DestructiveChange, requiresForceFlag } from \"./destructiveness\";\n\n// Export everything from submodules\nexport * from \"./collections\";\nexport * from \"./config\";\nexport * from \"./destructiveness\";\nexport * from \"./fields\";\nexport * from \"./indexes\";\nexport * from \"./rules\";\nexport * from \"./summary\";\nexport * from \"./utils\";\n\n/**\n * Checks if a collection modification has any actual changes\n *\n * @param modification - Collection modification to check\n * @returns True if there are any changes\n */\nfunction hasChanges(modification: CollectionModification): boolean {\n return (\n modification.fieldsToAdd.length > 0 ||\n modification.fieldsToRemove.length > 0 ||\n modification.fieldsToModify.length > 0 ||\n modification.indexesToAdd.length > 0 ||\n modification.indexesToRemove.length > 0 ||\n modification.rulesToUpdate.length > 0 ||\n modification.permissionsToUpdate.length > 0 ||\n modification.viewQueryUpdate !== undefined\n );\n}\n\n/**\n * Aggregates all detected changes into a SchemaDiff\n * Main entry point for diff comparison\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @param config - Optional configuration\n * @returns Complete SchemaDiff with all changes\n */\nexport function aggregateChanges(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null,\n config?: DiffEngineConfig\n): SchemaDiff {\n // Build lookup map for ID -> Name from previous snapshot\n // This helps resolve relations where snapshot uses ID but schema uses Name\n const collectionIdToName = new Map<string, string>();\n if (previousSnapshot) {\n for (const [name, collection] of previousSnapshot.collections) {\n if (collection.id) {\n collectionIdToName.set(collection.id, name);\n }\n }\n }\n\n // Find new and removed collections\n const collectionsToCreate = findNewCollections(currentSchema, previousSnapshot);\n const collectionsToDelete = findRemovedCollections(currentSchema, previousSnapshot);\n\n // Filter out system collections from create and delete operations\n const filteredCollectionsToCreate = collectionsToCreate.filter(\n (collection) => !isSystemCollection(collection.name, config)\n );\n const filteredCollectionsToDelete = collectionsToDelete.filter(\n (collection) => !isSystemCollection(collection.name, config)\n );\n\n // Generate and assign collection IDs for new collections\n const registry = new CollectionIdRegistry();\n const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {\n // If the collection already has an ID, register it and use it\n if (collection.id) {\n registry.register(collection.id);\n return collection;\n }\n\n // Generate a new ID for the collection (pass name for special handling)\n const id = registry.generate(collection.name);\n return {\n ...collection,\n id,\n };\n });\n\n // Find modified collections\n const collectionsToModify: CollectionModification[] = [];\n const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);\n\n for (const [currentCollection, previousCollection] of matchedCollections) {\n const modification = buildCollectionModification(currentCollection, previousCollection, config, collectionIdToName);\n\n // Only include if there are actual changes\n // Note: We allow modifications to the users collection (non-system)\n if (hasChanges(modification)) {\n collectionsToModify.push(modification);\n }\n }\n\n // Build map of existing collection names to their IDs from the snapshot\n // This is used by the generator to resolve relation field references\n const existingCollectionIds = new Map<string, string>();\n if (previousSnapshot) {\n for (const [name, collection] of previousSnapshot.collections) {\n if (collection.id) {\n existingCollectionIds.set(name, collection.id);\n }\n }\n }\n\n return {\n collectionsToCreate: collectionsWithIds,\n collectionsToDelete: filteredCollectionsToDelete,\n collectionsToModify,\n existingCollectionIds,\n };\n}\n\n/**\n * Main comparison function\n * Compares current schema with previous snapshot and returns complete diff\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot (null for first run)\n * @param config - Optional configuration\n * @returns Complete SchemaDiff with all detected changes\n */\nexport function compare(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null,\n config?: DiffEngineConfig\n): SchemaDiff {\n return aggregateChanges(currentSchema, previousSnapshot, config);\n}\n\n/**\n * DiffEngine class for object-oriented usage\n * Provides a stateful interface for schema comparison\n */\nexport class DiffEngine {\n private config: Required<DiffEngineConfig>;\n\n constructor(config?: DiffEngineConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Compares current schema with previous snapshot\n */\n compare(currentSchema: SchemaDefinition, previousSnapshot: SchemaSnapshot | null): SchemaDiff {\n return compare(currentSchema, previousSnapshot, this.config);\n }\n\n /**\n * Detects destructive changes in a diff\n */\n detectDestructiveChanges(diff: SchemaDiff): DestructiveChange[] {\n return detectDestructiveChanges(diff, this.config);\n }\n\n /**\n * Categorizes changes by severity\n */\n categorizeChangesBySeverity(diff: SchemaDiff): { destructive: string[]; nonDestructive: string[] } {\n return categorizeChangesBySeverity(diff, this.config);\n }\n\n /**\n * Generates a summary of changes\n */\n generateChangeSummary(diff: SchemaDiff): ChangeSummary {\n return generateChangeSummary(diff, this.config);\n }\n\n /**\n * Checks if force flag is required\n */\n requiresForceFlag(diff: SchemaDiff): boolean {\n return requiresForceFlag(diff, this.config);\n }\n}\nexport * from \"./filter.js\";\n","/**\n * Configuration options for the migration generator\n */\nexport interface MigrationGeneratorConfig {\n /**\n * Directory to write migration files\n */\n migrationDir: string;\n\n /**\n * Workspace root for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * Custom timestamp generator function\n * Defaults to Unix timestamp in seconds\n */\n timestampGenerator?: () => string;\n\n /**\n * Custom migration file template\n * Use {{UP_CODE}} and {{DOWN_CODE}} placeholders\n */\n template?: string;\n\n /**\n * Whether to include type reference comment\n * Defaults to true\n */\n includeTypeReference?: boolean;\n\n /**\n * Path to types.d.ts file for reference comment\n * Defaults to '../pb_data/types.d.ts'\n */\n typesPath?: string;\n\n /**\n * Whether to force generation even if duplicate migration exists\n * Defaults to false\n */\n force?: boolean;\n}\n\n/**\n * Default migration template\n */\nexport const DEFAULT_TEMPLATE = `/// <reference path=\"{{TYPES_PATH}}\" />\nmigrate((app) => {\n{{UP_CODE}}\n}, (app) => {\n{{DOWN_CODE}}\n});\n`;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Omit<Required<MigrationGeneratorConfig>, \"migrationDir\" | \"force\"> = {\n workspaceRoot: process.cwd(),\n timestampGenerator: () => Math.floor(Date.now() / 1000).toString(),\n template: DEFAULT_TEMPLATE,\n includeTypeReference: true,\n typesPath: \"../pb_data/types.d.ts\",\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(config: MigrationGeneratorConfig): Required<MigrationGeneratorConfig> {\n return {\n ...DEFAULT_CONFIG,\n force: false,\n ...config,\n };\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, MigrationGenerationError } from \"../errors\";\nimport { DEFAULT_CONFIG, mergeConfig, type MigrationGeneratorConfig } from \"./config\";\n\n/**\n * Resolves the migration directory path\n */\nexport function resolveMigrationDir(config: MigrationGeneratorConfig): string {\n const workspaceRoot = config.workspaceRoot || process.cwd();\n\n if (path.isAbsolute(config.migrationDir)) {\n return config.migrationDir;\n }\n\n return path.join(workspaceRoot, config.migrationDir);\n}\n\n/**\n * Creates the migration file structure with up and down functions\n *\n * @param upCode - Code for the up migration\n * @param downCode - Code for the down migration\n * @param config - Optional configuration with custom template\n * @returns Complete migration file content\n */\nexport function createMigrationFileStructure(\n upCode: string,\n downCode: string,\n config?: MigrationGeneratorConfig\n): string {\n const mergedConfig = config ? mergeConfig(config) : DEFAULT_CONFIG;\n let template = mergedConfig.template;\n\n // Replace placeholders using functions to avoid special character expansion (like $')\n template = template.replace(\"{{TYPES_PATH}}\", () => mergedConfig.typesPath);\n template = template.replace(\"{{UP_CODE}}\", () => upCode);\n template = template.replace(\"{{DOWN_CODE}}\", () => downCode);\n\n // Remove type reference if disabled\n if (!mergedConfig.includeTypeReference) {\n template = template.replace(/\\/\\/\\/ <reference path=\"[^\"]*\" \\/>\\n?/, \"\");\n }\n\n return template;\n}\n\n/**\n * Writes migration file to the specified directory\n * Creates directory if it doesn't exist\n *\n * @param migrationDir - Directory to write migration file\n * @param filename - Migration filename\n * @param content - Migration file content\n * @returns Full path to the created migration file\n */\nexport function writeMigrationFile(migrationDir: string, filename: string, content: string): string {\n try {\n // Ensure migration directory exists\n if (!fs.existsSync(migrationDir)) {\n try {\n fs.mkdirSync(migrationDir, { recursive: true });\n } catch (error) {\n const fsError = error as NodeJS.ErrnoException;\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied creating migration directory. Check directory permissions.`,\n migrationDir,\n \"create\",\n fsError.code,\n error as Error\n );\n }\n throw new FileSystemError(\n `Failed to create migration directory: ${fsError.message}`,\n migrationDir,\n \"create\",\n fsError.code,\n error as Error\n );\n }\n }\n\n // Full path to migration file\n const filePath = path.join(migrationDir, filename);\n\n // Write migration file\n fs.writeFileSync(filePath, content, \"utf-8\");\n\n return filePath;\n } catch (error) {\n // If it's already a FileSystemError, re-throw it\n if (error instanceof FileSystemError) {\n throw error;\n }\n\n const fsError = error as NodeJS.ErrnoException;\n const filePath = path.join(migrationDir, filename);\n\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied writing migration file. Check file and directory permissions.`,\n filePath,\n \"write\",\n fsError.code,\n error as Error\n );\n } else if (fsError.code === \"ENOSPC\") {\n throw new FileSystemError(\n `No space left on device when writing migration file.`,\n filePath,\n \"write\",\n fsError.code,\n error as Error\n );\n }\n\n throw new MigrationGenerationError(`Failed to write migration file: ${fsError.message}`, filePath, error as Error);\n }\n}\n","import type { FieldDefinition } from \"../types\";\nimport type { MigrationGeneratorConfig } from \"./config\";\n\n/**\n * Generates a timestamp for migration filename\n * Format: Unix timestamp in seconds (e.g., 1687801090)\n *\n * @param config - Optional configuration with custom timestamp generator\n * @returns Timestamp string\n */\nexport function generateTimestamp(config?: MigrationGeneratorConfig): string {\n if (config?.timestampGenerator) {\n return config.timestampGenerator();\n }\n return Math.floor(Date.now() / 1000).toString();\n}\n\n/**\n * Increments a timestamp by 1 second\n * Ensures sequential ordering of migration files\n *\n * @param timestamp - Current timestamp string\n * @returns Incremented timestamp string\n */\nexport function incrementTimestamp(timestamp: string): string {\n const currentTimestamp = parseInt(timestamp, 10);\n return (currentTimestamp + 1).toString();\n}\n\n/**\n * Formats a value for JavaScript code generation\n * Handles strings, numbers, booleans, null, arrays, and objects\n *\n * @param value - Value to format\n * @returns Formatted string representation\n */\nexport function formatValue(value: any): string {\n if (value === null || value === undefined) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n // Use JSON.stringify to properly escape all special characters\n return JSON.stringify(value);\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n // Use JSON.stringify for arrays to properly handle all special characters\n // Then format with spaces after commas to match expected test output\n return JSON.stringify(value).replace(/\",\"/g, '\", \"');\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value)\n .filter(([_k, v]) => v !== undefined) // Omit undefined values\n .map(([k, v]) => `${k}: ${formatValue(v)}`)\n .join(\", \");\n return `{ ${entries} }`;\n }\n\n return String(value);\n}\n\n/**\n * Formats a SQL view query as a JavaScript template literal\n *\n * Emitted as a backtick template (rather than a JSON string) so the SQL stays\n * readable in the generated migration. Backticks and `${` are escaped so the\n * query can never break out of the literal or be interpolated.\n *\n * @param query - The SQL query\n * @param indent - Indentation prefix applied to each line of SQL\n * @returns Template literal source, including the surrounding backticks\n */\nexport function formatSqlTemplate(query: string, indent: string = \" \"): string {\n const escaped = query.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n\n const body = escaped\n .split(\"\\n\")\n .map((line) => (line.trim() === \"\" ? \"\" : `${indent}${line}`))\n .join(\"\\n\");\n\n return `\\`\\n${body}\\n${indent.slice(0, -2)}\\``;\n}\n\n/**\n * Gets the appropriate Field constructor name for a field type\n *\n * @param fieldType - PocketBase field type\n * @returns Field constructor name\n */\nexport function getFieldConstructorName(fieldType: string): string {\n const constructorMap: Record<string, string> = {\n text: \"TextField\",\n email: \"EmailField\",\n url: \"URLField\",\n number: \"NumberField\",\n bool: \"BoolField\",\n date: \"DateField\",\n select: \"SelectField\",\n relation: \"RelationField\",\n file: \"FileField\",\n json: \"JSONField\",\n editor: \"EditorField\",\n autodate: \"AutodateField\",\n };\n\n return constructorMap[fieldType] || \"TextField\";\n}\n\n/**\n * Generates system fields that are required for all PocketBase collections\n * These fields (id, created, updated) must be explicitly included in migrations\n *\n * @returns Array of system field definitions\n */\nexport function getSystemFields(): FieldDefinition[] {\n return [\n // id field - primary key, auto-generated\n {\n name: \"id\",\n id: \"text3208210256\",\n type: \"text\",\n required: true,\n options: {\n autogeneratePattern: \"[a-z0-9]{15}\",\n hidden: false,\n max: 15,\n min: 15,\n pattern: \"^[a-z0-9]+$\",\n presentable: false,\n primaryKey: true,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates the autodate timestamp system fields (created, updated)\n * These appear at the end of every collection's field list, after user fields\n *\n * @returns Array of system timestamp field definitions\n */\nexport function getSystemTimestampFields(): FieldDefinition[] {\n return [\n {\n name: \"created\",\n id: \"autodate2990389176\",\n type: \"autodate\",\n required: false,\n options: {\n hidden: false,\n onCreate: true,\n onUpdate: false,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"updated\",\n id: \"autodate3332085495\",\n type: \"autodate\",\n required: false,\n options: {\n hidden: false,\n onCreate: true,\n onUpdate: true,\n presentable: false,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates auth-specific system fields\n *\n * @returns Array of auth system field definitions\n */\nexport function getAuthSystemFields(): FieldDefinition[] {\n return [\n {\n name: \"password\",\n id: \"password3208210256\",\n type: \"text\",\n required: true,\n options: {\n hidden: true,\n max: 0,\n min: 0,\n pattern: \"\",\n presentable: false,\n system: true,\n },\n },\n {\n name: \"tokenKey\",\n id: \"tokenKey3208210256\",\n type: \"text\",\n required: true,\n options: {\n hidden: true,\n max: 0,\n min: 0,\n pattern: \"\",\n presentable: false,\n system: true,\n },\n },\n {\n name: \"email\",\n id: \"email3208210256\",\n type: \"email\",\n required: true,\n options: {\n exceptDomains: null,\n hidden: false,\n onlyDomains: null,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"emailVisibility\",\n id: \"bool3208210256\",\n type: \"bool\",\n required: false,\n options: {\n hidden: false,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"verified\",\n id: \"bool1547992826\",\n type: \"bool\",\n required: false,\n options: {\n hidden: false,\n presentable: false,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates default system indexes for auth collections\n *\n * @param collectionName - Name of the auth collection\n * @returns Array of index SQL statements\n */\nexport function getAuthSystemIndexes(collectionName: string): string[] {\n return [\n `CREATE UNIQUE INDEX \\`idx_tokenKey_pbc_2283551112\\` ON \\`${collectionName}\\` (\\`tokenKey\\`)`,\n `CREATE UNIQUE INDEX \\`idx_email_pbc_2283551112\\` ON \\`${collectionName}\\` (\\`email\\`) WHERE \\`email\\` != ''`,\n ];\n}\n\n/**\n * Generates the code to find a collection by ID if available, otherwise by name\n *\n * @param name - Collection name\n * @param collectionIdMap - Map of collection names to IDs\n * @returns Code string like `app.findCollectionByNameOrId(\"id\") // name` or `app.findCollectionByNameOrId(\"name\")`\n */\nexport function generateFindCollectionCode(name: string, collectionIdMap?: Map<string, string>): string {\n if (collectionIdMap && collectionIdMap.has(name)) {\n const id = collectionIdMap.get(name);\n return `app.findCollectionByNameOrId(\"${id}\") // ${name}`;\n }\n return `app.findCollectionByNameOrId(\"${name}\")`;\n}\n","import type { FieldDefinition, FieldModification } from \"../types\";\nimport { formatValue, generateFindCollectionCode, getFieldConstructorName } from \"./utils\";\n\n/**\n * Generates field definition object for collection creation\n * Creates the field configuration object used in Collection constructor\n *\n * @param field - Field definition\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Field definition object as string\n */\nexport function generateFieldDefinitionObject(field: FieldDefinition, collectionIdMap?: Map<string, string>): string {\n const parts: string[] = [];\n\n // Add field name\n parts.push(` \"name\": \"${field.name}\"`);\n\n // Add field id\n parts.push(` \"id\": \"${field.id}\"`);\n\n // Add field type\n parts.push(` \"type\": \"${field.type}\"`);\n\n // Add required flag\n parts.push(` \"required\": ${field.required}`);\n\n // Add unique flag if present\n if (field.unique !== undefined) {\n parts.push(` \"unique\": ${field.unique}`);\n }\n\n // Add explicit defaults for select fields\n if (field.type === \"select\") {\n // Always include maxSelect (default: 1)\n const maxSelect = field.options?.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include values array (default: [])\n const values = field.options?.values ?? [];\n parts.push(` \"values\": ${formatValue(values)}`);\n }\n\n // Add options if present (excluding select-specific options already handled)\n if (field.options && Object.keys(field.options).length > 0) {\n for (const [key, value] of Object.entries(field.options)) {\n // Skip select-specific options as they're handled above\n if (field.type === \"select\" && (key === \"maxSelect\" || key === \"values\")) {\n continue;\n }\n // Skip id as it's already added explicitly above\n if (key === \"id\") {\n continue;\n }\n // Convert noDecimal to onlyInt for number fields (PocketBase uses onlyInt)\n if (field.type === \"number\" && key === \"noDecimal\") {\n parts.push(` \"onlyInt\": ${formatValue(value)}`);\n } else {\n parts.push(` \"${key}\": ${formatValue(value)}`);\n }\n }\n }\n\n // Add relation configuration if present\n if (field.relation) {\n // Use pre-generated collection ID from map if available\n // Otherwise fall back to runtime lookup (for existing collections not in the current diff)\n const isUsersCollection = field.relation.collection.toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n // Special case: users collection always uses the constant\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {\n // Use pre-generated ID from map\n collectionIdValue = `\"${collectionIdMap.get(field.relation.collection)}\"`;\n } else {\n // Fall back to runtime lookup for existing collections\n collectionIdValue = `app.findCollectionByNameOrId(\"${field.relation.collection}\").id`;\n }\n\n parts.push(` \"collectionId\": ${collectionIdValue}`);\n\n // Always include maxSelect (default: 1)\n const maxSelect = field.relation.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include minSelect (default: null)\n const minSelect = field.relation.minSelect ?? null;\n parts.push(` \"minSelect\": ${minSelect}`);\n\n // Always include cascadeDelete (default: false)\n const cascadeDelete = field.relation.cascadeDelete ?? false;\n parts.push(` \"cascadeDelete\": ${cascadeDelete}`);\n\n // Always include displayFields (default: null)\n const displayFields = field.relation.displayFields ?? null;\n parts.push(` \"displayFields\": ${formatValue(displayFields)}`);\n }\n\n return ` {\\n${parts.join(\",\\n\")},\\n }`;\n}\n\n/**\n * Generates fields array for collection creation\n *\n * @param fields - Array of field definitions\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Fields array as string\n */\nexport function generateFieldsArray(fields: FieldDefinition[], collectionIdMap?: Map<string, string>): string {\n if (fields.length === 0) {\n return \"[]\";\n }\n\n const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));\n return `[\\n${fieldObjects.join(\",\\n\")},\\n ]`;\n}\n\n/**\n * Generates field constructor options object\n *\n * @param field - Field definition\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Options object as string\n */\nexport function generateFieldConstructorOptions(field: FieldDefinition, collectionIdMap?: Map<string, string>): string {\n const parts: string[] = [];\n\n // Add field name\n parts.push(` \"name\": \"${field.name}\"`);\n\n // Add field id\n parts.push(` \"id\": \"${field.id}\"`);\n\n // Add required flag\n parts.push(` \"required\": ${field.required}`);\n\n // Add unique flag if present\n if (field.unique !== undefined) {\n parts.push(` \"unique\": ${field.unique}`);\n }\n\n // Add explicit defaults for select fields\n if (field.type === \"select\") {\n // Always include maxSelect (default: 1)\n const maxSelect = field.options?.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include values array (default: [])\n const values = field.options?.values ?? [];\n parts.push(` \"values\": ${formatValue(values)}`);\n }\n\n // Add options if present (excluding select-specific options already handled)\n if (field.options && Object.keys(field.options).length > 0) {\n for (const [key, value] of Object.entries(field.options)) {\n // Skip select-specific options as they're handled above\n if (field.type === \"select\" && (key === \"maxSelect\" || key === \"values\")) {\n continue;\n }\n // Skip id as it's already added explicitly above\n if (key === \"id\") {\n continue;\n }\n // Convert noDecimal to onlyInt for number fields (PocketBase uses onlyInt)\n if (field.type === \"number\" && key === \"noDecimal\") {\n parts.push(` \"onlyInt\": ${formatValue(value)}`);\n } else {\n parts.push(` \"${key}\": ${formatValue(value)}`);\n }\n }\n }\n\n // Add relation-specific options\n if (field.relation && field.type === \"relation\") {\n // Use pre-generated collection ID from map if available\n // Otherwise fall back to runtime lookup (for existing collections not in the current diff)\n const isUsersCollection = field.relation.collection.toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n // Special case: users collection always uses the constant\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {\n // Use pre-generated ID from map\n collectionIdValue = `\"${collectionIdMap.get(field.relation.collection)}\"`;\n } else {\n // Fall back to runtime lookup for existing collections\n collectionIdValue = `app.findCollectionByNameOrId(\"${field.relation.collection}\").id`;\n }\n\n parts.push(` \"collectionId\": ${collectionIdValue}`);\n\n // Always include maxSelect (default: 1)\n const maxSelect = field.relation.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include minSelect (default: null)\n const minSelect = field.relation.minSelect ?? null;\n parts.push(` \"minSelect\": ${minSelect}`);\n\n // Always include cascadeDelete (default: false)\n const cascadeDelete = field.relation.cascadeDelete ?? false;\n parts.push(` \"cascadeDelete\": ${cascadeDelete}`);\n\n if (field.relation.displayFields) {\n parts.push(` \"displayFields\": ${formatValue(field.relation.displayFields)}`);\n }\n }\n\n return parts.join(\",\\n\");\n}\n\n/**\n * Generates code for adding a field to an existing collection\n * Uses the appropriate Field constructor based on field type\n *\n * @param collectionName - Name of the collection\n * @param field - Field definition to add\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for adding the field\n */\nexport function generateFieldAddition(\n collectionName: string,\n field: FieldDefinition,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const constructorName = getFieldConstructorName(field.type);\n const collectionVar = varName || `collection_${collectionName}_${field.name}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(``);\n lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);\n lines.push(generateFieldConstructorOptions(field, collectionIdMap));\n lines.push(` }));`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for modifying an existing field\n * Updates field properties based on detected changes\n *\n * @param collectionName - Name of the collection\n * @param modification - Field modification details\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for modifying the field\n */\nexport function generateFieldModification(\n collectionName: string,\n modification: FieldModification,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;\n const fieldVar = `${collectionVar}_field`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` const ${fieldVar} = ${collectionVar}.fields.getByName(\"${modification.fieldName}\");`);\n lines.push(``);\n\n // Apply each change\n for (const change of modification.changes) {\n if (change.property.startsWith(\"options.\")) {\n // Handle nested options properties\n const optionKey = change.property.replace(\"options.\", \"\");\n // In PocketBase, field properties are set directly on the field, not in an options object\n lines.push(` ${fieldVar}.${optionKey} = ${formatValue(change.newValue)};`);\n } else if (change.property.startsWith(\"relation.\")) {\n // Handle nested relation properties\n const relationKey = change.property.replace(\"relation.\", \"\");\n\n if (relationKey === \"collection\") {\n // Special handling for collection ID\n // Use case-insensitive check for \"users\" to handle both explicit and implicit relation definitions\n const isUsersCollection = String(change.newValue).toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(String(change.newValue))) {\n // Use pre-generated ID from map (for existing collections)\n collectionIdValue = `\"${collectionIdMap.get(String(change.newValue))}\"`;\n } else {\n // Fall back to runtime lookup (should not happen if snapshot is properly loaded)\n collectionIdValue = `app.findCollectionByNameOrId(\"${change.newValue}\").id`;\n }\n lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);\n } else {\n lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);\n }\n } else {\n // Handle top-level properties\n lines.push(` ${fieldVar}.${change.property} = ${formatValue(change.newValue)};`);\n }\n }\n\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for deleting a field from a collection\n *\n * @param collectionName - Name of the collection\n * @param fieldName - Name of the field to delete\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for deleting the field\n */\nexport function generateFieldDeletion(\n collectionName: string,\n fieldName: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${fieldName}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(``);\n lines.push(` ${collectionVar}.fields.removeByName(\"${fieldName}\");`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import { generateFindCollectionCode } from \"./utils\";\n\n/**\n * Generates indexes array for collection creation\n *\n * @param indexes - Array of index definitions\n * @returns Indexes array as string\n */\nexport function generateIndexesArray(indexes?: string[]): string {\n if (!indexes || indexes.length === 0) {\n return \"[]\";\n }\n\n const indexStrings = indexes.map((idx) => JSON.stringify(idx));\n return `[\\n ${indexStrings.join(\",\\n \")},\\n ]`;\n}\n\n/**\n * Generates code for adding an index to a collection\n *\n * @param collectionName - Name of the collection\n * @param index - Index SQL statement\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for adding the index\n */\nexport function generateIndexAddition(\n collectionName: string,\n index: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_idx`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for removing an index from a collection\n *\n * @param collectionName - Name of the collection\n * @param index - Index SQL statement\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for removing the index\n */\nexport function generateIndexRemoval(\n collectionName: string,\n index: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_idx`;\n const indexVar = `${collectionVar}_indexToRemove`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);\n lines.push(` if (${indexVar} !== -1) {`);\n lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);\n lines.push(` }`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionSchema } from \"../types\";\nimport { formatSqlTemplate, formatValue, generateFindCollectionCode } from \"./utils\";\n\n/**\n * Generates collection rules object\n *\n * @param rules - Collection rules\n * @returns Rules configuration as string\n */\nexport function generateCollectionRules(rules?: CollectionSchema[\"rules\"], collectionType: string = \"base\"): string {\n if (!rules) {\n return \"\";\n }\n\n // View collections are read-only: the write rules are always null and\n // manageRule is not applicable\n if (collectionType === \"view\") {\n return [\n `\"listRule\": ${formatValue(rules.listRule ?? null)}`,\n `\"viewRule\": ${formatValue(rules.viewRule ?? null)}`,\n `\"createRule\": null`,\n `\"updateRule\": null`,\n `\"deleteRule\": null`,\n ].join(\",\\n \");\n }\n\n const parts: string[] = [];\n\n if (rules.listRule !== undefined) {\n parts.push(`\"listRule\": ${formatValue(rules.listRule)}`);\n }\n\n if (rules.viewRule !== undefined) {\n parts.push(`\"viewRule\": ${formatValue(rules.viewRule)}`);\n }\n\n if (rules.createRule !== undefined) {\n parts.push(`\"createRule\": ${formatValue(rules.createRule)}`);\n }\n\n if (rules.updateRule !== undefined) {\n parts.push(`\"updateRule\": ${formatValue(rules.updateRule)}`);\n }\n\n if (rules.deleteRule !== undefined) {\n parts.push(`\"deleteRule\": ${formatValue(rules.deleteRule)}`);\n }\n\n if (collectionType === \"auth\" && rules.manageRule !== undefined) {\n parts.push(`\"manageRule\": ${formatValue(rules.manageRule)}`);\n }\n\n return parts.join(\",\\n \");\n}\n\n/**\n * Generates collection permissions object\n * Permissions are the same as rules but extracted from schema metadata\n *\n * @param permissions - Collection permissions\n * @returns Permissions configuration as string\n */\nexport function generateCollectionPermissions(\n permissions?: CollectionSchema[\"permissions\"],\n collectionType: string = \"base\"\n): string {\n if (!permissions) {\n return \"\";\n }\n\n // View collections are read-only: the write rules are always null and\n // manageRule is not applicable\n if (collectionType === \"view\") {\n return [\n `\"listRule\": ${formatValue(permissions.listRule ?? null)}`,\n `\"viewRule\": ${formatValue(permissions.viewRule ?? null)}`,\n `\"createRule\": null`,\n `\"updateRule\": null`,\n `\"deleteRule\": null`,\n ].join(\",\\n \");\n }\n\n const parts: string[] = [];\n\n if (permissions.listRule !== undefined) {\n parts.push(`\"listRule\": ${formatValue(permissions.listRule)}`);\n }\n\n if (permissions.viewRule !== undefined) {\n parts.push(`\"viewRule\": ${formatValue(permissions.viewRule)}`);\n }\n\n if (permissions.createRule !== undefined) {\n parts.push(`\"createRule\": ${formatValue(permissions.createRule)}`);\n }\n\n if (permissions.updateRule !== undefined) {\n parts.push(`\"updateRule\": ${formatValue(permissions.updateRule)}`);\n }\n\n if (permissions.deleteRule !== undefined) {\n parts.push(`\"deleteRule\": ${formatValue(permissions.deleteRule)}`);\n }\n\n if (collectionType === \"auth\" && permissions.manageRule !== undefined) {\n parts.push(`\"manageRule\": ${formatValue(permissions.manageRule)}`);\n }\n\n return parts.join(\",\\n \");\n}\n\n/**\n * Generates code for updating collection rules\n *\n * @param collectionName - Name of the collection\n * @param ruleType - Type of rule to update\n * @param newValue - New rule value\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for updating the rule\n */\nexport function generateRuleUpdate(\n collectionName: string,\n ruleType: string,\n newValue: string | null,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${ruleType}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for updating collection permissions\n * Handles permission rule updates including manageRule for auth collections\n *\n * @param collectionName - Name of the collection\n * @param ruleType - Type of permission rule to update\n * @param newValue - New permission rule value\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for updating the permission\n */\nexport function generatePermissionUpdate(\n collectionName: string,\n ruleType: string,\n newValue: string | null,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${ruleType}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for updating a view collection's SQL query\n *\n * Applied in place so the collection ID stays stable - PocketBase re-derives\n * the view's fields when the collection is saved.\n *\n * Uses unmarshal() rather than a direct `collection.viewQuery = ...`\n * assignment: viewQuery lives on an embedded struct in PocketBase's Go model,\n * and a direct assignment from the migration JS runtime is silently dropped.\n *\n * @param collectionName - Name of the view collection\n * @param viewQuery - The SQL query to set\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @param collectionIdMap - Map of collection names to IDs\n * @returns JavaScript code for updating the view query\n */\nexport function generateViewQueryUpdate(\n collectionName: string,\n viewQuery: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_viewQuery`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` unmarshal({`);\n lines.push(` \"viewQuery\": ${formatSqlTemplate(viewQuery, \" \")},`);\n lines.push(` }, ${collectionVar})`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates a single unmarshal({...}, collection) block for multiple rule/permission changes.\n * Used when 2+ rules change at once to match PocketBase's native migration style.\n *\n * @param collectionName - Name of the collection\n * @param entries - Array of { ruleType, value } to include in the unmarshal object\n * @param varSuffix - Suffix for the variable name (e.g. \"rules\" or \"revert_rules\")\n * @param isLast - Whether this is the last operation (will use return app.save)\n * @param collectionIdMap - Map of collection names to IDs\n * @returns JavaScript code block\n */\nexport function generateGroupedRuleUpdates(\n collectionName: string,\n entries: Array<{ ruleType: string; value: string | null }>,\n varSuffix: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const collectionVar = `collection_${collectionName}_${varSuffix}`;\n const lines: string[] = [];\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` unmarshal({`);\n for (const entry of entries) {\n lines.push(` \"${entry.ruleType}\": ${formatValue(entry.value)},`);\n }\n lines.push(` }, ${collectionVar})`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionSchema } from \"../types\";\nimport { generateFieldsArray } from \"./fields\";\nimport { generateIndexesArray } from \"./indexes\";\nimport { generateCollectionPermissions, generateCollectionRules } from \"./rules\";\nimport {\n formatSqlTemplate,\n formatValue,\n generateFindCollectionCode,\n getAuthSystemFields,\n getAuthSystemIndexes,\n getSystemFields,\n getSystemTimestampFields,\n} from \"./utils\";\n\n/**\n * Generates Collection constructor call for creating a new collection\n *\n * @param collection - Collection schema\n * @param varName - Variable name to use for the collection (default: 'collection')\n * @returns JavaScript code for creating the collection\n */\nexport function generateCollectionCreation(\n collection: CollectionSchema,\n varName: string = \"collection\",\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n\n lines.push(` const ${varName} = new Collection({`);\n if (collection.id) {\n lines.push(` \"id\": ${formatValue(collection.id)},`);\n }\n lines.push(` \"name\": \"${collection.name}\",`);\n lines.push(` \"type\": \"${collection.type}\",`);\n lines.push(` \"system\": false,`);\n\n // Add permissions (preferred) or rules\n // Permissions take precedence if both are defined\n const permissionsCode = generateCollectionPermissions(collection.permissions, collection.type);\n const rulesCode = generateCollectionRules(collection.rules, collection.type);\n\n if (permissionsCode) {\n lines.push(` ${permissionsCode},`);\n } else if (rulesCode) {\n lines.push(` ${rulesCode},`);\n }\n\n // View collections are defined by their SQL query: PocketBase derives the\n // fields by running it, and views support neither fields nor indexes here\n if (collection.type === \"view\") {\n lines.push(` \"viewQuery\": ${formatSqlTemplate(collection.viewQuery ?? \"\")},`);\n lines.push(` });`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);\n\n return lines.join(\"\\n\");\n }\n\n // Filter out system fields (they will be added back in correct order)\n const systemFieldNames = [\"created\", \"updated\", \"id\"];\n if (collection.type === \"auth\") {\n systemFieldNames.push(...getAuthSystemFields().map((f) => f.name));\n }\n const userFields = collection.fields.filter((f) => !systemFieldNames.includes(f.name));\n\n // Build field list in correct order: id, [auth fields], user fields, created, updated\n const allFields = [...getSystemFields()];\n\n if (collection.type === \"auth\") {\n allFields.push(...getAuthSystemFields());\n }\n\n allFields.push(...userFields);\n allFields.push(...getSystemTimestampFields());\n\n // Add fields\n lines.push(` \"fields\": ${generateFieldsArray(allFields, collectionIdMap)},`);\n\n // Add indexes\n let allIndexes = [...(collection.indexes || [])];\n if (collection.type === \"auth\") {\n allIndexes = [...getAuthSystemIndexes(collection.name), ...allIndexes];\n }\n lines.push(` \"indexes\": ${generateIndexesArray(allIndexes)},`);\n\n lines.push(` });`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for deleting a collection\n *\n * @param collectionName - Name of the collection to delete\n * @param varName - Variable name to use for the collection (default: 'collection')\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for deleting the collection\n */\nexport function generateCollectionDeletion(\n collectionName: string,\n varName: string = \"collection\",\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n\n lines.push(` const ${varName} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionOperation, CollectionSchema, FieldModification, SchemaDiff } from \"../types\";\nimport { generateCollectionCreation, generateCollectionDeletion } from \"./collections\";\nimport { generateFieldAddition, generateFieldDeletion, generateFieldModification } from \"./fields\";\nimport { generateIndexAddition, generateIndexRemoval } from \"./indexes\";\nimport { generateGroupedRuleUpdates, generatePermissionUpdate, generateRuleUpdate, generateViewQueryUpdate } from \"./rules\";\n\n/**\n * Generates the up migration code for a single collection operation\n * Handles create, modify, and delete operations\n *\n * @param operation - Collection operation to generate migration for\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for up migration\n */\nexport function generateOperationUpMigration(\n operation: CollectionOperation,\n collectionIdMap: Map<string, string>\n): string {\n const lines: string[] = [];\n\n if (operation.type === \"create\") {\n // Handle collection creation\n const collection = operation.collection as CollectionSchema;\n const varName = \"collection\";\n lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));\n } else if (operation.type === \"modify\") {\n // Handle collection modification\n const modification = operation.modifications!;\n const collectionName =\n typeof operation.collection === \"string\"\n ? operation.collection\n : (operation.collection?.name ?? modification.collection);\n\n let operationCount = 0;\n const totalOperations =\n modification.fieldsToAdd.length +\n modification.fieldsToModify.length +\n modification.fieldsToRemove.length +\n modification.indexesToAdd.length +\n modification.indexesToRemove.length +\n (modification.viewQueryUpdate ? 1 : 0) +\n (modification.permissionsToUpdate.length > 0 ? 1 : modification.rulesToUpdate.length > 0 ? 1 : 0);\n\n // Update the view query (view collections only)\n if (modification.viewQueryUpdate) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.newValue,\n undefined,\n isLast,\n collectionIdMap\n )\n );\n if (!isLast) lines.push(\"\");\n }\n\n // Add new fields\n for (let i = 0; i < modification.fieldsToAdd.length; i++) {\n const field = modification.fieldsToAdd[i];\n operationCount++;\n const varName = `collection_${collectionName}_add_${field.name}_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Modify existing fields\n for (const fieldMod of modification.fieldsToModify) {\n operationCount++;\n const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Remove fields\n for (const field of modification.fieldsToRemove) {\n operationCount++;\n const varName = `collection_${collectionName}_remove_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Add indexes\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n operationCount++;\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_addidx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexAddition(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Remove indexes\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n operationCount++;\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_rmidx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexRemoval(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Update permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", isLast, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n } else if (modification.rulesToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", isLast, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n }\n } else if (operation.type === \"delete\") {\n // Handle collection deletion\n const collectionName = typeof operation.collection === \"string\" ? operation.collection : operation.collection.name;\n const varName = \"collection\";\n lines.push(generateCollectionDeletion(collectionName, varName, true, collectionIdMap));\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the down migration code for a single collection operation\n * Reverts the operation (inverse of up migration)\n *\n * @param operation - Collection operation to generate rollback for\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for down migration\n */\nexport function generateOperationDownMigration(\n operation: CollectionOperation,\n collectionIdMap: Map<string, string>\n): string {\n const lines: string[] = [];\n\n if (operation.type === \"create\") {\n // Rollback: delete the created collection\n const collection = operation.collection as CollectionSchema;\n const varName = \"collection\";\n lines.push(generateCollectionDeletion(collection.name, varName, true, collectionIdMap));\n } else if (operation.type === \"modify\") {\n // Rollback: revert all modifications\n const modification = operation.modifications!;\n const collectionName =\n typeof operation.collection === \"string\"\n ? operation.collection\n : (operation.collection?.name ?? modification.collection);\n\n let operationCount = 0;\n const totalOperations =\n modification.fieldsToAdd.length +\n modification.fieldsToModify.length +\n modification.fieldsToRemove.length +\n modification.indexesToAdd.length +\n modification.indexesToRemove.length +\n (modification.viewQueryUpdate ? 1 : 0) +\n (modification.permissionsToUpdate.length > 0 ? 1 : modification.rulesToUpdate.length > 0 ? 1 : 0);\n\n // Restore the previous view query (view collections only)\n if (modification.viewQueryUpdate) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.oldValue ?? \"\",\n `collection_${collectionName}_revert_viewQuery`,\n isLast,\n collectionIdMap\n )\n );\n if (!isLast) lines.push(\"\");\n }\n\n // Revert permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", isLast, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n } else if (modification.rulesToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", isLast, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n }\n\n // Revert index removals (add them back)\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n operationCount++;\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_restore_idx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexAddition(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert index additions (remove them)\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n operationCount++;\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_revert_idx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexRemoval(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field removals (add them back)\n for (const field of modification.fieldsToRemove) {\n operationCount++;\n const varName = `collection_${collectionName}_restore_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field modifications\n for (const fieldMod of modification.fieldsToModify) {\n operationCount++;\n // Create a reverse modification\n const reverseChanges = fieldMod.changes.map((change) => ({\n property: change.property,\n oldValue: change.newValue,\n newValue: change.oldValue,\n }));\n\n const reverseMod: FieldModification = {\n fieldName: fieldMod.fieldName,\n currentDefinition: fieldMod.newDefinition,\n newDefinition: fieldMod.currentDefinition,\n changes: reverseChanges,\n };\n\n const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field additions (remove them)\n for (const field of modification.fieldsToAdd) {\n operationCount++;\n const varName = `collection_${collectionName}_revert_add_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n } else if (operation.type === \"delete\") {\n // Rollback: recreate the deleted collection\n const collection = operation.collection;\n if (typeof collection !== \"string\") {\n const varName = \"collection\";\n lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));\n }\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the up migration function code\n * Applies all changes from the diff in the correct order\n *\n * @param diff - Schema diff containing all changes\n * @returns JavaScript code for up migration\n */\nexport function generateUpMigration(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Add comment header\n lines.push(` // UP MIGRATION`);\n lines.push(``);\n\n // Build collection ID map from collections being created and existing collections\n // This map will be used to resolve relation field references\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // 1. Create new collections\n if (diff.collectionsToCreate.length > 0) {\n lines.push(` // Create new collections`);\n for (let i = 0; i < diff.collectionsToCreate.length; i++) {\n const collection = diff.collectionsToCreate[i];\n const varName = `collection_${collection.name}_create`;\n lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // 2. Modify existing collections\n if (diff.collectionsToModify.length > 0) {\n lines.push(` // Modify existing collections`);\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Update the view query (view collections only)\n if (modification.viewQueryUpdate) {\n lines.push(` // Update the view query of ${collectionName}`);\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.newValue,\n undefined,\n false,\n collectionIdMap\n )\n );\n lines.push(``);\n }\n\n // Add new fields\n if (modification.fieldsToAdd.length > 0) {\n lines.push(` // Add fields to ${collectionName}`);\n for (let i = 0; i < modification.fieldsToAdd.length; i++) {\n const field = modification.fieldsToAdd[i];\n const varName = `collection_${collectionName}_add_${field.name}_${i}`;\n lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Modify existing fields\n if (modification.fieldsToModify.length > 0) {\n lines.push(` // Modify fields in ${collectionName}`);\n for (const fieldMod of modification.fieldsToModify) {\n const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;\n lines.push(generateFieldModification(collectionName, fieldMod, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Remove fields\n if (modification.fieldsToRemove.length > 0) {\n lines.push(` // Remove fields from ${collectionName}`);\n for (const field of modification.fieldsToRemove) {\n const varName = `collection_${collectionName}_remove_${field.name}`;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Add indexes\n if (modification.indexesToAdd.length > 0) {\n lines.push(` // Add indexes to ${collectionName}`);\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_addidx_${i}`;\n lines.push(generateIndexAddition(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Remove indexes\n if (modification.indexesToRemove.length > 0) {\n lines.push(` // Remove indexes from ${collectionName}`);\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_rmidx_${i}`;\n lines.push(generateIndexRemoval(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Update permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n lines.push(` // Update permissions for ${collectionName}`);\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", false, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n } else if (modification.rulesToUpdate.length > 0) {\n lines.push(` // Update rules for ${collectionName}`);\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", false, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n }\n }\n }\n\n // 3. Delete collections\n if (diff.collectionsToDelete.length > 0) {\n lines.push(` // Delete collections`);\n for (let i = 0; i < diff.collectionsToDelete.length; i++) {\n const collection = diff.collectionsToDelete[i];\n const varName = `collection_${collection.name}_delete`;\n lines.push(generateCollectionDeletion(collection.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // If no changes, add a comment\n if (lines.length === 2) {\n lines.push(` // No changes detected`);\n lines.push(``);\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the down migration function code\n * Reverts all changes from the diff in reverse order\n *\n * @param diff - Schema diff containing all changes\n * @returns JavaScript code for down migration\n */\nexport function generateDownMigration(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Add comment header\n lines.push(` // DOWN MIGRATION (ROLLBACK)`);\n lines.push(``);\n\n // Build collection ID map from collections being created (for rollback)\n // This map will be used to resolve relation field references\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Also include deleted collections that might have IDs\n for (const collection of diff.collectionsToDelete) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // Reverse order: delete -> modify -> create\n\n // 1. Recreate deleted collections\n if (diff.collectionsToDelete.length > 0) {\n lines.push(` // Recreate deleted collections`);\n for (let i = 0; i < diff.collectionsToDelete.length; i++) {\n const collection = diff.collectionsToDelete[i];\n const varName = `collection_${collection.name}_recreate`;\n lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // 2. Revert modifications (in reverse order)\n if (diff.collectionsToModify.length > 0) {\n lines.push(` // Revert modifications`);\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Restore the previous view query (view collections only)\n if (modification.viewQueryUpdate) {\n lines.push(` // Restore the view query of ${collectionName}`);\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.oldValue ?? \"\",\n `collection_${collectionName}_revert_viewQuery`,\n false,\n collectionIdMap\n )\n );\n lines.push(``);\n }\n\n // Revert permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n lines.push(` // Revert permissions for ${collectionName}`);\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", false, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n } else if (modification.rulesToUpdate.length > 0) {\n lines.push(` // Revert rules for ${collectionName}`);\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", false, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n }\n\n // Revert index removals (add them back)\n if (modification.indexesToRemove.length > 0) {\n lines.push(` // Restore indexes to ${collectionName}`);\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_restore_idx_${i}`;\n lines.push(generateIndexAddition(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert index additions (remove them)\n if (modification.indexesToAdd.length > 0) {\n lines.push(` // Remove indexes from ${collectionName}`);\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_revert_idx_${i}`;\n lines.push(generateIndexRemoval(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field removals (add them back)\n if (modification.fieldsToRemove.length > 0) {\n lines.push(` // Restore fields to ${collectionName}`);\n for (const field of modification.fieldsToRemove) {\n const varName = `collection_${collectionName}_restore_${field.name}`;\n lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field modifications\n if (modification.fieldsToModify.length > 0) {\n lines.push(` // Revert field modifications in ${collectionName}`);\n for (const fieldMod of modification.fieldsToModify) {\n // Create a reverse modification\n const reverseChanges = fieldMod.changes.map((change) => ({\n property: change.property,\n oldValue: change.newValue,\n newValue: change.oldValue,\n }));\n\n const reverseMod: FieldModification = {\n fieldName: fieldMod.fieldName,\n currentDefinition: fieldMod.newDefinition,\n newDefinition: fieldMod.currentDefinition,\n changes: reverseChanges,\n };\n\n const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;\n lines.push(generateFieldModification(collectionName, reverseMod, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field additions (remove them)\n if (modification.fieldsToAdd.length > 0) {\n lines.push(` // Remove added fields from ${collectionName}`);\n for (const field of modification.fieldsToAdd) {\n const varName = `collection_${collectionName}_revert_add_${field.name}`;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n }\n }\n\n // 3. Delete created collections\n if (diff.collectionsToCreate.length > 0) {\n lines.push(` // Delete created collections`);\n for (let i = 0; i < diff.collectionsToCreate.length; i++) {\n const collection = diff.collectionsToCreate[i];\n const varName = `collection_${collection.name}_rollback`;\n lines.push(generateCollectionDeletion(collection.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // If no changes, add a comment\n if (lines.length === 2) {\n lines.push(` // No changes to revert`);\n lines.push(``);\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n","import type { CollectionSchema } from \"../types\";\n\n/**\n * Sorts collections based on their relationship dependencies.\n * Collections that are referenced by others should be created first.\n *\n * @param collections - List of collections to sort\n * @returns Sorted list of collections\n */\nexport function sortCollectionsByDependency(collections: CollectionSchema[]): CollectionSchema[] {\n // Map collection names to schema objects for easy lookup\n const collectionMap = new Map<string, CollectionSchema>();\n collections.forEach((col) => collectionMap.set(col.name, col));\n\n // Build dependency graph\n // Adjacency list: dependency -> [dependents]\n // In this graph, an edge A -> B means A must be created before B.\n const adjList = new Map<string, string[]>();\n // In-degree: number of dependencies a collection has that are also in the list\n const inDegree = new Map<string, number>();\n\n // Initialize graph\n collections.forEach((col) => {\n adjList.set(col.name, []);\n inDegree.set(col.name, 0);\n });\n\n // Populate graph\n collections.forEach((col) => {\n col.fields.forEach((field) => {\n // Check if field is a relation\n if (field.relation) {\n const targetName = field.relation.collection;\n\n // We only care about dependencies on collections that are currently being created.\n // If the target collection is not in the list, it's assumed to already exist.\n if (collectionMap.has(targetName)) {\n // If self-reference, ignore for topological sort (creation order doesn't matter strictly,\n // but usually we want to avoid cycles if possible. Self-ref is cycle size 1).\n if (targetName === col.name) {\n return;\n }\n\n // Edge: Target -> Collection (Target comes before Collection)\n adjList.get(targetName)?.push(col.name);\n inDegree.set(col.name, (inDegree.get(col.name) || 0) + 1);\n }\n }\n });\n });\n\n // Kahn's algorithm for topological sort\n const queue: string[] = [];\n const sortedResult: CollectionSchema[] = [];\n\n // Add all nodes with in-degree 0 to queue\n inDegree.forEach((degree, name) => {\n if (degree === 0) {\n queue.push(name);\n }\n });\n\n // Process queue\n while (queue.length > 0) {\n const currentName = queue.shift()!;\n const currentCollection = collectionMap.get(currentName);\n\n if (currentCollection) {\n sortedResult.push(currentCollection);\n }\n\n const neighbors = adjList.get(currentName) || [];\n for (const neighbor of neighbors) {\n inDegree.set(neighbor, (inDegree.get(neighbor) || 0) - 1);\n if (inDegree.get(neighbor) === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Check for cycles\n if (sortedResult.length !== collections.length) {\n const remainingCount = collections.length - sortedResult.length;\n console.warn(\n `Warning: Circular dependencies detected involving ${remainingCount} collections. ` +\n `Migrations may fail if strict foreign key checks are enabled. ` +\n `Check your schema for circular relations.`\n );\n\n // Append remaining collections (those involved in cycles)\n // We can't determine a perfect order, so we append them in their original order\n // (excluding those already sorted)\n const sortedNames = new Set(sortedResult.map((c) => c.name));\n collections.forEach((col) => {\n if (!sortedNames.has(col.name)) {\n sortedResult.push(col);\n }\n });\n }\n\n return sortedResult;\n}\n","import type { CollectionOperation, SchemaDiff } from \"../types\";\nimport { sortCollectionsByDependency } from \"../utils\";\nimport { type MigrationGeneratorConfig } from \"./config\";\nimport { generateTimestamp } from \"./utils\";\n\n/**\n * Splits a SchemaDiff into individual collection operations\n * Each operation will generate a separate migration file\n *\n * @param diff - Schema diff containing all changes\n * @param baseTimestamp - Base timestamp for the first operation\n * @returns Array of collection operations\n */\nexport function splitDiffByCollection(diff: SchemaDiff, baseTimestamp: string): CollectionOperation[] {\n const operations: CollectionOperation[] = [];\n let currentTimestamp = parseInt(baseTimestamp, 10);\n\n // Split collectionsToCreate into individual operations\n // Sort collections by dependency to ensure collections are created in the correct order\n const sortedCollections = sortCollectionsByDependency(diff.collectionsToCreate);\n for (const collection of sortedCollections) {\n operations.push({\n type: \"create\",\n collection: collection,\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n // Split collectionsToModify into individual operations\n for (const modification of diff.collectionsToModify) {\n operations.push({\n type: \"modify\",\n collection: modification.collection,\n modifications: modification,\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n // Split collectionsToDelete into individual operations\n for (const collection of diff.collectionsToDelete) {\n operations.push({\n type: \"delete\",\n collection: collection, // Handle both object and string\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n return operations;\n}\n\n/**\n * Generates migration filename for a collection operation\n * Format: {timestamp}_{operation}_{collection_name}.js\n *\n * @param operation - Collection operation\n * @returns Migration filename\n */\nexport function generateCollectionMigrationFilename(operation: CollectionOperation): string {\n const timestamp = operation.timestamp;\n const operationType = operation.type === \"modify\" ? \"updated\" : operation.type === \"create\" ? \"created\" : \"deleted\";\n\n // Get collection name\n let collectionName: string;\n if (typeof operation.collection === \"string\") {\n collectionName = operation.collection;\n } else {\n collectionName = operation.collection.name;\n }\n\n // Sanitize collection name for filename (replace spaces and special chars with underscores)\n const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\n return `${timestamp}_${operationType}_${sanitizedName}.js`;\n}\n\n/**\n * Generates a human-readable description from the diff\n * Creates a concise summary of the main changes\n *\n * @param diff - Schema diff containing all changes\n * @returns Description string for filename\n */\nexport function generateMigrationDescription(diff: SchemaDiff): string {\n const parts: string[] = [];\n\n // Summarize collection changes\n if (diff.collectionsToCreate.length > 0) {\n if (diff.collectionsToCreate.length === 1) {\n parts.push(`created_${diff.collectionsToCreate[0].name}`);\n } else {\n parts.push(`created_${diff.collectionsToCreate.length}_collections`);\n }\n }\n\n if (diff.collectionsToDelete.length > 0) {\n if (diff.collectionsToDelete.length === 1) {\n parts.push(`deleted_${diff.collectionsToDelete[0].name}`);\n } else {\n parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);\n }\n }\n\n if (diff.collectionsToModify.length > 0) {\n if (diff.collectionsToModify.length === 1) {\n parts.push(`updated_${diff.collectionsToModify[0].collection}`);\n } else {\n parts.push(`updated_${diff.collectionsToModify.length}_collections`);\n }\n }\n\n // Default description if no changes\n if (parts.length === 0) {\n return \"no_changes\";\n }\n\n // Join parts with underscores and limit length\n let description = parts.join(\"_\");\n\n // Truncate if too long (keep under 100 chars for filename)\n if (description.length > 80) {\n description = description.substring(0, 77) + \"...\";\n }\n\n return description;\n}\n\n/**\n * Generates the migration filename\n * Format: {timestamp}_{description}.js\n *\n * @param diff - Schema diff containing all changes\n * @param config - Optional configuration\n * @returns Migration filename\n */\nexport function generateMigrationFilename(diff: SchemaDiff, config?: MigrationGeneratorConfig): string {\n const timestamp = generateTimestamp(config);\n const description = generateMigrationDescription(diff);\n\n return `${timestamp}_${description}.js`;\n}\n","/**\n * Migration Generator component\n * Creates PocketBase migration files based on detected differences\n *\n * This module provides a standalone, configurable migration generator that can be used\n * by consumer projects to generate PocketBase-compatible migration files.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, MigrationGenerationError } from \"../errors\";\nimport type { SchemaDiff } from \"../types\";\nimport { mergeConfig, type MigrationGeneratorConfig } from \"./config\";\nimport { createMigrationFileStructure, resolveMigrationDir, writeMigrationFile } from \"./file-writer\";\nimport { generateDownMigration, generateOperationDownMigration, generateOperationUpMigration, generateUpMigration } from \"./migrator\";\nimport { generateCollectionMigrationFilename, generateMigrationFilename, splitDiffByCollection } from \"./operations\";\nimport { generateTimestamp } from \"./utils\";\n\n// Export everything from submodules\nexport * from \"./collections\";\nexport * from \"./config\";\nexport * from \"./fields\";\nexport * from \"./file-writer\";\nexport * from \"./indexes\";\nexport * from \"./migrator\";\nexport * from \"./operations\";\nexport * from \"./rules\";\nexport * from \"./utils\";\n\n/**\n * Main generation function\n * Generates migration files from schema diff (one file per collection operation)\n *\n * @param diff - Schema diff containing all changes\n * @param config - Migration generator configuration\n * @returns Array of paths to the generated migration files\n */\nexport function generate(diff: SchemaDiff, config: MigrationGeneratorConfig | string): string[] {\n // Support legacy string-only parameter (migration directory)\n const normalizedConfig: MigrationGeneratorConfig = typeof config === \"string\" ? { migrationDir: config } : config;\n\n try {\n const migrationDir = resolveMigrationDir(normalizedConfig);\n\n // Check if there are any changes\n const hasChanges =\n diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;\n\n // If no changes, return empty array\n if (!hasChanges) {\n return [];\n }\n\n // Build collection ID map from collections being created\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Also include deleted collections that might have IDs (for rollback)\n for (const collection of diff.collectionsToDelete) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // Generate base timestamp\n const baseTimestamp = generateTimestamp(normalizedConfig);\n\n // Split diff into individual collection operations\n const operations = splitDiffByCollection(diff, baseTimestamp);\n\n // Generate migration file for each operation\n const filePaths: string[] = [];\n\n // Read existing files for duplicate check\n let existingFiles: string[] = [];\n if (!normalizedConfig.force && fs.existsSync(migrationDir)) {\n existingFiles = fs\n .readdirSync(migrationDir)\n .filter((f) => f.endsWith(\".js\") || f.endsWith(\".ts\"))\n .map((f) => fs.readFileSync(path.join(migrationDir, f), \"utf-8\"));\n }\n\n for (const operation of operations) {\n // Generate up and down migration code for this operation\n const upCode = generateOperationUpMigration(operation, collectionIdMap);\n const downCode = generateOperationDownMigration(operation, collectionIdMap);\n\n // Create migration file structure\n const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);\n\n // Check for duplicates\n if (!normalizedConfig.force && existingFiles.some((existingContent) => existingContent === content)) {\n console.warn(\n `Duplicate migration detected for ${operation.type} ${\n typeof operation.collection === \"string\" ? operation.collection : operation.collection.name\n }. Skipping...`\n );\n continue;\n }\n\n // Generate filename for this operation\n const filename = generateCollectionMigrationFilename(operation);\n\n // Write migration file\n const filePath = writeMigrationFile(migrationDir, filename, content);\n\n filePaths.push(filePath);\n }\n\n return filePaths;\n } catch (error) {\n // If it's already a MigrationGenerationError or FileSystemError, re-throw it\n if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {\n throw error;\n }\n\n // Otherwise, wrap it in a MigrationGenerationError\n throw new MigrationGenerationError(\n `Failed to generate migration: ${error instanceof Error ? error.message : String(error)}`,\n normalizedConfig.migrationDir,\n error as Error\n );\n }\n}\n\n/**\n * MigrationGenerator class for object-oriented usage\n * Provides a stateful interface for migration generation\n */\nexport class MigrationGenerator {\n private config: Required<MigrationGeneratorConfig>;\n\n constructor(config: MigrationGeneratorConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Generates migration files from a schema diff\n * Returns array of file paths (one per collection operation)\n */\n generate(diff: SchemaDiff): string[] {\n return generate(diff, this.config);\n }\n\n /**\n * Generates the up migration code without writing to file\n */\n generateUpMigration(diff: SchemaDiff): string {\n return generateUpMigration(diff);\n }\n\n /**\n * Generates the down migration code without writing to file\n */\n generateDownMigration(diff: SchemaDiff): string {\n return generateDownMigration(diff);\n }\n\n /**\n * Generates a migration filename\n */\n generateMigrationFilename(diff: SchemaDiff): string {\n return generateMigrationFilename(diff, this.config);\n }\n}\n","/**\n * Validation and warning utilities for migration tool\n * Detects destructive changes and provides warnings\n */\n\nimport type { SchemaDiff } from \"./types\";\n\n/**\n * Types of destructive changes\n */\nexport enum DestructiveChangeType {\n COLLECTION_DELETION = \"collection_deletion\",\n FIELD_DELETION = \"field_deletion\",\n FIELD_TYPE_CHANGE = \"field_type_change\",\n FIELD_REQUIRED_CHANGE = \"field_required_change\",\n}\n\n/**\n * Represents a destructive change with details\n */\nexport interface DestructiveChange {\n type: DestructiveChangeType;\n description: string;\n collection: string;\n field?: string;\n details?: {\n oldValue?: any;\n newValue?: any;\n };\n severity: \"high\" | \"medium\" | \"low\";\n warning: string;\n}\n\n/**\n * Detects collection deletions\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for collection deletions\n */\nfunction detectCollectionDeletions(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const collection of diff.collectionsToDelete) {\n // View collections store no data, so dropping one is not destructive\n if (collection.type === \"view\") {\n continue;\n }\n\n changes.push({\n type: DestructiveChangeType.COLLECTION_DELETION,\n description: `Delete collection: ${collection.name}`,\n collection: collection.name,\n severity: \"high\",\n warning: `All data in the \"${collection.name}\" collection will be permanently deleted.`,\n });\n }\n\n return changes;\n}\n\n/**\n * Detects field deletions\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for field deletions\n */\nfunction detectFieldDeletions(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const field of modification.fieldsToRemove) {\n changes.push({\n type: DestructiveChangeType.FIELD_DELETION,\n description: `Delete field: ${modification.collection}.${field.name}`,\n collection: modification.collection,\n field: field.name,\n severity: \"high\",\n warning: `All data in the \"${field.name}\" field of \"${modification.collection}\" will be permanently deleted.`,\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Detects field type changes\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for field type changes\n */\nfunction detectFieldTypeChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const fieldMod of modification.fieldsToModify) {\n const typeChange = fieldMod.changes.find((c) => c.property === \"type\");\n\n if (typeChange) {\n changes.push({\n type: DestructiveChangeType.FIELD_TYPE_CHANGE,\n description: `Change field type: ${modification.collection}.${fieldMod.fieldName}`,\n collection: modification.collection,\n field: fieldMod.fieldName,\n details: {\n oldValue: typeChange.oldValue,\n newValue: typeChange.newValue,\n },\n severity: \"high\",\n warning: `Changing field type from \"${typeChange.oldValue}\" to \"${typeChange.newValue}\" may cause data loss or conversion errors.`,\n });\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Detects field required changes (making optional field required)\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for required field changes\n */\nfunction detectFieldRequiredChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const fieldMod of modification.fieldsToModify) {\n const requiredChange = fieldMod.changes.find(\n (c) => c.property === \"required\" && c.newValue === true && c.oldValue === false\n );\n\n if (requiredChange) {\n changes.push({\n type: DestructiveChangeType.FIELD_REQUIRED_CHANGE,\n description: `Make field required: ${modification.collection}.${fieldMod.fieldName}`,\n collection: modification.collection,\n field: fieldMod.fieldName,\n details: {\n oldValue: false,\n newValue: true,\n },\n severity: \"medium\",\n warning: `Making \"${fieldMod.fieldName}\" required may cause issues with existing records that have null/empty values.`,\n });\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Detects all destructive changes in a schema diff\n *\n * @param diff - Schema diff to analyze\n * @returns Array of all destructive changes\n */\nexport function detectDestructiveChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n // Detect collection deletions\n changes.push(...detectCollectionDeletions(diff));\n\n // Detect field deletions\n changes.push(...detectFieldDeletions(diff));\n\n // Detect field type changes\n changes.push(...detectFieldTypeChanges(diff));\n\n // Detect field required changes\n changes.push(...detectFieldRequiredChanges(diff));\n\n return changes;\n}\n\n/**\n * Checks if a diff contains any destructive changes\n *\n * @param diff - Schema diff to check\n * @returns True if there are destructive changes\n */\nexport function hasDestructiveChanges(diff: SchemaDiff): boolean {\n const changes = detectDestructiveChanges(diff);\n return changes.length > 0;\n}\n\n/**\n * Formats destructive changes for display\n * Groups changes by severity and provides clear warnings\n *\n * @param changes - Array of destructive changes\n * @returns Formatted string for display\n */\nexport function formatDestructiveChanges(changes: DestructiveChange[]): string {\n if (changes.length === 0) {\n return \"No destructive changes detected.\";\n }\n\n const lines: string[] = [];\n\n // Group by severity\n const highSeverity = changes.filter((c) => c.severity === \"high\");\n const mediumSeverity = changes.filter((c) => c.severity === \"medium\");\n const lowSeverity = changes.filter((c) => c.severity === \"low\");\n\n // Display high severity changes\n if (highSeverity.length > 0) {\n lines.push(\"🔴 HIGH SEVERITY CHANGES (Data Loss Risk):\");\n lines.push(\"\");\n for (const change of highSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ⚠️ ${change.warning}`);\n if (change.details) {\n if (change.details.oldValue !== undefined && change.details.newValue !== undefined) {\n lines.push(` Old: ${change.details.oldValue} → New: ${change.details.newValue}`);\n }\n }\n lines.push(\"\");\n }\n }\n\n // Display medium severity changes\n if (mediumSeverity.length > 0) {\n lines.push(\"🟡 MEDIUM SEVERITY CHANGES (Potential Issues):\");\n lines.push(\"\");\n for (const change of mediumSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ⚠️ ${change.warning}`);\n if (change.details) {\n if (change.details.oldValue !== undefined && change.details.newValue !== undefined) {\n lines.push(` Old: ${change.details.oldValue} → New: ${change.details.newValue}`);\n }\n }\n lines.push(\"\");\n }\n }\n\n // Display low severity changes\n if (lowSeverity.length > 0) {\n lines.push(\"🟢 LOW SEVERITY CHANGES:\");\n lines.push(\"\");\n for (const change of lowSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ℹ️ ${change.warning}`);\n lines.push(\"\");\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates a summary of destructive changes\n *\n * @param changes - Array of destructive changes\n * @returns Summary object with counts by severity\n */\nexport function summarizeDestructiveChanges(changes: DestructiveChange[]): {\n total: number;\n high: number;\n medium: number;\n low: number;\n} {\n return {\n total: changes.length,\n high: changes.filter((c) => c.severity === \"high\").length,\n medium: changes.filter((c) => c.severity === \"medium\").length,\n low: changes.filter((c) => c.severity === \"low\").length,\n };\n}\n\n/**\n * Checks if force flag is required for the given changes\n * Force is required if there are any high or medium severity changes\n *\n * @param changes - Array of destructive changes\n * @returns True if force flag should be required\n */\nexport function requiresForceFlag(changes: DestructiveChange[]): boolean {\n return changes.some((c) => c.severity === \"high\" || c.severity === \"medium\");\n}\n","/**\n * Configuration loader for migration tool\n * Handles loading and merging configuration from various sources\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { ConfigurationError } from \"../../migration/errors.js\";\n\n/**\n * Migration tool configuration\n */\nexport interface MigrationConfig {\n schema: {\n directory: string;\n exclude: string[];\n };\n migrations: {\n directory: string;\n format: string;\n };\n diff: {\n warnOnDelete: boolean;\n requireForceForDestructive: boolean;\n };\n typeGen: {\n outPath: string;\n };\n}\n\n/**\n * Partial configuration for merging\n */\nexport type PartialMigrationConfig = {\n schema?: Partial<MigrationConfig[\"schema\"]>;\n migrations?: Partial<MigrationConfig[\"migrations\"]>;\n diff?: Partial<MigrationConfig[\"diff\"]>;\n typeGen?: Partial<MigrationConfig[\"typeGen\"]>;\n};\n\n/**\n * Configuration file names to search for\n */\nconst CONFIG_FILE_NAMES = [\n \"pocketbase-migrate.config.js\",\n \"pocketbase-migrate.config.mjs\",\n \"pocketbase-migrate.config.json\",\n \"migrate.config.js\",\n \"migrate.config.mjs\",\n \"migrate.config.json\",\n];\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: MigrationConfig = {\n schema: {\n directory: \"src/schema\",\n exclude: [\"base.ts\", \"index.ts\", \"permissions.ts\", \"permission-templates.ts\"],\n },\n migrations: {\n directory: \"pocketbase/pb_migrations\",\n format: \"timestamp_description\",\n },\n diff: {\n warnOnDelete: true,\n requireForceForDestructive: true,\n },\n typeGen: {\n outPath: \"pocketbase-types.ts\",\n },\n};\n\n/**\n * Finds a configuration file in the given directory\n */\nfunction findConfigFile(directory: string): string | null {\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = path.join(directory, fileName);\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n }\n return null;\n}\n\n/**\n * Loads configuration from a JSON file\n */\nfunction loadJsonConfig(configPath: string): PartialMigrationConfig {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n return JSON.parse(content);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConfigurationError(\"Invalid JSON syntax in configuration file\", configPath, undefined, error);\n }\n throw new ConfigurationError(\n \"Failed to read configuration file\",\n configPath,\n undefined,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Loads configuration from a JavaScript file\n */\nasync function loadJsConfig(configPath: string): Promise<PartialMigrationConfig> {\n try {\n const fileUrl = `file://${configPath}`;\n const module = await import(fileUrl);\n return module.default || module;\n } catch (error) {\n throw new ConfigurationError(\n \"Failed to load JavaScript configuration file\",\n configPath,\n undefined,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Loads configuration from file if it exists\n */\nasync function loadConfigFile(configPath: string): Promise<PartialMigrationConfig | null> {\n if (!fs.existsSync(configPath)) {\n return null;\n }\n\n const ext = path.extname(configPath).toLowerCase();\n\n if (ext === \".json\") {\n return loadJsonConfig(configPath);\n } else if (ext === \".js\" || ext === \".mjs\") {\n return loadJsConfig(configPath);\n } else {\n throw new ConfigurationError(`Unsupported configuration file format: ${ext}`, configPath, undefined);\n }\n}\n\n/**\n * Merges configuration objects with deep merge\n */\nfunction mergeConfig(base: MigrationConfig, override: PartialMigrationConfig): MigrationConfig {\n return {\n schema: { ...base.schema, ...override.schema },\n migrations: { ...base.migrations, ...override.migrations },\n diff: { ...base.diff, ...override.diff },\n typeGen: { ...base.typeGen, ...override.typeGen },\n };\n}\n\n/**\n * Loads configuration from environment variables\n */\nfunction loadConfigFromEnv(): PartialMigrationConfig {\n const config: PartialMigrationConfig = {};\n\n if (process.env.MIGRATION_SCHEMA_DIR) {\n config.schema = { directory: process.env.MIGRATION_SCHEMA_DIR };\n }\n\n if (process.env.MIGRATION_SCHEMA_EXCLUDE) {\n config.schema = {\n ...config.schema,\n exclude: process.env.MIGRATION_SCHEMA_EXCLUDE.split(\",\").map((s) => s.trim()),\n };\n }\n\n if (process.env.MIGRATION_OUTPUT_DIR) {\n config.migrations = { directory: process.env.MIGRATION_OUTPUT_DIR };\n }\n\n if (process.env.MIGRATION_REQUIRE_FORCE !== undefined) {\n config.diff = { requireForceForDestructive: process.env.MIGRATION_REQUIRE_FORCE === \"true\" };\n }\n\n return config;\n}\n\n/**\n * Loads configuration from CLI arguments\n */\nexport function loadConfigFromArgs(options: any): PartialMigrationConfig {\n const config: PartialMigrationConfig = {};\n\n if (options.output) {\n config.migrations = { directory: options.output };\n }\n\n if (options.schemaDir) {\n config.schema = { directory: options.schemaDir };\n }\n\n return config;\n}\n\n/**\n * Validates configuration values\n */\nfunction validateConfig(config: MigrationConfig, configPath?: string): void {\n const invalidFields: string[] = [];\n\n if (typeof config.schema.directory !== \"string\" || config.schema.directory.trim() === \"\") {\n invalidFields.push(\"schema.directory (must be a non-empty string)\");\n }\n\n if (!Array.isArray(config.schema.exclude)) {\n invalidFields.push(\"schema.exclude (must be an array of strings)\");\n }\n\n if (typeof config.migrations.directory !== \"string\" || config.migrations.directory.trim() === \"\") {\n invalidFields.push(\"migrations.directory (must be a non-empty string)\");\n }\n\n if (typeof config.diff.warnOnDelete !== \"boolean\") {\n invalidFields.push(\"diff.warnOnDelete (must be a boolean)\");\n }\n\n if (typeof config.diff.requireForceForDestructive !== \"boolean\") {\n invalidFields.push(\"diff.requireForceForDestructive (must be a boolean)\");\n }\n\n if (typeof config.typeGen.outPath !== \"string\" || config.typeGen.outPath.trim() === \"\") {\n invalidFields.push(\"typeGen.outPath (must be a non-empty string)\");\n }\n\n if (invalidFields.length > 0) {\n throw new ConfigurationError(\"Invalid configuration values\", configPath, invalidFields);\n }\n\n // Validate schema directory exists - try multiple locations\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.schema.directory),\n path.resolve(cwd, \"shared\", config.schema.directory),\n ];\n\n const schemaDir = possiblePaths.find((p) => fs.existsSync(p));\n\n if (!schemaDir) {\n throw new ConfigurationError(`Schema directory not found. Tried: ${possiblePaths.join(\", \")}`, configPath, [\n \"schema.directory\",\n ]);\n }\n}\n\n/**\n * Loads and merges configuration from all sources\n * Priority: CLI args > Environment variables > Config file > Defaults\n */\nexport async function loadConfig(options: any = {}): Promise<MigrationConfig> {\n let config: MigrationConfig = { ...DEFAULT_CONFIG };\n let configFilePath: string | undefined;\n\n const cwd = process.cwd();\n\n // Check for explicit config path from CLI\n if (options.config) {\n const explicitPath = path.resolve(cwd, options.config);\n if (!fs.existsSync(explicitPath)) {\n throw new ConfigurationError(`Configuration file not found: ${explicitPath}`, explicitPath);\n }\n configFilePath = explicitPath;\n } else {\n // Search for config file in current directory and shared directory\n const searchDirs = [cwd, path.join(cwd, \"shared\")];\n\n for (const dir of searchDirs) {\n if (fs.existsSync(dir)) {\n const found = findConfigFile(dir);\n if (found) {\n configFilePath = found;\n break;\n }\n }\n }\n }\n\n // Load config file if found\n if (configFilePath) {\n const fileConfig = await loadConfigFile(configFilePath);\n if (fileConfig) {\n config = mergeConfig(config, fileConfig);\n }\n }\n\n // Merge environment variables\n const envConfig = loadConfigFromEnv();\n if (Object.keys(envConfig).length > 0) {\n config = mergeConfig(config, envConfig);\n }\n\n // Merge CLI arguments (highest priority)\n const argsConfig = loadConfigFromArgs(options);\n if (Object.keys(argsConfig).length > 0) {\n config = mergeConfig(config, argsConfig);\n }\n\n // Validate final configuration\n validateConfig(config, configFilePath);\n\n return config;\n}\n\n/**\n * Gets the absolute path to the schema directory\n */\nexport function getSchemaDirectory(config: MigrationConfig): string {\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.schema.directory),\n path.resolve(cwd, \"shared\", config.schema.directory),\n ];\n\n return possiblePaths.find((p) => fs.existsSync(p)) || possiblePaths[0];\n}\n\n/**\n * Gets the absolute path to the migrations directory\n */\nexport function getMigrationsDirectory(config: MigrationConfig): string {\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.migrations.directory),\n path.resolve(cwd, \"shared\", config.migrations.directory),\n ];\n\n return possiblePaths.find((p) => fs.existsSync(p)) || possiblePaths[0];\n}\n\n/**\n * Gets the default configuration\n */\nexport function getDefaultConfig(): MigrationConfig {\n return { ...DEFAULT_CONFIG };\n}\n\n/**\n * Creates a sample configuration file content\n */\nexport function getSampleConfig(format: \"json\" | \"js\"): string {\n if (format === \"json\") {\n return JSON.stringify(DEFAULT_CONFIG, null, 2);\n }\n\n return `/**\n * PocketBase Zod Migration Configuration\n * @type {import('pocketbase-zod-schema/cli').MigrationConfig}\n */\nexport default {\n schema: {\n directory: \"/src/schema\",\n exclude: [\"base.ts\", \"index.ts\", \"permissions.ts\", \"permission-templates.ts\"],\n },\n migrations: {\n directory: \"pocketbase/pb_migrations\",\n format: \"timestamp_description\",\n },\n diff: {\n warnOnDelete: true,\n requireForceForDestructive: true,\n },\n typeGen: {\n outPath: \"pocketbase-types.ts\",\n },\n};\n`;\n}\n","/**\n * Logging utilities for CLI output\n * Provides colored console output and formatting helpers\n */\n\nimport chalk from \"chalk\";\nimport ora, { type Ora } from \"ora\";\nimport type { FieldChange, SchemaDiff } from \"../../migration/types.js\";\n\n/**\n * Verbosity levels for logging\n */\nexport type VerbosityLevel = \"quiet\" | \"normal\" | \"verbose\";\n\n/**\n * Current verbosity level\n */\nlet currentVerbosity: VerbosityLevel = \"normal\";\n\n/**\n * Sets the verbosity level for logging\n *\n * @param level - Verbosity level to set\n */\nexport function setVerbosity(level: VerbosityLevel): void {\n currentVerbosity = level;\n}\n\n/**\n * Gets the current verbosity level\n *\n * @returns Current verbosity level\n */\nexport function getVerbosity(): VerbosityLevel {\n return currentVerbosity;\n}\n\n/**\n * Checks if output should be shown based on verbosity\n *\n * @param requiredLevel - Minimum verbosity level required\n * @returns True if output should be shown\n */\nfunction shouldLog(requiredLevel: VerbosityLevel): boolean {\n const levels: VerbosityLevel[] = [\"quiet\", \"normal\", \"verbose\"];\n const currentIndex = levels.indexOf(currentVerbosity);\n const requiredIndex = levels.indexOf(requiredLevel);\n return currentIndex >= requiredIndex;\n}\n\n/**\n * Creates a spinner for long-running operations\n *\n * @param text - Initial spinner text\n * @returns Ora spinner instance\n */\nexport function createSpinner(text: string): Ora {\n // In quiet mode, create a silent spinner\n if (currentVerbosity === \"quiet\") {\n return ora({ text, isSilent: true });\n }\n return ora(text);\n}\n\n/**\n * Logs a success message in green\n *\n * @param message - Message to log\n */\nexport function logSuccess(message: string): void {\n if (shouldLog(\"normal\")) {\n console.log(chalk.green(\"✓\"), message);\n }\n}\n\n/**\n * Logs an error message in red\n * Always shown regardless of verbosity level\n *\n * @param message - Message to log\n */\nexport function logError(message: string): void {\n console.error(chalk.red(\"✗\"), message);\n}\n\n/**\n * Logs a warning message in yellow\n *\n * @param message - Message to log\n */\nexport function logWarning(message: string): void {\n if (shouldLog(\"normal\")) {\n console.warn(chalk.yellow(\"⚠\"), message);\n }\n}\n\n/**\n * Logs an info message in blue\n *\n * @param message - Message to log\n */\nexport function logInfo(message: string): void {\n if (shouldLog(\"normal\")) {\n console.log(chalk.blue(\"ℹ\"), message);\n }\n}\n\n/**\n * Logs a debug message in gray\n * Only shown in verbose mode\n *\n * @param message - Message to log\n */\nexport function logDebug(message: string): void {\n if (shouldLog(\"verbose\")) {\n console.log(chalk.gray(\"⚙\"), chalk.gray(message));\n }\n}\n\n/**\n * Logs a section header\n *\n * @param title - Section title\n */\nexport function logSection(title: string): void {\n if (shouldLog(\"normal\")) {\n console.log();\n console.log(chalk.bold.cyan(title));\n console.log(chalk.cyan(\"─\".repeat(title.length)));\n }\n}\n\n/**\n * Formats a field change for display\n *\n * @param change - Field change object\n * @returns Formatted string\n */\nfunction formatFieldChange(change: FieldChange): string {\n const oldValue = change.oldValue === null ? \"null\" : JSON.stringify(change.oldValue);\n const newValue = change.newValue === null ? \"null\" : JSON.stringify(change.newValue);\n\n return `${change.property}: ${chalk.red(oldValue)} → ${chalk.green(newValue)}`;\n}\n\n/**\n * Formats a change summary for display\n * Creates a formatted, colored summary of detected changes\n *\n * @param diff - Schema diff containing all changes\n * @returns Formatted summary string\n */\nexport function formatChangeSummary(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Count total changes\n const totalCollectionsToCreate = diff.collectionsToCreate.length;\n const totalCollectionsToDelete = diff.collectionsToDelete.length;\n const totalCollectionsToModify = diff.collectionsToModify.length;\n\n const totalChanges = totalCollectionsToCreate + totalCollectionsToDelete + totalCollectionsToModify;\n\n if (totalChanges === 0) {\n return chalk.gray(\"No changes detected\");\n }\n\n lines.push(chalk.bold(`Found ${totalChanges} collection change(s):`));\n lines.push(\"\");\n\n // New collections\n if (totalCollectionsToCreate > 0) {\n lines.push(chalk.green.bold(`✓ ${totalCollectionsToCreate} collection(s) to create:`));\n for (const collection of diff.collectionsToCreate) {\n lines.push(chalk.green(` + ${collection.name} (${collection.type})`));\n if (collection.type === \"view\") {\n // A view's fields are derived by PocketBase from its SQL query\n lines.push(chalk.gray(` fields derived from the view query`));\n } else {\n lines.push(chalk.gray(` ${collection.fields.length} field(s)`));\n }\n }\n lines.push(\"\");\n }\n\n // Deleted collections\n if (totalCollectionsToDelete > 0) {\n lines.push(chalk.red.bold(`✗ ${totalCollectionsToDelete} collection(s) to delete:`));\n for (const collection of diff.collectionsToDelete) {\n lines.push(chalk.red(` - ${collection.name}`));\n }\n lines.push(\"\");\n }\n\n // Modified collections\n if (totalCollectionsToModify > 0) {\n lines.push(chalk.yellow.bold(`⚡ ${totalCollectionsToModify} collection(s) to modify:`));\n\n for (const modification of diff.collectionsToModify) {\n lines.push(chalk.yellow(` ~ ${modification.collection}`));\n\n // Fields to add\n if (modification.fieldsToAdd.length > 0) {\n lines.push(chalk.green(` + ${modification.fieldsToAdd.length} field(s) to add:`));\n for (const field of modification.fieldsToAdd) {\n lines.push(chalk.green(` + ${field.name} (${field.type})`));\n }\n }\n\n // Fields to remove\n if (modification.fieldsToRemove.length > 0) {\n lines.push(chalk.red(` - ${modification.fieldsToRemove.length} field(s) to remove:`));\n for (const field of modification.fieldsToRemove) {\n lines.push(chalk.red(` - ${field.name}`));\n }\n }\n\n // Fields to modify\n if (modification.fieldsToModify.length > 0) {\n lines.push(chalk.yellow(` ~ ${modification.fieldsToModify.length} field(s) to modify:`));\n for (const fieldMod of modification.fieldsToModify) {\n lines.push(chalk.yellow(` ~ ${fieldMod.fieldName}`));\n for (const change of fieldMod.changes) {\n lines.push(chalk.gray(` ${formatFieldChange(change)}`));\n }\n }\n }\n\n // Indexes\n if (modification.indexesToAdd.length > 0) {\n lines.push(chalk.green(` + ${modification.indexesToAdd.length} index(es) to add`));\n }\n\n if (modification.indexesToRemove.length > 0) {\n lines.push(chalk.red(` - ${modification.indexesToRemove.length} index(es) to remove`));\n }\n\n // Rules\n if (modification.rulesToUpdate.length > 0) {\n lines.push(chalk.yellow(` ~ ${modification.rulesToUpdate.length} rule(s) to update`));\n }\n\n // View query\n if (modification.viewQueryUpdate) {\n lines.push(chalk.yellow(` ~ view query to update`));\n }\n\n lines.push(\"\");\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Displays a progress indicator for a long operation\n *\n * @param message - Progress message\n * @param operation - Async operation to perform\n * @returns Result of the operation\n */\nexport async function withProgress<T>(message: string, operation: () => Promise<T>): Promise<T> {\n const spinner = createSpinner(message).start();\n\n try {\n const result = await operation();\n spinner.succeed();\n return result;\n } catch (error) {\n spinner.fail();\n throw error;\n }\n}\n\n/**\n * Logs a step in a multi-step process\n *\n * @param step - Current step number\n * @param total - Total number of steps\n * @param message - Step description\n */\nexport function logStep(step: number, total: number, message: string): void {\n if (shouldLog(\"normal\")) {\n const progress = chalk.gray(`[${step}/${total}]`);\n console.log(progress, message);\n }\n}\n\n/**\n * Logs a list of items with bullet points\n *\n * @param items - Items to list\n * @param indent - Indentation level (default: 2)\n */\nexport function logList(items: string[], indent: number = 2): void {\n if (shouldLog(\"normal\")) {\n const padding = \" \".repeat(indent);\n for (const item of items) {\n console.log(`${padding}• ${item}`);\n }\n }\n}\n\n/**\n * Logs a key-value pair\n *\n * @param key - Key name\n * @param value - Value to display\n * @param indent - Indentation level (default: 2)\n */\nexport function logKeyValue(key: string, value: string, indent: number = 2): void {\n if (shouldLog(\"normal\")) {\n const padding = \" \".repeat(indent);\n console.log(`${padding}${chalk.gray(key + \":\")} ${value}`);\n }\n}\n\n/**\n * Logs a table of data\n *\n * @param headers - Column headers\n * @param rows - Data rows\n */\nexport function logTable(headers: string[], rows: string[][]): void {\n if (!shouldLog(\"normal\")) return;\n\n // Calculate column widths\n const widths = headers.map((h, i) => {\n const maxRowWidth = Math.max(...rows.map((r) => (r[i] || \"\").length));\n return Math.max(h.length, maxRowWidth);\n });\n\n // Print header\n const headerLine = headers.map((h, i) => h.padEnd(widths[i])).join(\" \");\n console.log(chalk.bold(headerLine));\n console.log(chalk.gray(\"─\".repeat(headerLine.length)));\n\n // Print rows\n for (const row of rows) {\n const rowLine = row.map((cell, i) => (cell || \"\").padEnd(widths[i])).join(\" \");\n console.log(rowLine);\n }\n}\n\n/**\n * Logs a box with a title and content\n *\n * @param title - Box title\n * @param content - Box content (array of lines)\n */\nexport function logBox(title: string, content: string[]): void {\n if (!shouldLog(\"normal\")) return;\n\n const maxWidth = Math.max(title.length, ...content.map((c) => c.length));\n const border = \"─\".repeat(maxWidth + 2);\n\n console.log();\n console.log(chalk.cyan(`┌${border}┐`));\n console.log(chalk.cyan(\"│ \") + chalk.bold(title.padEnd(maxWidth)) + chalk.cyan(\" │\"));\n console.log(chalk.cyan(`├${border}┤`));\n for (const line of content) {\n console.log(chalk.cyan(\"│ \") + line.padEnd(maxWidth) + chalk.cyan(\" │\"));\n }\n console.log(chalk.cyan(`└${border}┘`));\n}\n\n/**\n * Creates a progress bar string\n *\n * @param current - Current progress value\n * @param total - Total value\n * @param width - Bar width in characters (default: 20)\n * @returns Formatted progress bar string\n */\nexport function createProgressBar(current: number, total: number, width: number = 20): string {\n const percentage = Math.min(100, Math.round((current / total) * 100));\n const filled = Math.round((percentage / 100) * width);\n const empty = width - filled;\n\n const bar = chalk.green(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n return `${bar} ${percentage}%`;\n}\n\n/**\n * Logs a timestamp with a message\n *\n * @param message - Message to log\n */\nexport function logTimestamp(message: string): void {\n if (shouldLog(\"verbose\")) {\n const timestamp = new Date().toISOString();\n console.log(chalk.gray(`[${timestamp}]`), message);\n }\n}\n\n/**\n * Formats a duration in milliseconds to a human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns Formatted duration string\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n }\n}\n\n/**\n * Logs a timed operation result\n *\n * @param message - Operation description\n * @param startTime - Start time from Date.now()\n */\nexport function logTimed(message: string, startTime: number): void {\n if (shouldLog(\"normal\")) {\n const duration = Date.now() - startTime;\n console.log(chalk.green(\"✓\"), message, chalk.gray(`(${formatDuration(duration)})`));\n }\n}\n\n/**\n * Status output interface for JSON output mode\n */\nexport interface StatusOutput {\n status: \"up-to-date\" | \"changes-pending\" | \"first-time-setup\";\n collections: {\n current: number;\n snapshot: number;\n };\n changes: {\n create: number;\n delete: number;\n modify: number;\n };\n destructive: boolean;\n}\n\n/**\n * Formats status output as JSON\n *\n * @param output - Status output object\n * @returns JSON string\n */\nexport function formatStatusJson(output: StatusOutput): string {\n return JSON.stringify(output, null, 2);\n}\n","/**\n * Generate command implementation\n * Generates migrations from schema changes\n */\n\nimport { Command } from \"commander\";\nimport * as path from \"path\";\nimport {\n compare,\n detectDestructiveChangesValidation as detectDestructiveChanges,\n formatDestructiveChanges,\n generate,\n parseSchemaFiles,\n requiresForceFlagValidation as requiresForceFlag,\n summarizeDestructiveChanges,\n filterDiff,\n} from \"../../migration/index.js\";\nimport {\n ConfigurationError,\n FileSystemError,\n MigrationGenerationError,\n SchemaParsingError,\n SnapshotError,\n} from \"../../migration/errors.js\";\nimport { loadSnapshotWithMigrations } from \"../../migration/snapshot.js\";\nimport type { SchemaDefinition } from \"../../migration/types.js\";\nimport { getMigrationsDirectory, getSchemaDirectory, loadConfig, type MigrationConfig } from \"../utils/config.js\";\nimport {\n formatChangeSummary,\n logDebug,\n logError,\n logInfo,\n logSection,\n logSuccess,\n logWarning,\n setVerbosity,\n withProgress,\n} from \"../utils/logger.js\";\n\n/**\n * Checks if there are any changes in the diff\n *\n * @param diff - Schema diff to check\n * @returns True if there are changes\n */\nfunction hasChanges(diff: any): boolean {\n return (\n diff.collectionsToCreate.length > 0 || diff.collectionsToDelete.length > 0 || diff.collectionsToModify.length > 0\n );\n}\n\n/**\n * Handles destructive changes with warnings and force flag\n *\n * @param diff - Schema diff containing changes\n * @param config - Migration configuration\n * @param force - Force flag from CLI\n * @returns True if should proceed, false otherwise\n */\nfunction handleDestructiveChanges(diff: any, config: MigrationConfig, force: boolean): boolean {\n // Detect destructive changes\n const destructiveChanges = detectDestructiveChanges(diff);\n\n if (destructiveChanges.length === 0) {\n return true; // No destructive changes, proceed\n }\n\n // Display destructive changes warning\n logSection(\"⚠️ Destructive Changes Detected\");\n console.log();\n\n // Format and display destructive changes\n console.log(formatDestructiveChanges(destructiveChanges));\n\n // Display summary\n const summary = summarizeDestructiveChanges(destructiveChanges);\n console.log(\"Summary:\");\n console.log(` Total: ${summary.total} destructive change(s)`);\n if (summary.high > 0) {\n console.log(` High Severity: ${summary.high}`);\n }\n if (summary.medium > 0) {\n console.log(` Medium Severity: ${summary.medium}`);\n }\n if (summary.low > 0) {\n console.log(` Low Severity: ${summary.low}`);\n }\n console.log();\n\n // Check if force flag is required\n const forceRequired = config.diff.requireForceForDestructive && requiresForceFlag(destructiveChanges);\n\n if (forceRequired && !force) {\n // This path should technically be unreachable if we filtered destructive changes when !force\n // But keeping it as a safety net\n logError(\"Destructive changes require the --force flag to proceed.\");\n console.log();\n logInfo(\"To proceed with these changes, run the command again with --force:\");\n console.log(\" yarn migrate:generate --force\");\n console.log();\n logWarning(\"⚠️ WARNING: Using --force will apply these changes and may result in data loss!\");\n return false;\n }\n\n if (force) {\n logWarning(\"Proceeding with destructive changes (--force flag provided)\");\n console.log();\n }\n\n return true;\n}\n\n/**\n * Executes the generate command\n *\n * @param filters - Optional filters for collection/field names\n * @param options - Command options\n */\nexport async function executeGenerate(filters: string[], options: any): Promise<void> {\n try {\n // Set verbosity based on global options\n const parentOpts = options.parent?.opts?.() || {};\n if (parentOpts.verbose) {\n setVerbosity(\"verbose\");\n } else if (parentOpts.quiet) {\n setVerbosity(\"quiet\");\n }\n\n logDebug(\"Starting migration generation...\");\n logDebug(`Options: ${JSON.stringify(options, null, 2)}`);\n if (filters && filters.length > 0) {\n logDebug(`Filters: ${JSON.stringify(filters)}`);\n }\n\n // Load configuration\n const config = await loadConfig(options);\n\n // Get paths\n const schemaDir = getSchemaDirectory(config);\n const migrationsDir = getMigrationsDirectory(config);\n\n logSection(\"🔍 Analyzing Schema\");\n\n // Parse schema files with full config (including exclude patterns)\n const analyzerConfig = {\n schemaDir,\n excludePatterns: config.schema.exclude,\n useCompiledFiles: false, // Use source files since we're in development/testing\n };\n const currentSchema: SchemaDefinition = await withProgress(\"Parsing Zod schemas...\", () => parseSchemaFiles(analyzerConfig));\n\n logSuccess(`Found ${currentSchema.collections.size} collection(s)`);\n\n // Load previous snapshot from migrations directory and apply subsequent migrations\n logInfo(\"Loading previous snapshot...\");\n const previousSnapshot = loadSnapshotWithMigrations({\n migrationsPath: migrationsDir,\n workspaceRoot: process.cwd(),\n });\n\n if (!previousSnapshot) {\n logInfo(\"No previous snapshot found - treating as empty database (first-time generation)\");\n } else {\n logSuccess(\"Loaded previous snapshot as base reference\");\n }\n\n // Compare schemas\n logSection(\"📊 Comparing Schemas\");\n let diff = compare(currentSchema, previousSnapshot);\n\n // Apply filtering (patterns and destructive skipping)\n const skipDestructive = !options.force;\n\n // Check for destructive changes BEFORE filtering if we are going to skip them (for logging)\n // Only if we are NOT forcing.\n if (skipDestructive) {\n const destructive = detectDestructiveChanges(diff);\n if (destructive.length > 0) {\n logInfo(`ℹ️ Omitting ${destructive.length} destructive change(s) because --force is not set.`);\n }\n }\n\n // Apply filter\n diff = filterDiff(diff, {\n patterns: filters,\n skipDestructive: skipDestructive\n });\n\n // Check if there are any changes\n if (!hasChanges(diff)) {\n logInfo(\"No changes detected\");\n console.log();\n logSuccess(\"Schema is up to date!\");\n return;\n }\n\n // Display change summary\n console.log();\n console.log(formatChangeSummary(diff));\n\n // Handle destructive changes\n // If skipDestructive was true, diff shouldn't have any destructive changes, so this will pass.\n // If force was true, skipDestructive was false, diff might have destructive changes, this will warn and proceed.\n if (!handleDestructiveChanges(diff, config, options.force)) {\n process.exit(1);\n }\n\n // Generate migration\n logSection(\"📝 Generating Migration\");\n\n const migrationPaths = await withProgress(\"Creating migration file...\", () =>\n Promise.resolve(generate(diff, { migrationDir: migrationsDir, force: options.force }))\n );\n\n if (migrationPaths.length === 0) {\n logWarning(\"No migration files were generated (no changes detected or duplicate migration).\");\n return;\n }\n\n if (migrationPaths.length === 1) {\n logSuccess(`Migration file created: ${path.basename(migrationPaths[0])}`);\n } else {\n logSuccess(`Created ${migrationPaths.length} migration files`);\n }\n\n // Note: Snapshot is embedded in the generated migration file\n // No separate snapshot file needed\n\n // Display next steps\n logSection(\"✅ Next Steps\");\n console.log();\n console.log(\" 1. Review the generated migration file(s):\");\n migrationPaths.forEach((migrationPath: string) => {\n console.log(` ${migrationPath}`);\n });\n console.log();\n console.log(\" 2. Apply the migration by running PocketBase:\");\n console.log(\" yarn pb\");\n console.log();\n console.log(\" Or apply migrations manually:\");\n console.log(\" cd pb && ./pocketbase migrate up\");\n console.log();\n } catch (error) {\n // Handle specific error types with helpful messages\n if (error instanceof SchemaParsingError) {\n logError(\"Schema Parsing Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Make sure your schema files are valid Zod schemas\");\n console.log(' • Run \"yarn build\" in the shared workspace to compile TypeScript files');\n console.log(' • Check that schema files export schemas ending with \"Schema\" or \"InputSchema\"');\n } else if (error instanceof SnapshotError) {\n logError(\"Snapshot Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the snapshot file is not corrupted\");\n console.log(\" • Verify file permissions for the snapshot file\");\n console.log(\" • If this is the first run, this error should not occur\");\n } else if (error instanceof MigrationGenerationError) {\n logError(\"Migration Generation Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the migration directory exists and is writable\");\n console.log(\" • Verify you have sufficient disk space\");\n console.log(\" • Check file permissions for the migration directory\");\n } else if (error instanceof FileSystemError) {\n logError(\"File System Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check file and directory permissions\");\n console.log(\" • Verify you have sufficient disk space\");\n console.log(\" • Ensure the paths are correct and accessible\");\n } else if (error instanceof ConfigurationError) {\n logError(\"Configuration Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check your configuration file syntax\");\n console.log(\" • Verify all paths are correct and accessible\");\n console.log(\" • Run with --verbose flag for more details\");\n } else {\n // Generic error handling\n logError(`Failed to generate migration: ${error}`);\n if (error instanceof Error && error.stack) {\n console.error();\n console.error(error.stack);\n }\n }\n\n console.error();\n process.exit(1);\n }\n}\n\n/**\n * Creates the generate command\n *\n * @returns Commander command instance\n */\nexport function createGenerateCommand(): Command {\n return new Command(\"generate\")\n .description(\"Generate a migration from schema changes\")\n .argument(\"[filters...]\", \"Filter migrations by collection or field name (regex supported)\")\n .option(\"-o, --output <directory>\", \"Output directory for migration files\")\n .option(\"-f, --force\", \"Force generation even with destructive changes or duplicates\", false)\n .option(\"--dry-run\", \"Show what would be generated without creating files\", false)\n .option(\"--schema-dir <directory>\", \"Directory containing Zod schema files\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ pocketbase-migrate generate Generate migration from schema changes\n $ pocketbase-migrate generate User Generate migration only for User collection\n $ pocketbase-migrate generate User.name Generate migration only for User.name field\n $ pocketbase-migrate generate --force Force generation with destructive changes\n $ pocketbase-migrate generate --dry-run Preview changes without generating files\n $ pocketbase-migrate generate -o ./migrations Specify output directory\n`\n )\n .action(executeGenerate);\n}\n","/**\n * Status command implementation\n * Shows current migration status without generating files\n */\n\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { categorizeChangesBySeverity, compare, parseSchemaFiles } from \"../../migration/index.js\";\nimport { ConfigurationError, SchemaParsingError, SnapshotError } from \"../../migration/errors.js\";\nimport { loadSnapshotWithMigrations } from \"../../migration/snapshot.js\";\nimport type { SchemaDefinition, SchemaDiff } from \"../../migration/types.js\";\nimport { getMigrationsDirectory, getSchemaDirectory, loadConfig } from \"../utils/config.js\";\nimport {\n formatChangeSummary,\n formatStatusJson,\n logDebug,\n logError,\n logInfo,\n logKeyValue,\n logSection,\n logSuccess,\n logTable,\n setVerbosity,\n withProgress,\n type StatusOutput,\n} from \"../utils/logger.js\";\n\n/**\n * Checks if there are any changes in the diff\n *\n * @param diff - Schema diff to check\n * @returns True if there are changes\n */\nfunction hasChanges(diff: SchemaDiff): boolean {\n return (\n diff.collectionsToCreate.length > 0 || diff.collectionsToDelete.length > 0 || diff.collectionsToModify.length > 0\n );\n}\n\n/**\n * Checks if there are any destructive changes\n *\n * @param diff - Schema diff to check\n * @returns True if there are destructive changes\n */\nfunction hasDestructiveChanges(diff: SchemaDiff): boolean {\n const { destructive } = categorizeChangesBySeverity(diff);\n return destructive.length > 0;\n}\n\n/**\n * Creates a status output object for JSON mode\n *\n * @param status - Status type\n * @param currentCount - Current schema collection count\n * @param snapshotCount - Snapshot collection count\n * @param diff - Schema diff (optional)\n * @returns Status output object\n */\nfunction createStatusOutput(\n status: StatusOutput[\"status\"],\n currentCount: number,\n snapshotCount: number,\n diff?: SchemaDiff\n): StatusOutput {\n return {\n status,\n collections: {\n current: currentCount,\n snapshot: snapshotCount,\n },\n changes: {\n create: diff?.collectionsToCreate.length ?? 0,\n delete: diff?.collectionsToDelete.length ?? 0,\n modify: diff?.collectionsToModify.length ?? 0,\n },\n destructive: diff ? hasDestructiveChanges(diff) : false,\n };\n}\n\n/**\n * Displays destructive changes summary\n *\n * @param diff - Schema diff containing changes\n */\nfunction displayDestructiveChangesSummary(diff: SchemaDiff): void {\n const { destructive, nonDestructive } = categorizeChangesBySeverity(diff);\n\n if (destructive.length > 0) {\n logSection(\"⚠️ Destructive Changes\");\n console.log();\n for (const change of destructive) {\n console.log(chalk.red(` ${change}`));\n }\n console.log();\n }\n\n if (nonDestructive.length > 0) {\n logSection(\"✓ Non-Destructive Changes\");\n console.log();\n for (const change of nonDestructive) {\n console.log(chalk.green(` ${change}`));\n }\n console.log();\n }\n}\n\n/**\n * Displays a detailed change table\n *\n * @param diff - Schema diff containing changes\n */\nfunction displayChangeTable(diff: SchemaDiff): void {\n const rows: string[][] = [];\n\n // Add collections to create\n for (const collection of diff.collectionsToCreate) {\n rows.push([\n chalk.green(\"+\"),\n collection.name,\n collection.type,\n `${collection.fields.length} fields`,\n chalk.green(\"Create\"),\n ]);\n }\n\n // Add collections to delete\n for (const collection of diff.collectionsToDelete) {\n rows.push([chalk.red(\"-\"), collection.name, collection.type || \"base\", \"-\", chalk.red(\"Delete\")]);\n }\n\n // Add collections to modify\n for (const mod of diff.collectionsToModify) {\n const changes: string[] = [];\n if (mod.fieldsToAdd.length > 0) changes.push(`+${mod.fieldsToAdd.length} fields`);\n if (mod.fieldsToRemove.length > 0) changes.push(`-${mod.fieldsToRemove.length} fields`);\n if (mod.fieldsToModify.length > 0) changes.push(`~${mod.fieldsToModify.length} fields`);\n if (mod.indexesToAdd.length > 0) changes.push(`+${mod.indexesToAdd.length} indexes`);\n if (mod.indexesToRemove.length > 0) changes.push(`-${mod.indexesToRemove.length} indexes`);\n if (mod.rulesToUpdate.length > 0) changes.push(`~${mod.rulesToUpdate.length} rules`);\n\n rows.push([chalk.yellow(\"~\"), mod.collection, \"-\", changes.join(\", \") || \"No changes\", chalk.yellow(\"Modify\")]);\n }\n\n if (rows.length > 0) {\n logTable([\"\", \"Collection\", \"Type\", \"Changes\", \"Action\"], rows);\n }\n}\n\n/**\n * Executes the status command\n *\n * @param options - Command options\n */\nexport async function executeStatus(options: any): Promise<void> {\n const isJsonMode = options.json === true;\n\n try {\n // Set verbosity based on global options (quiet in JSON mode)\n if (isJsonMode) {\n setVerbosity(\"quiet\");\n } else {\n const parentOpts = options.parent?.opts?.() || {};\n if (parentOpts.verbose) {\n setVerbosity(\"verbose\");\n } else if (parentOpts.quiet) {\n setVerbosity(\"quiet\");\n }\n }\n\n logDebug(\"Checking migration status...\");\n logDebug(`Options: ${JSON.stringify(options, null, 2)}`);\n\n // Load configuration\n const config = await loadConfig(options);\n\n // Get paths\n const schemaDir = getSchemaDirectory(config);\n const migrationsDir = getMigrationsDirectory(config);\n\n logSection(\"🔍 Checking Migration Status\");\n\n // Parse schema files with full config (including exclude patterns)\n const analyzerConfig = {\n schemaDir,\n excludePatterns: config.schema.exclude,\n useCompiledFiles: false, // Use source files since we're in development/testing\n };\n const currentSchema: SchemaDefinition = await withProgress(\"Parsing Zod schemas...\", () => parseSchemaFiles(analyzerConfig));\n\n logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);\n\n // Load previous snapshot from migrations directory and apply subsequent migrations\n logInfo(\"Loading previous snapshot...\");\n const previousSnapshot = loadSnapshotWithMigrations({\n migrationsPath: migrationsDir,\n workspaceRoot: process.cwd(),\n });\n\n // Handle first-time setup\n if (!previousSnapshot) {\n if (isJsonMode) {\n const output = createStatusOutput(\"first-time-setup\", currentSchema.collections.size, 0);\n console.log(formatStatusJson(output));\n return;\n }\n\n logSection(\"🆕 First-Time Setup Detected\");\n console.log();\n logInfo(\"No previous snapshot found. This appears to be a first-time setup.\");\n console.log();\n logKeyValue(\"Collections in schema\", String(currentSchema.collections.size));\n console.log();\n logInfo('Run \"pocketbase-migrate generate\" to create the initial migration.');\n return;\n }\n\n logSuccess(`Loaded snapshot with ${previousSnapshot.collections.size} collection(s)`);\n\n // Compare schemas\n logSection(\"📊 Schema Comparison\");\n const diff = compare(currentSchema, previousSnapshot);\n\n // Check if there are any changes\n if (!hasChanges(diff)) {\n if (isJsonMode) {\n const output = createStatusOutput(\n \"up-to-date\",\n currentSchema.collections.size,\n previousSnapshot.collections.size,\n diff\n );\n console.log(formatStatusJson(output));\n return;\n }\n\n console.log();\n logSuccess(\"✓ Schema is in sync with snapshot\");\n logInfo(\"No pending changes detected\");\n console.log();\n logKeyValue(\"Collections\", String(currentSchema.collections.size));\n return;\n }\n\n // Handle JSON output mode\n if (isJsonMode) {\n const output = createStatusOutput(\n \"changes-pending\",\n currentSchema.collections.size,\n previousSnapshot.collections.size,\n diff\n );\n console.log(formatStatusJson(output));\n return;\n }\n\n // Display change summary\n console.log();\n console.log(formatChangeSummary(diff));\n\n // Display change table in verbose mode\n logDebug(\"Detailed change table:\");\n displayChangeTable(diff);\n\n // Display categorized changes\n displayDestructiveChangesSummary(diff);\n\n // Display next steps\n logSection(\"📝 Next Steps\");\n console.log();\n console.log(\" To generate a migration for these changes, run:\");\n console.log(chalk.cyan(\" pocketbase-migrate generate\"));\n console.log();\n\n const { destructive } = categorizeChangesBySeverity(diff);\n if (destructive.length > 0) {\n console.log(chalk.yellow(\" ⚠️ Destructive changes detected. Use --force flag when generating:\"));\n console.log(chalk.cyan(\" pocketbase-migrate generate --force\"));\n console.log();\n }\n } catch (error) {\n // Handle specific error types with helpful messages\n if (error instanceof SchemaParsingError) {\n logError(\"Schema Parsing Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Make sure your schema files are valid Zod schemas\");\n console.log(' • Check that schema files export schemas ending with \"Schema\" or \"InputSchema\"');\n } else if (error instanceof SnapshotError) {\n logError(\"Snapshot Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the snapshot file is not corrupted\");\n console.log(\" • Verify file permissions for the snapshot file\");\n } else if (error instanceof ConfigurationError) {\n logError(\"Configuration Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check your configuration file syntax\");\n console.log(\" • Verify all paths are correct and accessible\");\n } else {\n logError(`Failed to check status: ${error}`);\n if (error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n }\n process.exit(1);\n }\n}\n\n/**\n * Creates the status command\n *\n * @returns Commander command instance\n */\nexport function createStatusCommand(): Command {\n return new Command(\"status\")\n .description(\"Show current migration status without generating files\")\n .option(\"--schema-dir <directory>\", \"Directory containing Zod schema files\")\n .option(\"--json\", \"Output status as JSON for programmatic use\", false)\n .addHelpText(\n \"after\",\n `\nExamples:\n $ pocketbase-migrate status Check for pending schema changes\n $ pocketbase-migrate status --json Output status as JSON\n $ pocketbase-migrate status --verbose Show detailed status information\n`\n )\n .action(executeStatus);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/migration/errors.ts","../../src/migration/analyzer/config.ts","../../src/schema/base.ts","../../src/schema/fields.ts","../../src/utils/permission-templates.ts","../../src/migration/utils/collection-id-generator.ts","../../src/migration/rule-validator.ts","../../src/migration/permission-analyzer.ts","../../src/migration/utils/pluralize.ts","../../src/migration/utils/relation-detector.ts","../../src/migration/utils/type-mapper.ts","../../src/schema/view.ts","../../src/migration/analyzer/extractors.ts","../../src/migration/generator/utils.ts","../../src/migration/analyzer/converter.ts","../../src/migration/analyzer/loader.ts","../../src/migration/analyzer/index.ts","../../src/migration/engine/fields.ts","../../src/migration/engine/fields-list.ts","../../src/migration/engine/collection.ts","../../src/migration/engine/expression.ts","../../src/migration/engine/dbx.ts","../../src/migration/engine/records.ts","../../src/migration/engine/data-api.ts","../../src/migration/engine/app.ts","../../src/migration/engine/unmarshal.ts","../../src/migration/engine/globals.ts","../../src/migration/engine/runner.ts","../../src/migration/engine/applied-migrations.ts","../../src/migration/engine/migration-plan.ts","../../src/migration/pocketbase-converter.ts","../../src/migration/engine/store.ts","../../src/migration/engine/replayer.ts","../../src/migration/snapshot.ts","../../src/migration/diff/config.ts","../../src/migration/diff/utils.ts","../../src/migration/diff/fields.ts","../../src/migration/diff/indexes.ts","../../src/migration/diff/rules.ts","../../src/migration/diff/collections.ts","../../src/migration/diff/summary.ts","../../src/migration/diff/filter.ts","../../src/migration/diff/index.ts","../../src/migration/generator/config.ts","../../src/migration/generator/file-writer.ts","../../src/migration/generator/fields.ts","../../src/migration/generator/indexes.ts","../../src/migration/generator/rules.ts","../../src/migration/generator/collections.ts","../../src/migration/generator/migrator.ts","../../src/migration/utils/dependency-sorter.ts","../../src/migration/generator/operations.ts","../../src/migration/generator/index.ts","../../src/migration/engine/goja-lint.ts","../../src/migration/engine/state-compare.ts","../../src/migration/engine/verify.ts","../../src/migration/validation.ts","../../src/cli/utils/config.ts","../../src/cli/utils/logger.ts","../../src/cli/commands/generate.ts","../../src/cli/commands/status.ts"],"names":["path","isAuthCollection","expression","z","getChecks","getJsonSchema","path2","required","options","fieldDef","relationMetadata","fs","path3","fs2","negated","fs3","path4","fs4","fs5","path5","snapshot","extractFieldOptions","fs6","DEFAULT_CONFIG","mergeConfig","compare","path6","fs7","hasChanges","fs8","path7","compareIndexes","path9","hasDestructiveChanges","chalk"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Custom error classes for migration tool\n * Provides specific error types for better error handling and user feedback\n */\n\n/**\n * Base error class for all migration-related errors\n */\nexport class MigrationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MigrationError\";\n Object.setPrototypeOf(this, MigrationError.prototype);\n }\n}\n\n/**\n * Error thrown when schema parsing fails\n * Used when Zod schemas cannot be parsed or are invalid\n */\nexport class SchemaParsingError extends MigrationError {\n public readonly filePath?: string;\n public readonly originalError?: Error;\n\n constructor(message: string, filePath?: string, originalError?: Error) {\n super(message);\n this.name = \"SchemaParsingError\";\n this.filePath = filePath;\n this.originalError = originalError;\n Object.setPrototypeOf(this, SchemaParsingError.prototype);\n }\n\n /**\n * Creates a formatted error message with file path and original error details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.filePath) {\n parts.push(`\\nFile: ${this.filePath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when snapshot operations fail\n * Used for snapshot file read/write/parse errors\n */\nexport class SnapshotError extends MigrationError {\n public readonly snapshotPath?: string;\n public readonly operation?: \"read\" | \"write\" | \"parse\" | \"validate\";\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n snapshotPath?: string,\n operation?: \"read\" | \"write\" | \"parse\" | \"validate\",\n originalError?: Error\n ) {\n super(message);\n this.name = \"SnapshotError\";\n this.snapshotPath = snapshotPath;\n this.operation = operation;\n this.originalError = originalError;\n Object.setPrototypeOf(this, SnapshotError.prototype);\n }\n\n /**\n * Creates a formatted error message with snapshot path and operation details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.operation) {\n parts.push(`\\nOperation: ${this.operation}`);\n }\n\n if (this.snapshotPath) {\n parts.push(`\\nSnapshot: ${this.snapshotPath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when the execution engine fails to run a migration file\n * Carries the file path and the phase that failed so the user can pinpoint\n * (and fix or exclude) the offending migration\n */\nexport class MigrationExecutionError extends MigrationError {\n public readonly filePath?: string;\n public readonly phase?: \"evaluate\" | \"up\" | \"down\";\n public readonly originalError?: Error;\n\n constructor(message: string, filePath?: string, phase?: \"evaluate\" | \"up\" | \"down\", originalError?: Error) {\n super(message);\n this.name = \"MigrationExecutionError\";\n this.filePath = filePath;\n this.phase = phase;\n this.originalError = originalError;\n Object.setPrototypeOf(this, MigrationExecutionError.prototype);\n }\n\n /**\n * Creates a formatted error message with file path and phase details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.filePath) {\n parts.push(`\\nFile: ${this.filePath}`);\n }\n\n if (this.phase) {\n parts.push(`\\nPhase: ${this.phase}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when migration file generation fails\n * Used when migration files cannot be created or written\n */\nexport class MigrationGenerationError extends MigrationError {\n public readonly migrationPath?: string;\n public readonly originalError?: Error;\n\n constructor(message: string, migrationPath?: string, originalError?: Error) {\n super(message);\n this.name = \"MigrationGenerationError\";\n this.migrationPath = migrationPath;\n this.originalError = originalError;\n Object.setPrototypeOf(this, MigrationGenerationError.prototype);\n }\n\n /**\n * Creates a formatted error message with migration path and original error details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.migrationPath) {\n parts.push(`\\nMigration: ${this.migrationPath}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when file system operations fail\n * Used for directory creation, file permissions, disk space issues\n */\nexport class FileSystemError extends MigrationError {\n public readonly path?: string;\n public readonly operation?: \"read\" | \"write\" | \"create\" | \"delete\" | \"access\";\n public readonly code?: string;\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n path?: string,\n operation?: \"read\" | \"write\" | \"create\" | \"delete\" | \"access\",\n code?: string,\n originalError?: Error\n ) {\n super(message);\n this.name = \"FileSystemError\";\n this.path = path;\n this.operation = operation;\n this.code = code;\n this.originalError = originalError;\n Object.setPrototypeOf(this, FileSystemError.prototype);\n }\n\n /**\n * Creates a formatted error message with path, operation, and error code details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.operation) {\n parts.push(`\\nOperation: ${this.operation}`);\n }\n\n if (this.path) {\n parts.push(`\\nPath: ${this.path}`);\n }\n\n if (this.code) {\n parts.push(`\\nError Code: ${this.code}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when configuration is invalid\n * Used for configuration file parsing, validation, and path resolution errors\n */\nexport class ConfigurationError extends MigrationError {\n public readonly configPath?: string;\n public readonly invalidFields?: string[];\n public readonly originalError?: Error;\n\n constructor(message: string, configPath?: string, invalidFields?: string[], originalError?: Error) {\n super(message);\n this.name = \"ConfigurationError\";\n this.configPath = configPath;\n this.invalidFields = invalidFields;\n this.originalError = originalError;\n Object.setPrototypeOf(this, ConfigurationError.prototype);\n }\n\n /**\n * Creates a formatted error message with configuration details\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.configPath) {\n parts.push(`\\nConfiguration File: ${this.configPath}`);\n }\n\n if (this.invalidFields && this.invalidFields.length > 0) {\n parts.push(`\\nInvalid Fields: ${this.invalidFields.join(\", \")}`);\n }\n\n if (this.originalError) {\n parts.push(`\\nCause: ${this.originalError.message}`);\n }\n\n return parts.join(\"\");\n }\n}\n\n/**\n * Error thrown when CLI command usage is incorrect\n * Used for invalid arguments, missing required options, etc.\n */\nexport class CLIUsageError extends MigrationError {\n public readonly command?: string;\n public readonly suggestion?: string;\n\n constructor(message: string, command?: string, suggestion?: string) {\n super(message);\n this.name = \"CLIUsageError\";\n this.command = command;\n this.suggestion = suggestion;\n Object.setPrototypeOf(this, CLIUsageError.prototype);\n }\n\n /**\n * Creates a formatted error message with usage suggestions\n */\n public getDetailedMessage(): string {\n const parts: string[] = [this.message];\n\n if (this.command) {\n parts.push(`\\nCommand: ${this.command}`);\n }\n\n if (this.suggestion) {\n parts.push(`\\nSuggestion: ${this.suggestion}`);\n }\n\n return parts.join(\"\");\n }\n}\n","import * as path from \"path\";\n\n/**\n * Configuration options for schema discovery and parsing\n */\nexport interface SchemaAnalyzerConfig {\n /**\n * Directory containing schema files (source or compiled)\n * Can be absolute or relative to workspaceRoot\n */\n schemaDir: string;\n\n /**\n * Workspace root directory for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * File patterns to exclude from schema discovery\n * Defaults to ['base.ts', 'index.ts', 'permissions.ts', 'permission-templates.ts']\n */\n excludePatterns?: string[];\n\n /**\n * File extensions to include in schema discovery\n * Defaults to ['.ts', '.js']\n */\n includeExtensions?: string[];\n\n /**\n * Schema export name patterns to look for\n * Defaults to ['Schema', 'InputSchema']\n */\n schemaPatterns?: string[];\n\n /**\n * Whether to use compiled JavaScript files instead of TypeScript source\n * When true, looks for .js files; when false, looks for .ts files\n * Defaults to true (use compiled files for dynamic import)\n */\n useCompiledFiles?: boolean;\n\n /**\n * Custom path transformation function for converting source paths to import paths\n * Useful for monorepo setups where source and dist directories differ\n * If not provided, uses the schemaDir directly\n */\n pathTransformer?: (sourcePath: string) => string;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<Omit<SchemaAnalyzerConfig, \"schemaDir\" | \"pathTransformer\">> = {\n workspaceRoot: process.cwd(),\n excludePatterns: [\n \"base.ts\",\n \"index.ts\",\n \"permissions.ts\",\n \"permission-templates.ts\",\n \"base.js\",\n \"index.js\",\n \"permissions.js\",\n \"permission-templates.js\",\n ],\n includeExtensions: [\".ts\", \".js\"],\n schemaPatterns: [\"Schema\", \"InputSchema\", \"Collection\"],\n useCompiledFiles: true,\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(\n config: SchemaAnalyzerConfig\n): Required<Omit<SchemaAnalyzerConfig, \"pathTransformer\">> & { pathTransformer?: (sourcePath: string) => string } {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n excludePatterns: config.excludePatterns || DEFAULT_CONFIG.excludePatterns,\n includeExtensions: config.includeExtensions || DEFAULT_CONFIG.includeExtensions,\n schemaPatterns: config.schemaPatterns || DEFAULT_CONFIG.schemaPatterns,\n };\n}\n\n/**\n * Resolves the schema directory path\n */\nexport function resolveSchemaDir(config: SchemaAnalyzerConfig): string {\n const workspaceRoot = config.workspaceRoot || process.cwd();\n\n if (path.isAbsolute(config.schemaDir)) {\n return config.schemaDir;\n }\n\n return path.join(workspaceRoot, config.schemaDir);\n}\n","import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n id: z.string().describe(\"unique id\"),\n collectionId: z.string().describe(\"collection id\"),\n collectionName: z.string().describe(\"collection name\"),\n expand: z.record(z.string(), z.any()).describe(\"expandable fields\"),\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Extended base schema with timestamp fields\n * Includes created and updated autodate fields\n */\nexport const baseSchemaWithTimestamps = {\n ...baseSchema,\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Base schema for image file collections\n * Extends base schema with thumbnail URL and image files array\n */\nexport const baseImageFileSchema = {\n ...baseSchema,\n thumbnailURL: z.string().optional(),\n imageFiles: z.array(z.string()),\n};\n\n/**\n * Input schema for image file uploads\n * Used in forms where users upload File objects\n * Requires Node.js 20+ or browser environment with File API\n */\nexport const inputImageFileSchema = {\n imageFiles: z.array(z.instanceof(File)),\n};\n\n/**\n * Helper constant for omitting image files from schemas\n * Used with Zod's .omit() method\n */\nexport const omitImageFilesSchema = {\n imageFiles: true,\n} as const;\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n// Note: Field type helpers are now exported from ./fields.ts with PascalCase names\n// (e.g., TextField, EmailField, JSONField, etc.) to ensure consistent naming.\n\n// ============================================================================\n// Relation Field Helpers - Explicit Relationship Definitions\n// ============================================================================\n\n/**\n * Relation field configuration options\n */\nexport interface RelationConfig {\n /**\n * Target collection name (e.g., 'users', 'posts', 'tags')\n * This is the PocketBase collection that the relation points to\n */\n collection: string;\n\n /**\n * Whether to cascade delete related records when this record is deleted\n * @default false\n */\n cascadeDelete?: boolean;\n\n /**\n * Fields to display in the admin UI\n */\n displayFields?: string[] | null;\n}\n\n/**\n * Multiple relation field configuration options\n */\nexport interface RelationsConfig extends RelationConfig {\n /**\n * Minimum number of relations required\n * @default 0\n */\n minSelect?: number;\n\n /**\n * Maximum number of relations allowed\n * @default 999\n */\n maxSelect?: number;\n}\n\n/**\n * Internal marker for relation metadata\n * Used by the analyzer to detect explicit relation definitions\n */\nconst RELATION_METADATA_KEY = \"__pocketbase_relation__\";\n\n/**\n * Creates a single relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect=1\n *\n * This is the recommended way to define relations - it's explicit and doesn't\n * rely on naming conventions.\n *\n * @param config - Relation configuration with target collection\n * @returns Zod string schema with relation metadata\n *\n * @example\n * // Single relation to users collection\n * const PostSchema = z.object({\n * title: z.string(),\n * author: RelationField({ collection: 'users' }),\n * });\n *\n * @example\n * // Relation with cascade delete\n * const CommentSchema = z.object({\n * content: z.string(),\n * post: RelationField({ collection: 'posts', cascadeDelete: true }),\n * });\n */\nexport function RelationField(config: RelationConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"single\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: 1,\n minSelect: 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect>1\n *\n * This is the recommended way to define multi-relations - it's explicit and\n * doesn't rely on naming conventions.\n *\n * @param config - Relations configuration with target collection and limits\n * @returns Zod array of strings schema with relation metadata\n *\n * @example\n * // Multiple relations to tags collection\n * const PostSchema = z.object({\n * title: z.string(),\n * tags: RelationsField({ collection: 'tags' }),\n * });\n *\n * @example\n * // Relations with min/max constraints\n * const ProjectSchema = z.object({\n * title: z.string(),\n * collaborators: RelationsField({\n * collection: 'users',\n * minSelect: 1,\n * maxSelect: 10,\n * }),\n * });\n */\nexport function RelationsField(config: RelationsConfig) {\n const metadata = {\n [RELATION_METADATA_KEY]: {\n type: \"multiple\",\n collection: config.collection,\n cascadeDelete: config.cascadeDelete ?? false,\n maxSelect: config.maxSelect ?? 999,\n minSelect: config.minSelect ?? 0,\n displayFields: config.displayFields ?? null,\n },\n };\n\n let schema = z.array(z.string());\n\n // Apply array constraints for Zod validation\n if (config.minSelect !== undefined) {\n schema = schema.min(config.minSelect);\n }\n if (config.maxSelect !== undefined) {\n schema = schema.max(config.maxSelect);\n }\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Extracts relation metadata from a Zod type's description\n * Used internally by the analyzer to detect explicit relation definitions\n *\n * @param description - The Zod type's description string\n * @returns Relation metadata if present, null otherwise\n */\nexport function extractRelationMetadata(description: string | undefined): {\n type: \"single\" | \"multiple\";\n collection: string;\n cascadeDelete: boolean;\n maxSelect: number;\n minSelect: number;\n displayFields?: string[] | null;\n} | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[RELATION_METADATA_KEY]) {\n return parsed[RELATION_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n/**\n * Attach permission metadata to a Zod schema\n *\n * This helper function allows you to define PocketBase API rules alongside your\n * entity schema definitions. The permissions are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach permissions to\n * @param config - Either a PermissionTemplateConfig (for template-based permissions)\n * or a PermissionSchema (for custom permissions)\n * @returns The schema with permission metadata attached\n *\n * @example\n * // Using a template\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * { template: 'owner-only', ownerField: 'User' }\n * );\n *\n * @example\n * // Using custom rules\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string() }),\n * { listRule: '@request.auth.id != \"\"', viewRule: '' }\n * );\n *\n * @example\n * // Using template with custom rule overrides\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * {\n * template: 'owner-only',\n * ownerField: 'User',\n * customRules: { listRule: '@request.auth.id != \"\"' }\n * }\n * );\n */\nexport function withPermissions<T extends z.ZodTypeAny>(\n schema: T,\n config: PermissionTemplateConfig | PermissionSchema\n): T {\n // Create metadata object with permissions config directly\n // The PermissionAnalyzer will handle resolving templates vs direct schemas\n const metadata = {\n permissions: config,\n };\n\n // Attach permission metadata to schema using Zod's describe() method\n // The metadata is serialized as JSON and stored in the schema's description\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Attach index definitions to a Zod schema\n *\n * This helper function allows you to define PocketBase indexes alongside your\n * entity schema definitions. The indexes are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach indexes to\n * @param indexes - Array of PocketBase index SQL statements\n * @returns The schema with index metadata attached\n *\n * @example\n * // Define indexes for a user schema\n * const UserSchema = withIndexes(\n * withPermissions(\n * z.object({ name: z.string(), email: z.string().email() }),\n * userPermissions\n * ),\n * [\n * 'CREATE UNIQUE INDEX idx_users_email ON users (email)',\n * 'CREATE INDEX idx_users_name ON users (name)'\n * ]\n * );\n *\n * @example\n * // Single index\n * const ProjectSchema = withIndexes(\n * ProjectDatabaseSchema,\n * ['CREATE INDEX idx_projects_status ON projects (status)']\n * );\n */\nexport function withIndexes<T extends z.ZodTypeAny>(schema: T, indexes: string[]): T {\n // Extract existing metadata if present\n let existingMetadata: any = {};\n\n if (schema.description) {\n try {\n existingMetadata = JSON.parse(schema.description);\n } catch {\n // If description is not JSON, ignore it\n }\n }\n\n // Merge indexes with existing metadata\n const metadata = {\n ...existingMetadata,\n indexes,\n };\n\n // Attach metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Configuration options for defining a collection\n */\nexport interface CollectionConfig {\n /**\n * The name of the PocketBase collection\n * This will be used when generating migrations\n */\n collectionName: string;\n\n /**\n * The Zod schema definition for the collection\n */\n schema: z.ZodObject<any>;\n\n /**\n * Optional permission configuration\n * Can be a template-based config or custom permission rules\n */\n permissions?: PermissionTemplateConfig | PermissionSchema;\n\n /**\n * Optional array of index SQL statements\n * Example: ['CREATE UNIQUE INDEX idx_users_email ON users (email)']\n */\n indexes?: string[];\n\n /**\n * Optional collection type\n * - \"base\": Standard collection (default)\n * - \"auth\": Authentication collection with system auth fields\n * - \"view\": Read-only collection backed by a SQL query (requires viewQuery)\n *\n * If not specified, the type will be auto-detected based on field presence\n * (collections with both email and password fields are detected as auth)\n *\n * Prefer defineView() over type: \"view\" - it enforces the constraints\n * PocketBase places on view collections at compile time.\n */\n type?: \"base\" | \"auth\" | \"view\";\n\n /**\n * SQL SELECT statement backing a view collection\n *\n * Only valid when type is \"view\", where it is required. PocketBase derives\n * the collection's fields by running this query, so the Zod schema is used\n * for TypeScript types only.\n */\n viewQuery?: string;\n\n /**\n * Future extensibility - additional options can be added here\n */\n [key: string]: unknown;\n}\n\n/**\n * High-level wrapper for defining a PocketBase collection with all metadata\n *\n * This is the recommended way to define collections as it provides a single\n * entry point for collection name, schema, permissions, indexes, and future features.\n *\n * @param config - Collection configuration object\n * @returns The schema with all metadata attached\n *\n * @example\n * // Recommended: Use default export for clarity\n * const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n * export default PostCollection;\n *\n * @example\n * // Also supported: Named export (backward compatible)\n * export const PostCollection = defineCollection({\n * collectionName: \"posts\",\n * schema: z.object({\n * title: z.string(),\n * content: z.string(),\n * author: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"author\",\n * },\n * });\n *\n * @example\n * // Collection with permissions and indexes\n * export const UserSchema = defineCollection({\n * collectionName: \"users\",\n * schema: z.object({\n * name: z.string(),\n * email: z.string().email(),\n * }),\n * permissions: {\n * listRule: \"id = @request.auth.id\",\n * viewRule: \"id = @request.auth.id\",\n * createRule: \"\",\n * updateRule: \"id = @request.auth.id\",\n * deleteRule: \"id = @request.auth.id\",\n * },\n * indexes: [\n * \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n * ],\n * });\n *\n * @example\n * // Collection with template and custom rule overrides\n * export const ProjectSchema = defineCollection({\n * collectionName: \"projects\",\n * schema: z.object({\n * title: z.string(),\n * owner: RelationField({ collection: \"users\" }),\n * }),\n * permissions: {\n * template: \"owner-only\",\n * ownerField: \"owner\",\n * customRules: {\n * listRule: '@request.auth.id != \"\"',\n * },\n * },\n * });\n */\nexport function defineCollection(config: CollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, permissions, indexes, type, viewQuery, ...futureOptions } = config;\n\n // Build metadata object\n const metadata: any = {\n collectionName,\n };\n\n // Add type if provided\n if (type) {\n metadata.type = type;\n }\n\n // Add the SQL query backing a view collection\n if (viewQuery !== undefined) {\n metadata.viewQuery = viewQuery;\n }\n\n // Add permissions if provided\n if (permissions) {\n metadata.permissions = permissions;\n }\n\n // Add indexes if provided\n if (indexes) {\n metadata.indexes = indexes;\n }\n\n // Add any future options\n if (Object.keys(futureOptions).length > 0) {\n Object.assign(metadata, futureOptions);\n }\n\n // Attach all metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as z.ZodObject<any>;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Field Metadata System\n// ============================================================================\n\n/**\n * Internal marker for field metadata\n * Used by the migration generator to detect explicit field type definitions\n */\nexport const FIELD_METADATA_KEY = \"__pocketbase_field__\";\n\n/**\n * PocketBase field types\n */\nexport type PocketBaseFieldType =\n | \"text\"\n | \"email\"\n | \"url\"\n | \"editor\"\n | \"number\"\n | \"bool\"\n | \"date\"\n | \"autodate\"\n | \"select\"\n | \"relation\"\n | \"file\"\n | \"json\"\n | \"geoPoint\"\n | \"password\";\n\n/**\n * Field metadata structure embedded in Zod schema descriptions\n */\nexport interface FieldMetadata {\n type: PocketBaseFieldType;\n options?: Record<string, any>;\n}\n\n/**\n * Extracts field metadata from a Zod type's description\n * Used by the migration generator to detect explicit field type definitions\n *\n * @param description - The Zod type's description string\n * @returns Field metadata if present, null otherwise\n *\n * @example\n * const schema = TextField({ min: 1, max: 100 });\n * const metadata = extractFieldMetadata(schema.description);\n * // Returns: { type: \"text\", options: { min: 1, max: 100 } }\n */\nexport function extractFieldMetadata(description: string | undefined): FieldMetadata | null {\n if (!description) return null;\n\n try {\n const parsed = JSON.parse(description);\n if (parsed[FIELD_METADATA_KEY]) {\n return parsed[FIELD_METADATA_KEY];\n }\n } catch {\n // Not JSON, ignore\n }\n\n return null;\n}\n\n// ============================================================================\n// Field Options Interfaces\n// ============================================================================\n\n/**\n * Text field configuration options\n */\nexport interface TextFieldOptions {\n /**\n * Minimum length constraint\n */\n min?: number;\n\n /**\n * Maximum length constraint\n */\n max?: number;\n\n /**\n * Pattern constraint (regex)\n */\n pattern?: RegExp | string;\n\n /**\n * Auto-generate pattern for automatic value generation\n * Example: \"[A-Z]{3}-[0-9]{6}\" generates values like \"ABC-123456\"\n */\n autogeneratePattern?: string;\n}\n\n/**\n * Number field configuration options\n */\nexport interface NumberFieldOptions {\n /**\n * Minimum value constraint\n */\n min?: number;\n\n /**\n * Maximum value constraint\n */\n max?: number;\n\n /**\n * Whether to disallow decimal values (integers only)\n */\n noDecimal?: boolean;\n\n /**\n * Whether the field is required\n * @default false\n *\n * Note: In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you want to allow zero values (e.g., for progress: 0-100), keep this as `false`.\n * Set to `true` only if you want to enforce non-zero values.\n */\n required?: boolean;\n}\n\n/**\n * Date field configuration options\n */\nexport interface DateFieldOptions {\n /**\n * Minimum date constraint\n */\n min?: Date | string;\n\n /**\n * Maximum date constraint\n */\n max?: Date | string;\n}\n\n/**\n * Autodate field configuration options\n */\nexport interface AutodateFieldOptions {\n /**\n * Set date automatically on record creation\n * @default false\n */\n onCreate?: boolean;\n\n /**\n * Update date automatically on record update\n * @default false\n */\n onUpdate?: boolean;\n}\n\n/**\n * Select field configuration options\n */\nexport interface SelectFieldOptions {\n /**\n * Maximum number of selections allowed\n * If > 1, enables multiple selection\n * @default 1\n */\n maxSelect?: number;\n}\n\ntype EnumFromArray<T extends readonly [string, ...string[]]> = z.ZodEnum<z.core.util.ToEnum<T[number]>>;\n\n/**\n * Human-friendly byte size input.\n *\n * - Use a number for raw bytes (e.g. `5242880`)\n * - Use a string with unit suffix for kibibytes/mebibytes/gibibytes (e.g. `\"5M\"`, `\"1G\"`)\n *\n * Supported suffixes: `K`, `M`, `G` (case-insensitive).\n */\nexport type ByteSize = number | `${number}${\"K\" | \"M\" | \"G\" | \"k\" | \"m\" | \"g\"}`;\n\n/**\n * File field configuration options\n */\nexport interface FileFieldOptions {\n /**\n * Allowed MIME types\n * Example: [\"image/*\", \"application/pdf\"]\n */\n mimeTypes?: string[];\n\n /**\n * Maximum file size.\n *\n * - Provide a number for raw bytes\n * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n *\n * Max allowed is `8G`.\n *\n * @example\n * maxSize: 5242880\n * maxSize: \"5M\"\n * maxSize: \"1G\"\n */\n maxSize?: ByteSize;\n\n /**\n * Thumbnail sizes to generate\n * Example: [\"100x100\", \"200x200\"]\n * Set to null to explicitly disable thumbnails\n */\n thumbs?: string[];\n\n /**\n * Whether the file is protected (requires auth to access)\n * @default false\n */\n protected?: boolean;\n}\n\n/**\n * Multiple files field configuration options\n */\nexport interface FilesFieldOptions extends FileFieldOptions {\n /**\n * Minimum number of files required\n */\n minSelect?: number;\n\n /**\n * Maximum number of files allowed\n */\n maxSelect?: number;\n}\n\nconst MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024; // 8G\n\nfunction parseByteSizeToBytes(value: ByteSize, context: string): number {\n let bytes: number;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(`${context}: maxSize must be a finite number of bytes`);\n }\n bytes = Math.round(value);\n } else {\n const trimmed = value.trim();\n const match = /^(\\d+(?:\\.\\d+)?)\\s*([KMG])$/i.exec(trimmed);\n if (!match) {\n throw new Error(`${context}: maxSize string must be like \"10K\", \"5M\", or \"1G\" (case-insensitive)`);\n }\n\n const amount = Number(match[1]);\n const unit = match[2].toUpperCase() as \"K\" | \"M\" | \"G\";\n\n if (!Number.isFinite(amount)) {\n throw new Error(`${context}: maxSize must be a valid number`);\n }\n\n const multiplier = unit === \"K\" ? 1024 : unit === \"M\" ? 1024 * 1024 : 1024 * 1024 * 1024;\n bytes = Math.round(amount * multiplier);\n }\n\n if (bytes < 0) {\n throw new Error(`${context}: maxSize must be >= 0`);\n }\n\n if (bytes > MAX_FILE_SIZE_BYTES) {\n throw new Error(`${context}: maxSize cannot exceed 8G (${MAX_FILE_SIZE_BYTES} bytes)`);\n }\n\n return bytes;\n}\n\nfunction normalizeFileFieldOptions(\n options: FileFieldOptions | undefined,\n context: string\n): FileFieldOptions | undefined {\n if (!options) return options;\n if (options.maxSize === undefined) return options;\n\n return {\n ...options,\n // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.\n maxSize: parseByteSizeToBytes(options.maxSize, context),\n };\n}\n\n// ============================================================================\n// Field Helper Functions\n// ============================================================================\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n *\n * @returns Zod boolean schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * active: BoolField(),\n * featured: BoolField().optional(),\n * });\n */\nexport function BoolField(): z.ZodBoolean {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"bool\" as const,\n },\n };\n\n return z.boolean().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a number field schema with optional constraints\n * Maps to PocketBase 'number' field type\n *\n * @param options - Optional constraints for the number field\n * @returns Zod number schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * price: NumberField({ min: 0 }),\n * quantity: NumberField({ min: 0, noDecimal: true }),\n * rating: NumberField({ min: 0, max: 5 }),\n * progress: NumberField({ min: 0, max: 100 }), // required defaults to false, allowing zero\n * score: NumberField({ min: 1, max: 10, required: true }), // requires non-zero value\n * });\n *\n * @remarks\n * By default, number fields are not required (`required: false`), which allows zero values.\n * In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you set `min: 0` and want to allow zero, keep `required: false` (the default).\n */\nexport function NumberField(options?: NumberFieldOptions): z.ZodNumber {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"NumberField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.number();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"number\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a text field schema with optional constraints\n * Maps to PocketBase 'text' field type\n *\n * @param options - Optional constraints for the text field\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * name: TextField({ min: 1, max: 200 }),\n * sku: TextField({ autogeneratePattern: \"[A-Z]{3}-[0-9]{6}\" }),\n * description: TextField({ max: 1000 }),\n * });\n */\nexport function TextField(options?: TextFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n if (options.min > options.max) {\n throw new Error(\"TextField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n let schema = z.string();\n\n // Apply Zod validations\n if (options?.min !== undefined) {\n schema = schema.min(options.min);\n }\n if (options?.max !== undefined) {\n schema = schema.max(options.max);\n }\n if (options?.pattern !== undefined) {\n const pattern = options.pattern instanceof RegExp ? options.pattern : new RegExp(options.pattern);\n schema = schema.regex(pattern);\n }\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"text\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n *\n * @returns Zod string schema with email validation and PocketBase metadata\n *\n * @example\n * const UserSchema = z.object({\n * email: EmailField(),\n * alternateEmail: EmailField().optional(),\n * });\n */\nexport function EmailField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"email\" as const,\n },\n };\n\n return z.string().email().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n *\n * @returns Zod string schema with URL validation and PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n * website: URLField(),\n * documentation: URLField().optional(),\n * });\n */\nexport function URLField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"url\" as const,\n },\n };\n\n return z.string().url().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a rich text editor field schema\n * Maps to PocketBase 'editor' field type\n *\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * content: EditorField(),\n * summary: EditorField().optional(),\n * });\n */\nexport function EditorField(): z.ZodString {\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"editor\" as const,\n },\n };\n\n return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a date field schema with optional constraints\n * Maps to PocketBase 'date' field type\n *\n * @param options - Optional date constraints\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const EventSchema = z.object({\n * startDate: DateField(),\n * endDate: DateField({ min: new Date('2024-01-01') }),\n * releaseDate: DateField().optional(),\n * });\n */\nexport function DateField(options?: DateFieldOptions): z.ZodString {\n // Validate options\n if (options?.min !== undefined && options?.max !== undefined) {\n const minDate = typeof options.min === \"string\" ? new Date(options.min) : options.min;\n const maxDate = typeof options.max === \"string\" ? new Date(options.max) : options.max;\n if (minDate > maxDate) {\n throw new Error(\"DateField: min cannot be greater than max\");\n }\n }\n\n // Create base schema\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"date\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an autodate field schema with automatic timestamp management\n * Maps to PocketBase 'autodate' field type\n *\n * @param options - Optional autodate configuration\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n * createdAt: AutodateField({ onCreate: true }),\n * updatedAt: AutodateField({ onUpdate: true }),\n * publishedAt: AutodateField({ onCreate: true, onUpdate: false }),\n * });\n */\nexport function AutodateField(options?: AutodateFieldOptions): z.ZodString {\n const schema = z.string();\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"autodate\" as const,\n options: options || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod enum or array schema with PocketBase metadata\n *\n * @example\n * // Single select\n * const PostSchema = z.object({\n * status: SelectField([\"draft\", \"published\", \"archived\"]),\n * });\n *\n * @example\n * // Multiple select\n * const ProductSchema = z.object({\n * categories: SelectField([\"electronics\", \"clothing\", \"food\"], { maxSelect: 3 }),\n * });\n */\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): EnumFromArray<T> | z.ZodArray<EnumFromArray<T>> {\n // Return array schema if maxSelect > 1\n if (options?.maxSelect && options.maxSelect > 1) {\n return MultiSelectField(values, options);\n }\n\n return SingleSelectField(values);\n}\n\n/**\n * Creates a single select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect=1\n *\n * @param values - Array of allowed string values\n * @returns Zod enum schema with PocketBase metadata\n */\nexport function SingleSelectField<const T extends readonly [string, ...string[]]>(values: T): EnumFromArray<T> {\n const enumSchema = z.enum(values);\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect: 1,\n },\n },\n };\n\n return enumSchema.describe(JSON.stringify(metadata)) as EnumFromArray<T>;\n}\n\n/**\n * Creates a multiple select field schema from enum values\n * Maps to PocketBase 'select' field type with maxSelect>1\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod array schema with PocketBase metadata\n */\nexport function MultiSelectField<const T extends readonly [string, ...string[]]>(\n values: T,\n options?: SelectFieldOptions\n): z.ZodArray<EnumFromArray<T>> {\n const enumSchema = z.enum(values);\n const maxSelect = options?.maxSelect ?? 999;\n\n if (maxSelect <= 1) {\n throw new Error(\"MultiSelectField: maxSelect must be greater than 1\");\n }\n\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"select\" as const,\n options: {\n values,\n maxSelect,\n },\n },\n };\n\n return z.array(enumSchema).describe(JSON.stringify(metadata)) as z.ZodArray<EnumFromArray<T>>;\n}\n\n/**\n * Creates a single file field schema\n * Maps to PocketBase 'file' field type with maxSelect=1\n *\n * @param options - Optional file constraints\n * @returns Zod schema that accepts File on input and returns string when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n * document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File objects\n * - When reading from PocketBase: returns string (filename)\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<string, File | string> {\n // Accept File for input (when creating/updating) or string (when reading from DB)\n // Output is always string (as returned by PocketBase)\n const schema = z.preprocess((val) => {\n // If it's a File, return its name (or empty string if no name)\n // If it's already a string (from DB), return as-is\n return val instanceof File ? val.name || \"\" : val;\n }, z.string()) as z.ZodType<string, File | string>;\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FileField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple files field schema\n * Maps to PocketBase 'file' field type with maxSelect>1\n *\n * @param options - Optional file constraints\n * @returns Zod array schema that accepts File[] on input and returns string[] when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n * images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n * attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File[]\n * - When reading from PocketBase: returns string[] (filenames)\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodType<string[], (File | string)[]> {\n // Validate options\n if (options?.minSelect !== undefined && options?.maxSelect !== undefined) {\n if (options.minSelect > options.maxSelect) {\n throw new Error(\"FilesField: minSelect cannot be greater than maxSelect\");\n }\n }\n\n // Accept File[] for input (when creating/updating) or string[] (when reading from DB)\n // Output is always string[] (as returned by PocketBase)\n let baseArraySchema = z.array(z.string());\n\n // Apply Zod validations first\n if (options?.minSelect !== undefined) {\n baseArraySchema = baseArraySchema.min(options.minSelect);\n }\n if (options?.maxSelect !== undefined) {\n baseArraySchema = baseArraySchema.max(options.maxSelect);\n }\n\n const schema = z.preprocess((val) => {\n // Handle array of Files or strings\n if (Array.isArray(val)) {\n return val.map((item) => (item instanceof File ? item.name || \"\" : item));\n }\n return val;\n }, baseArraySchema);\n\n const normalizedOptions = normalizeFileFieldOptions(options, \"FilesField\");\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"file\" as const,\n options: normalizedOptions || {},\n },\n };\n\n return schema.describe(JSON.stringify(metadata)) as z.ZodType<string[], (File | string)[]>;\n}\n\n/**\n * Creates a JSON field schema with optional inner schema validation\n * Maps to PocketBase 'json' field type\n *\n * @param schema - Optional Zod schema for the JSON structure\n * @returns Zod schema with PocketBase metadata\n *\n * @example\n * // Any JSON\n * const ProductSchema = z.object({\n * metadata: JSONField(),\n * });\n *\n * @example\n * // Typed JSON\n * const ProductSchema = z.object({\n * settings: JSONField(z.object({\n * theme: z.string(),\n * notifications: z.boolean(),\n * })),\n * });\n */\nexport function JSONField<T extends z.ZodTypeAny>(schema?: T): T | z.ZodRecord<z.ZodString, z.ZodAny> {\n const baseSchema = schema ?? z.record(z.string(), z.any());\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"json\" as const,\n },\n };\n\n return baseSchema.describe(JSON.stringify(metadata)) as T | z.ZodRecord<z.ZodString, z.ZodAny>;\n}\n\n/**\n * Creates a geographic point field schema\n * Maps to PocketBase 'geoPoint' field type\n *\n * @returns Zod object schema with lon/lat fields and PocketBase metadata\n *\n * @example\n * const LocationSchema = z.object({\n * coordinates: GeoPointField(),\n * homeLocation: GeoPointField().optional(),\n * });\n */\nexport function GeoPointField(): z.ZodObject<{\n lon: z.ZodNumber;\n lat: z.ZodNumber;\n}> {\n const schema = z.object({\n lon: z.number(),\n lat: z.number(),\n });\n\n // Build metadata\n const metadata = {\n [FIELD_METADATA_KEY]: {\n type: \"geoPoint\" as const,\n },\n };\n\n return schema.describe(JSON.stringify(metadata));\n}\n","import 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","/**\n * Collection ID generation utilities for PocketBase migrations\n */\n\nimport { createHash, randomBytes } from \"crypto\";\n\n/**\n * Generates a unique collection ID in PocketBase format\n * Format: pb_ followed by 15 alphanumeric lowercase characters\n *\n * @returns A unique collection ID string (e.g., \"pb_a1b2c3d4e5f6g7h\")\n */\nexport function generateCollectionId(): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const idLength = 15;\n\n // Generate cryptographically secure random bytes\n const bytes = randomBytes(idLength);\n\n // Convert bytes to alphanumeric characters\n let id = \"pb_\";\n for (let i = 0; i < idLength; i++) {\n const index = bytes[i] % chars.length;\n id += chars[index];\n }\n\n return id;\n}\n\n/**\n * Generates a unique field ID based on type and name\n * Format: type followed by 10 alphanumeric lowercase characters\n * If name is provided, the ID is deterministic\n *\n * @param type - PocketBase field type\n * @param name - Optional field name for deterministic ID\n * @returns A unique field ID string\n */\nexport function generateFieldId(type: string, name?: string): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const idLength = 10;\n\n let bytes: Buffer | Uint8Array;\n if (name) {\n // Deterministic based on name to ensure stability across runs\n bytes = createHash(\"sha256\").update(name).digest();\n } else {\n // Random\n bytes = randomBytes(idLength);\n }\n\n // Convert bytes to alphanumeric characters\n let suffix = \"\";\n for (let i = 0; i < idLength; i++) {\n const index = bytes[i] % chars.length;\n suffix += chars[index];\n }\n\n return `${type}${suffix}`;\n}\n\n/**\n * Registry to track generated collection IDs and ensure uniqueness within a migration batch\n */\nexport class CollectionIdRegistry {\n private ids: Set<string>;\n\n constructor() {\n this.ids = new Set<string>();\n }\n\n /**\n * Generates a unique collection ID for a given collection name\n * Retries up to 10 times if collision occurs (extremely rare)\n * Special case: returns \"_pb_users_auth_\" for users collection\n *\n * @param collectionName - The name of the collection (optional)\n * @returns A unique collection ID\n * @throws Error if unable to generate unique ID after max attempts\n */\n generate(collectionName?: string): string {\n // Special case: users collection always uses the constant\n if (collectionName && collectionName.toLowerCase() === \"users\") {\n const usersId = \"_pb_users_auth_\";\n if (!this.has(usersId)) {\n this.register(usersId);\n }\n return usersId;\n }\n\n const maxAttempts = 10;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const id = generateCollectionId();\n\n if (!this.has(id)) {\n this.register(id);\n return id;\n }\n }\n\n throw new Error(\"Failed to generate unique collection ID after maximum attempts\");\n }\n\n /**\n * Checks if an ID has already been registered\n *\n * @param id - The collection ID to check\n * @returns True if the ID exists in the registry\n */\n has(id: string): boolean {\n return this.ids.has(id);\n }\n\n /**\n * Registers a collection ID in the registry\n *\n * @param id - The collection ID to register\n */\n register(id: string): void {\n this.ids.add(id);\n }\n}\n","/**\n * Rule validator for PocketBase API rule expressions\n *\n * Validates permission rule expressions against PocketBase syntax rules,\n * including field references, @request references, and basic syntax validation.\n */\n\nimport type { APIRuleType, RuleExpression } from \"../utils/permissions\";\nimport type { FieldDefinition } from \"./types\";\nimport { generateFieldId } from \"./utils/collection-id-generator.js\";\n\n/**\n * Validation result for rule expressions\n */\nexport interface RuleValidationResult {\n /** Whether the rule expression is valid */\n valid: boolean;\n\n /** List of validation errors */\n errors: string[];\n\n /** List of validation warnings */\n warnings: string[];\n\n /** List of field references found in the expression */\n fieldReferences: string[];\n}\n\n/**\n * Rule expression validator\n *\n * Validates PocketBase API rule expressions for:\n * - Field reference existence and validity\n * - @request reference syntax\n * - Basic expression syntax (parentheses, operators)\n * - Auth collection specific rules (manageRule)\n */\nexport class RuleValidator {\n private fields: Map<string, FieldDefinition>;\n private collectionName: string;\n private isAuthCollection: boolean;\n\n constructor(collectionName: string, fields: FieldDefinition[], isAuthCollection: boolean = false) {\n this.collectionName = collectionName;\n this.fields = new Map(fields.map((f) => [f.name, f]));\n this.isAuthCollection = isAuthCollection;\n\n // Add system fields that are always available in PocketBase\n this.addSystemFields();\n }\n\n /**\n * Add system fields that are always available in PocketBase collections\n * These fields are automatically added by PocketBase and can be referenced in rules\n */\n private addSystemFields(): void {\n // Base system fields available in all collections\n const systemFields: FieldDefinition[] = [\n { name: \"id\", id: generateFieldId(\"text\", \"id\"), type: \"text\", required: true, options: {} },\n { name: \"created\", id: generateFieldId(\"date\", \"created\"), type: \"date\", required: true, options: {} },\n { name: \"updated\", id: generateFieldId(\"date\", \"updated\"), type: \"date\", required: true, options: {} },\n { name: \"collectionId\", id: generateFieldId(\"text\", \"collectionId\"), type: \"text\", required: true, options: {} },\n { name: \"collectionName\", id: generateFieldId(\"text\", \"collectionName\"), type: \"text\", required: true, options: {} },\n ];\n\n // Auth collection specific system fields\n if (this.isAuthCollection) {\n systemFields.push(\n { name: \"email\", id: generateFieldId(\"email\", \"email\"), type: \"email\", required: true, options: {} },\n { name: \"emailVisibility\", id: generateFieldId(\"bool\", \"emailVisibility\"), type: \"bool\", required: false, options: {} },\n { name: \"verified\", id: generateFieldId(\"bool\", \"verified\"), type: \"bool\", required: false, options: {} },\n { name: \"tokenKey\", id: generateFieldId(\"text\", \"tokenKey\"), type: \"text\", required: true, options: {} },\n { name: \"password\", id: generateFieldId(\"text\", \"password\"), type: \"text\", required: true, options: {} }\n );\n }\n\n // Add system fields to the fields map (don't overwrite user-defined fields)\n for (const field of systemFields) {\n if (!this.fields.has(field.name)) {\n this.fields.set(field.name, field);\n }\n }\n }\n\n /**\n * Validate a rule expression\n *\n * @param ruleType - The type of rule being validated\n * @param expression - The rule expression to validate\n * @returns Validation result with errors, warnings, and field references\n */\n validate(ruleType: APIRuleType, expression: RuleExpression): RuleValidationResult {\n const result: RuleValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n fieldReferences: [],\n };\n\n // Null means locked (superuser only) - always valid\n if (expression === null) {\n return result;\n }\n\n // Empty string means public - always valid but warn\n if (expression === \"\") {\n result.warnings.push(`${ruleType} is public - anyone can perform this operation`);\n return result;\n }\n\n // Validate manageRule only for auth collections\n if (ruleType === \"manageRule\" && !this.isAuthCollection) {\n result.valid = false;\n result.errors.push(\"manageRule is only valid for auth collections\");\n return result;\n }\n\n // Extract and validate field references\n const fieldRefs = this.extractFieldReferences(expression);\n result.fieldReferences = fieldRefs;\n\n for (const fieldRef of fieldRefs) {\n this.validateFieldReference(fieldRef, result);\n }\n\n // Validate @request references\n this.validateRequestReferences(expression, result);\n\n // Validate syntax patterns\n this.validateSyntax(expression, result);\n\n return result;\n }\n\n /**\n * Extract field references from expression\n *\n * Matches field names that are not @request references.\n * Handles dot notation for relations: user.email, post.author.name\n *\n * @param expression - The rule expression\n * @returns Array of unique field references\n */\n private extractFieldReferences(expression: string): string[] {\n const refs: string[] = [];\n\n // First, remove string literals and @request references to avoid matching them\n let cleaned = expression.replace(/\"[^\"]*\"/g, '\"\"').replace(/'[^']*'/g, \"''\");\n cleaned = cleaned.replace(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g, \"\");\n\n // Match field names (not starting with @)\n // Handles dot notation for relations: user.email, post.author.name\n const fieldPattern = /(?:^|[^@\\w])([a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*)(?=[^a-zA-Z0-9_.]|$)/g;\n\n let match;\n while ((match = fieldPattern.exec(cleaned)) !== null) {\n const ref = match[1];\n // Exclude PocketBase keywords and operators\n if (!this.isKeyword(ref)) {\n refs.push(ref);\n }\n }\n\n return [...new Set(refs)]; // Remove duplicates\n }\n\n /**\n * Check if a word is a PocketBase keyword\n *\n * @param word - The word to check\n * @returns True if the word is a keyword\n */\n private isKeyword(word: string): boolean {\n const keywords = [\"true\", \"false\", \"null\", \"AND\", \"OR\", \"NOT\", \"LIKE\", \"IN\"];\n return keywords.includes(word.toUpperCase());\n }\n\n /**\n * Validate a field reference exists in schema\n *\n * Checks if the root field exists and validates relation chains.\n * For nested references, warns about potential issues since we can't\n * validate across collections without loading related schemas.\n *\n * @param fieldRef - The field reference to validate (e.g., \"user\" or \"user.email\")\n * @param result - The validation result to update\n */\n private validateFieldReference(fieldRef: string, result: RuleValidationResult): void {\n const parts = fieldRef.split(\".\");\n const rootField = parts[0];\n\n if (!this.fields.has(rootField)) {\n result.errors.push(`Field '${rootField}' does not exist in collection '${this.collectionName}'`);\n result.valid = false;\n return;\n }\n\n // For nested references, validate relation chain\n if (parts.length > 1) {\n const field = this.fields.get(rootField)!;\n if (field.type !== \"relation\") {\n result.errors.push(`Field '${rootField}' is not a relation field, cannot access nested property '${parts[1]}'`);\n result.valid = false;\n } else {\n // Note: We can't validate nested fields without loading related schemas\n // This would require cross-schema validation\n result.warnings.push(\n `Nested field reference '${fieldRef}' - ensure target collection has field '${parts.slice(1).join(\".\")}'`\n );\n }\n }\n }\n\n /**\n * Validate @request references\n *\n * Checks that @request references follow valid PocketBase patterns:\n * - @request.auth.* - authenticated user data\n * - @request.body.* - request body fields\n * - @request.query.* - query parameters\n * - @request.headers.* - request headers\n * - @request.method - HTTP method\n * - @request.context - execution context\n *\n * @param expression - The rule expression\n * @param result - The validation result to update\n */\n private validateRequestReferences(expression: string, result: RuleValidationResult): void {\n // Find all @request references\n const requestRefs = expression.match(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];\n\n for (const ref of requestRefs) {\n // Check if the reference starts with a valid pattern\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\n /**\n * Validate basic syntax patterns\n *\n * Checks for:\n * - Balanced parentheses\n * - Common operator mistakes (== instead of =)\n *\n * @param expression - The rule expression\n * @param result - The validation result to update\n */\n private validateSyntax(expression: string, result: RuleValidationResult): void {\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 in expression\");\n result.valid = false;\n return;\n }\n }\n if (parenCount !== 0) {\n result.errors.push(\"Unbalanced parentheses in expression\");\n result.valid = false;\n }\n\n // Warn about common mistakes\n if (expression.includes(\"==\")) {\n result.warnings.push(\"Use '=' instead of '==' for equality comparison in PocketBase rules\");\n }\n }\n}\n","/**\n * Permission analyzer for extracting and validating permissions from Zod schemas\n *\n * This module provides utilities to:\n * - Extract permission metadata from Zod schema descriptions\n * - Resolve template configurations to concrete permission schemas\n * - Validate permission rules against collection fields\n * - Merge permissions with default values\n */\n\nimport { resolveTemplate } from \"../utils/permission-templates\";\nimport type { APIRuleType, PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\nimport type { RuleValidationResult } from \"./rule-validator\";\nimport { RuleValidator } from \"./rule-validator\";\nimport type { FieldDefinition } from \"./types\";\n\n/**\n * Extract and analyze permissions from schema\n *\n * The PermissionAnalyzer class provides methods to work with permission\n * definitions attached to Zod schemas, including extraction, resolution,\n * validation, and normalization.\n */\nexport class PermissionAnalyzer {\n /**\n * Extract permission metadata from Zod schema description\n *\n * Zod schemas can have permission metadata attached via the describe() method.\n * This method parses the description and extracts the permission configuration.\n *\n * @param schemaDescription - The Zod schema description string\n * @returns Permission schema if found, null otherwise\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const permissions = analyzer.extractPermissions(schema.description);\n * ```\n */\n extractPermissions(schemaDescription: string | undefined): PermissionSchema | null {\n if (!schemaDescription) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(schemaDescription);\n if (metadata.permissions) {\n return metadata.permissions;\n }\n } catch {\n // Not JSON or no permissions - this is expected for schemas without permissions\n return null;\n }\n\n return null;\n }\n\n /**\n * Resolve template configuration to concrete rules\n *\n * Takes either a template configuration or a direct permission schema\n * and returns a fully resolved permission schema with all rules defined.\n *\n * If the input is already a permission schema (has rule properties),\n * it's returned as-is. Otherwise, the template is resolved using the\n * template resolver.\n *\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n *\n * // Resolve from template\n * const permissions = analyzer.resolvePermissions({\n * template: 'owner-only',\n * ownerField: 'User'\n * });\n *\n * // Or pass direct schema\n * const permissions = analyzer.resolvePermissions({\n * listRule: '@request.auth.id != \"\"',\n * viewRule: '@request.auth.id != \"\"'\n * });\n * ```\n */\n resolvePermissions(config: PermissionTemplateConfig | PermissionSchema): PermissionSchema {\n // If it's already a permission schema (has rule properties), return as-is\n if (\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 return config as PermissionSchema;\n }\n\n // Otherwise resolve template\n return resolveTemplate(config as PermissionTemplateConfig);\n }\n\n /**\n * Validate all rules in a permission schema\n *\n * Validates each rule in the permission schema against the collection's\n * field definitions. Returns a map of validation results keyed by rule type.\n *\n * Only validates rules that are defined (not undefined). Undefined rules\n * are treated as null (locked) by default.\n *\n * @param collectionName - Name of the collection being validated\n * @param permissions - Permission schema to validate\n * @param fields - Collection field definitions\n * @param isAuthCollection - Whether this is an auth collection (allows manageRule)\n * @returns Map of validation results by rule type\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const results = analyzer.validatePermissions(\n * 'posts',\n * { listRule: '@request.auth.id != \"\"', viewRule: 'author = @request.auth.id' },\n * fields,\n * false\n * );\n *\n * for (const [ruleType, result] of results) {\n * if (!result.valid) {\n * console.error(`${ruleType} validation failed:`, result.errors);\n * }\n * }\n * ```\n */\n validatePermissions(\n collectionName: string,\n permissions: PermissionSchema,\n fields: FieldDefinition[],\n isAuthCollection: boolean = false\n ): Map<APIRuleType, RuleValidationResult> {\n const validator = new RuleValidator(collectionName, fields, isAuthCollection);\n const results = new Map<APIRuleType, RuleValidationResult>();\n\n // Define all possible rule types\n const ruleTypes: APIRuleType[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\"];\n\n // Add manageRule for auth collections\n if (isAuthCollection) {\n ruleTypes.push(\"manageRule\");\n }\n\n // Validate each defined rule\n for (const ruleType of ruleTypes) {\n const expression = permissions[ruleType];\n if (expression !== undefined) {\n results.set(ruleType, validator.validate(ruleType, expression));\n }\n }\n\n return results;\n }\n\n /**\n * Merge permissions with defaults\n *\n * Ensures all rule types have a defined value. Undefined rules are set\n * to null (locked to superusers only), which is the PocketBase default.\n *\n * This is useful when generating migrations to ensure all rules are\n * explicitly set in the collection configuration.\n *\n * @param permissions - Permission schema (may have undefined rules)\n * @returns Permission schema with all rules defined (null if not specified)\n *\n * @example\n * ```typescript\n * const analyzer = new PermissionAnalyzer();\n * const merged = analyzer.mergeWithDefaults({\n * listRule: '@request.auth.id != \"\"'\n * // other rules undefined\n * });\n *\n * // Result:\n * // {\n * // listRule: '@request.auth.id != \"\"',\n * // viewRule: null,\n * // createRule: null,\n * // updateRule: null,\n * // deleteRule: null,\n * // manageRule: null\n * // }\n * ```\n */\n mergeWithDefaults(permissions: 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 * Collection name pluralization utilities\n */\n\n/**\n * Special case pluralization rules\n * Maps singular forms to their plural forms\n */\nconst SPECIAL_CASES: Record<string, string> = {\n // Common irregular plurals\n person: \"people\",\n Person: \"People\",\n child: \"children\",\n Child: \"Children\",\n man: \"men\",\n Man: \"Men\",\n woman: \"women\",\n Woman: \"Women\",\n tooth: \"teeth\",\n Tooth: \"Teeth\",\n foot: \"feet\",\n Foot: \"Feet\",\n mouse: \"mice\",\n Mouse: \"Mice\",\n goose: \"geese\",\n Goose: \"Geese\",\n\n // Words ending in -y\n category: \"categories\",\n Category: \"Categories\",\n company: \"companies\",\n Company: \"Companies\",\n city: \"cities\",\n City: \"Cities\",\n country: \"countries\",\n Country: \"Countries\",\n story: \"stories\",\n Story: \"Stories\",\n party: \"parties\",\n Party: \"Parties\",\n family: \"families\",\n Family: \"Families\",\n activity: \"activities\",\n Activity: \"Activities\",\n priority: \"priorities\",\n Priority: \"Priorities\",\n\n // Words ending in -f or -fe\n life: \"lives\",\n Life: \"Lives\",\n wife: \"wives\",\n Wife: \"Wives\",\n knife: \"knives\",\n Knife: \"Knives\",\n leaf: \"leaves\",\n Leaf: \"Leaves\",\n shelf: \"shelves\",\n Shelf: \"Shelves\",\n half: \"halves\",\n Half: \"Halves\",\n\n // Words ending in -is\n analysis: \"analyses\",\n Analysis: \"Analyses\",\n basis: \"bases\",\n Basis: \"Bases\",\n crisis: \"crises\",\n Crisis: \"Crises\",\n thesis: \"theses\",\n Thesis: \"Theses\",\n\n // Words ending in -us\n cactus: \"cacti\",\n Cactus: \"Cacti\",\n focus: \"foci\",\n Focus: \"Foci\",\n fungus: \"fungi\",\n Fungus: \"Fungi\",\n nucleus: \"nuclei\",\n Nucleus: \"Nuclei\",\n radius: \"radii\",\n Radius: \"Radii\",\n\n // Words ending in -on\n phenomenon: \"phenomena\",\n Phenomenon: \"Phenomena\",\n criterion: \"criteria\",\n Criterion: \"Criteria\",\n\n // Words ending in -um\n datum: \"data\",\n Datum: \"Data\",\n medium: \"media\",\n Medium: \"Media\",\n curriculum: \"curricula\",\n Curriculum: \"Curricula\",\n\n // Unchanged plurals\n sheep: \"sheep\",\n Sheep: \"Sheep\",\n deer: \"deer\",\n Deer: \"Deer\",\n fish: \"fish\",\n Fish: \"Fish\",\n species: \"species\",\n Species: \"Species\",\n series: \"series\",\n Series: \"Series\",\n};\n\n/**\n * Pluralizes a singular noun to its plural form\n * Handles special cases and common English pluralization rules\n *\n * @param singular - The singular form of the noun\n * @returns The plural form of the noun\n */\nexport function pluralize(singular: string): string {\n // Check special cases first (before checking if already plural)\n if (SPECIAL_CASES[singular]) {\n return SPECIAL_CASES[singular];\n }\n\n // Check if it's already plural (ends with 's' and is longer than 3 chars)\n if (singular.length > 3 && singular.endsWith(\"s\") && !singular.endsWith(\"ss\")) {\n // Could already be plural, return as-is\n return singular;\n }\n\n // Preserve case for the transformation\n const lowerSingular = singular.toLowerCase();\n\n let plural: string;\n\n // Rule 1: Words ending in -s, -ss, -sh, -ch, -x, -z -> add -es\n if (/(?:s|ss|sh|ch|x|z)$/.test(lowerSingular)) {\n plural = singular + \"es\";\n }\n // Rule 2: Words ending in consonant + y -> change y to ies\n else if (/[^aeiou]y$/.test(lowerSingular)) {\n plural = singular.slice(0, -1) + \"ies\";\n }\n // Rule 3: Words ending in consonant + o -> add -es\n else if (/[^aeiou]o$/.test(lowerSingular)) {\n plural = singular + \"es\";\n }\n // Rule 4: Words ending in -f or -fe -> change to -ves\n else if (/fe?$/.test(lowerSingular)) {\n if (lowerSingular.endsWith(\"fe\")) {\n plural = singular.slice(0, -2) + \"ves\";\n } else {\n plural = singular.slice(0, -1) + \"ves\";\n }\n }\n // Rule 5: Default -> add -s\n else {\n plural = singular + \"s\";\n }\n\n return plural;\n}\n\n/**\n * Converts a singular entity name to a collection name\n * This is an alias for pluralize for better semantic clarity\n *\n * @param entityName - The singular entity name (e.g., \"User\", \"Project\")\n * @returns The collection name (e.g., \"Users\", \"Projects\")\n */\nexport function toCollectionName(entityName: string): string {\n return pluralize(entityName);\n}\n\n/**\n * Attempts to singularize a plural noun (reverse of pluralize)\n * Note: This is a best-effort implementation and may not handle all edge cases\n *\n * @param plural - The plural form of the noun\n * @returns The singular form of the noun\n */\nexport function singularize(plural: string): string {\n // Check reverse special cases\n for (const [singular, pluralForm] of Object.entries(SPECIAL_CASES)) {\n if (pluralForm === plural) {\n return singular;\n }\n }\n\n const lower = plural.toLowerCase();\n\n // Rule 1: Words ending in -ies -> change to -y\n if (lower.endsWith(\"ies\") && plural.length > 3) {\n return plural.slice(0, -3) + \"y\";\n }\n\n // Rule 2: Words ending in -ves -> change to -f or -fe\n if (lower.endsWith(\"ves\")) {\n // Try -fe first (more common)\n return plural.slice(0, -3) + \"fe\";\n }\n\n // Rule 3: Words ending in -ses, -shes, -ches, -xes, -zes -> remove -es\n if (/(?:ses|shes|ches|xes|zes)$/.test(lower)) {\n return plural.slice(0, -2);\n }\n\n // Rule 4: Words ending in -s -> remove -s\n if (lower.endsWith(\"s\") && plural.length > 1) {\n return plural.slice(0, -1);\n }\n\n // Default: return as-is\n return plural;\n}\n","/**\n * Relation field detection utilities\n */\n\nimport { z } from \"zod\";\nimport { pluralize } from \"./pluralize\";\n\n/**\n * Detects if a field is a single relation based on naming convention\n * Single relation: field name matches a collection name (e.g., \"User\" -> \"Users\" collection)\n */\nfunction unwrapType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let unwrappedType = zodType;\n\n if (unwrappedType instanceof z.ZodOptional) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n if (unwrappedType instanceof z.ZodNullable) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n if (unwrappedType instanceof z.ZodDefault) {\n unwrappedType = unwrappedType.unwrap() as z.ZodTypeAny;\n }\n\n return unwrappedType;\n}\n\nfunction getChecks(zodType: z.ZodTypeAny): any[] {\n const def = (zodType as any).def ?? (zodType as any)._def;\n return (def?.checks ?? []) as any[];\n}\n\nfunction getJsonSchema(zodType: z.ZodTypeAny): any | null {\n try {\n const toJSONSchema = (zodType as any).toJSONSchema;\n return typeof toJSONSchema === \"function\" ? toJSONSchema.call(zodType) : null;\n } catch {\n return null;\n }\n}\n\nexport function isSingleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n const unwrappedType = unwrapType(zodType);\n\n // Must be a string type\n if (!(unwrappedType instanceof z.ZodString)) {\n return false;\n }\n\n // Field name should start with uppercase (convention for entity references)\n // and not be a common string field name\n const startsWithUppercase = /^[A-Z]/.test(fieldName);\n\n // Exclude common string fields that start with uppercase\n const commonStringFields = [\"Title\", \"Name\", \"Description\", \"Content\", \"Summary\", \"Status\", \"Type\"];\n const isCommonField = commonStringFields.includes(fieldName);\n\n return startsWithUppercase && !isCommonField;\n}\n\n/**\n * Detects if a field is a multiple relation based on naming convention\n * Multiple relation: field name is an array of strings ending with entity name\n * (e.g., \"SubscriberUsers\" -> \"Users\" collection)\n */\nexport function isMultipleRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n const unwrappedType = unwrapType(zodType);\n\n // Must be an array type\n if (!(unwrappedType instanceof z.ZodArray)) {\n return false;\n }\n\n // Element type must be string\n const elementType = unwrappedType.element;\n if (!(elementType instanceof z.ZodString)) {\n return false;\n }\n\n // Field name should contain an uppercase letter (entity reference pattern)\n const hasUppercase = /[A-Z]/.test(fieldName);\n\n return hasUppercase;\n}\n\n/**\n * Resolves the target collection name from a relation field name\n * Examples:\n * - \"User\" -> \"Users\"\n * - \"SubscriberUsers\" -> \"Users\"\n * - \"Author\" -> \"Authors\"\n * - \"Category\" -> \"Categories\"\n */\nexport function resolveTargetCollection(fieldName: string): string {\n // For single relations, the field name is typically the entity name\n // For multiple relations, extract the entity name from the end\n\n // Check if field name ends with a known plural entity name\n // Common patterns: \"SubscriberUsers\", \"RelatedPosts\", \"Tags\"\n\n // Try to find the entity name by looking for uppercase letters\n const matches = fieldName.match(/[A-Z][a-z]+/g);\n\n if (!matches || matches.length === 0) {\n // Fallback: pluralize the entire field name\n return pluralize(fieldName);\n }\n\n // Take the last matched entity name (e.g., \"Users\" from \"SubscriberUsers\")\n const entityName = matches[matches.length - 1];\n\n // Pluralize the entity name to get collection name\n return pluralize(entityName);\n}\n\n/**\n * Detects if a field is any type of relation (single or multiple)\n */\nexport function isRelationField(fieldName: string, zodType: z.ZodTypeAny): boolean {\n return isSingleRelationField(fieldName, zodType) || isMultipleRelationField(fieldName, zodType);\n}\n\n/**\n * Gets the maximum number of relations allowed for a relation field\n * Returns 1 for single relations, or the max constraint for multiple relations\n */\nexport function getMaxSelect(fieldName: string, zodType: z.ZodTypeAny): number {\n if (isSingleRelationField(fieldName, zodType)) {\n return 1;\n }\n\n if (isMultipleRelationField(fieldName, zodType)) {\n const unwrappedType = unwrapType(zodType);\n if (unwrappedType instanceof z.ZodArray) {\n const checks = getChecks(unwrappedType);\n const maxCheck = checks.find((check) => check.kind === \"max\");\n if (maxCheck) {\n return maxCheck.value;\n }\n const schema = getJsonSchema(unwrappedType);\n if (schema && typeof schema.maxItems === \"number\") {\n return schema.maxItems;\n }\n // Default to 999 for multiple relations without explicit max\n return 999;\n }\n }\n\n return 1;\n}\n\n/**\n * Gets the minimum number of relations required for a relation field\n * Returns 0 as default for all relation fields (single or multiple)\n * PocketBase always expects minSelect to be defined for relation fields\n */\nexport function getMinSelect(fieldName: string, zodType: z.ZodTypeAny): number {\n // For single relations, always return 0\n if (isSingleRelationField(fieldName, zodType)) {\n return 0;\n }\n\n // For multiple relations, check for explicit min constraint\n if (isMultipleRelationField(fieldName, zodType)) {\n const unwrappedType = unwrapType(zodType);\n if (unwrappedType instanceof z.ZodArray) {\n const checks = getChecks(unwrappedType);\n const minCheck = checks.find((check) => check.kind === \"min\");\n if (minCheck) {\n return minCheck.value;\n }\n const schema = getJsonSchema(unwrappedType);\n if (schema && typeof schema.minItems === \"number\") {\n return schema.minItems;\n }\n }\n }\n\n // Default to 0 for all relation fields\n return 0;\n}\n","/**\n * Zod to PocketBase type mapping utilities\n *\n * This module provides comprehensive mapping between Zod schema types\n * and PocketBase field types, including support for all PocketBase field types:\n * - text, email, url, editor\n * - number, bool\n * - date, autodate\n * - select (single/multiple)\n * - relation (single/multiple)\n * - file (single/multiple)\n * - json\n * - geoPoint\n */\n\nimport { z } from \"zod\";\nimport type { PocketBaseFieldType } from \"../types\";\nimport { extractFieldMetadata, FIELD_METADATA_KEY } from \"../../schema/fields\";\n\n// Re-export extractFieldMetadata from fields.ts for backward compatibility\nexport { extractFieldMetadata, FIELD_METADATA_KEY };\nexport type { FieldMetadata } from \"../../schema/fields\";\n\n/**\n * All supported PocketBase field types\n */\nexport const POCKETBASE_FIELD_TYPES: readonly PocketBaseFieldType[] = [\n \"text\",\n \"email\",\n \"url\",\n \"number\",\n \"bool\",\n \"date\",\n \"select\",\n \"relation\",\n \"file\",\n \"json\",\n \"editor\",\n \"geoPoint\",\n \"autodate\",\n \"password\",\n] as const;\n\n/**\n * Field type metadata for documentation and validation\n */\nexport interface FieldTypeInfo {\n type: PocketBaseFieldType;\n description: string;\n zodTypes: string[];\n supportsMultiple: boolean;\n}\n\n/**\n * Metadata about each PocketBase field type\n */\nexport const FIELD_TYPE_INFO: Record<PocketBaseFieldType, FieldTypeInfo> = {\n text: {\n type: \"text\",\n description: \"Plain text field\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n password: {\n type: \"password\",\n description: \"Password field (system)\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n email: {\n type: \"email\",\n description: \"Email address field with validation\",\n zodTypes: [\"ZodString with email()\"],\n supportsMultiple: false,\n },\n url: {\n type: \"url\",\n description: \"URL field with validation\",\n zodTypes: [\"ZodString with url()\"],\n supportsMultiple: false,\n },\n editor: {\n type: \"editor\",\n description: \"Rich text editor field\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n number: {\n type: \"number\",\n description: \"Numeric field (integer or float)\",\n zodTypes: [\"ZodNumber\"],\n supportsMultiple: false,\n },\n bool: {\n type: \"bool\",\n description: \"Boolean field\",\n zodTypes: [\"ZodBoolean\"],\n supportsMultiple: false,\n },\n date: {\n type: \"date\",\n description: \"Date/datetime field\",\n zodTypes: [\"ZodDate\", \"ZodString with datetime format\"],\n supportsMultiple: false,\n },\n autodate: {\n type: \"autodate\",\n description: \"Auto-managed date field (created/updated)\",\n zodTypes: [\"ZodString\"],\n supportsMultiple: false,\n },\n select: {\n type: \"select\",\n description: \"Single or multiple select from predefined values\",\n zodTypes: [\"ZodEnum\", \"ZodArray<ZodEnum>\"],\n supportsMultiple: true,\n },\n relation: {\n type: \"relation\",\n description: \"Reference to another collection\",\n zodTypes: [\"ZodString\", \"ZodArray<ZodString>\"],\n supportsMultiple: true,\n },\n file: {\n type: \"file\",\n description: \"File upload field\",\n zodTypes: [\"File\", \"ZodArray<File>\"],\n supportsMultiple: true,\n },\n json: {\n type: \"json\",\n description: \"JSON data field\",\n zodTypes: [\"ZodRecord\", \"ZodObject\", \"ZodArray\"],\n supportsMultiple: false,\n },\n geoPoint: {\n type: \"geoPoint\",\n description: \"Geographic coordinates (lon, lat)\",\n zodTypes: [\"ZodObject with lon/lat\"],\n supportsMultiple: false,\n },\n};\n\nfunction getChecks(zodType: z.ZodTypeAny): any[] {\n const def = (zodType as any).def ?? (zodType as any)._def;\n return (def?.checks ?? []) as any[];\n}\n\nfunction getJsonSchema(zodType: z.ZodTypeAny): any | null {\n try {\n const toJSONSchema = (zodType as any).toJSONSchema;\n return typeof toJSONSchema === \"function\" ? toJSONSchema.call(zodType) : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Maps Zod string types to PocketBase field types\n */\nexport function mapZodStringType(zodType: z.ZodString): PocketBaseFieldType {\n const checks = getChecks(zodType);\n\n // Check for email validation\n const hasEmail = checks.some((check: any) => check.kind === \"email\" || check.def?.format === \"email\");\n if (hasEmail) {\n return \"email\";\n }\n\n // Check for URL validation\n const hasUrl = checks.some((check: any) => check.kind === \"url\" || check.def?.format === \"url\");\n if (hasUrl) {\n return \"url\";\n }\n\n // Check for datetime validation (could be date field)\n const hasDatetime = checks.some(\n (check: any) => check.kind === \"datetime\" || check.def?.format === \"datetime\" || check.def?.format === \"date-time\"\n );\n if (hasDatetime) {\n return \"date\";\n }\n\n // Default to text\n return \"text\";\n}\n\n/**\n * Maps Zod number types to PocketBase number type\n */\nexport function mapZodNumberType(_zodType: z.ZodNumber): PocketBaseFieldType {\n return \"number\";\n}\n\n/**\n * Maps Zod boolean types to PocketBase bool type\n */\nexport function mapZodBooleanType(_zodType: z.ZodBoolean): PocketBaseFieldType {\n return \"bool\";\n}\n\n/**\n * Maps Zod enum types to PocketBase select type\n */\nexport function mapZodEnumType(_zodType: z.ZodEnum<any>): PocketBaseFieldType {\n return \"select\";\n}\n\n/**\n * Maps Zod array types to appropriate PocketBase types\n * Arrays of strings could be relations or file fields depending on context\n */\nexport function mapZodArrayType(zodType: z.ZodArray<any>, _fieldName: string): PocketBaseFieldType {\n const elementType = zodType.element as z.ZodTypeAny;\n\n if (elementType instanceof z.ZodFile) {\n return \"file\";\n }\n\n // Array of strings - could be relation (will be determined by relation detector)\n if (elementType instanceof z.ZodString) {\n return \"relation\";\n }\n\n // Default to JSON for other array types\n return \"json\";\n}\n\n/**\n * Maps Zod date types to PocketBase date type\n */\nexport function mapZodDateType(_zodType: z.ZodDate): PocketBaseFieldType {\n return \"date\";\n}\n\n/**\n * Maps Zod record/object types to PocketBase JSON type\n */\nexport function mapZodRecordType(_zodType: z.ZodRecord | z.ZodObject<any>): PocketBaseFieldType {\n return \"json\";\n}\n\n/**\n * Main type mapping function that determines PocketBase field type from Zod type\n */\nexport function mapZodTypeToPocketBase(zodType: z.ZodTypeAny, fieldName: string): PocketBaseFieldType {\n const unwrappedType = unwrapZodType(zodType);\n\n // Check for metadata first (explicit type overrides)\n const metadata = extractFieldMetadata(unwrappedType.description);\n if (metadata && metadata.type) {\n return metadata.type;\n }\n\n if (unwrappedType instanceof z.ZodFile) {\n return \"file\";\n }\n\n // Map based on Zod type\n let type: PocketBaseFieldType = \"text\";\n\n if (unwrappedType instanceof z.ZodString) {\n type = mapZodStringType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodNumber) {\n type = mapZodNumberType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodBoolean) {\n type = mapZodBooleanType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodEnum) {\n type = mapZodEnumType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodArray) {\n type = mapZodArrayType(unwrappedType, fieldName);\n } else if (unwrappedType instanceof z.ZodDate) {\n type = mapZodDateType(unwrappedType);\n } else if (unwrappedType instanceof z.ZodRecord || unwrappedType instanceof z.ZodObject) {\n type = mapZodRecordType(unwrappedType);\n }\n\n return type;\n}\n\n/**\n * Extracts field options from Zod type (min, max, pattern, etc.)\n */\nexport function extractFieldOptions(zodType: z.ZodTypeAny): Record<string, any> {\n const options: Record<string, any> = {};\n\n const unwrappedType = unwrapZodType(zodType);\n const checks = getChecks(unwrappedType);\n\n // Extract string constraints\n if (unwrappedType instanceof z.ZodString) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n if (check.kind === \"regex\") {\n options.pattern = check.regex.source;\n }\n }\n\n if (options.min === undefined || options.max === undefined || options.pattern === undefined) {\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.min === undefined && typeof schema.minLength === \"number\") {\n options.min = schema.minLength;\n }\n if (options.max === undefined && typeof schema.maxLength === \"number\") {\n options.max = schema.maxLength;\n }\n if (options.pattern === undefined && typeof schema.pattern === \"string\") {\n options.pattern = schema.pattern;\n }\n }\n }\n }\n\n // Extract number constraints\n if (unwrappedType instanceof z.ZodNumber) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n }\n\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.min === undefined && typeof schema.minimum === \"number\") {\n options.min = schema.minimum;\n }\n if (options.max === undefined && typeof schema.maximum === \"number\") {\n options.max = schema.maximum;\n }\n }\n\n // `z.number().int()` is how an integer column is spelled in Zod; it maps\n // onto PocketBase's onlyInt, which the generator writes from noDecimal\n const isInteger =\n schema?.type === \"integer\" ||\n checks.some((check: any) => check.kind === \"int\" || String(check.def?.format ?? \"\").includes(\"int\"));\n if (isInteger) {\n options.noDecimal = true;\n }\n }\n\n // Extract enum values\n if (unwrappedType instanceof z.ZodEnum) {\n options.values = unwrappedType.options.map(String);\n }\n\n // Extract array constraints\n if (unwrappedType instanceof z.ZodArray) {\n const arrayChecks = getChecks(unwrappedType);\n for (const check of arrayChecks) {\n if (check.kind === \"min\") {\n options.minSelect = check.value;\n }\n if (check.kind === \"max\") {\n options.maxSelect = check.value;\n }\n }\n\n if (options.minSelect === undefined || options.maxSelect === undefined) {\n const schema = getJsonSchema(unwrappedType);\n if (schema) {\n if (options.minSelect === undefined && typeof schema.minItems === \"number\") {\n options.minSelect = schema.minItems;\n }\n if (options.maxSelect === undefined && typeof schema.maxItems === \"number\") {\n options.maxSelect = schema.maxItems;\n }\n }\n }\n }\n\n return options;\n}\n\n/**\n * Determines if a Zod field is required (not optional)\n */\nexport function isFieldRequired(zodType: z.ZodTypeAny): boolean {\n // Check if it's optional\n if (zodType instanceof z.ZodOptional) {\n return false;\n }\n\n // Check if it has a default value (makes it optional)\n if (zodType instanceof z.ZodDefault) {\n return false;\n }\n\n // Check for nullable (in PocketBase context, nullable means optional)\n if (zodType instanceof z.ZodNullable) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Unwraps a Zod type to get the inner type\n * Handles optional, nullable, and default wrappers\n */\nexport function unwrapZodType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let unwrapped = zodType;\n let previous = null;\n\n while (unwrapped !== previous) {\n previous = unwrapped;\n if (unwrapped instanceof z.ZodOptional) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n } else if (unwrapped instanceof z.ZodNullable) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n } else if (unwrapped instanceof z.ZodDefault) {\n unwrapped = unwrapped.unwrap() as z.ZodTypeAny;\n }\n }\n\n return unwrapped;\n}\n\n/**\n * Gets the default value from a Zod type if it has one\n */\nexport function getDefaultValue(zodType: z.ZodTypeAny): any {\n if (zodType instanceof z.ZodDefault) {\n return zodType.def.defaultValue;\n }\n return undefined;\n}\n\n/**\n * Checks if a Zod type is an array type\n */\nexport function isArrayType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapZodType(zodType);\n return unwrapped instanceof z.ZodArray;\n}\n\n/**\n * Gets the element type of an array Zod type\n */\nexport function getArrayElementType(zodType: z.ZodTypeAny): z.ZodTypeAny | null {\n const unwrapped = unwrapZodType(zodType);\n if (unwrapped instanceof z.ZodArray) {\n return unwrapped.element as z.ZodTypeAny;\n }\n return null;\n}\n\n/**\n * Checks if a Zod type represents a geo point (object with lon/lat)\n */\nexport function isGeoPointType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapZodType(zodType);\n if (!(unwrapped instanceof z.ZodObject)) {\n return false;\n }\n\n const shape = unwrapped.shape;\n const hasLon = \"lon\" in shape && shape.lon instanceof z.ZodNumber;\n const hasLat = \"lat\" in shape && shape.lat instanceof z.ZodNumber;\n\n return hasLon && hasLat;\n}\n\n/**\n * Complete field options extracted from a Zod type\n */\nexport interface ExtractedFieldOptions {\n min?: number;\n max?: number;\n pattern?: string;\n values?: string[];\n minSelect?: number;\n maxSelect?: number;\n mimeTypes?: string[];\n maxSize?: number;\n thumbs?: string[];\n}\n\n/**\n * Extracts comprehensive field options from Zod type\n * Includes all constraints that can be mapped to PocketBase field options\n */\nexport function extractComprehensiveFieldOptions(zodType: z.ZodTypeAny): ExtractedFieldOptions {\n const options: ExtractedFieldOptions = {};\n const unwrapped = unwrapZodType(zodType);\n const checks = getChecks(unwrapped);\n\n // Extract string constraints\n if (unwrapped instanceof z.ZodString) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n if (check.kind === \"regex\") {\n options.pattern = check.regex.source;\n }\n }\n\n if (options.min === undefined || options.max === undefined || options.pattern === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.min === undefined && typeof schema.minLength === \"number\") {\n options.min = schema.minLength;\n }\n if (options.max === undefined && typeof schema.maxLength === \"number\") {\n options.max = schema.maxLength;\n }\n if (options.pattern === undefined && typeof schema.pattern === \"string\") {\n options.pattern = schema.pattern;\n }\n }\n }\n }\n\n // Extract number constraints\n if (unwrapped instanceof z.ZodNumber) {\n for (const check of checks) {\n if (check.kind === \"min\") {\n options.min = check.value;\n }\n if (check.kind === \"max\") {\n options.max = check.value;\n }\n }\n\n if (options.min === undefined || options.max === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.min === undefined && typeof schema.minimum === \"number\") {\n options.min = schema.minimum;\n }\n if (options.max === undefined && typeof schema.maximum === \"number\") {\n options.max = schema.maximum;\n }\n }\n }\n }\n\n // Extract enum values\n if (unwrapped instanceof z.ZodEnum) {\n options.values = unwrapped.options.map(String);\n }\n\n // Extract array constraints\n if (unwrapped instanceof z.ZodArray) {\n const arrayChecks = getChecks(unwrapped);\n for (const check of arrayChecks) {\n if (check.kind === \"min\") {\n options.minSelect = check.value;\n }\n if (check.kind === \"max\") {\n options.maxSelect = check.value;\n }\n }\n\n if (options.minSelect === undefined || options.maxSelect === undefined) {\n const schema = getJsonSchema(unwrapped);\n if (schema) {\n if (options.minSelect === undefined && typeof schema.minItems === \"number\") {\n options.minSelect = schema.minItems;\n }\n if (options.maxSelect === undefined && typeof schema.maxItems === \"number\") {\n options.maxSelect = schema.maxItems;\n }\n }\n }\n\n // Check for enum element type\n const elementType = unwrapped.element as z.ZodTypeAny;\n if (elementType instanceof z.ZodEnum) {\n options.values = elementType.options.map(String);\n }\n }\n\n return options;\n}\n\n\n\n/**\n * Options every PocketBase field carries, whatever its type\n */\nconst UNIVERSAL_FIELD_OPTIONS = [\"hidden\", \"presentable\", \"system\"] as const;\n\n/**\n * The options PocketBase actually stores per field type.\n *\n * Zod validators do not line up with PocketBase's option set: `z.string()\n * .email()` carries a regex that becomes `pattern`, but PocketBase's `email`\n * type has no `pattern` and drops it on save. Emitting one leaves the\n * migration file describing a collection the server never had — the file and\n * the database disagree from the moment it is applied.\n *\n * Keys are PocketBase's own, plus the internal aliases the generator\n * translates on the way out (`noDecimal` -> `onlyInt`).\n */\nconst SUPPORTED_FIELD_OPTIONS: Record<PocketBaseFieldType, readonly string[]> = {\n text: [\"min\", \"max\", \"pattern\", \"autogeneratePattern\", \"primaryKey\"],\n password: [\"min\", \"max\", \"pattern\", \"cost\"],\n email: [\"exceptDomains\", \"onlyDomains\"],\n url: [\"exceptDomains\", \"onlyDomains\"],\n editor: [\"convertURLs\", \"maxSize\"],\n number: [\"min\", \"max\", \"onlyInt\", \"noDecimal\"],\n bool: [],\n date: [\"min\", \"max\"],\n autodate: [\"onCreate\", \"onUpdate\"],\n select: [\"values\", \"maxSelect\"],\n file: [\"mimeTypes\", \"thumbs\", \"maxSelect\", \"maxSize\", \"protected\"],\n relation: [\"collectionId\", \"cascadeDelete\", \"minSelect\", \"maxSelect\"],\n json: [\"maxSize\"],\n geoPoint: [],\n};\n\n/**\n * The option keys a field of `fieldType` can carry — the same set the\n * generator is allowed to emit.\n *\n * The reader (`pocketbase-converter.extractFieldOptions`) uses this so that\n * every option the generator writes is read back on replay. A key that is\n * emitted but not read makes `compare()` see a modification on every run and\n * emit the same `updated_*` migration forever.\n *\n * @param fieldType - The PocketBase field type, if known\n * @returns The option keys readable for that type (every known key when the\n * type is unrecognized)\n */\nexport function getSupportedFieldOptionKeys(fieldType?: string): string[] {\n const typeSpecific =\n fieldType && fieldType in SUPPORTED_FIELD_OPTIONS\n ? SUPPORTED_FIELD_OPTIONS[fieldType as PocketBaseFieldType]\n : Object.values(SUPPORTED_FIELD_OPTIONS).flat();\n\n return [...new Set([...typeSpecific, ...UNIVERSAL_FIELD_OPTIONS])];\n}\n\n/**\n * Drops the options a PocketBase field type does not support.\n *\n * @param fieldType - The resolved PocketBase field type\n * @param options - Options collected from the Zod schema or field metadata\n * @returns The supported subset, or undefined when nothing is left\n */\nexport function filterSupportedFieldOptions(\n fieldType: PocketBaseFieldType,\n options: Record<string, any> | undefined\n): Record<string, any> | undefined {\n if (!options) {\n return options;\n }\n\n const supported = SUPPORTED_FIELD_OPTIONS[fieldType];\n if (!supported) {\n return options;\n }\n\n const allowed = new Set<string>([...supported, ...UNIVERSAL_FIELD_OPTIONS]);\n const filtered: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(options)) {\n if (allowed.has(key)) {\n filtered[key] = value;\n }\n }\n\n return Object.keys(filtered).length > 0 ? filtered : undefined;\n}\n\n/**\n * Gets the PocketBase field type with additional context\n */\nexport interface FieldTypeResult {\n type: PocketBaseFieldType;\n isMultiple: boolean;\n options: ExtractedFieldOptions;\n}\n\n/**\n * Comprehensive type mapping that returns full field information\n */\nexport function getFieldTypeInfo(zodType: z.ZodTypeAny, fieldName: string): FieldTypeResult {\n const type = mapZodTypeToPocketBase(zodType, fieldName);\n const isMultiple = isArrayType(zodType);\n const options = extractComprehensiveFieldOptions(zodType);\n\n return {\n type,\n isMultiple,\n options,\n };\n}\n","import { z } from \"zod\";\nimport type { RuleExpression } from \"../utils/permissions\";\nimport { defineCollection } from \"./base\";\n\n/**\n * Permission rules that apply to a view collection\n *\n * View collections are read-only: PocketBase rejects createRule, updateRule,\n * deleteRule and manageRule on them, so only the two read rules are accepted.\n */\nexport interface ViewPermissionSchema {\n /** Controls who can list/query the view's rows */\n listRule?: RuleExpression;\n\n /** Controls who can view an individual row */\n viewRule?: RuleExpression;\n}\n\n/**\n * Configuration options for defining a view collection\n */\nexport interface ViewCollectionConfig {\n /**\n * The name of the PocketBase collection\n */\n collectionName: string;\n\n /**\n * The Zod schema describing the shape of a row\n *\n * For views this is used for TypeScript type generation and application-side\n * parsing only - PocketBase derives the collection's actual fields from the\n * SQL query when the collection is saved.\n */\n schema: z.ZodObject<any>;\n\n /**\n * The SQL SELECT statement backing the view\n *\n * Use the `sql` tagged template for consistent formatting.\n */\n viewQuery: string;\n\n /**\n * Optional read permissions (listRule / viewRule)\n */\n permissions?: ViewPermissionSchema;\n}\n\n/**\n * Removes the common leading indentation from a multi-line string and trims\n * blank leading/trailing lines\n *\n * Keeps generated migrations stable when a query is re-indented in the source\n * file, since only the relative indentation is preserved. Also used when\n * reading a query back out of a migration file, where the generator has\n * indented it to fit the surrounding code.\n *\n * @param value - Raw multi-line string\n * @returns Dedented string\n */\nexport function dedentSql(value: string): string {\n const lines = value.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\n // Drop leading and trailing blank lines\n while (lines.length > 0 && lines[0].trim() === \"\") {\n lines.shift();\n }\n while (lines.length > 0 && lines[lines.length - 1].trim() === \"\") {\n lines.pop();\n }\n\n if (lines.length === 0) {\n return \"\";\n }\n\n // Find the smallest indentation across all non-blank lines\n let minIndent = Infinity;\n for (const line of lines) {\n if (line.trim() === \"\") continue;\n const indent = line.length - line.trimStart().length;\n if (indent < minIndent) {\n minIndent = indent;\n }\n }\n\n if (!Number.isFinite(minIndent) || minIndent === 0) {\n return lines.map((line) => line.trimEnd()).join(\"\\n\");\n }\n\n return lines.map((line) => line.slice(minIndent).trimEnd()).join(\"\\n\");\n}\n\n/**\n * Tagged template for SQL view queries\n *\n * Interpolates values, strips the common leading indentation and trims blank\n * leading/trailing lines. Returns a plain string, so a regular string literal\n * works anywhere `sql` does.\n *\n * @example\n * const query = sql`\n * SELECT p.id AS id, p.title AS title\n * FROM Projects p\n * `;\n * // \"SELECT p.id AS id, p.title AS title\\n FROM Projects p\"\n */\nexport function sql(strings: TemplateStringsArray, ...values: Array<string | number>): string {\n let result = \"\";\n\n for (let i = 0; i < strings.length; i++) {\n result += strings[i];\n if (i < values.length) {\n result += String(values[i]);\n }\n }\n\n return dedentSql(result);\n}\n\n/**\n * Strips SQL comments and leading whitespace so the first real token can be checked\n *\n * @param query - The SQL query\n * @returns The query with leading comments and whitespace removed\n */\nfunction stripLeadingComments(query: string): string {\n let remaining = query.trim();\n\n // Repeatedly strip line comments (-- ...) and block comments (/* ... */)\n while (remaining.length > 0) {\n if (remaining.startsWith(\"--\")) {\n const newline = remaining.indexOf(\"\\n\");\n remaining = newline === -1 ? \"\" : remaining.slice(newline + 1).trim();\n continue;\n }\n\n if (remaining.startsWith(\"/*\")) {\n const end = remaining.indexOf(\"*/\");\n remaining = end === -1 ? \"\" : remaining.slice(end + 2).trim();\n continue;\n }\n\n break;\n }\n\n return remaining;\n}\n\n/**\n * Validates a view query, throwing with an actionable message when it can't work\n *\n * @param collectionName - Collection name, used in error messages\n * @param viewQuery - The SQL query to validate\n */\nexport function validateViewQuery(collectionName: string, viewQuery: unknown): asserts viewQuery is string {\n if (typeof viewQuery !== \"string\" || viewQuery.trim() === \"\") {\n throw new Error(\n `View collection \"${collectionName}\" requires a non-empty viewQuery. ` +\n `Provide the SQL SELECT statement backing the view.`\n );\n }\n\n const body = stripLeadingComments(viewQuery);\n if (!/^(select|with)\\b/i.test(body)) {\n throw new Error(\n `View collection \"${collectionName}\" has an invalid viewQuery: it must start with SELECT or WITH. ` +\n `Received: ${body.slice(0, 40)}${body.length > 40 ? \"...\" : \"\"}`\n );\n }\n}\n\n/**\n * Defines a read-only PocketBase view collection backed by a SQL query\n *\n * PocketBase derives the collection's fields by running the query, so the Zod\n * schema only describes the shape for TypeScript types and application-side\n * parsing. Views cannot have indexes and only support listRule / viewRule.\n *\n * The generated migration creates the collection with `type: \"view\"` and the\n * query; changing the SQL later produces an in-place `viewQuery` update, which\n * keeps the collection id stable.\n *\n * @param config - View collection configuration\n * @returns The schema with view metadata attached\n *\n * @example\n * export default defineView({\n * collectionName: \"ProjectStats\",\n * schema: ProjectStatsSchema,\n * viewQuery: sql`\n * SELECT p.OwnerUser AS id,\n * p.OwnerUser AS OwnerUser,\n * COUNT(*) AS projectCount\n * FROM Projects p\n * GROUP BY p.OwnerUser\n * `,\n * permissions: {\n * listRule: \"OwnerUser = @request.auth.id\",\n * viewRule: \"OwnerUser = @request.auth.id\",\n * },\n * });\n *\n * @example\n * // Requirements PocketBase places on the query:\n * // - the outermost SELECT must expose an `id` column\n * // - a relation column must be selected bare (e.g. `p.OwnerUser AS OwnerUser`)\n * // from the outer table for PocketBase to infer it as a relation field\n * // - no top-level UNION (wrap unions in a subquery)\n */\nexport function defineView(config: ViewCollectionConfig): z.ZodObject<any> {\n const { collectionName, schema, viewQuery, permissions } = config;\n\n validateViewQuery(collectionName, viewQuery);\n\n return defineCollection({\n collectionName,\n schema,\n type: \"view\",\n viewQuery,\n // Write rules are always locked for views - PocketBase rejects anything else\n permissions: {\n listRule: permissions?.listRule ?? null,\n viewRule: permissions?.viewRule ?? null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n },\n });\n}\n","import * as path from \"path\";\nimport { z } from \"zod\";\nimport { toCollectionName } from \"../utils/pluralize\";\n\n/**\n * Gets the collection name from a schema file path\n * Converts the filename (without extension) to a pluralized collection name\n *\n * @param filePath - Path to the schema file (with or without extension)\n * @returns The collection name\n */\nexport function getCollectionNameFromFile(filePath: string): string {\n // Remove both .ts and .js extensions if present\n const filename = path.basename(filePath).replace(/\\.(ts|js)$/, \"\");\n return toCollectionName(filename);\n}\n\n/**\n * Extracts the collection name from a Zod schema's metadata\n * Checks if the schema was created with defineCollection() which stores\n * the collection name in the schema description\n *\n * @param zodSchema - The Zod schema to extract collection name from\n * @returns The collection name if found in metadata, null otherwise\n */\nexport function extractCollectionNameFromSchema(zodSchema: z.ZodTypeAny): string | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (metadata.collectionName && typeof metadata.collectionName === \"string\") {\n return metadata.collectionName;\n }\n } catch {\n // Not JSON or no collectionName - this is expected for schemas without defineCollection\n }\n\n return null;\n}\n\n/**\n * Extracts the collection type from a Zod schema's metadata\n * Checks if the schema was created with defineCollection() which stores\n * the collection type in the schema description\n *\n * @param zodSchema - The Zod schema to extract collection type from\n * @returns The collection type (\"base\" | \"auth\" | \"view\") if found in metadata, null otherwise\n */\nexport function extractCollectionTypeFromSchema(zodSchema: z.ZodTypeAny): \"base\" | \"auth\" | \"view\" | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (metadata.type === \"base\" || metadata.type === \"auth\" || metadata.type === \"view\") {\n return metadata.type;\n }\n } catch {\n // Not JSON or no type - this is expected for schemas without explicit type\n }\n\n return null;\n}\n\n/**\n * Extracts the SQL query backing a view collection from a Zod schema's metadata\n * Set by defineView() (or defineCollection with type: \"view\")\n *\n * @param zodSchema - The Zod schema to extract the view query from\n * @returns The SQL query if found in metadata, null otherwise\n */\nexport function extractViewQueryFromSchema(zodSchema: z.ZodTypeAny): string | null {\n if (!zodSchema.description) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(zodSchema.description);\n if (typeof metadata.viewQuery === \"string\") {\n return metadata.viewQuery;\n }\n } catch {\n // Not JSON or no viewQuery - expected for non-view collections\n }\n\n return null;\n}\n\n/**\n * Extracts Zod schema definitions from a module\n *\n * Detection priority (highest to lowest):\n * 1. Default export - recommended pattern for clarity and explicitness\n * 2. Named exports ending with \"Collection\" - contains metadata (indexes, permissions)\n * 3. Named exports ending with \"Schema\" - basic schema definitions\n * 4. Named exports ending with \"InputSchema\" - form input schemas\n *\n * @param module - The imported schema module\n * @param patterns - Schema name patterns to look for (default: ['Schema', 'InputSchema', 'Collection'])\n * @returns Object containing found schemas\n *\n * @example\n * // Recommended: Use default export\n * const UserCollection = defineCollection({ ... });\n * export default UserCollection;\n *\n * @example\n * // Also supported: Named export with pattern\n * export const UserCollection = defineCollection({ ... });\n */\nexport function extractSchemaDefinitions(\n module: any,\n patterns: string[] = [\"Schema\", \"InputSchema\", \"Collection\"]\n): { inputSchema?: z.ZodObject<any>; schema?: z.ZodObject<any> } {\n const result: { inputSchema?: z.ZodObject<any>; schema?: z.ZodObject<any> } = {};\n\n // Priority 1: Check for default export (highest priority, most explicit)\n // This allows each file to have one clear schema definition\n if (module.default instanceof z.ZodObject) {\n // Default export is always the primary schema\n result.schema = module.default as z.ZodObject<any>;\n // If we have a default export, we can return early as it takes precedence\n // But we still check for InputSchema for backward compatibility\n }\n\n // Priority 2: Look for named exports matching patterns (for backward compatibility)\n for (const [key, value] of Object.entries(module)) {\n // Skip default export as we already handled it\n if (key === \"default\") continue;\n\n // Check if it's a Zod schema\n if (value instanceof z.ZodObject) {\n // Check for InputSchema pattern (used for form validation)\n if (patterns.includes(\"InputSchema\") && key.endsWith(\"InputSchema\")) {\n result.inputSchema = value as z.ZodObject<any>;\n } else if (!result.schema) {\n // Only set schema if we haven't found one via default export\n if (patterns.includes(\"Collection\") && key.endsWith(\"Collection\")) {\n // Prefer Collection over Schema as it has metadata (indexes, permissions)\n result.schema = value as z.ZodObject<any>;\n } else if (patterns.includes(\"Schema\") && key.endsWith(\"Schema\") && !key.endsWith(\"InputSchema\")) {\n result.schema = value as z.ZodObject<any>;\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Identifies whether to use InputSchema or Schema pattern\n * Prefers Schema over InputSchema as it includes base fields\n *\n * @param schemas - Object containing inputSchema and/or schema\n * @returns The schema to use for collection definition\n */\nexport function selectSchemaForCollection(schemas: {\n inputSchema?: z.ZodObject<any>;\n schema?: z.ZodObject<any>;\n}): z.ZodObject<any> | null {\n // Prefer the full Schema over InputSchema as it includes base fields\n if (schemas.schema) {\n return schemas.schema;\n }\n\n if (schemas.inputSchema) {\n return schemas.inputSchema;\n }\n\n return null;\n}\n\n/**\n * Extracts field definitions from a Zod object schema\n * Filters out base schema fields (id, collectionId, created, updated, expand)\n *\n * @param zodSchema - The Zod object schema\n * @param excludeFields - Additional fields to exclude (default: base schema fields)\n * @returns Array of field names and their Zod types\n */\nexport function extractFieldDefinitions(\n zodSchema: z.ZodObject<any>,\n excludeFields?: string[]\n): Array<{ name: string; zodType: z.ZodTypeAny }> {\n const shape = zodSchema.shape;\n const fields: Array<{ name: string; zodType: z.ZodTypeAny }> = [];\n\n // Base schema fields to exclude (these are system fields in PocketBase)\n const baseFields = [\"id\", \"collectionId\", \"collectionName\", \"created\", \"updated\", \"expand\"];\n\n // Additional fields to exclude (image file handling fields)\n const defaultExcludeFields = [\"thumbnailURL\", \"imageFiles\"];\n\n // Combine all exclusions\n const allExclusions = new Set([...baseFields, ...defaultExcludeFields, ...(excludeFields || [])]);\n\n for (const [fieldName, zodType] of Object.entries(shape)) {\n // Skip excluded fields\n if (!allExclusions.has(fieldName)) {\n fields.push({ name: fieldName, zodType: zodType as z.ZodTypeAny });\n }\n }\n\n return fields;\n}\n\n/**\n * Extracts index definitions from a Zod schema\n * Parses the schema description metadata to find index definitions\n *\n * @param schema - Zod schema with index metadata\n * @returns Array of index SQL statements or undefined\n */\nexport function extractIndexes(schema: z.ZodTypeAny): string[] | undefined {\n // Try to extract indexes from schema description\n const schemaDescription = schema.description;\n\n if (!schemaDescription) {\n return undefined;\n }\n\n try {\n const metadata = JSON.parse(schemaDescription);\n\n // Check if indexes are present in metadata\n if (metadata.indexes && Array.isArray(metadata.indexes)) {\n return metadata.indexes;\n }\n } catch {\n // If description is not valid JSON, return undefined\n }\n\n return undefined;\n}\n","import type { FieldDefinition } from \"../types\";\nimport type { MigrationGeneratorConfig } from \"./config\";\n\n/**\n * Generates a timestamp for migration filename\n * Format: Unix timestamp in seconds (e.g., 1687801090)\n *\n * @param config - Optional configuration with custom timestamp generator\n * @returns Timestamp string\n */\nexport function generateTimestamp(config?: MigrationGeneratorConfig): string {\n if (config?.timestampGenerator) {\n return config.timestampGenerator();\n }\n return Math.floor(Date.now() / 1000).toString();\n}\n\n/**\n * Increments a timestamp by 1 second\n * Ensures sequential ordering of migration files\n *\n * @param timestamp - Current timestamp string\n * @returns Incremented timestamp string\n */\nexport function incrementTimestamp(timestamp: string): string {\n const currentTimestamp = parseInt(timestamp, 10);\n return (currentTimestamp + 1).toString();\n}\n\n/**\n * Formats a value for JavaScript code generation\n * Handles strings, numbers, booleans, null, arrays, and objects\n *\n * @param value - Value to format\n * @returns Formatted string representation\n */\nexport function formatValue(value: any): string {\n if (value === null || value === undefined) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n // Use JSON.stringify to properly escape all special characters\n return JSON.stringify(value);\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n // Use JSON.stringify for arrays to properly handle all special characters\n // Then format with spaces after commas to match expected test output\n return JSON.stringify(value).replace(/\",\"/g, '\", \"');\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value)\n .filter(([_k, v]) => v !== undefined) // Omit undefined values\n .map(([k, v]) => `${k}: ${formatValue(v)}`)\n .join(\", \");\n return `{ ${entries} }`;\n }\n\n return String(value);\n}\n\n/**\n * Formats a SQL view query as a JavaScript template literal\n *\n * Emitted as a backtick template (rather than a JSON string) so the SQL stays\n * readable in the generated migration. Backticks and `${` are escaped so the\n * query can never break out of the literal or be interpolated.\n *\n * @param query - The SQL query\n * @param indent - Indentation prefix applied to each line of SQL\n * @returns Template literal source, including the surrounding backticks\n */\nexport function formatSqlTemplate(query: string, indent: string = \" \"): string {\n const escaped = query.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n\n const body = escaped\n .split(\"\\n\")\n .map((line) => (line.trim() === \"\" ? \"\" : `${indent}${line}`))\n .join(\"\\n\");\n\n return `\\`\\n${body}\\n${indent.slice(0, -2)}\\``;\n}\n\n/**\n * Gets the appropriate Field constructor name for a field type\n *\n * @param fieldType - PocketBase field type\n * @returns Field constructor name\n */\nexport function getFieldConstructorName(fieldType: string): string {\n const constructorMap: Record<string, string> = {\n text: \"TextField\",\n email: \"EmailField\",\n url: \"URLField\",\n number: \"NumberField\",\n bool: \"BoolField\",\n date: \"DateField\",\n select: \"SelectField\",\n relation: \"RelationField\",\n file: \"FileField\",\n json: \"JSONField\",\n editor: \"EditorField\",\n autodate: \"AutodateField\",\n };\n\n return constructorMap[fieldType] || \"TextField\";\n}\n\n/**\n * Generates system fields that are required for all PocketBase collections\n * These fields (id, created, updated) must be explicitly included in migrations\n *\n * @returns Array of system field definitions\n */\nexport function getSystemFields(): FieldDefinition[] {\n return [\n // id field - primary key, auto-generated\n {\n name: \"id\",\n id: \"text3208210256\",\n type: \"text\",\n required: true,\n options: {\n autogeneratePattern: \"[a-z0-9]{15}\",\n hidden: false,\n max: 15,\n min: 15,\n pattern: \"^[a-z0-9]+$\",\n presentable: false,\n primaryKey: true,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates the autodate timestamp system fields (created, updated)\n * These appear at the end of every collection's field list, after user fields\n *\n * @returns Array of system timestamp field definitions\n */\nexport function getSystemTimestampFields(): FieldDefinition[] {\n return [\n {\n name: \"created\",\n id: \"autodate2990389176\",\n type: \"autodate\",\n required: false,\n options: {\n hidden: false,\n onCreate: true,\n onUpdate: false,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"updated\",\n id: \"autodate3332085495\",\n type: \"autodate\",\n required: false,\n options: {\n hidden: false,\n onCreate: true,\n onUpdate: true,\n presentable: false,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates auth-specific system fields\n *\n * @returns Array of auth system field definitions\n */\nexport function getAuthSystemFields(): FieldDefinition[] {\n return [\n {\n name: \"password\",\n id: \"password3208210256\",\n // PocketBase stores the password as its own field type with an 8\n // character minimum; emitting it as `text` makes PocketBase rewrite the\n // field on apply, leaving the migration file describing a collection\n // the server never had\n type: \"password\",\n required: true,\n options: {\n cost: 0,\n hidden: true,\n max: 0,\n min: 8,\n pattern: \"\",\n presentable: false,\n system: true,\n },\n },\n {\n name: \"tokenKey\",\n id: \"tokenKey3208210256\",\n type: \"text\",\n required: true,\n options: {\n autogeneratePattern: \"[a-zA-Z0-9]{50}\",\n hidden: true,\n max: 60,\n min: 30,\n pattern: \"\",\n presentable: false,\n system: true,\n },\n },\n {\n name: \"email\",\n id: \"email3208210256\",\n type: \"email\",\n required: true,\n options: {\n exceptDomains: null,\n hidden: false,\n onlyDomains: null,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"emailVisibility\",\n id: \"bool3208210256\",\n type: \"bool\",\n required: false,\n options: {\n hidden: false,\n presentable: false,\n system: true,\n },\n },\n {\n name: \"verified\",\n id: \"bool1547992826\",\n type: \"bool\",\n required: false,\n options: {\n hidden: false,\n presentable: false,\n system: true,\n },\n },\n ];\n}\n\n/**\n * Generates default system indexes for auth collections\n *\n * PocketBase names these after the collection they belong to\n * (`idx_tokenKey_<collectionId>`). SQLite index names are database-wide, so\n * the suffix has to vary per collection — a fixed one makes a second auth\n * collection fail to apply with \"index ... already exists\".\n *\n * @param collectionName - Name of the auth collection\n * @param collectionId - Id of the auth collection; falls back to its name\n * @returns Array of index SQL statements\n */\nexport function getAuthSystemIndexes(collectionName: string, collectionId?: string): string[] {\n const suffix = collectionId || collectionName;\n\n return [\n `CREATE UNIQUE INDEX \\`idx_tokenKey_${suffix}\\` ON \\`${collectionName}\\` (\\`tokenKey\\`)`,\n `CREATE UNIQUE INDEX \\`idx_email_${suffix}\\` ON \\`${collectionName}\\` (\\`email\\`) WHERE \\`email\\` != ''`,\n ];\n}\n\n/**\n * Generates the code to find a collection by ID if available, otherwise by name\n *\n * @param name - Collection name\n * @param collectionIdMap - Map of collection names to IDs\n * @returns Code string like `app.findCollectionByNameOrId(\"id\") // name` or `app.findCollectionByNameOrId(\"name\")`\n */\nexport function generateFindCollectionCode(name: string, collectionIdMap?: Map<string, string>): string {\n if (collectionIdMap && collectionIdMap.has(name)) {\n const id = collectionIdMap.get(name);\n return `app.findCollectionByNameOrId(\"${id}\") // ${name}`;\n }\n return `app.findCollectionByNameOrId(\"${name}\")`;\n}\n","import { z } from \"zod\";\nimport { extractRelationMetadata } from \"../../schema/base\";\nimport { extractFieldMetadata } from \"../../schema/fields\";\nimport type { PermissionSchema } from \"../../utils/permissions\";\nimport { PermissionAnalyzer } from \"../permission-analyzer\";\nimport type { CollectionSchema, FieldDefinition } from \"../types\";\nimport { getMaxSelect, getMinSelect, isRelationField, resolveTargetCollection } from \"../utils/relation-detector\";\nimport {\n extractFieldOptions,\n filterSupportedFieldOptions,\n isFieldRequired,\n mapZodTypeToPocketBase,\n unwrapZodType,\n} from \"../utils/type-mapper\";\nimport { validateViewQuery } from \"../../schema/view\";\nimport {\n extractCollectionTypeFromSchema,\n extractFieldDefinitions,\n extractIndexes,\n extractViewQueryFromSchema,\n} from \"./extractors\";\nimport { generateFieldId } from \"../utils/collection-id-generator.js\";\nimport { getAuthSystemFields } from \"../generator/utils\";\n\n/**\n * Detects if a collection is an auth collection\n * Auth collections have email and password fields\n *\n * @param fields - Array of field definitions\n * @returns True if the collection is an auth collection\n */\nexport function isAuthCollection(fields: Array<{ name: string; zodType: z.ZodTypeAny }>): boolean {\n const fieldNames = fields.map((f) => f.name.toLowerCase());\n\n // Auth collections must have both email and password fields\n const hasEmail = fieldNames.includes(\"email\");\n const hasPassword = fieldNames.includes(\"password\");\n\n return hasEmail && hasPassword;\n}\n\n/**\n * Extracts validation constraints from Zod type\n * Includes min, max, required, unique, and other options\n *\n * @param fieldName - The field name\n * @param zodType - The Zod type\n * @returns Field definition with constraints\n */\nexport function buildFieldDefinition(fieldName: string, zodType: z.ZodTypeAny): FieldDefinition {\n // Check for explicit field metadata first (from field helper functions)\n const unwrappedType = unwrapZodType(zodType);\n const fieldMetadata = extractFieldMetadata(unwrappedType.description ?? zodType.description);\n\n if (fieldMetadata) {\n // Use explicit metadata from field helpers\n // For number fields, default to required: false unless explicitly set\n // (because required: true in PocketBase means non-zero, which is often not desired)\n let required: boolean;\n if (fieldMetadata.type === \"number\") {\n // Check if required is explicitly set in options\n if (fieldMetadata.options?.required !== undefined) {\n required = fieldMetadata.options.required;\n } else {\n // Default to false for number fields to allow zero values\n // This allows zero values (e.g., progress: 0-100) unless explicitly set to required: true\n required = false;\n }\n } else {\n // For other field types, use standard logic\n required = isFieldRequired(zodType);\n }\n\n // Remove 'required' from options if present (it's a top-level property, not an option)\n const { required: _required, ...options } = fieldMetadata.options || {};\n\n const fieldDef: FieldDefinition = {\n name: fieldName,\n id: generateFieldId(fieldMetadata.type, fieldName),\n type: fieldMetadata.type,\n required,\n options: filterSupportedFieldOptions(fieldMetadata.type, Object.keys(options).length > 0 ? options : undefined),\n zodType: zodType,\n };\n\n // If it's a relation type from metadata, we still need to extract relation config\n if (fieldMetadata.type === \"relation\") {\n const relationMetadata = extractRelationMetadata(unwrappedType.description ?? zodType.description);\n if (relationMetadata) {\n fieldDef.relation = {\n collection: relationMetadata.collection,\n maxSelect: relationMetadata.maxSelect,\n minSelect: relationMetadata.minSelect,\n cascadeDelete: relationMetadata.cascadeDelete,\n displayFields: relationMetadata.displayFields,\n };\n }\n }\n\n return fieldDef;\n }\n\n // Fall back to existing type inference logic\n const fieldType = mapZodTypeToPocketBase(zodType, fieldName);\n const required = isFieldRequired(zodType);\n const options = extractFieldOptions(zodType);\n\n const fieldDef: FieldDefinition = {\n name: fieldName,\n id: generateFieldId(fieldType, fieldName),\n type: fieldType,\n required,\n options,\n zodType: zodType,\n };\n\n // Check for explicit relation metadata first (from relation() or relations() helpers)\n const relationMetadata = extractRelationMetadata(unwrappedType.description ?? zodType.description);\n\n if (relationMetadata) {\n // Explicit relation definition found\n fieldDef.type = \"relation\";\n fieldDef.relation = {\n collection: relationMetadata.collection,\n maxSelect: relationMetadata.maxSelect,\n minSelect: relationMetadata.minSelect,\n cascadeDelete: relationMetadata.cascadeDelete,\n displayFields: relationMetadata.displayFields,\n };\n\n // Clear out string-specific options that don't apply to relation fields\n fieldDef.options = undefined;\n }\n // Fall back to naming convention detection for backward compatibility\n else if (isRelationField(fieldName, zodType)) {\n // Override type to 'relation' for relation fields\n fieldDef.type = \"relation\";\n\n const targetCollection = resolveTargetCollection(fieldName);\n const maxSelect = getMaxSelect(fieldName, zodType);\n const minSelect = getMinSelect(fieldName, zodType);\n\n fieldDef.relation = {\n collection: targetCollection,\n maxSelect,\n minSelect,\n cascadeDelete: false, // Default to false, can be configured later\n displayFields: null,\n };\n\n // Clear out string-specific options that don't apply to relation fields\n // Options like 'min', 'max', 'pattern' are from string validation and don't apply to relations\n if (fieldDef.options) {\n const { min: _min, max: _max, pattern: _pattern, ...relationSafeOptions } = fieldDef.options;\n fieldDef.options = Object.keys(relationSafeOptions).length ? relationSafeOptions : undefined;\n }\n }\n\n // Special handling for autodate fields\n if (fieldDef.type === \"autodate\") {\n // Autodate fields shouldn't have pattern or other string options\n // and should have onCreate/onUpdate set by default\n fieldDef.options = {\n onCreate: true,\n onUpdate: true,\n ...(fieldDef.options || {}),\n };\n // Remove options that don't apply to autodate\n delete fieldDef.options.pattern;\n delete fieldDef.options.min;\n delete fieldDef.options.max;\n }\n\n // Zod validators are richer than PocketBase's option set, and the type is\n // only settled here (relation detection above can still change it), so the\n // unsupported leftovers are dropped last\n fieldDef.options = filterSupportedFieldOptions(fieldDef.type, fieldDef.options);\n\n return fieldDef;\n}\n\n/**\n * Converts a Zod schema to a CollectionSchema interface\n *\n * @param collectionName - The name of the collection\n * @param zodSchema - The Zod object schema\n * @returns CollectionSchema definition\n */\nexport function convertZodSchemaToCollectionSchema(\n collectionName: string,\n zodSchema: z.ZodObject<any>\n): CollectionSchema {\n // Extract field definitions from Zod schema\n const rawFields = extractFieldDefinitions(zodSchema);\n\n // Determine collection type (auth, view or base)\n // Prefer explicit type from metadata, fall back to field detection\n const explicitType = extractCollectionTypeFromSchema(zodSchema);\n const collectionType = explicitType ?? (isAuthCollection(rawFields) ? \"auth\" : \"base\");\n const isView = collectionType === \"view\";\n\n // View collections are backed by SQL - the query is required\n const viewQuery = extractViewQueryFromSchema(zodSchema);\n if (isView) {\n validateViewQuery(collectionName, viewQuery);\n } else if (viewQuery !== null) {\n console.warn(\n `[${collectionName}] viewQuery is only used by view collections and will be ignored. ` +\n `Use defineView() or set type: \"view\" to define a view collection.`\n );\n }\n\n // Build field definitions with constraints\n const fields: FieldDefinition[] = rawFields\n // Explicitly filter out system fields that might have slipped through\n // This can happen if the schema was constructed manually without base schema\n .filter((f) => ![\"created\", \"updated\"].includes(f.name))\n .map(({ name, zodType }) => buildFieldDefinition(name, zodType));\n\n // Ensure auth system fields exist for auth collections\n if (collectionType === \"auth\") {\n // These fields are required for auth collections and should match the\n // native CLI output. The generator writes its own definitions for them\n // (getAuthSystemFields), so taking the options from the same place keeps\n // the analyzed schema equal to what replaying the generated migration\n // reads back — otherwise every run re-emits the same field modifications\n const authSystemFields = getAuthSystemFields();\n\n // Add or update auth fields\n for (const authField of authSystemFields) {\n const existingFieldIndex = fields.findIndex((f) => f.name === authField.name);\n\n if (existingFieldIndex !== -1) {\n // Update existing field to ensure correct type and required status\n const existingField = fields[existingFieldIndex];\n\n // Merge options: defaults -> existing -> forced overrides (none currently)\n // We want to ensure specific options like min/max match defaults if not set\n const mergedOptions = { ...authField.options, ...existingField.options };\n\n fields[existingFieldIndex] = {\n ...existingField,\n type: authField.type, // Force correct type (e.g. 'text' -> 'password')\n required: authField.required, // Force correct required status\n options: mergedOptions,\n };\n } else {\n // Add missing field\n fields.push({\n name: authField.name,\n id: generateFieldId(authField.type, authField.name),\n type: authField.type,\n required: authField.required,\n options: authField.options,\n });\n }\n }\n }\n\n // Extract indexes from schema\n // View collections cannot have indexes - PocketBase rejects them\n const indexes = extractIndexes(zodSchema) || [];\n if (isView && indexes.length > 0) {\n throw new Error(\n `View collection \"${collectionName}\" cannot declare indexes. ` +\n `PocketBase view collections are backed by a SQL query and do not support indexes.`\n );\n }\n\n // Extract and validate permissions from schema\n const permissionAnalyzer = new PermissionAnalyzer();\n let permissions: PermissionSchema | undefined = undefined;\n\n // Try to extract permissions from schema description\n const schemaDescription = zodSchema.description;\n const extractedPermissions = permissionAnalyzer.extractPermissions(schemaDescription);\n\n if (extractedPermissions) {\n // Resolve template configurations to concrete rules\n const resolvedPermissions = permissionAnalyzer.resolvePermissions(extractedPermissions);\n\n // View collections are read-only - warn and drop any write rules\n if (isView) {\n for (const ruleType of [\"createRule\", \"updateRule\", \"deleteRule\", \"manageRule\"] as const) {\n if (resolvedPermissions[ruleType]) {\n console.warn(\n `[${collectionName}] ${ruleType} is not supported on view collections and will be set to null.`\n );\n }\n resolvedPermissions[ruleType] = null;\n }\n }\n\n // Validate permissions against collection fields\n // Skipped for views: their real fields come from the SQL query, so field\n // references in the rules can't be checked against the Zod shape\n if (!isView) {\n const validationResults = permissionAnalyzer.validatePermissions(\n collectionName,\n resolvedPermissions,\n fields,\n collectionType === \"auth\"\n );\n\n // Log validation errors and warnings\n for (const [ruleType, result] of validationResults) {\n if (!result.valid) {\n console.error(`[${collectionName}] Permission validation failed for ${ruleType}:`);\n result.errors.forEach((error) => console.error(` - ${error}`));\n }\n\n if (result.warnings.length > 0) {\n console.warn(`[${collectionName}] Permission warnings for ${ruleType}:`);\n result.warnings.forEach((warning) => console.warn(` - ${warning}`));\n }\n }\n }\n\n // Merge with defaults to ensure all rules are defined\n permissions = permissionAnalyzer.mergeWithDefaults(resolvedPermissions);\n }\n\n // Build collection schema\n // Use extracted permissions for rules, falling back to nulls\n const collectionSchema: CollectionSchema = {\n name: collectionName,\n type: collectionType,\n fields,\n indexes,\n rules: {\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 // Omit manageRule for base collections to match native CLI behavior\n manageRule: collectionType === \"auth\" ? (permissions?.manageRule ?? null) : undefined,\n },\n permissions,\n };\n\n if (isView) {\n collectionSchema.viewQuery = viewQuery as string;\n }\n\n return collectionSchema;\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, SchemaParsingError } from \"../errors\";\nimport { mergeConfig, resolveSchemaDir, type SchemaAnalyzerConfig } from \"./config\";\n\n// Register tsx loader for TypeScript file support\n// This allows dynamic imports of .ts files to work\nlet tsxLoaderRegistered = false;\nasync function ensureTsxLoader(): Promise<void> {\n if (tsxLoaderRegistered) return;\n\n try {\n // Import tsx/esm to register the TypeScript loader hooks\n // This enables dynamic imports of .ts files in Node.js ESM\n await import(\"tsx/esm\");\n tsxLoaderRegistered = true;\n } catch {\n // tsx is not available - will handle in importSchemaModule\n tsxLoaderRegistered = false;\n }\n}\n\n/**\n * Discovers schema files in the specified directory\n * Filters based on configuration patterns\n *\n * @param config - Schema analyzer configuration\n * @returns Array of schema file paths (without extension)\n */\nexport function discoverSchemaFiles(config: SchemaAnalyzerConfig | string): string[] {\n // Support legacy string-only parameter\n const normalizedConfig: SchemaAnalyzerConfig = typeof config === \"string\" ? { schemaDir: config } : config;\n\n const mergedConfig = mergeConfig(normalizedConfig);\n const schemaDir = resolveSchemaDir(normalizedConfig);\n\n try {\n if (!fs.existsSync(schemaDir)) {\n throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, \"access\", \"ENOENT\");\n }\n\n const files = fs.readdirSync(schemaDir);\n\n // Pre-compile exclusion patterns to regexes for performance\n const excludeMatchers = mergedConfig.excludePatterns.map((pattern) => {\n if (pattern.includes(\"*\")) {\n return new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n }\n return pattern; // For exact match\n });\n\n // Filter files based on configuration\n const schemaFiles = files.filter((file) => {\n // Check extension\n const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));\n if (!hasValidExtension) return false;\n\n // Check exclusion patterns\n const isExcluded = excludeMatchers.some((matcher) => {\n if (typeof matcher === \"string\") {\n return file === matcher;\n }\n return matcher.test(file); // It's a regex\n });\n if (isExcluded) return false;\n\n return true;\n });\n\n // Create a single regex to remove any of the valid extensions, escaping special characters\n const extensionRemovalRegex = new RegExp(\n `(${mergedConfig.includeExtensions.map((ext) => ext.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\"|\")})$`\n );\n\n // Return full paths without extension (for dynamic import)\n return schemaFiles.map((file) => {\n return path.join(schemaDir, file.replace(extensionRemovalRegex, \"\"));\n });\n } catch (error) {\n if (error instanceof FileSystemError) {\n throw error;\n }\n\n const fsError = error as NodeJS.ErrnoException;\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied reading schema directory: ${schemaDir}`,\n schemaDir,\n \"read\",\n fsError.code,\n error as Error\n );\n }\n\n throw new FileSystemError(\n `Failed to read schema directory: ${schemaDir}`,\n schemaDir,\n \"read\",\n fsError.code,\n error as Error\n );\n }\n}\n\n/**\n * Dynamically imports a schema module\n * Supports both JavaScript and TypeScript files using tsx\n *\n * @param filePath - Path to the schema file (without extension)\n * @param config - Optional configuration for path transformation\n * @returns The imported module\n */\nexport async function importSchemaModule(filePath: string, config?: SchemaAnalyzerConfig): Promise<any> {\n try {\n let importPath = filePath;\n\n // Apply path transformation if provided\n if (config?.pathTransformer) {\n importPath = config.pathTransformer(filePath);\n }\n\n // Determine the file extension to use\n // Try .js first (for compiled files), then .ts (for source files)\n let resolvedPath: string | null = null;\n const jsPath = `${importPath}.js`;\n const tsPath = `${importPath}.ts`;\n\n if (fs.existsSync(jsPath)) {\n resolvedPath = jsPath;\n } else if (fs.existsSync(tsPath)) {\n resolvedPath = tsPath;\n } else {\n // Default to .js extension for ESM import\n resolvedPath = jsPath;\n }\n\n // If it's a TypeScript file, ensure tsx loader is registered\n if (resolvedPath.endsWith(\".ts\")) {\n await ensureTsxLoader();\n\n // Check if tsx was successfully registered\n if (!tsxLoaderRegistered) {\n throw new SchemaParsingError(\n `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.\\n` +\n `Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)\\n` +\n `Alternatively, compile your schema files to JavaScript first.`,\n filePath\n );\n }\n }\n\n // Convert to file URL for proper ESM import\n const fileUrl = new URL(`file://${path.resolve(resolvedPath)}`);\n\n // Use dynamic import to load the module\n // tsx/esm will handle TypeScript files automatically if registered\n const module = await import(fileUrl.href);\n return module;\n } catch (error) {\n // Check if we're trying to import a TypeScript file\n const tsPath = `${filePath}.ts`;\n const isTypeScriptFile = fs.existsSync(tsPath);\n\n if (isTypeScriptFile && error instanceof SchemaParsingError) {\n // Re-throw SchemaParsingError as-is (already has helpful message)\n throw error;\n }\n\n if (isTypeScriptFile) {\n throw new SchemaParsingError(\n `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.\\n` +\n `Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)\\n` +\n `Alternatively, compile your schema files to JavaScript first.`,\n filePath,\n error as Error\n );\n }\n\n throw new SchemaParsingError(\n `Failed to import schema module. Make sure the schema files exist and are valid.`,\n filePath,\n error as Error\n );\n }\n}\n","/**\n * Schema Analyzer - Parses Zod schemas and extracts field definitions\n *\n * This module provides a standalone, configurable schema analyzer that can be used\n * by consumer projects to parse Zod schemas and convert them to PocketBase collection schemas.\n */\n\nimport * as fs from \"fs\";\nimport { z } from \"zod\";\nimport { SchemaParsingError } from \"../errors\";\nimport type { CollectionSchema, SchemaDefinition } from \"../types\";\nimport { mergeConfig, resolveSchemaDir, type SchemaAnalyzerConfig } from \"./config\";\nimport { convertZodSchemaToCollectionSchema } from \"./converter\";\nimport {\n extractCollectionNameFromSchema,\n extractSchemaDefinitions,\n getCollectionNameFromFile,\n selectSchemaForCollection,\n} from \"./extractors\";\nimport { discoverSchemaFiles, importSchemaModule } from \"./loader\";\n\n// Export everything from submodules\nexport * from \"./config\";\nexport * from \"./converter\";\nexport * from \"./extractors\";\nexport * from \"./loader\";\n\n/**\n * Builds a complete SchemaDefinition from schema files\n * Main entry point for the Schema Analyzer\n *\n * @param config - Schema analyzer configuration or path to schema directory\n * @returns Complete SchemaDefinition with all collections\n */\nexport async function buildSchemaDefinition(config: SchemaAnalyzerConfig | string): Promise<SchemaDefinition> {\n // Support legacy string-only parameter\n const normalizedConfig: SchemaAnalyzerConfig = typeof config === \"string\" ? { schemaDir: config } : config;\n\n const mergedConfig = mergeConfig(normalizedConfig);\n const collections = new Map<string, CollectionSchema>();\n\n // Discover schema files\n const schemaFiles = discoverSchemaFiles(normalizedConfig);\n\n if (schemaFiles.length === 0) {\n const schemaDir = resolveSchemaDir(normalizedConfig);\n throw new SchemaParsingError(\n `No schema files found in ${schemaDir}. Make sure you have schema files in the directory.`,\n schemaDir\n );\n }\n\n // Process each schema file\n for (const filePath of schemaFiles) {\n try {\n let importPath = filePath;\n\n // Apply path transformation if provided (for monorepo setups)\n if (normalizedConfig.pathTransformer) {\n importPath = normalizedConfig.pathTransformer(filePath);\n } else if (mergedConfig.useCompiledFiles) {\n // Default transformation: convert /src/ to /dist/ for compiled files\n // This is a common pattern but can be overridden with pathTransformer\n const distPath = filePath.replace(/\\/src\\//, \"/dist/\");\n // Only use dist path if it actually exists (i.e., files are compiled)\n // Otherwise, fall back to source path for TypeScript files\n if (fs.existsSync(`${distPath}.js`) || fs.existsSync(`${distPath}.mjs`)) {\n importPath = distPath;\n } else {\n // Files aren't compiled, use source path\n importPath = filePath;\n }\n }\n\n // Import the module\n const module = await importSchemaModule(importPath, normalizedConfig);\n\n // Extract schema definitions\n const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);\n\n // Select the appropriate schema\n const zodSchema = selectSchemaForCollection(schemas);\n\n if (!zodSchema) {\n console.warn(`No valid schema found in ${filePath}, skipping...`);\n continue;\n }\n\n // Get collection name - prefer metadata from defineCollection(), fall back to filename\n const collectionNameFromSchema = extractCollectionNameFromSchema(zodSchema);\n const collectionName = collectionNameFromSchema ?? getCollectionNameFromFile(filePath);\n\n // Convert to CollectionSchema\n const collectionSchema = convertZodSchemaToCollectionSchema(collectionName, zodSchema);\n\n // Add to collections map\n collections.set(collectionName, collectionSchema);\n } catch (error) {\n // If it's already a SchemaParsingError, re-throw it\n if (error instanceof SchemaParsingError) {\n throw error;\n }\n\n // Otherwise, wrap it in a SchemaParsingError\n throw new SchemaParsingError(\n `Error processing schema file: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error as Error\n );\n }\n }\n\n return { collections };\n}\n\n/**\n * Parses schema files and returns SchemaDefinition\n * Alias for buildSchemaDefinition for better semantic clarity\n *\n * @param config - Schema analyzer configuration or path to schema directory\n * @returns Complete SchemaDefinition with all collections\n */\nexport async function parseSchemaFiles(config: SchemaAnalyzerConfig | string): Promise<SchemaDefinition> {\n return buildSchemaDefinition(config);\n}\n\n/**\n * Creates a SchemaAnalyzer instance with the given configuration\n * Provides an object-oriented interface for schema analysis\n */\nexport class SchemaAnalyzer {\n private config: Required<Omit<SchemaAnalyzerConfig, \"pathTransformer\">> & {\n pathTransformer?: (sourcePath: string) => string;\n };\n\n constructor(config: SchemaAnalyzerConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Discovers schema files in the configured directory\n */\n discoverSchemaFiles(): string[] {\n return discoverSchemaFiles(this.config);\n }\n\n /**\n * Parses all schema files and returns a SchemaDefinition\n */\n async parseSchemaFiles(): Promise<SchemaDefinition> {\n return buildSchemaDefinition(this.config);\n }\n\n /**\n * Converts a single Zod schema to a CollectionSchema\n */\n convertZodSchemaToCollectionSchema(name: string, schema: z.ZodObject<any>): CollectionSchema {\n return convertZodSchemaToCollectionSchema(name, schema);\n }\n}\n","/**\n * Runtime field constructors matching the PocketBase JSVM globals\n *\n * In the PocketBase JSVM, migrations construct fields via `new Field({...})`\n * or typed constructors like `new TextField({...})`. Instances are plain\n * mutable objects; migrations freely assign properties after construction\n * (e.g. `field.max = 500`).\n *\n * The constructors deliberately add no default properties beyond `type`:\n * the resulting state must match what the migration file literally declares,\n * the same data the literal declares, materialized as a real object.\n */\n\n/**\n * Generic field constructor: `new Field({type: \"number\", ...})`.\n * PocketBase's own generated migrations use this form with an explicit type.\n */\nexport class Field {\n [key: string]: any;\n\n constructor(data: Record<string, any> = {}) {\n Object.assign(this, data);\n }\n}\n\nfunction typedField(type: string): new (data?: Record<string, any>) => Field {\n return class extends Field {\n constructor(data: Record<string, any> = {}) {\n super({ type, ...data });\n }\n };\n}\n\n// One constructor per PocketBase field type (see POCKETBASE_FIELD_TYPES)\nexport const TextField = typedField(\"text\");\nexport const EmailField = typedField(\"email\");\nexport const URLField = typedField(\"url\");\nexport const NumberField = typedField(\"number\");\nexport const BoolField = typedField(\"bool\");\nexport const DateField = typedField(\"date\");\nexport const SelectField = typedField(\"select\");\nexport const RelationField = typedField(\"relation\");\nexport const FileField = typedField(\"file\");\nexport const JSONField = typedField(\"json\");\nexport const EditorField = typedField(\"editor\");\nexport const GeoPointField = typedField(\"geoPoint\");\nexport const AutodateField = typedField(\"autodate\");\nexport const PasswordField = typedField(\"password\");\n\nexport const FIELD_CONSTRUCTORS: Record<string, new (data?: Record<string, any>) => Field> = {\n Field,\n TextField,\n EmailField,\n URLField,\n NumberField,\n BoolField,\n DateField,\n SelectField,\n RelationField,\n FileField,\n JSONField,\n EditorField,\n GeoPointField,\n AutodateField,\n PasswordField,\n};\n\n/**\n * Generates a field id in PocketBase's `<type><digits>` style when a\n * migration saves a field without one. PocketBase derives the digits from\n * crc32(name); a random suffix is sufficient here because diffing matches\n * fields by name, not id.\n */\nexport function generateRuntimeFieldId(type: string): string {\n let digits = \"\";\n for (let i = 0; i < 10; i++) {\n digits += Math.floor(Math.random() * 10).toString();\n }\n return `${type || \"field\"}${digits}`;\n}\n","/**\n * FieldsList — runtime equivalent of a PocketBase collection's `fields`\n *\n * Mirrors the methods the JSVM exposes on `collection.fields`:\n * add / addAt / removeById / removeByName / getById / getByName, plus\n * read-side iteration. Field entries are live objects — mutations through\n * getByName() are visible when the collection is saved, exactly like the\n * generator's `const f = collection.fields.getByName(\"x\"); f.max = 500;`\n * output expects.\n */\n\nimport { Field } from \"./fields\";\n\nexport class FieldsList {\n private items: Field[] = [];\n\n constructor(fields?: any[]) {\n if (Array.isArray(fields)) {\n for (const field of fields) {\n this.items.push(field instanceof Field ? field : new Field(field));\n }\n }\n }\n\n get length(): number {\n return this.items.length;\n }\n\n /**\n * Appends fields; a field whose id matches an existing entry replaces it\n * in place (position preserved), matching PocketBase upsert semantics.\n */\n add(...fields: any[]): void {\n for (const raw of fields) {\n const field = raw instanceof Field ? raw : new Field(raw);\n const existing = this.indexOfId(field.id);\n if (existing >= 0) {\n this.items[existing] = field;\n } else {\n this.items.push(field);\n }\n }\n }\n\n /**\n * Inserts fields at a position. A field with an already-present id is\n * moved: the old entry is removed first, then the field is inserted at\n * the requested position.\n */\n addAt(position: number, ...fields: any[]): void {\n let insertAt = Math.max(0, Math.min(position, this.items.length));\n for (const raw of fields) {\n const field = raw instanceof Field ? raw : new Field(raw);\n const existing = this.indexOfId(field.id);\n if (existing >= 0) {\n this.items.splice(existing, 1);\n if (existing < insertAt) {\n insertAt--;\n }\n }\n insertAt = Math.max(0, Math.min(insertAt, this.items.length));\n this.items.splice(insertAt, 0, field);\n insertAt++;\n }\n }\n\n removeById(id: string): void {\n const index = this.indexOfId(id);\n if (index >= 0) {\n this.items.splice(index, 1);\n }\n }\n\n removeByName(name: string): void {\n const index = this.items.findIndex((f) => f.name === name);\n if (index >= 0) {\n this.items.splice(index, 1);\n }\n }\n\n getById(id: string): Field | undefined {\n const index = this.indexOfId(id);\n return index >= 0 ? this.items[index] : undefined;\n }\n\n getByName(name: string): Field | undefined {\n return this.items.find((f) => f.name === name);\n }\n\n at(index: number): Field | undefined {\n return this.items.at(index);\n }\n\n find(predicate: (field: Field, index: number) => boolean): Field | undefined {\n return this.items.find(predicate);\n }\n\n filter(predicate: (field: Field, index: number) => boolean): Field[] {\n return this.items.filter(predicate);\n }\n\n map<T>(mapper: (field: Field, index: number) => T): T[] {\n return this.items.map(mapper);\n }\n\n forEach(callback: (field: Field, index: number) => void): void {\n this.items.forEach(callback);\n }\n\n [Symbol.iterator](): Iterator<Field> {\n return this.items[Symbol.iterator]();\n }\n\n /** Replaces the whole list (used by unmarshal({fields: [...]}, collection)) */\n replaceAll(fields: any[]): void {\n this.items = [];\n this.add(...fields);\n }\n\n /** Plain objects, in order */\n serialize(): Record<string, any>[] {\n return this.items.map((field) => ({ ...field }));\n }\n\n private indexOfId(id: unknown): number {\n if (typeof id !== \"string\" || id === \"\") {\n return -1;\n }\n return this.items.findIndex((f) => f.id === id);\n }\n}\n","/**\n * Runtime Collection class matching the PocketBase JSVM global\n *\n * `new Collection({...})` in a migration produces one of these. All data\n * properties are copied verbatim (auth options, templates, etc. survive a\n * snapshot import round-trip); `fields` becomes a live FieldsList and\n * `indexes` a real array so `push`/`findIndex`/`splice` work natively.\n *\n * No rule properties are defaulted: the serialized collection must contain\n * exactly what the migration declared, so engine output stays byte-parity\n * with static analysis of the same literals.\n */\n\nimport { FieldsList } from \"./fields-list\";\nimport type { RawCollection } from \"./types\";\n\n/**\n * Auth collections in real PocketBase always carry these system fields.\n * PocketBase injects the missing ones *when the collection is saved*\n * (`initDefaultFields`), not when the model is constructed — so this list is\n * applied by `ensureAuthSystemFields()` on the save path, never in the\n * constructor. Injecting on construction would also re-add them every time a\n * collection is rebuilt (`CollectionStore.clone()`), silently undoing a\n * migration that dropped one. Shapes and ids mirror what PocketBase\n * serializes into its own migration files.\n */\nconst AUTH_SYSTEM_FIELDS: RawCollection[] = [\n {\n autogeneratePattern: \"\",\n hidden: true,\n id: \"password901924565\",\n max: 0,\n min: 8,\n name: \"password\",\n pattern: \"\",\n presentable: false,\n required: true,\n system: true,\n type: \"password\",\n },\n {\n autogeneratePattern: \"[a-zA-Z0-9]{50}\",\n hidden: true,\n id: \"text2504183744\",\n max: 60,\n min: 30,\n name: \"tokenKey\",\n pattern: \"\",\n presentable: false,\n primaryKey: false,\n required: true,\n system: true,\n type: \"text\",\n },\n {\n exceptDomains: null,\n hidden: false,\n id: \"email3885137012\",\n name: \"email\",\n onlyDomains: null,\n presentable: false,\n required: true,\n system: true,\n type: \"email\",\n },\n {\n hidden: false,\n id: \"bool1547992806\",\n name: \"emailVisibility\",\n presentable: false,\n required: false,\n system: true,\n type: \"bool\",\n },\n {\n hidden: false,\n id: \"bool256245529\",\n name: \"verified\",\n presentable: false,\n required: false,\n system: true,\n type: \"bool\",\n },\n];\n\nexport function generateRuntimeCollectionId(): string {\n let digits = \"\";\n for (let i = 0; i < 10; i++) {\n digits += Math.floor(Math.random() * 10).toString();\n }\n return `pbc_${digits}`;\n}\n\nexport class Collection {\n [key: string]: any;\n\n id: string;\n name: string;\n type: string;\n system: boolean;\n fields: FieldsList;\n indexes: string[];\n\n constructor(data: RawCollection = {}) {\n const { fields, indexes, ...rest } = data;\n Object.assign(this, rest);\n\n this.id = typeof data.id === \"string\" && data.id !== \"\" ? data.id : generateRuntimeCollectionId();\n this.name = typeof data.name === \"string\" ? data.name : \"\";\n this.type = typeof data.type === \"string\" && data.type !== \"\" ? data.type : \"base\";\n this.system = data.system === true;\n this.fields = new FieldsList(Array.isArray(fields) ? fields : []);\n this.indexes = Array.isArray(indexes) ? [...indexes] : [];\n }\n\n /** PocketBase-shaped plain object (what a snapshot array entry looks like) */\n serialize(): RawCollection {\n const raw: RawCollection = {};\n for (const [key, value] of Object.entries(this)) {\n if (key === \"fields\" || key === \"indexes\") {\n continue;\n }\n raw[key] = value;\n }\n raw.fields = this.fields.serialize();\n raw.indexes = [...this.indexes];\n return raw;\n }\n}\n\n/**\n * PocketBase's `initDefaultFields` for auth collections: on save, any missing\n * system field is put back. Call this from the save path only — the resulting\n * collection is then stable across serialize/rebuild cycles, so replaying the\n * next migration file sees exactly what the previous one committed.\n */\nexport function ensureAuthSystemFields(collection: Collection): void {\n if (collection.type !== \"auth\") {\n return;\n }\n for (const systemField of AUTH_SYSTEM_FIELDS) {\n if (!collection.fields.getByName(systemField.name)) {\n collection.fields.add({ ...systemField });\n }\n }\n}\n","/**\n * Condition expressions — one evaluator for PocketBase filters and SQL WHERE\n *\n * Data migrations select records two ways: PocketBase's filter syntax\n * (`status = \"draft\" && views > 10`) and raw SQL through `$dbx`/`app.db()`\n * (`WHERE status = {:status}`). The two dialects overlap almost completely —\n * the same comparison operators over the same field/literal operands — so the\n * simulation parses both with one grammar and evaluates the result against a\n * record.\n *\n * Deliberately small: comparisons, `LIKE`/`~`, `IN`, `IS NULL`, `AND`/`OR`/\n * `NOT`, parentheses, and `{:name}` bindings. Anything outside that raises\n * `ExpressionError`, which the caller reports as an unsupported query rather\n * than silently matching the wrong rows.\n */\n\nexport class ExpressionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ExpressionError\";\n Object.setPrototypeOf(this, ExpressionError.prototype);\n }\n}\n\n/** Resolves a field reference to the value stored on the row being tested */\nexport interface EvaluationContext {\n field: (name: string) => unknown;\n params?: Record<string, unknown>;\n}\n\nexport type Condition =\n | { kind: \"and\"; operands: Condition[] }\n | { kind: \"or\"; operands: Condition[] }\n | { kind: \"not\"; operand: Condition }\n | { kind: \"compare\"; operator: CompareOperator; left: Operand; right: Operand }\n | { kind: \"in\"; negated: boolean; left: Operand; values: Operand[] }\n | { kind: \"like\"; negated: boolean; left: Operand; pattern: Operand; implicitWildcards: boolean }\n | { kind: \"null\"; negated: boolean; operand: Operand }\n | { kind: \"between\"; negated: boolean; operand: Operand; from: Operand; to: Operand }\n | { kind: \"literal\"; value: boolean };\n\nexport type CompareOperator = \"=\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\";\n\nexport type Operand =\n | { kind: \"field\"; name: string }\n | { kind: \"value\"; value: unknown }\n | { kind: \"param\"; name: string };\n\n// ---------------------------------------------------------------------------\n// Tokenizer\n// ---------------------------------------------------------------------------\n\ntype TokenType = \"identifier\" | \"number\" | \"string\" | \"param\" | \"operator\" | \"punct\";\n\ninterface Token {\n type: TokenType;\n value: string;\n position: number;\n}\n\nconst OPERATORS = [\"?!=\", \"!~\", \"?=\", \"?~\", \"!=\", \"<>\", \">=\", \"<=\", \"==\", \"&&\", \"||\", \"=\", \">\", \"<\", \"~\"];\n\nfunction tokenize(input: string): Token[] {\n const tokens: Token[] = [];\n let index = 0;\n\n while (index < input.length) {\n const char = input[index];\n\n if (/\\s/.test(char)) {\n index++;\n continue;\n }\n\n // {:name} — dbx/PocketBase parameter binding\n if (char === \"{\" && input[index + 1] === \":\") {\n const end = input.indexOf(\"}\", index);\n if (end === -1) {\n throw new ExpressionError(`Unterminated parameter placeholder at position ${index}`);\n }\n tokens.push({ type: \"param\", value: input.slice(index + 2, end).trim(), position: index });\n index = end + 1;\n continue;\n }\n\n if (char === \"'\" || char === '\"') {\n const { value, next } = readString(input, index);\n tokens.push({ type: \"string\", value, position: index });\n index = next;\n continue;\n }\n\n if (/[0-9]/.test(char) || (char === \".\" && /[0-9]/.test(input[index + 1] ?? \"\"))) {\n const match = /^[0-9]*\\.?[0-9]+(?:[eE][+-]?[0-9]+)?/.exec(input.slice(index));\n if (!match) {\n throw new ExpressionError(`Invalid number at position ${index}`);\n }\n tokens.push({ type: \"number\", value: match[0], position: index });\n index += match[0].length;\n continue;\n }\n\n // Identifiers may be qualified (table.column) or backtick/bracket quoted\n if (/[A-Za-z_`[]/.test(char)) {\n const { value, next } = readIdentifier(input, index);\n tokens.push({ type: \"identifier\", value, position: index });\n index = next;\n continue;\n }\n\n const operator = OPERATORS.find((candidate) => input.startsWith(candidate, index));\n if (operator) {\n tokens.push({ type: \"operator\", value: operator, position: index });\n index += operator.length;\n continue;\n }\n\n if (char === \"(\" || char === \")\" || char === \",\") {\n tokens.push({ type: \"punct\", value: char, position: index });\n index++;\n continue;\n }\n\n throw new ExpressionError(`Unexpected character ${JSON.stringify(char)} at position ${index}`);\n }\n\n return tokens;\n}\n\nfunction readString(input: string, start: number): { value: string; next: number } {\n const quote = input[start];\n let index = start + 1;\n let value = \"\";\n\n while (index < input.length) {\n const char = input[index];\n if (char === \"\\\\\" && index + 1 < input.length) {\n value += unescapeChar(input[index + 1]);\n index += 2;\n continue;\n }\n // SQL doubles the quote to escape it: 'it''s'\n if (char === quote && input[index + 1] === quote) {\n value += quote;\n index += 2;\n continue;\n }\n if (char === quote) {\n return { value, next: index + 1 };\n }\n value += char;\n index++;\n }\n\n throw new ExpressionError(`Unterminated string starting at position ${start}`);\n}\n\nfunction unescapeChar(char: string): string {\n switch (char) {\n case \"n\":\n return \"\\n\";\n case \"t\":\n return \"\\t\";\n case \"r\":\n return \"\\r\";\n default:\n return char;\n }\n}\n\nfunction readIdentifier(input: string, start: number): { value: string; next: number } {\n let index = start;\n let value = \"\";\n\n while (index < input.length) {\n const char = input[index];\n if (char === \"`\" || char === \"[\" || char === \"]\" || char === '\"') {\n // Quoted identifier segment: `my table`.`col`\n if (char === \"`\" || char === \"[\") {\n const closing = char === \"`\" ? \"`\" : \"]\";\n const end = input.indexOf(closing, index + 1);\n if (end === -1) {\n throw new ExpressionError(`Unterminated quoted identifier at position ${index}`);\n }\n value += input.slice(index + 1, end);\n index = end + 1;\n continue;\n }\n break;\n }\n if (/[A-Za-z0-9_.$]/.test(char)) {\n value += char;\n index++;\n continue;\n }\n break;\n }\n\n if (value === \"\") {\n throw new ExpressionError(`Invalid identifier at position ${start}`);\n }\n return { value, next: index };\n}\n\n// ---------------------------------------------------------------------------\n// Parser\n// ---------------------------------------------------------------------------\n\nconst KEYWORDS = new Set([\"and\", \"or\", \"not\", \"in\", \"is\", \"null\", \"like\", \"true\", \"false\", \"between\"]);\n\nclass Parser {\n private index = 0;\n\n constructor(private tokens: Token[]) {}\n\n parse(): Condition {\n if (this.tokens.length === 0) {\n return { kind: \"literal\", value: true };\n }\n const condition = this.parseOr();\n if (this.index < this.tokens.length) {\n const token = this.tokens[this.index];\n throw new ExpressionError(`Unexpected ${JSON.stringify(token.value)} at position ${token.position}`);\n }\n return condition;\n }\n\n private parseOr(): Condition {\n const operands = [this.parseAnd()];\n while (this.matchOperator(\"||\") || this.matchKeyword(\"or\")) {\n operands.push(this.parseAnd());\n }\n return operands.length === 1 ? operands[0] : { kind: \"or\", operands };\n }\n\n private parseAnd(): Condition {\n const operands = [this.parseNot()];\n while (this.matchOperator(\"&&\") || this.matchKeyword(\"and\")) {\n operands.push(this.parseNot());\n }\n return operands.length === 1 ? operands[0] : { kind: \"and\", operands };\n }\n\n private parseNot(): Condition {\n if (this.matchKeyword(\"not\")) {\n return { kind: \"not\", operand: this.parseNot() };\n }\n return this.parseComparison();\n }\n\n private parseComparison(): Condition {\n if (this.peekPunct(\"(\")) {\n // Only a parenthesized condition can start here; a parenthesized value\n // list is consumed by IN below\n this.index++;\n const condition = this.parseOr();\n this.expectPunct(\")\");\n return condition;\n }\n\n const left = this.parseOperand();\n\n if (this.matchKeyword(\"is\")) {\n const negated = this.matchKeyword(\"not\");\n this.expectKeyword(\"null\");\n return { kind: \"null\", negated, operand: left };\n }\n\n // Postfix negation: `status NOT IN (...)`, `title NOT LIKE 'x'`,\n // `n NOT BETWEEN 1 AND 5`. Nothing else may follow an operand.\n const negated = this.matchKeyword(\"not\");\n\n if (this.matchKeyword(\"in\")) {\n return { kind: \"in\", negated, left, values: this.parseValueList() };\n }\n\n if (this.matchKeyword(\"like\")) {\n return { kind: \"like\", negated, left, pattern: this.parseOperand(), implicitWildcards: false };\n }\n\n if (this.matchKeyword(\"between\")) {\n const from = this.parseOperand();\n this.expectKeyword(\"and\");\n return { kind: \"between\", negated, operand: left, from, to: this.parseOperand() };\n }\n\n if (negated) {\n const token = this.tokens[this.index];\n throw new ExpressionError(\n token\n ? `Expected IN, LIKE or BETWEEN after NOT at position ${token.position}`\n : \"Expected IN, LIKE or BETWEEN after NOT at end of expression\"\n );\n }\n\n const operator = this.peekOperator();\n if (!operator) {\n const token = this.tokens[this.index];\n throw new ExpressionError(\n token\n ? `Expected a comparison operator at position ${token.position}`\n : \"Expected a comparison operator at end of expression\"\n );\n }\n this.index++;\n\n switch (operator) {\n case \"~\":\n case \"?~\":\n return { kind: \"like\", negated: false, left, pattern: this.parseOperand(), implicitWildcards: true };\n case \"!~\":\n return { kind: \"like\", negated: true, left, pattern: this.parseOperand(), implicitWildcards: true };\n default:\n return { kind: \"compare\", operator: normalizeOperator(operator), left, right: this.parseOperand() };\n }\n }\n\n private parseValueList(): Operand[] {\n this.expectPunct(\"(\");\n const values: Operand[] = [];\n if (this.peekPunct(\")\")) {\n this.index++;\n return values;\n }\n values.push(this.parseOperand());\n while (this.peekPunct(\",\")) {\n this.index++;\n values.push(this.parseOperand());\n }\n this.expectPunct(\")\");\n return values;\n }\n\n parseOperand(): Operand {\n const token = this.tokens[this.index];\n if (!token) {\n throw new ExpressionError(\"Unexpected end of expression\");\n }\n this.index++;\n\n switch (token.type) {\n case \"string\":\n return { kind: \"value\", value: token.value };\n case \"number\":\n return { kind: \"value\", value: Number(token.value) };\n case \"param\":\n return { kind: \"param\", name: token.value };\n case \"identifier\": {\n const lowered = token.value.toLowerCase();\n if (lowered === \"true\" || lowered === \"false\") {\n return { kind: \"value\", value: lowered === \"true\" };\n }\n if (lowered === \"null\") {\n return { kind: \"value\", value: null };\n }\n return { kind: \"field\", name: token.value };\n }\n default:\n throw new ExpressionError(`Unexpected ${JSON.stringify(token.value)} at position ${token.position}`);\n }\n }\n\n private peekOperator(): string | null {\n const token = this.tokens[this.index];\n return token?.type === \"operator\" ? token.value : null;\n }\n\n private matchOperator(value: string): boolean {\n if (this.peekOperator() === value) {\n this.index++;\n return true;\n }\n return false;\n }\n\n private matchKeyword(keyword: string): boolean {\n const token = this.tokens[this.index];\n if (token?.type === \"identifier\" && token.value.toLowerCase() === keyword && KEYWORDS.has(keyword)) {\n this.index++;\n return true;\n }\n return false;\n }\n\n private expectKeyword(keyword: string): void {\n if (!this.matchKeyword(keyword)) {\n const token = this.tokens[this.index];\n throw new ExpressionError(\n `Expected ${keyword.toUpperCase()}${token ? ` at position ${token.position}` : \" at end of expression\"}`\n );\n }\n }\n\n private peekPunct(value: string): boolean {\n const token = this.tokens[this.index];\n return token?.type === \"punct\" && token.value === value;\n }\n\n private expectPunct(value: string): void {\n if (!this.peekPunct(value)) {\n const token = this.tokens[this.index];\n throw new ExpressionError(\n `Expected ${JSON.stringify(value)}${token ? ` at position ${token.position}` : \" at end of expression\"}`\n );\n }\n this.index++;\n }\n}\n\nfunction normalizeOperator(operator: string): CompareOperator {\n switch (operator) {\n case \"==\":\n case \"=\":\n case \"?=\":\n return \"=\";\n case \"!=\":\n case \"<>\":\n case \"?!=\":\n return \"!=\";\n default:\n return operator as CompareOperator;\n }\n}\n\n/** Parses a filter or SQL condition into an evaluable tree */\nexport function parseCondition(source: string): Condition {\n return new Parser(tokenize(source)).parse();\n}\n\n/** Parses a standalone value (a SET assignment or a VALUES entry) */\nexport function parseValueOperand(source: string): Operand {\n const tokens = tokenize(source);\n if (tokens.length === 0) {\n throw new ExpressionError(\"Expected a value\");\n }\n return new Parser(tokens).parseOperand();\n}\n\n// ---------------------------------------------------------------------------\n// Evaluation\n// ---------------------------------------------------------------------------\n\nexport function evaluateCondition(condition: Condition, context: EvaluationContext): boolean {\n switch (condition.kind) {\n case \"literal\":\n return condition.value;\n case \"and\":\n return condition.operands.every((operand) => evaluateCondition(operand, context));\n case \"or\":\n return condition.operands.some((operand) => evaluateCondition(operand, context));\n case \"not\":\n return !evaluateCondition(condition.operand, context);\n case \"null\": {\n const value = resolveOperand(condition.operand, context);\n const isNull = value === null || value === undefined;\n return condition.negated ? !isNull : isNull;\n }\n case \"in\": {\n const value = resolveOperand(condition.left, context);\n const matches = condition.values.some((candidate) => looseEquals(value, resolveOperand(candidate, context)));\n return condition.negated ? !matches : matches;\n }\n case \"like\": {\n const value = resolveOperand(condition.left, context);\n const pattern = resolveOperand(condition.pattern, context);\n const matches = matchesLike(value, pattern, condition.implicitWildcards);\n return condition.negated ? !matches : matches;\n }\n case \"between\": {\n const value = resolveOperand(condition.operand, context);\n const from = resolveOperand(condition.from, context);\n const to = resolveOperand(condition.to, context);\n const inRange = compareValues(value, from) >= 0 && compareValues(value, to) <= 0;\n return condition.negated ? !inRange : inRange;\n }\n case \"compare\": {\n const left = resolveOperand(condition.left, context);\n const right = resolveOperand(condition.right, context);\n switch (condition.operator) {\n case \"=\":\n return looseEquals(left, right);\n case \"!=\":\n return !looseEquals(left, right);\n case \">\":\n return compareValues(left, right) > 0;\n case \">=\":\n return compareValues(left, right) >= 0;\n case \"<\":\n return compareValues(left, right) < 0;\n case \"<=\":\n return compareValues(left, right) <= 0;\n }\n }\n }\n}\n\nexport function resolveOperand(operand: Operand, context: EvaluationContext): unknown {\n switch (operand.kind) {\n case \"value\":\n return operand.value;\n case \"field\":\n return context.field(operand.name);\n case \"param\": {\n const params = context.params ?? {};\n if (!(operand.name in params)) {\n throw new ExpressionError(`Missing bound parameter {:${operand.name}}`);\n }\n return params[operand.name];\n }\n }\n}\n\n/** Every field a condition reads, for callers that need to validate up front */\nexport function conditionFields(condition: Condition): string[] {\n const names = new Set<string>();\n const visitOperand = (operand: Operand) => {\n if (operand.kind === \"field\") {\n names.add(operand.name);\n }\n };\n\n const visit = (node: Condition) => {\n switch (node.kind) {\n case \"and\":\n case \"or\":\n node.operands.forEach(visit);\n break;\n case \"not\":\n visit(node.operand);\n break;\n case \"compare\":\n visitOperand(node.left);\n visitOperand(node.right);\n break;\n case \"in\":\n visitOperand(node.left);\n node.values.forEach(visitOperand);\n break;\n case \"like\":\n visitOperand(node.left);\n visitOperand(node.pattern);\n break;\n case \"between\":\n visitOperand(node.operand);\n visitOperand(node.from);\n visitOperand(node.to);\n break;\n case \"null\":\n visitOperand(node.operand);\n break;\n case \"literal\":\n break;\n }\n };\n\n visit(condition);\n return [...names];\n}\n\n/**\n * SQLite comparison semantics, narrowed to what migrations rely on: numbers\n * compare numerically even when one side arrived as a string, everything else\n * compares as text.\n */\nexport function looseEquals(left: unknown, right: unknown): boolean {\n if (left === null || left === undefined) {\n return right === null || right === undefined;\n }\n if (right === null || right === undefined) {\n return false;\n }\n if (typeof left === \"boolean\" || typeof right === \"boolean\") {\n return toBoolean(left) === toBoolean(right);\n }\n if (typeof left === \"number\" || typeof right === \"number\") {\n const leftNumber = Number(left);\n const rightNumber = Number(right);\n if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {\n return leftNumber === rightNumber;\n }\n }\n if (Array.isArray(left) || Array.isArray(right)) {\n return JSON.stringify(left) === JSON.stringify(right);\n }\n return String(left) === String(right);\n}\n\nexport function compareValues(left: unknown, right: unknown): number {\n if (left === null || left === undefined) {\n return right === null || right === undefined ? 0 : -1;\n }\n if (right === null || right === undefined) {\n return 1;\n }\n const leftNumber = Number(left);\n const rightNumber = Number(right);\n if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber) && left !== \"\" && right !== \"\") {\n return leftNumber === rightNumber ? 0 : leftNumber < rightNumber ? -1 : 1;\n }\n const leftText = String(left);\n const rightText = String(right);\n return leftText === rightText ? 0 : leftText < rightText ? -1 : 1;\n}\n\n/**\n * Ordering used by every sort surface (`sort: \"-views\"` and SQL `ORDER BY`),\n * so the two agree on the same rows: equality is the filter's `=`, and the\n * ordering below it is SQLite-ish — numeric when both sides are numbers.\n */\nexport function compareForSort(left: unknown, right: unknown): number {\n if (looseEquals(left, right)) {\n return 0;\n }\n return compareValues(left, right) < 0 ? -1 : 1;\n}\n\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value !== 0;\n }\n if (typeof value === \"string\") {\n return value !== \"\" && value !== \"0\" && value.toLowerCase() !== \"false\";\n }\n return Boolean(value);\n}\n\n/**\n * SQL LIKE. `implicitWildcards` is PocketBase's `~`, which wraps the term in\n * `%` unless the term already contains a wildcard.\n */\nfunction matchesLike(value: unknown, pattern: unknown, implicitWildcards: boolean): boolean {\n if (value === null || value === undefined || pattern === null || pattern === undefined) {\n return false;\n }\n\n let text = String(pattern);\n if (implicitWildcards && !text.includes(\"%\") && !text.includes(\"_\")) {\n text = `%${text}%`;\n }\n\n const regex = new RegExp(`^${likeToRegexSource(text)}$`, \"is\");\n return regex.test(String(value));\n}\n\nfunction likeToRegexSource(pattern: string): string {\n let source = \"\";\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index];\n if (char === \"\\\\\" && index + 1 < pattern.length) {\n source += escapeRegex(pattern[++index]);\n continue;\n }\n if (char === \"%\") {\n source += \"[\\\\s\\\\S]*\";\n continue;\n }\n if (char === \"_\") {\n source += \"[\\\\s\\\\S]\";\n continue;\n }\n source += escapeRegex(char);\n }\n return source;\n}\n\nfunction escapeRegex(char: string): string {\n return char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","/**\n * `$dbx` and `app.db()` simulation\n *\n * PocketBase exposes two query surfaces to a migration: `$dbx` expression\n * builders passed to the record finders, and `app.db().newQuery(sql)` for raw\n * SQL. Both are simulated against the in-memory record store (`records.ts`).\n *\n * The SQL support is a deliberate subset — SELECT / INSERT / UPDATE / DELETE\n * against a single collection table, with the condition grammar from\n * `expression.ts`. Anything beyond it raises `UnsupportedQueryError`, which\n * the caller turns into a warning (lenient) or a throw (strict): reporting\n * \"this query is not simulated\" is useful, quietly matching the wrong rows is\n * not.\n */\n\nimport {\n ExpressionError,\n compareForSort,\n evaluateCondition,\n parseCondition,\n parseValueOperand,\n resolveOperand,\n type Condition,\n type Operand,\n} from \"./expression\";\nimport type { RecordModel } from \"./records\";\n\nexport class UnsupportedQueryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"UnsupportedQueryError\";\n Object.setPrototypeOf(this, UnsupportedQueryError.prototype);\n }\n}\n\n/** Marks the objects `$dbx.*` returns so the finders can recognize them */\nconst DBX_EXPRESSION = Symbol.for(\"pocketbase-zod-schema.dbxExpression\");\n\nexport interface DbxExpression {\n [DBX_EXPRESSION]: true;\n /** The SQL fragment, as `$dbx` would build it (for messages and debugging) */\n build(): string;\n matches(record: RecordModel): boolean;\n}\n\nexport function isDbxExpression(value: unknown): value is DbxExpression {\n return typeof value === \"object\" && value !== null && (value as Record<symbol, unknown>)[DBX_EXPRESSION] === true;\n}\n\nfunction expression(sql: string, matches: (record: RecordModel) => boolean): DbxExpression {\n return { [DBX_EXPRESSION]: true, build: () => sql, matches };\n}\n\n/** Evaluates a parsed condition against one record */\nexport function matchCondition(condition: Condition, record: RecordModel, params?: Record<string, unknown>): boolean {\n return evaluateCondition(condition, { field: (name) => readField(record, name), params });\n}\n\n/**\n * Column references may be qualified (`posts.status`) or quoted; the record\n * only knows the bare name.\n */\nexport function readField(record: RecordModel, name: string): unknown {\n const bare = name.includes(\".\") ? name.slice(name.lastIndexOf(\".\") + 1) : name;\n return record.get(bare);\n}\n\nfunction quoteLiteral(value: unknown): string {\n if (value === null || value === undefined) {\n return \"NULL\";\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return `'${String(value).replace(/'/g, \"''\")}'`;\n}\n\n// ---------------------------------------------------------------------------\n// $dbx\n// ---------------------------------------------------------------------------\n\nexport function createDbx(): Record<string, unknown> {\n const exp = (raw: string, params: Record<string, unknown> = {}): DbxExpression => {\n const condition = parseCondition(raw);\n return expression(raw, (record) => matchCondition(condition, record, params));\n };\n\n const hashExp = (pairs: Record<string, unknown>): DbxExpression => {\n const entries = Object.entries(pairs ?? {});\n const sql = entries.map(([key, value]) => `${key}=${quoteLiteral(value)}`).join(\" AND \") || \"1=1\";\n return expression(sql, (record) => entries.every(([key, value]) => looseMatch(readField(record, key), value)));\n };\n\n const combine = (keyword: \"AND\" | \"OR\", operands: unknown[]): DbxExpression => {\n const expressions = operands.filter(isDbxExpression);\n const sql = expressions.map((operand) => `(${operand.build()})`).join(` ${keyword} `) || \"1=1\";\n return expression(sql, (record) =>\n keyword === \"AND\"\n ? expressions.every((operand) => operand.matches(record))\n : expressions.some((operand) => operand.matches(record))\n );\n };\n\n const inList = (column: string, values: unknown[], negated: boolean): DbxExpression => {\n const flat = values.flat();\n const sql = `${column} ${negated ? \"NOT IN\" : \"IN\"} (${flat.map(quoteLiteral).join(\", \")})`;\n return expression(sql, (record) => {\n const matched = flat.some((value) => looseMatch(readField(record, column), value));\n return negated ? !matched : matched;\n });\n };\n\n const like = (column: string, values: unknown[], negated: boolean, anyOf: boolean): DbxExpression => {\n const terms = values.flat().map((value) => String(value));\n const keyword = negated ? \"NOT LIKE\" : \"LIKE\";\n const sql = terms.map((term) => `${column} ${keyword} '%${term}%'`).join(anyOf ? \" OR \" : \" AND \") || \"1=1\";\n return expression(sql, (record) => {\n const text = String(readField(record, column) ?? \"\").toLowerCase();\n const test = (term: string) => text.includes(term.toLowerCase());\n const matched = anyOf ? terms.some(test) : terms.every(test);\n return negated ? !matched : matched;\n });\n };\n\n return {\n exp,\n hashExp,\n and: (...operands: unknown[]) => combine(\"AND\", operands),\n or: (...operands: unknown[]) => combine(\"OR\", operands),\n not: (operand: unknown) => {\n const inner = isDbxExpression(operand) ? operand : null;\n return expression(inner ? `NOT (${inner.build()})` : \"1=0\", (record) => !inner || !inner.matches(record));\n },\n in: (column: string, ...values: unknown[]) => inList(column, values, false),\n notIn: (column: string, ...values: unknown[]) => inList(column, values, true),\n like: (column: string, ...values: unknown[]) => like(column, values, false, false),\n notLike: (column: string, ...values: unknown[]) => like(column, values, true, false),\n orLike: (column: string, ...values: unknown[]) => like(column, values, false, true),\n between: (column: string, from: unknown, to: unknown) =>\n expression(`${column} BETWEEN ${quoteLiteral(from)} AND ${quoteLiteral(to)}`, (record) => {\n const value = readField(record, column);\n return compare(value, from) >= 0 && compare(value, to) <= 0;\n }),\n notBetween: (column: string, from: unknown, to: unknown) =>\n expression(`${column} NOT BETWEEN ${quoteLiteral(from)} AND ${quoteLiteral(to)}`, (record) => {\n const value = readField(record, column);\n return !(compare(value, from) >= 0 && compare(value, to) <= 0);\n }),\n };\n}\n\nfunction looseMatch(left: unknown, right: unknown): boolean {\n return evaluateCondition(\n { kind: \"compare\", operator: \"=\", left: { kind: \"value\", value: left }, right: { kind: \"value\", value: right } },\n { field: () => undefined }\n );\n}\n\nconst compare = compareForSort;\n\n// ---------------------------------------------------------------------------\n// SQL subset\n// ---------------------------------------------------------------------------\n\nexport type ParsedStatement =\n | {\n kind: \"select\";\n table: string;\n columns: string[];\n where?: Condition;\n order?: OrderTerm[];\n limit?: number;\n offset?: number;\n }\n | { kind: \"update\"; table: string; assignments: { column: string; value: Operand }[]; where?: Condition }\n | { kind: \"delete\"; table: string; where?: Condition }\n | { kind: \"insert\"; table: string; columns: string[]; values: Operand[] };\n\nexport interface OrderTerm {\n column: string;\n descending: boolean;\n}\n\nconst SELECT_PATTERN = /^SELECT\\s+(?<columns>[\\s\\S]+?)\\s+FROM\\s+(?<table>[`\"[\\]\\w.]+)(?<rest>[\\s\\S]*)$/i;\nconst UPDATE_PATTERN = /^UPDATE\\s+(?<table>[`\"[\\]\\w.]+)\\s+SET\\s+(?<rest>[\\s\\S]+)$/i;\nconst DELETE_PATTERN = /^DELETE\\s+FROM\\s+(?<table>[`\"[\\]\\w.]+)(?<rest>[\\s\\S]*)$/i;\nconst INSERT_PATTERN =\n /^INSERT\\s+INTO\\s+(?<table>[`\"[\\]\\w.]+)\\s*\\((?<columns>[^)]*)\\)\\s*VALUES\\s*\\((?<values>[\\s\\S]*)\\)\\s*$/i;\n\n/**\n * Parses one statement of the supported subset.\n *\n * @throws UnsupportedQueryError for anything outside it\n */\nexport function parseStatement(sql: string): ParsedStatement {\n const trimmed = sql.trim().replace(/;\\s*$/, \"\");\n\n const insert = INSERT_PATTERN.exec(trimmed);\n if (insert?.groups) {\n const columns = splitTopLevel(insert.groups.columns).map(unquoteIdentifier);\n const values = splitTopLevel(insert.groups.values).map((value) => parseOperandOrThrow(value, trimmed));\n if (columns.length !== values.length) {\n throw new UnsupportedQueryError(`INSERT column/value count mismatch: ${trimmed}`);\n }\n return { kind: \"insert\", table: unquoteIdentifier(insert.groups.table), columns, values };\n }\n\n const update = UPDATE_PATTERN.exec(trimmed);\n if (update?.groups) {\n const { clause, where } = splitWhere(update.groups.rest, trimmed);\n const assignments = splitTopLevel(clause).map((assignment) => {\n const separator = assignment.indexOf(\"=\");\n if (separator === -1) {\n throw new UnsupportedQueryError(`Unsupported SET assignment ${JSON.stringify(assignment)} in: ${trimmed}`);\n }\n return {\n column: unquoteIdentifier(assignment.slice(0, separator)),\n value: parseOperandOrThrow(assignment.slice(separator + 1), trimmed),\n };\n });\n return { kind: \"update\", table: unquoteIdentifier(update.groups.table), assignments, where };\n }\n\n const remove = DELETE_PATTERN.exec(trimmed);\n if (remove?.groups) {\n const { clause, where } = splitWhere(remove.groups.rest, trimmed);\n if (clause.trim() !== \"\") {\n throw new UnsupportedQueryError(`Unsupported DELETE clause ${JSON.stringify(clause.trim())} in: ${trimmed}`);\n }\n return { kind: \"delete\", table: unquoteIdentifier(remove.groups.table), where };\n }\n\n const select = SELECT_PATTERN.exec(trimmed);\n if (select?.groups) {\n const { clause, where, order, limit, offset } = splitSelectTail(select.groups.rest, trimmed);\n if (clause.trim() !== \"\") {\n throw new UnsupportedQueryError(`Unsupported SELECT clause ${JSON.stringify(clause.trim())} in: ${trimmed}`);\n }\n return {\n kind: \"select\",\n table: unquoteIdentifier(select.groups.table),\n columns: splitTopLevel(select.groups.columns).map((column) => unquoteIdentifier(stripAlias(column))),\n where,\n order,\n limit,\n offset,\n };\n }\n\n throw new UnsupportedQueryError(`Only single-table SELECT/INSERT/UPDATE/DELETE are simulated. Got: ${trimmed}`);\n}\n\n/** Runs a parsed statement over a collection's rows */\nexport interface StatementTarget {\n /** Records of the statement's table, in insertion order */\n rows: () => RecordModel[];\n insert: (values: Record<string, unknown>) => RecordModel;\n remove: (record: RecordModel) => void;\n persist: (record: RecordModel) => void;\n}\n\nexport interface StatementResult {\n /** Rows a SELECT produced, as plain objects */\n rows: Record<string, unknown>[];\n /** Rows an INSERT/UPDATE/DELETE touched */\n affected: number;\n}\n\nexport function executeStatement(\n statement: ParsedStatement,\n target: StatementTarget,\n params: Record<string, unknown>\n): StatementResult {\n const matching = (where?: Condition) =>\n target.rows().filter((record) => (where ? matchCondition(where, record, params) : true));\n\n switch (statement.kind) {\n case \"select\": {\n let rows = matching(statement.where);\n const order = statement.order;\n if (order?.length) {\n rows = [...rows].sort((a, b) => {\n for (const term of order) {\n const result = compare(readField(a, term.column), readField(b, term.column));\n if (result !== 0) {\n return term.descending ? -result : result;\n }\n }\n return 0;\n });\n }\n if (statement.offset !== undefined) {\n rows = rows.slice(statement.offset);\n }\n if (statement.limit !== undefined) {\n rows = rows.slice(0, statement.limit);\n }\n\n const selectAll = statement.columns.length === 0 || statement.columns.includes(\"*\");\n return {\n rows: rows.map((record) => {\n if (selectAll) {\n return record.export();\n }\n const projected: Record<string, unknown> = {};\n for (const column of statement.columns) {\n projected[column] = readField(record, column);\n }\n return projected;\n }),\n affected: 0,\n };\n }\n\n case \"update\": {\n const rows = matching(statement.where);\n for (const record of rows) {\n for (const assignment of statement.assignments) {\n record.set(\n assignment.column,\n resolveOperand(assignment.value, { field: (name) => readField(record, name), params })\n );\n }\n target.persist(record);\n }\n return { rows: [], affected: rows.length };\n }\n\n case \"delete\": {\n const rows = matching(statement.where);\n for (const record of rows) {\n target.remove(record);\n }\n return { rows: [], affected: rows.length };\n }\n\n case \"insert\": {\n const values: Record<string, unknown> = {};\n statement.columns.forEach((column, index) => {\n values[column] = resolveOperand(statement.values[index], { field: () => undefined, params });\n });\n target.insert(values);\n return { rows: [], affected: 1 };\n }\n }\n}\n\nfunction parseOperandOrThrow(source: string, sql: string): Operand {\n try {\n return parseValueOperand(source);\n } catch (error) {\n if (error instanceof ExpressionError) {\n throw new UnsupportedQueryError(`Unsupported value ${JSON.stringify(source.trim())} in: ${sql}`);\n }\n throw error;\n }\n}\n\nfunction parseConditionOrThrow(source: string, sql: string): Condition {\n try {\n return parseCondition(source);\n } catch (error) {\n if (error instanceof ExpressionError) {\n throw new UnsupportedQueryError(`Unsupported WHERE clause in ${sql}: ${error.message}`);\n }\n throw error;\n }\n}\n\nfunction splitWhere(rest: string, sql: string): { clause: string; where?: Condition } {\n const index = indexOfKeyword(rest, \"WHERE\");\n if (index === -1) {\n return { clause: rest };\n }\n return {\n clause: rest.slice(0, index),\n where: parseConditionOrThrow(rest.slice(index + \"WHERE\".length), sql),\n };\n}\n\nfunction splitSelectTail(\n rest: string,\n sql: string\n): { clause: string; where?: Condition; order?: OrderTerm[]; limit?: number; offset?: number } {\n let remainder = rest;\n let offset: number | undefined;\n let limit: number | undefined;\n let order: OrderTerm[] | undefined;\n\n const offsetIndex = indexOfKeyword(remainder, \"OFFSET\");\n if (offsetIndex !== -1) {\n offset = parseCount(remainder.slice(offsetIndex + \"OFFSET\".length), sql);\n remainder = remainder.slice(0, offsetIndex);\n }\n\n const limitIndex = indexOfKeyword(remainder, \"LIMIT\");\n if (limitIndex !== -1) {\n limit = parseCount(remainder.slice(limitIndex + \"LIMIT\".length), sql);\n remainder = remainder.slice(0, limitIndex);\n }\n\n const orderIndex = indexOfKeyword(remainder, \"ORDER BY\");\n if (orderIndex !== -1) {\n order = splitTopLevel(remainder.slice(orderIndex + \"ORDER BY\".length)).map((term) => {\n const parts = term.trim().split(/\\s+/);\n return {\n column: unquoteIdentifier(parts[0]),\n descending: (parts[1] ?? \"\").toUpperCase() === \"DESC\",\n };\n });\n remainder = remainder.slice(0, orderIndex);\n }\n\n const { clause, where } = splitWhere(remainder, sql);\n return { clause, where, order, limit, offset };\n}\n\nfunction parseCount(source: string, sql: string): number {\n const value = Number(source.trim());\n if (!Number.isInteger(value) || value < 0) {\n throw new UnsupportedQueryError(`Unsupported LIMIT/OFFSET ${JSON.stringify(source.trim())} in: ${sql}`);\n }\n return value;\n}\n\n/** Finds a keyword outside of quotes and parentheses */\nfunction indexOfKeyword(source: string, keyword: string): number {\n const upper = source.toUpperCase();\n const target = keyword.toUpperCase();\n let depth = 0;\n let quote: string | null = null;\n\n for (let index = 0; index < source.length; index++) {\n const char = source[index];\n if (quote) {\n if (char === \"\\\\\") {\n index++;\n } else if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === \"'\" || char === '\"' || char === \"`\") {\n quote = char;\n continue;\n }\n if (char === \"(\") {\n depth++;\n continue;\n }\n if (char === \")\") {\n depth--;\n continue;\n }\n if (depth !== 0) {\n continue;\n }\n if (upper.startsWith(target, index) && isBoundary(source, index - 1) && isBoundary(source, index + target.length)) {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction isBoundary(source: string, index: number): boolean {\n if (index < 0 || index >= source.length) {\n return true;\n }\n return !/[A-Za-z0-9_]/.test(source[index]);\n}\n\n/** Splits on commas that are not inside quotes or parentheses */\nfunction splitTopLevel(source: string): string[] {\n const parts: string[] = [];\n let current = \"\";\n let depth = 0;\n let quote: string | null = null;\n\n for (let index = 0; index < source.length; index++) {\n const char = source[index];\n if (quote) {\n current += char;\n if (char === \"\\\\\" && index + 1 < source.length) {\n current += source[++index];\n } else if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === \"'\" || char === '\"' || char === \"`\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === \"(\") {\n depth++;\n } else if (char === \")\") {\n depth--;\n }\n if (char === \",\" && depth === 0) {\n parts.push(current);\n current = \"\";\n continue;\n }\n current += char;\n }\n\n if (current.trim() !== \"\") {\n parts.push(current);\n }\n return parts.map((part) => part.trim()).filter((part) => part !== \"\");\n}\n\nfunction stripAlias(column: string): string {\n return column.replace(/\\s+AS\\s+[\\s\\S]+$/i, \"\").trim();\n}\n\nfunction unquoteIdentifier(identifier: string): string {\n const trimmed = identifier.trim();\n const unquoted = trimmed.replace(/^[`\"[]/, \"\").replace(/[`\"\\]]$/, \"\");\n // Qualified names (`posts.status`) reduce to the column\n return unquoted.includes(\".\") ? unquoted.slice(unquoted.lastIndexOf(\".\") + 1) : unquoted;\n}\n","/**\n * Record simulation — an in-memory row store per collection\n *\n * Schema reconstruction never needs this: a migration that seeds or rewrites\n * data does not change the shape of a collection. It matters for the other\n * job the engine can do — running a hand-written data migration before it\n * touches production and seeing what it actually does.\n *\n * Enabled with `records: \"simulate\"`. Left off, `Record` and the data-layer\n * `app.*` methods stay the inert stubs they have always been, so schema-only\n * replay is unchanged.\n *\n * The store lives on `CollectionStore`, which means it inherits the runner's\n * transaction semantics for free: a migration that throws halfway through a\n * data rewrite leaves neither schema nor records behind.\n */\n\nimport type { Collection } from \"./collection\";\n\n/**\n * Fields PocketBase manages itself. `id` is generated on save; `created` and\n * `updated` are autodate columns the server stamps.\n */\nconst SYSTEM_RECORD_FIELDS = [\"id\", \"created\", \"updated\"];\n\n/** PocketBase record ids are 15 lowercase alphanumeric characters */\nexport function generateRecordId(): string {\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let id = \"\";\n for (let index = 0; index < 15; index++) {\n id += alphabet[Math.floor(Math.random() * alphabet.length)];\n }\n return id;\n}\n\n/**\n * The `Record` global a migration sees. Mirrors `core.Record`'s JSVM surface:\n * `get`/`set` plus the typed getters, `load`, `publicExport`, `originalCopy`.\n *\n * Arbitrary property access (`record.title`) is deliberately *not* supported —\n * `core.Record` is a Go struct and does not support it either, so a migration\n * that relies on it would fail in PocketBase.\n */\nexport class RecordModel {\n private data: Record<string, unknown> = {};\n private original: Record<string, unknown> = {};\n private readonly owner: Collection;\n /** Set by setPassword(); PocketBase stores a hash, the simulation the value */\n private password?: string;\n\n constructor(collection: Collection, data: Record<string, unknown> = {}) {\n if (!collection || typeof collection !== \"object\" || typeof (collection as Collection).name !== \"string\") {\n throw new Error(\"[engine] new Record() expects a collection\");\n }\n this.owner = collection;\n this.load(data);\n this.original = { ...this.data };\n }\n\n get id(): string {\n return typeof this.data.id === \"string\" ? this.data.id : \"\";\n }\n\n set id(value: string) {\n this.data.id = value;\n }\n\n collection(): Collection {\n return this.owner;\n }\n\n /** PocketBase names a collection's table after the collection */\n tableName(): string {\n return this.owner.name;\n }\n\n get(key: string): unknown {\n return this.data[key];\n }\n\n set(key: string, value: unknown): void {\n this.data[key] = value;\n }\n\n getString(key: string): string {\n const value = this.get(key);\n if (value === null || value === undefined) {\n return \"\";\n }\n return typeof value === \"string\" ? value : String(value);\n }\n\n getBool(key: string): boolean {\n const value = this.get(key);\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value !== 0;\n }\n if (typeof value === \"string\") {\n return value !== \"\" && value !== \"0\" && value.toLowerCase() !== \"false\";\n }\n return Boolean(value);\n }\n\n getInt(key: string): number {\n const value = Number(this.get(key));\n return Number.isFinite(value) ? Math.trunc(value) : 0;\n }\n\n getFloat(key: string): number {\n const value = Number(this.get(key));\n return Number.isFinite(value) ? value : 0;\n }\n\n getDateTime(key: string): string {\n return this.getString(key);\n }\n\n getStringSlice(key: string): string[] {\n const value = this.get(key);\n if (Array.isArray(value)) {\n return value.map((entry) => (typeof entry === \"string\" ? entry : String(entry)));\n }\n if (typeof value === \"string\" && value !== \"\") {\n return [value];\n }\n return [];\n }\n\n /** Bulk assignment, as `record.load({...})` does in the JSVM */\n load(data: Record<string, unknown>): void {\n if (!data || typeof data !== \"object\") {\n return;\n }\n for (const [key, value] of Object.entries(data)) {\n this.data[key] = value;\n }\n }\n\n setPassword(password: string): void {\n this.password = password;\n this.data.password = password;\n }\n\n validatePassword(password: string): boolean {\n return this.password !== undefined && this.password === password;\n }\n\n /** The record as it was last read from (or written to) the store */\n originalCopy(): RecordModel {\n return new RecordModel(this.owner, { ...this.original });\n }\n\n /**\n * Deep, independent copy. `owner` rebinds the copy to another Collection\n * instance (what a transaction clone needs); everything the getters cannot\n * reach — the pre-modification `original` and the password `setPassword()`\n * stored — is carried over, so a copy behaves like the record it came from.\n */\n clone(owner: Collection = this.owner): RecordModel {\n const copy = new RecordModel(owner, structuredClone(this.data));\n copy.original = structuredClone(this.original);\n copy.password = this.password;\n return copy;\n }\n\n /** Plain object, the shape `publicExport()` returns in the JSVM */\n publicExport(): Record<string, unknown> {\n return { ...this.data };\n }\n\n /** Every stored value, including system columns */\n export(): Record<string, unknown> {\n return { ...this.data };\n }\n\n /** Called by the store once a save has committed */\n markPersisted(): void {\n this.original = { ...this.data };\n }\n\n /** Fields the record carries that the collection does not declare */\n undeclaredFields(): string[] {\n const declared = new Set<string>(SYSTEM_RECORD_FIELDS);\n for (const field of this.owner.fields) {\n if (typeof field.name === \"string\") {\n declared.add(field.name);\n }\n }\n return Object.keys(this.data).filter((key) => !declared.has(key));\n }\n}\n\n/**\n * Rows, keyed by collection id then record id. Insertion order is preserved\n * so unsorted queries come back the way they went in.\n */\nexport class RecordStore {\n private byCollection = new Map<string, Map<string, RecordModel>>();\n\n save(record: RecordModel): RecordModel {\n if (record.id === \"\") {\n record.id = generateRecordId();\n }\n const collection = record.collection();\n const rows = this.rowsFor(collection.id);\n rows.set(record.id, record);\n record.markPersisted();\n return record;\n }\n\n delete(record: RecordModel): boolean {\n return this.rowsFor(record.collection().id).delete(record.id);\n }\n\n deleteById(collectionId: string, recordId: string): boolean {\n return this.rowsFor(collectionId).delete(recordId);\n }\n\n getById(collectionId: string, recordId: string): RecordModel | undefined {\n return this.rowsFor(collectionId).get(recordId);\n }\n\n list(collectionId: string): RecordModel[] {\n return [...this.rowsFor(collectionId).values()];\n }\n\n count(collectionId: string): number {\n return this.rowsFor(collectionId).size;\n }\n\n /** Drops every row of a collection (what deleting the collection does) */\n dropCollection(collectionId: string): void {\n this.byCollection.delete(collectionId);\n }\n\n /** Every collection id that currently holds at least one record */\n collectionIds(): string[] {\n return [...this.byCollection.keys()].filter((id) => this.byCollection.get(id)!.size > 0);\n }\n\n /**\n * Deep copy. Records are rebound to the collections in `collections` so a\n * cloned record's `collection()` points at the cloned schema, not the one\n * the transaction started from.\n */\n clone(resolveCollection: (id: string) => Collection | undefined): RecordStore {\n const copy = new RecordStore();\n for (const [collectionId, rows] of this.byCollection.entries()) {\n const collection = resolveCollection(collectionId);\n if (!collection) {\n // The collection was dropped in this transaction; its rows go with it\n continue;\n }\n const copiedRows = new Map<string, RecordModel>();\n for (const [recordId, record] of rows.entries()) {\n copiedRows.set(recordId, record.clone(collection));\n }\n copy.byCollection.set(collectionId, copiedRows);\n }\n return copy;\n }\n\n /** Commit: adopt another store's rows */\n replaceWith(other: RecordStore): void {\n this.byCollection = new Map(other.byCollection);\n }\n\n private rowsFor(collectionId: string): Map<string, RecordModel> {\n let rows = this.byCollection.get(collectionId);\n if (!rows) {\n rows = new Map();\n this.byCollection.set(collectionId, rows);\n }\n return rows;\n }\n}\n","/**\n * The data-layer half of `app` — record finders and `app.db()`\n *\n * Installed on the simulated app only when `records: \"simulate\"` is set.\n * Without it these names fall through to the inert stubs, which is what\n * schema-only replay wants: a data migration should not be able to fail a\n * `generate` run over rows nobody is tracking.\n *\n * Finder semantics follow PocketBase: \"by id\" and \"first by ...\" throw\n * `sql: no rows in result set` on a miss, list finders return an empty array.\n * A migration that guards with try/catch behaves the same here as in\n * production.\n */\n\nimport type { Collection } from \"./collection\";\nimport {\n UnsupportedQueryError,\n executeStatement,\n isDbxExpression,\n matchCondition,\n parseStatement,\n readField,\n type DbxExpression,\n type StatementResult,\n} from \"./dbx\";\nimport { compareForSort, ExpressionError, parseCondition } from \"./expression\";\nimport { RecordModel } from \"./records\";\nimport type { CollectionStore } from \"./store\";\nimport type { EngineOptions, EngineWarning } from \"./types\";\n\nexport interface WarningSink {\n (warning: EngineWarning): void;\n}\n\n/** PocketBase's error text for a lookup that matched nothing */\nexport const NO_ROWS_ERROR = \"sql: no rows in result set\";\n\nexport interface DataApi {\n /** Methods to install on the simulated app */\n methods: Record<string, (...args: any[]) => unknown>;\n /**\n * Points `runInTransaction`'s callback argument at the app these methods\n * are installed on. Called once the proxy exists.\n */\n bindApp: (app: unknown) => void;\n}\n\nexport function createDataApi(store: CollectionStore, options: EngineOptions, warn: WarningSink): DataApi {\n const strict = options.strictness === \"strict\";\n\n /**\n * Accepts what PocketBase's finders accept: a name, an id, or a Collection.\n * A Collection is re-resolved through the store so the rows come from the\n * transaction's copy rather than whatever instance the caller held on to.\n */\n const resolveCollection = (target: unknown): Collection => {\n if (typeof target === \"string\") {\n const collection = store.getByNameOrId(target);\n if (collection) {\n return collection;\n }\n throw new Error(`${NO_ROWS_ERROR} (collection \"${target}\" not found)`);\n }\n\n if (target && typeof target === \"object\") {\n const candidate = target as Collection;\n const known =\n (typeof candidate.id === \"string\" ? store.getById(candidate.id) : undefined) ??\n (typeof candidate.name === \"string\" && candidate.name !== \"\" ? store.getByNameOrId(candidate.name) : undefined);\n if (known) {\n return known;\n }\n throw new Error(`${NO_ROWS_ERROR} (collection \"${candidate.name ?? candidate.id}\" not found)`);\n }\n\n throw new Error(\"[engine] expected a collection name, id, or Collection\");\n };\n\n const rowsOf = (target: unknown): RecordModel[] => store.records.list(resolveCollection(target).id);\n\n const applyExpressions = (records: RecordModel[], expressions: unknown[]): RecordModel[] => {\n const predicates = expressions.filter(isDbxExpression) as DbxExpression[];\n const ignored = expressions.length - predicates.length;\n if (ignored > 0) {\n warn({\n kind: \"unsupported-api\",\n api: \"$dbx\",\n message: `${ignored} query expression(s) were not built by $dbx and could not be evaluated; they were ignored`,\n });\n }\n return records.filter((record) => predicates.every((predicate) => predicate.matches(record)));\n };\n\n /**\n * PocketBase's `sort` string: comma-separated field names, `-` for\n * descending. An unknown field simply compares as undefined, the way a\n * missing column sorts in SQLite. Ordering is `compareForSort` — the same\n * comparator SQL `ORDER BY` uses, so numbers sort numerically.\n */\n const applySort = (records: RecordModel[], sort: unknown): RecordModel[] => {\n if (typeof sort !== \"string\" || sort.trim() === \"\") {\n return records;\n }\n const terms = sort\n .split(\",\")\n .map((term) => term.trim())\n .filter((term) => term !== \"\")\n .map((term) => ({ field: term.replace(/^[-+]/, \"\"), descending: term.startsWith(\"-\") }));\n\n return [...records].sort((a, b) => {\n for (const term of terms) {\n const result = compareForSort(readField(a, term.field), readField(b, term.field));\n if (result !== 0) {\n return term.descending ? -result : result;\n }\n }\n return 0;\n });\n };\n\n const filterRecords = (\n target: unknown,\n filter: unknown,\n sort?: unknown,\n limit?: unknown,\n offset?: unknown,\n params?: unknown\n ): RecordModel[] => {\n let records = rowsOf(target);\n\n if (typeof filter === \"string\" && filter.trim() !== \"\") {\n try {\n const condition = parseCondition(filter);\n const bound = (params && typeof params === \"object\" ? params : {}) as Record<string, unknown>;\n records = records.filter((record) => matchCondition(condition, record, bound));\n } catch (error) {\n if (!(error instanceof ExpressionError)) {\n throw error;\n }\n reportUnsupported(`filter ${JSON.stringify(filter)}: ${error.message}`);\n return [];\n }\n }\n\n records = applySort(records, sort);\n\n const start = typeof offset === \"number\" && offset > 0 ? offset : 0;\n const count = typeof limit === \"number\" && limit > 0 ? limit : undefined;\n records = records.slice(start, count === undefined ? undefined : start + count);\n\n return records;\n };\n\n function reportUnsupported(message: string): void {\n if (strict) {\n throw new UnsupportedQueryError(`[engine] ${message}`);\n }\n warn({ kind: \"unsupported-api\", api: \"app.db\", message: `${message}; the query was skipped` });\n }\n\n /** `app.db().newQuery(sql)` */\n const createQuery = (sql: unknown) => {\n let params: Record<string, unknown> = {};\n\n const run = (): StatementResult => {\n if (typeof sql !== \"string\") {\n reportUnsupported(\"newQuery() expects a SQL string\");\n return { rows: [], affected: 0 };\n }\n try {\n const statement = parseStatement(sql);\n const collection = resolveCollection(statement.table);\n return executeStatement(\n statement,\n {\n rows: () => store.records.list(collection.id),\n insert: (values) => store.records.save(new RecordModel(collection, values)),\n remove: (record) => store.records.delete(record),\n persist: (record) => store.records.save(record),\n },\n params\n );\n } catch (error) {\n if (error instanceof UnsupportedQueryError || error instanceof ExpressionError) {\n reportUnsupported(error.message);\n return { rows: [], affected: 0 };\n }\n throw error;\n }\n };\n\n const assignTo = (target: unknown, value: unknown): unknown => {\n if (target && typeof target === \"object\" && value && typeof value === \"object\") {\n Object.assign(target as Record<string, unknown>, value as Record<string, unknown>);\n return target;\n }\n return value;\n };\n\n const query = {\n bind(values: Record<string, unknown>) {\n params = { ...params, ...(values ?? {}) };\n return query;\n },\n execute() {\n const result = run();\n return { rowsAffected: () => result.affected, lastInsertId: () => 0 };\n },\n all(target?: unknown) {\n const rows = run().rows;\n return target === undefined ? rows : assignTo(target, rows);\n },\n one(target?: unknown) {\n const rows = run().rows;\n if (rows.length === 0) {\n throw new Error(NO_ROWS_ERROR);\n }\n return target === undefined ? rows[0] : assignTo(target, rows[0]);\n },\n row(target?: unknown) {\n return query.one(target);\n },\n };\n\n return query;\n };\n\n const methods: Record<string, (...args: any[]) => unknown> = {\n findRecordById(target: unknown, id: unknown) {\n const collection = resolveCollection(target);\n const record = store.records.getById(collection.id, String(id));\n if (!record) {\n throw new Error(`${NO_ROWS_ERROR} (record \"${String(id)}\" in \"${collection.name}\")`);\n }\n return record;\n },\n\n findRecordsByIds(target: unknown, ids: unknown, ...expressions: unknown[]) {\n const collection = resolveCollection(target);\n const wanted = Array.isArray(ids) ? ids.map((id) => String(id)) : [String(ids)];\n const found = wanted\n .map((id) => store.records.getById(collection.id, id))\n .filter((record): record is RecordModel => record !== undefined);\n return applyExpressions(found, expressions);\n },\n\n findAllRecords(target: unknown, ...expressions: unknown[]) {\n return applyExpressions(rowsOf(target), expressions);\n },\n\n findFirstRecordByData(target: unknown, key: unknown, value: unknown) {\n const match = rowsOf(target).find((record) =>\n matchCondition(\n {\n kind: \"compare\",\n operator: \"=\",\n left: { kind: \"field\", name: String(key) },\n right: { kind: \"value\", value },\n },\n record\n )\n );\n if (!match) {\n throw new Error(`${NO_ROWS_ERROR} (${String(key)}=${String(value)})`);\n }\n return match;\n },\n\n findRecordsByFilter(\n target: unknown,\n filter: unknown,\n sort?: unknown,\n limit?: unknown,\n offset?: unknown,\n params?: unknown\n ) {\n return filterRecords(target, filter, sort, limit, offset, params);\n },\n\n findFirstRecordByFilter(target: unknown, filter: unknown, params?: unknown) {\n const [first] = filterRecords(target, filter, undefined, 1, 0, params);\n if (!first) {\n throw new Error(`${NO_ROWS_ERROR} (${String(filter)})`);\n }\n return first;\n },\n\n findAuthRecordByEmail(target: unknown, email: unknown) {\n return methods.findFirstRecordByData(target, \"email\", email);\n },\n\n countRecords(target: unknown, ...expressions: unknown[]) {\n return applyExpressions(rowsOf(target), expressions).length;\n },\n\n db() {\n return { newQuery: (sql: unknown) => createQuery(sql) };\n },\n\n /**\n * PocketBase hands the callback a transactional app. Everything the\n * runner executes is already inside one transaction, so the callback\n * receives the same app; a throw still rolls the whole migration back.\n */\n runInTransaction(callback: unknown) {\n if (typeof callback === \"function\") {\n return (callback as (app: unknown) => unknown)(boundApp);\n }\n return undefined;\n },\n };\n\n let boundApp: unknown;\n\n return {\n methods,\n bindApp: (app: unknown) => {\n boundApp = app;\n },\n };\n}\n","/**\n * SimulatedApp — the `app` handed to a migration's up() function\n *\n * Implements the schema-level surface of PocketBase's transactional app\n * (findCollectionByNameOrId / save / delete / importCollections). Everything\n * else — record and query APIs like findRecordById, db(), etc. — is handled\n * by a strictness-controlled Proxy: lenient mode records a warning and\n * returns an inert no-op value so schema-only replay of hand-written data\n * migrations still succeeds; strict mode throws.\n *\n * With `records: \"simulate\"` those data-layer methods are real instead\n * (see `data-api.ts`), backed by the in-memory record store.\n */\n\nimport { Collection, ensureAuthSystemFields } from \"./collection\";\nimport { createDataApi } from \"./data-api\";\nimport { generateRuntimeFieldId } from \"./fields\";\nimport { RecordModel } from \"./records\";\nimport type { CollectionStore } from \"./store\";\nimport type { EngineOptions, EngineWarning, RawCollection } from \"./types\";\n\nexport interface WarningSink {\n (warning: EngineWarning): void;\n}\n\n/** Identifies the values `createInertStub` returns, which pretend to be anything */\nconst INERT_STUB = Symbol.for(\"pocketbase-zod-schema.inertStub\");\n\nexport function isInertStub(value: unknown): boolean {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) {\n return false;\n }\n return (value as Record<symbol, unknown>)[INERT_STUB] === true;\n}\n\n/**\n * A callable, chainable, inert value returned by lenient stubs so chains\n * like `app.db().newQuery(\"...\").execute()` don't crash. Every call and\n * property access returns the stub itself; primitive coercion yields\n * neutral values.\n */\nexport function createInertStub(name: string, options: EngineOptions, warn: WarningSink): any {\n // Must be a full function (not an arrow) so the Proxy construct trap can\n // service `new Record()`-style calls\n const target = function inertStubTarget() {\n return undefined;\n };\n const stub: any = new Proxy(target, {\n get(_target, prop) {\n if (prop === INERT_STUB) {\n return true;\n }\n if (prop === Symbol.toPrimitive) {\n return () => \"\";\n }\n if (prop === \"toString\") {\n return () => \"\";\n }\n if (prop === \"valueOf\") {\n return () => 0;\n }\n // Not a thenable — await/then chains must not treat this as a promise\n if (prop === \"then\") {\n return undefined;\n }\n if (typeof prop === \"symbol\") {\n return undefined;\n }\n return createInertStub(`${name}.${prop}`, options, warn);\n },\n apply() {\n if (options.strictness === \"strict\") {\n throw new Error(`[engine] ${name}() is not supported by the migration simulation engine (strict mode)`);\n }\n warn({\n kind: \"unsupported-api\",\n api: name,\n message: `${name}() is not simulated; call was a no-op`,\n });\n return stub;\n },\n construct() {\n if (options.strictness === \"strict\") {\n throw new Error(`[engine] new ${name}() is not supported by the migration simulation engine (strict mode)`);\n }\n warn({\n kind: \"unsupported-api\",\n api: name,\n message: `new ${name}() is not simulated; result is inert`,\n });\n return stub;\n },\n });\n return stub;\n}\n\nclass SimulatedAppImpl {\n constructor(\n private store: CollectionStore,\n private options: EngineOptions,\n private warn: WarningSink\n ) {}\n\n findCollectionByNameOrId(nameOrId: string): Collection {\n const collection = this.store.getByNameOrId(nameOrId);\n if (!collection) {\n // Matches the error PocketBase surfaces for a missing collection\n throw new Error(`sql: no rows in result set (collection \"${nameOrId}\" not found)`);\n }\n return collection;\n }\n\n save(model: any): void {\n // A record only reaches here with record simulation on; without it\n // `new Record()` produced an inert stub, handled below\n if (model instanceof RecordModel) {\n this.store.records.save(model);\n return;\n }\n if (this.skipInertModel(model, \"save\")) {\n return;\n }\n\n const collection = this.toCollection(model);\n if (!collection.name) {\n throw new Error(\"[engine] cannot save a collection without a name\");\n }\n // PocketBase restores missing auth system fields as part of the save\n ensureAuthSystemFields(collection);\n for (const field of collection.fields) {\n if (typeof field.id !== \"string\" || field.id === \"\") {\n field.id = generateRuntimeFieldId(typeof field.type === \"string\" ? field.type : \"\");\n }\n }\n this.store.upsert(collection);\n }\n\n delete(model: any): void {\n if (model instanceof RecordModel) {\n this.store.records.delete(model);\n return;\n }\n if (this.skipInertModel(model, \"delete\")) {\n return;\n }\n if (model instanceof Collection) {\n this.store.removeById(model.id);\n return;\n }\n if (typeof model === \"string\") {\n const collection = this.store.getByNameOrId(model);\n if (collection) {\n this.store.removeById(collection.id);\n }\n return;\n }\n if (model && typeof model.id === \"string\") {\n this.store.removeById(model.id);\n }\n }\n\n /**\n * `app.save(record)` in a data migration hands us whatever `new Record()`\n * produced. Without record simulation that is an inert stub, and treating\n * it as a collection would fail the whole replay over rows nobody is\n * tracking — so the call is reported and skipped, like every other\n * unsimulated data operation.\n */\n private skipInertModel(model: unknown, operation: string): boolean {\n if (!isInertStub(model)) {\n return false;\n }\n if (this.options.strictness === \"strict\") {\n throw new Error(`[engine] app.${operation}() received an unsimulated model (strict mode)`);\n }\n this.warn({\n kind: \"unsupported-api\",\n api: `app.${operation}`,\n message:\n `app.${operation}() was called with an unsimulated model; the call was a no-op. ` +\n `Set records: \"simulate\" to execute record operations.`,\n });\n return true;\n }\n\n /**\n * What native snapshot migrations call:\n * `return app.importCollections(snapshot, deleteMissing)`\n */\n importCollections(rawCollections: RawCollection[], deleteMissing = false): void {\n if (!Array.isArray(rawCollections)) {\n throw new Error(\"[engine] importCollections expects an array of collections\");\n }\n const imported = new Set<string>();\n for (const raw of rawCollections) {\n const collection = this.toCollection(raw);\n ensureAuthSystemFields(collection);\n this.store.upsert(collection);\n imported.add(collection.id);\n }\n if (deleteMissing) {\n for (const existing of this.store.list()) {\n if (!imported.has(existing.id)) {\n this.store.removeById(existing.id);\n }\n }\n }\n }\n\n private toCollection(model: any): Collection {\n if (model instanceof Collection) {\n return model;\n }\n if (model && typeof model === \"object\") {\n return new Collection(model);\n }\n throw new Error(\"[engine] expected a collection object\");\n }\n}\n\nexport type SimulatedApp = SimulatedAppImpl;\n\n/**\n * The data-layer surface installed alongside the app when record simulation\n * is on, so the sandbox can expose the same `Record` and `$dbx` objects the\n * app's finders return.\n */\nexport interface SimulatedAppBundle {\n app: SimulatedApp;\n /** Null when records are not simulated */\n data: ReturnType<typeof createDataApi> | null;\n}\n\nexport function createSimulatedAppBundle(\n store: CollectionStore,\n options: EngineOptions,\n warn: WarningSink\n): SimulatedAppBundle {\n const impl = new SimulatedAppImpl(store, options, warn);\n const data = options.records === \"simulate\" ? createDataApi(store, options, warn) : null;\n\n const app = new Proxy(impl, {\n get(target, prop, receiver) {\n if (prop in target || typeof prop === \"symbol\") {\n return Reflect.get(target, prop, receiver);\n }\n const name = String(prop);\n if (data && name in data.methods) {\n return data.methods[name];\n }\n return createInertStub(`app.${name}`, options, warn);\n },\n }) as SimulatedApp;\n\n data?.bindApp(app);\n\n return { app, data };\n}\n\nexport function createSimulatedApp(store: CollectionStore, options: EngineOptions, warn: WarningSink): SimulatedApp {\n return createSimulatedAppBundle(store, options, warn).app;\n}\n","/**\n * unmarshal(data, dst) — the PocketBase JSVM helper migrations use to merge\n * a JSON-shaped object into a collection (or any Go struct).\n *\n * Semantics follow Go's json.Unmarshal into an existing struct: plain\n * objects merge key by key, while arrays and scalars replace the target\n * value wholesale. `unmarshal({indexes: []}, collection)` therefore clears\n * the indexes list, which is exactly what PocketBase's generated down\n * migrations rely on.\n */\n\nimport { Collection } from \"./collection\";\nimport { FieldsList } from \"./fields-list\";\n\nfunction isPlainObject(value: unknown): value is Record<string, any> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n // Cross-realm safe: vm-created literals have a foreign Object prototype\n const proto = Object.getPrototypeOf(value);\n return proto === null || Object.getPrototypeOf(proto) === null;\n}\n\nexport function unmarshal(data: unknown, dst: unknown): void {\n if (!isPlainObject(data) || dst === null || typeof dst !== \"object\") {\n return;\n }\n\n const target = dst as Record<string, any>;\n\n for (const [key, value] of Object.entries(data)) {\n if (key === \"fields\" && target instanceof Collection && Array.isArray(value)) {\n target.fields.replaceAll(value);\n continue;\n }\n if (key === \"fields\" && target.fields instanceof FieldsList && Array.isArray(value)) {\n target.fields.replaceAll(value);\n continue;\n }\n\n if (Array.isArray(value)) {\n target[key] = [...value];\n } else if (isPlainObject(value)) {\n if (isPlainObject(target[key])) {\n unmarshal(value, target[key]);\n } else {\n target[key] = {};\n unmarshal(value, target[key]);\n }\n } else {\n target[key] = value;\n }\n }\n}\n","/**\n * Sandbox globals for the migration execution context\n *\n * Recreates the PocketBase JSVM global surface a migration file sees:\n * migrate(), the Collection/Field constructors, unmarshal(), and the Go\n * binding globals ($app, $os, $dbx, ...). The sandbox contains NO Node\n * globals — no require, process, or fs — approximating goja, where none\n * of those exist either.\n */\n\nimport { Collection } from \"./collection\";\nimport { createInertStub, type SimulatedApp, type WarningSink } from \"./app\";\nimport { createDbx } from \"./dbx\";\nimport { FIELD_CONSTRUCTORS } from \"./fields\";\nimport { RecordModel } from \"./records\";\nimport { unmarshal } from \"./unmarshal\";\nimport type { EngineOptions } from \"./types\";\n\nexport interface MigrationRegistration {\n up?: (app: SimulatedApp) => unknown;\n down?: (app: SimulatedApp) => unknown;\n}\n\nexport interface SandboxHandles {\n sandbox: Record<string, any>;\n registrations: MigrationRegistration[];\n /** The runner points this at the current transactional app during up() */\n setCurrentApp: (app: SimulatedApp | null) => void;\n}\n\nconst STUBBED_GLOBALS = [\"$os\", \"$dbx\", \"$security\", \"$filesystem\", \"$http\", \"$mails\", \"$template\", \"Record\", \"DateTime\"];\n\nexport function buildSandbox(options: EngineOptions, warn: WarningSink): SandboxHandles {\n const registrations: MigrationRegistration[] = [];\n let currentApp: SimulatedApp | null = null;\n\n const consoleMethod =\n (level: string) =>\n (...args: unknown[]) => {\n warn({\n kind: \"console\",\n message: `console.${level}: ${args.map((arg) => stringifyArg(arg)).join(\" \")}`,\n });\n };\n\n const sandbox: Record<string, any> = {\n migrate(up?: MigrationRegistration[\"up\"], down?: MigrationRegistration[\"down\"]) {\n registrations.push({ up, down });\n },\n Collection,\n unmarshal,\n ...FIELD_CONSTRUCTORS,\n console: {\n log: consoleMethod(\"log\"),\n info: consoleMethod(\"info\"),\n warn: consoleMethod(\"warn\"),\n error: consoleMethod(\"error\"),\n debug: consoleMethod(\"debug\"),\n },\n };\n\n // Record and $dbx become real when record simulation is on; they hold no\n // state of their own, so the sandbox can own them for the whole file while\n // the store-bound half lives on the per-run app (see data-api.ts)\n const simulatesRecords = options.records === \"simulate\";\n\n for (const name of STUBBED_GLOBALS) {\n if (simulatesRecords && (name === \"Record\" || name === \"$dbx\")) {\n continue;\n }\n sandbox[name] = createInertStub(name, options, warn);\n }\n\n if (simulatesRecords) {\n sandbox.Record = RecordModel;\n sandbox.$dbx = createDbx();\n }\n\n // Some migrations use the global $app instead of the up() callback\n // argument; bind it to the same transactional app while up() runs\n Object.defineProperty(sandbox, \"$app\", {\n enumerable: true,\n get() {\n return currentApp ?? createInertStub(\"$app\", options, warn);\n },\n });\n\n return {\n sandbox,\n registrations,\n setCurrentApp(app) {\n currentApp = app;\n },\n };\n}\n\nfunction stringifyArg(arg: unknown): string {\n if (typeof arg === \"string\") {\n return arg;\n }\n try {\n return JSON.stringify(arg) ?? String(arg);\n } catch {\n return String(arg);\n }\n}\n","/**\n * Runner — executes one migration file against a CollectionStore\n *\n * Evaluation happens in a vm context built from the sandbox globals; the\n * file's migrate(up, down) call registers its closures. The requested\n * direction then runs transactionally: the store is cloned, the closure is\n * applied to the clone, and the clone replaces the store only on success.\n * The closure is invoked from inside the context (not host code) so the vm\n * timeout also bounds infinite loops within migration bodies.\n *\n * State reconstruction only ever runs `up`, which structurally rules out\n * replaying rollback statements as forward operations. `down` is executed on request (`executeMigrationDownSource`),\n * for rollback verification — see `verify.ts`. Downs run in reverse\n * registration order, mirroring how PocketBase rolls back.\n */\n\nimport * as fs from \"fs\";\nimport * as vm from \"vm\";\nimport { MigrationExecutionError } from \"../errors\";\nimport { createSimulatedApp } from \"./app\";\nimport { buildSandbox } from \"./globals\";\nimport type { CollectionStore } from \"./store\";\nimport type { EngineOptions, EngineWarning, MigrationDirection, MigrationExecutionResult } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nexport function executeMigrationSource(\n source: string,\n store: CollectionStore,\n options: EngineOptions & { filename?: string } = {}\n): MigrationExecutionResult {\n return runMigrationSource(source, store, options, \"up\");\n}\n\nexport function executeMigrationFile(\n filePath: string,\n store: CollectionStore,\n options: EngineOptions = {}\n): MigrationExecutionResult {\n const source = fs.readFileSync(filePath, \"utf-8\");\n return executeMigrationSource(source, store, { ...options, filename: filePath });\n}\n\n/**\n * Runs the file's `down()` closures against the store, newest registration\n * first. A file that registers no `down` leaves the store untouched and\n * reports `applied: false`.\n */\nexport function executeMigrationDownSource(\n source: string,\n store: CollectionStore,\n options: EngineOptions & { filename?: string } = {}\n): MigrationExecutionResult {\n return runMigrationSource(source, store, options, \"down\");\n}\n\nexport function executeMigrationDownFile(\n filePath: string,\n store: CollectionStore,\n options: EngineOptions = {}\n): MigrationExecutionResult {\n const source = fs.readFileSync(filePath, \"utf-8\");\n return executeMigrationDownSource(source, store, { ...options, filename: filePath });\n}\n\nfunction runMigrationSource(\n source: string,\n store: CollectionStore,\n options: EngineOptions & { filename?: string },\n direction: MigrationDirection\n): MigrationExecutionResult {\n const filename = options.filename ?? \"<migration>\";\n const timeout = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const warnings: EngineWarning[] = [];\n const warn = (warning: EngineWarning) => {\n const withFile = { ...warning, file: warning.file ?? filename };\n warnings.push(withFile);\n options.onWarning?.(withFile);\n };\n\n const { sandbox, registrations, setCurrentApp } = buildSandbox(options, warn);\n const context = vm.createContext(sandbox);\n\n try {\n new vm.Script(source, { filename }).runInContext(context, { timeout });\n } catch (error) {\n throw new MigrationExecutionError(\n `Failed to evaluate migration file: ${error instanceof Error ? error.message : String(error)}`,\n filename,\n \"evaluate\",\n error instanceof Error ? error : undefined\n );\n }\n\n sandbox.__engineRegistrations__ = registrations;\n\n // Rollback undoes the most recent registration first\n const order = registrations.map((_, index) => index);\n if (direction === \"down\") {\n order.reverse();\n }\n\n let applied = false;\n for (const index of order) {\n const closure = registrations[index]?.[direction];\n if (typeof closure !== \"function\") {\n continue;\n }\n\n const tx = store.clone();\n const app = createSimulatedApp(tx, options, warn);\n sandbox.__engineApp__ = app;\n setCurrentApp(app);\n\n try {\n vm.runInContext(`__engineRegistrations__[${index}].${direction}(__engineApp__)`, context, { timeout });\n } catch (error) {\n throw new MigrationExecutionError(\n `Migration ${direction}() failed: ${error instanceof Error ? error.message : String(error)}`,\n filename,\n direction,\n error instanceof Error ? error : undefined\n );\n } finally {\n setCurrentApp(null);\n delete sandbox.__engineApp__;\n }\n\n store.replaceWith(tx);\n applied = true;\n }\n\n return { file: filename, direction, applied, warnings };\n}\n","/**\n * `_migrations` table awareness\n *\n * PocketBase records every migration it has run in an internal `_migrations`\n * table (`file` TEXT PRIMARY KEY, `applied` INTEGER). Replay that assumes\n * every file on disk is applied reconstructs a state the database may never\n * have been in: a file added but not yet run, or a file deleted from disk\n * after it ran, both produce silent drift.\n *\n * This module reads that table so replay can start from an actual checkpoint,\n * and so `status --verify` can name the difference between disk and database.\n *\n * The read is done with Node's built-in `node:sqlite` (Node >= 22.5), fetched\n * through `process.getBuiltinModule` so neither the ESM nor the CJS bundle\n * carries a hard dependency on it. `pb_data/data.db` is opened **read-only**;\n * a running PocketBase instance is never disturbed.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** PocketBase's internal table of applied migrations */\nexport const APPLIED_MIGRATIONS_TABLE = \"_migrations\";\n\n/** PocketBase's SQLite database file inside a pb_data directory */\nexport const POCKETBASE_DATABASE_FILENAME = \"data.db\";\n\nexport interface AppliedMigration {\n /** Filename as PocketBase recorded it, e.g. \"1712345678_created_Posts.js\" */\n file: string;\n /** Unix seconds from `_migrations.applied`, when the column has a value */\n applied?: number;\n}\n\nexport interface AppliedMigrationsSource {\n /** Where the list came from — a database path, or a caller-supplied label */\n origin: string;\n /** Every row, in application order */\n entries: AppliedMigration[];\n /**\n * Entries PocketBase's own Go core migrations contributed (`*.go`). They\n * never correspond to a file in a pb_migrations directory, so they are\n * kept separate from `entries` rather than reported as missing.\n */\n coreEntries: AppliedMigration[];\n}\n\n/**\n * Raised when an applied-migrations list was requested but could not be read.\n * Callers that treat the list as optional should catch this and fall back to\n * \"assume everything on disk is applied\".\n */\nexport class AppliedMigrationsError extends Error {\n public readonly source?: string;\n public readonly originalError?: Error;\n\n constructor(message: string, source?: string, originalError?: Error) {\n super(message);\n this.name = \"AppliedMigrationsError\";\n this.source = source;\n this.originalError = originalError;\n Object.setPrototypeOf(this, AppliedMigrationsError.prototype);\n }\n}\n\n/**\n * Builds a source from an explicit list of filenames (paths are reduced to\n * their basename, so a caller can pass either).\n */\nexport function appliedMigrationsFromList(files: string[], origin = \"<list>\"): AppliedMigrationsSource {\n const entries: AppliedMigration[] = [];\n const coreEntries: AppliedMigration[] = [];\n\n for (const file of files) {\n const entry: AppliedMigration = { file: path.basename(file) };\n (isCoreMigration(entry.file) ? coreEntries : entries).push(entry);\n }\n\n return { origin, entries, coreEntries };\n}\n\n/**\n * The pb_data directory PocketBase uses alongside a pb_migrations directory.\n * Both live under the PocketBase working directory, so pb_data is a sibling.\n */\nexport function defaultDataDirectory(migrationsPath: string): string {\n return path.resolve(path.dirname(path.resolve(migrationsPath)), \"pb_data\");\n}\n\n/**\n * Resolves a user-supplied pb_data path (directory or database file) to the\n * SQLite file to open. Returns null when nothing usable exists.\n */\nexport function resolveDatabasePath(dataPathOrFile: string): string | null {\n const resolved = path.resolve(dataPathOrFile);\n if (!fs.existsSync(resolved)) {\n return null;\n }\n if (fs.statSync(resolved).isDirectory()) {\n const candidate = path.join(resolved, POCKETBASE_DATABASE_FILENAME);\n return fs.existsSync(candidate) ? candidate : null;\n }\n return resolved;\n}\n\n/**\n * Reads `_migrations` out of a PocketBase SQLite database.\n *\n * @param dataPathOrFile - A pb_data directory or a data.db file\n * @throws AppliedMigrationsError when the runtime, file, or table is unusable\n */\nexport function readAppliedMigrations(dataPathOrFile: string): AppliedMigrationsSource {\n const databasePath = resolveDatabasePath(dataPathOrFile);\n if (!databasePath) {\n throw new AppliedMigrationsError(\n `No PocketBase database found at ${path.resolve(dataPathOrFile)}. ` +\n `Expected a data.db file, or a pb_data directory containing one.`,\n dataPathOrFile\n );\n }\n\n const sqlite = loadSqliteModule();\n if (!sqlite) {\n throw new AppliedMigrationsError(\n `Reading the _migrations table requires Node's built-in node:sqlite module (Node >= 22.5). ` +\n `This process runs ${process.version}. Pass the applied migrations explicitly instead.`,\n databasePath\n );\n }\n\n let database: { prepare: (sql: string) => { all: () => unknown[] }; close: () => void };\n try {\n database = withoutSqliteExperimentalWarning(() => new sqlite.DatabaseSync(databasePath, { readOnly: true }));\n } catch (error) {\n throw new AppliedMigrationsError(\n `Failed to open ${databasePath}: ${errorMessage(error)}`,\n databasePath,\n error instanceof Error ? error : undefined\n );\n }\n\n try {\n const rows = database\n .prepare(`SELECT file, applied FROM ${APPLIED_MIGRATIONS_TABLE} ORDER BY applied ASC, file ASC`)\n .all() as { file?: unknown; applied?: unknown }[];\n\n const entries: AppliedMigration[] = [];\n const coreEntries: AppliedMigration[] = [];\n\n for (const row of rows) {\n if (typeof row?.file !== \"string\" || row.file === \"\") {\n continue;\n }\n const entry: AppliedMigration = { file: row.file };\n const applied = Number(row.applied);\n if (Number.isFinite(applied) && applied > 0) {\n entry.applied = applied;\n }\n (isCoreMigration(entry.file) ? coreEntries : entries).push(entry);\n }\n\n return { origin: databasePath, entries, coreEntries };\n } catch (error) {\n if (error instanceof AppliedMigrationsError) {\n throw error;\n }\n throw new AppliedMigrationsError(\n `Failed to read the ${APPLIED_MIGRATIONS_TABLE} table from ${databasePath}: ${errorMessage(error)}`,\n databasePath,\n error instanceof Error ? error : undefined\n );\n } finally {\n try {\n database.close();\n } catch {\n // A close failure cannot invalidate rows already read\n }\n }\n}\n\n/**\n * Best-effort read: returns null instead of throwing when there is simply no\n * database to read (the common case for a checkout that has never run\n * PocketBase). Genuine failures — an unreadable file, a missing table, a\n * runtime without node:sqlite — still throw, because silently assuming\n * \"everything is applied\" is the drift this module exists to catch.\n */\nexport function readAppliedMigrationsIfPresent(dataPathOrFile: string): AppliedMigrationsSource | null {\n if (!resolveDatabasePath(dataPathOrFile)) {\n return null;\n }\n return readAppliedMigrations(dataPathOrFile);\n}\n\n/**\n * PocketBase's own Go core migrations are recorded in `_migrations` alongside\n * JS ones. They have no counterpart on disk in a pb_migrations directory.\n */\nfunction isCoreMigration(file: string): boolean {\n return !file.endsWith(\".js\");\n}\n\ninterface SqliteModule {\n DatabaseSync: new (\n path: string,\n options?: { readOnly?: boolean }\n ) => { prepare: (sql: string) => { all: () => unknown[] }; close: () => void };\n}\n\n/**\n * Loads node:sqlite without a static import, so the module keeps working on\n * runtimes that do not ship it (the rest of the engine does not need it).\n */\nfunction loadSqliteModule(): SqliteModule | null {\n const getBuiltinModule = (process as NodeJS.Process & { getBuiltinModule?: (id: string) => unknown })\n .getBuiltinModule;\n if (typeof getBuiltinModule !== \"function\") {\n return null;\n }\n try {\n const module = withoutSqliteExperimentalWarning(() => getBuiltinModule(\"node:sqlite\") as SqliteModule | undefined);\n return module && typeof module.DatabaseSync === \"function\" ? module : null;\n } catch {\n return null;\n }\n}\n\n/**\n * node:sqlite emits an ExperimentalWarning on load and on open. Reading a\n * read-only table is a bounded, deliberate use of it, and a CLI that prints a\n * Node warning every time someone runs `status --verify` is just noise —\n * so the warning is dropped for the duration of the call, and only that one.\n */\nfunction withoutSqliteExperimentalWarning<T>(operation: () => T): T {\n const original = process.emitWarning;\n\n process.emitWarning = ((warning: unknown, ...rest: unknown[]) => {\n const name = typeof warning === \"object\" && warning !== null ? (warning as Error).name : rest[0];\n const message = typeof warning === \"string\" ? warning : ((warning as Error)?.message ?? \"\");\n if (name === \"ExperimentalWarning\" && /sqlite/i.test(message)) {\n return;\n }\n (original as (...args: unknown[]) => void).call(process, warning, ...rest);\n }) as typeof process.emitWarning;\n\n try {\n return operation();\n } finally {\n process.emitWarning = original;\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","/**\n * Replay planning — which migration files reconstruct the current state\n *\n * Without knowledge of PocketBase's `_migrations` table, replay assumes every\n * file on disk has been applied. That is right for the common case and wrong\n * in exactly the situations that matter: a migration written but not yet run,\n * or a file removed from disk after it ran. Both produce a reconstructed state\n * the database was never in, and therefore a wrong diff.\n *\n * Given an applied-migrations list (see `applied-migrations.ts`), this module\n * turns a pb_migrations directory into a plan:\n *\n * - `filesToReplay` — the applied prefix, starting at the newest *applied*\n * snapshot, which is the checkpoint replay should start from\n * - `pending` — on disk, never applied\n * - `missing` — applied, no longer on disk\n * - `outOfOrder` — pending files whose timestamp sits behind an already\n * applied one, so they will be applied out of authoring order\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { AppliedMigrationsSource } from \"./applied-migrations\";\nimport { appliedMigrationsFromList } from \"./applied-migrations\";\n\n/**\n * Extracts the timestamp prefix from a migration filename.\n * Migration files are named `[timestamp]_[description].js`.\n *\n * @param filename - Migration filename (basename, not a path)\n * @returns Timestamp as a number, or null when the name is not prefixed\n */\nexport function extractTimestampFromFilename(filename: string): number | null {\n const match = filename.match(/^(\\d+)_/);\n if (match) {\n return parseInt(match[1], 10);\n }\n return null;\n}\n\n/** A migration file discovered on disk */\nexport interface DiscoveredMigration {\n /** Absolute path */\n path: string;\n /** Basename, which is what `_migrations.file` stores */\n name: string;\n timestamp: number;\n /** PocketBase's own `*_collections_snapshot.js` files */\n isSnapshot: boolean;\n}\n\nexport interface MigrationPlan {\n /** The snapshot the replay starts from, when the directory has one */\n snapshotFile: string | null;\n /** Absolute paths to execute, in timestamp order */\n filesToReplay: string[];\n /** Basenames present on disk but absent from `_migrations` */\n pending: string[];\n /** Basenames recorded in `_migrations` with no file on disk */\n missing: string[];\n /**\n * Basenames from `pending` whose timestamp precedes an already-applied\n * migration. PocketBase will still run them, but after migrations authored\n * later — so the state they produce depends on apply order.\n */\n outOfOrder: string[];\n /** False when no applied list was supplied: every file is assumed applied */\n appliedKnown: boolean;\n /** Where the applied list came from, when there was one */\n appliedOrigin?: string;\n /** Number of JS migrations recorded as applied */\n appliedCount: number;\n /** True when disk and `_migrations` agree exactly */\n inSync: boolean;\n}\n\nexport interface PlanOptions {\n /**\n * The applied-migrations list. A plain array of filenames is accepted as a\n * shorthand. Omit (or pass null) to assume every file on disk is applied.\n */\n applied?: AppliedMigrationsSource | string[] | null;\n}\n\n/**\n * Lists every timestamped `.js` migration in a directory, in timestamp order.\n * Returns an empty list when the directory does not exist.\n */\nexport function discoverMigrations(migrationsPath: string): DiscoveredMigration[] {\n if (!fs.existsSync(migrationsPath) || !fs.statSync(migrationsPath).isDirectory()) {\n return [];\n }\n\n const discovered: DiscoveredMigration[] = [];\n for (const name of fs.readdirSync(migrationsPath)) {\n if (!name.endsWith(\".js\")) {\n continue;\n }\n const timestamp = extractTimestampFromFilename(name);\n if (timestamp === null) {\n continue;\n }\n discovered.push({\n path: path.join(migrationsPath, name),\n name,\n timestamp,\n isSnapshot: name.endsWith(\"_collections_snapshot.js\") || name.endsWith(\"_snapshot.js\"),\n });\n }\n\n // Ties broken by name so the order is stable across filesystems\n discovered.sort((a, b) => a.timestamp - b.timestamp || a.name.localeCompare(b.name));\n return discovered;\n}\n\n/**\n * Builds the replay plan for a migrations directory.\n *\n * Without an applied list this reproduces the directory's default replay\n * window — newest snapshot plus everything after it — so the plan is a\n * drop-in for the previous file selection.\n */\nexport function planMigrationReplay(migrationsPath: string, options: PlanOptions = {}): MigrationPlan {\n const discovered = discoverMigrations(migrationsPath);\n const applied = normalizeApplied(options.applied);\n\n if (!applied) {\n const snapshot = lastSnapshot(discovered);\n return {\n snapshotFile: snapshot?.path ?? null,\n filesToReplay: replayWindow(discovered, snapshot).map((migration) => migration.path),\n pending: [],\n missing: [],\n outOfOrder: [],\n appliedKnown: false,\n appliedCount: 0,\n inSync: true,\n };\n }\n\n const appliedNames = new Set(applied.entries.map((entry) => entry.file));\n const onDisk = new Set(discovered.map((migration) => migration.name));\n\n // Start from the newest snapshot that was actually applied: a snapshot\n // sitting on disk unapplied is not a checkpoint the database ever reached\n const snapshot = lastSnapshot(discovered.filter((migration) => appliedNames.has(migration.name)));\n const filesToReplay = replayWindow(discovered, snapshot)\n .filter((migration) => appliedNames.has(migration.name))\n .map((migration) => migration.path);\n\n const pendingMigrations = discovered.filter((migration) => !appliedNames.has(migration.name));\n const missing = applied.entries.filter((entry) => !onDisk.has(entry.file)).map((entry) => entry.file);\n\n const newestAppliedTimestamp = discovered\n .filter((migration) => appliedNames.has(migration.name))\n .reduce((newest, migration) => Math.max(newest, migration.timestamp), 0);\n const outOfOrder = pendingMigrations\n .filter((migration) => migration.timestamp < newestAppliedTimestamp)\n .map((migration) => migration.name);\n\n const pending = pendingMigrations.map((migration) => migration.name);\n\n return {\n snapshotFile: snapshot?.path ?? null,\n filesToReplay,\n pending,\n missing,\n outOfOrder,\n appliedKnown: true,\n appliedOrigin: applied.origin,\n appliedCount: applied.entries.length,\n inSync: pending.length === 0 && missing.length === 0,\n };\n}\n\n/**\n * The files a replay executes: the snapshot, then every non-snapshot\n * migration authored after it. Snapshots supersede everything before them,\n * so earlier files are never re-executed.\n */\nfunction replayWindow(discovered: DiscoveredMigration[], snapshot: DiscoveredMigration | null): DiscoveredMigration[] {\n if (!snapshot) {\n return discovered.filter((migration) => !migration.isSnapshot);\n }\n return [\n snapshot,\n ...discovered.filter((migration) => !migration.isSnapshot && migration.timestamp > snapshot.timestamp),\n ];\n}\n\nfunction lastSnapshot(discovered: DiscoveredMigration[]): DiscoveredMigration | null {\n let latest: DiscoveredMigration | null = null;\n for (const migration of discovered) {\n if (migration.isSnapshot) {\n latest = migration;\n }\n }\n return latest;\n}\n\nfunction normalizeApplied(applied: PlanOptions[\"applied\"]): AppliedMigrationsSource | null {\n if (!applied) {\n return null;\n }\n return Array.isArray(applied) ? appliedMigrationsFromList(applied) : applied;\n}\n","/**\n * PocketBase Format Converter\n * Converts PocketBase collection objects to our internal CollectionSchema format\n *\n * This module handles conversion between PocketBase's native collection format\n * (as found in migration files and snapshots) and our internal schema representation.\n */\n\nimport { dedentSql } from \"../schema/view\";\nimport type { CollectionSchema, FieldDefinition, SchemaSnapshot } from \"./types\";\nimport { getSupportedFieldOptionKeys } from \"./utils/type-mapper\";\n\nconst SNAPSHOT_VERSION = \"1.0.0\";\n\n/**\n * Resolves a collection ID to a collection name\n * Uses known constants and parses migration expressions to resolve IDs\n *\n * @param collectionId - The collection ID to resolve\n * @returns The collection name, or the original ID if it can't be resolved\n */\nexport function resolveCollectionIdToName(collectionId: string): string {\n // Special case: _pb_users_auth_ is the constant for users collection\n if (collectionId === \"_pb_users_auth_\") {\n return \"users\";\n }\n\n // Try to extract collection name from expressions like app.findCollectionByNameOrId(\"Name\").id\n const nameMatch = collectionId.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (nameMatch) {\n return nameMatch[1];\n }\n\n // If we can't resolve it, return the original ID\n // This will cause a comparison issue, but it's better than failing\n return collectionId;\n}\n\n/**\n * Extracts field options from a PocketBase field object\n * Options can be placed directly on the field or in a nested options object\n * Direct properties take precedence over nested options\n *\n * @param pbField - PocketBase field object\n * @returns Merged options object\n */\nfunction extractFieldOptions(pbField: any): Record<string, any> {\n const options: Record<string, any> = {};\n\n // Start with nested options if present\n if (pbField.options && typeof pbField.options === \"object\") {\n Object.assign(options, pbField.options);\n }\n\n // Extract field options from direct properties\n // These take precedence over nested options\n //\n // The key list is the generator's own whitelist: anything the generator can\n // write has to be readable here, or replay loses it and every `db:generate`\n // re-emits the same modification\n const directOptionKeys = getSupportedFieldOptionKeys(pbField.type);\n\n for (const key of directOptionKeys) {\n if (pbField[key] !== undefined) {\n options[key] = pbField[key];\n }\n }\n\n return options;\n}\n\n/**\n * Converts a PocketBase field object to FieldDefinition format\n *\n * @param pbField - PocketBase field object\n * @returns FieldDefinition object\n */\nexport function convertPocketBaseField(pbField: any): FieldDefinition {\n const field: any = {\n name: pbField.name,\n id: pbField.id,\n type: pbField.type,\n required: pbField.required || false,\n };\n\n // Extract options from both direct properties and nested options object\n field.options = extractFieldOptions(pbField);\n\n // Convert onlyInt to noDecimal for number fields (PocketBase uses onlyInt, but our schema uses noDecimal)\n if (pbField.type === \"number\" && field.options.onlyInt !== undefined) {\n field.options.noDecimal = field.options.onlyInt;\n delete field.options.onlyInt;\n }\n\n // Handle relation fields\n if (pbField.type === \"relation\") {\n // Support both formats: collectionId directly on field or in options\n const collectionId = pbField.collectionId || pbField.options?.collectionId || \"\";\n // Resolve collectionId to collection name\n // collectionId is a system field (like _pb_users_auth_), not the collection name\n // We need to resolve it to the actual collection name for comparison\n const collectionName = resolveCollectionIdToName(collectionId || \"\");\n field.relation = {\n collection: collectionName,\n cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,\n maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,\n minSelect: pbField.minSelect ?? pbField.options?.minSelect,\n displayFields: pbField.displayFields ?? pbField.options?.displayFields ?? null,\n };\n\n // Remove relation-specific properties from options\n // These belong in the relation object, not options\n delete field.options.collectionId;\n delete field.options.maxSelect;\n delete field.options.minSelect;\n delete field.options.cascadeDelete;\n delete field.options.displayFields;\n }\n\n // Clean up empty options object, but preserve values for select fields\n // If options only contains values for a select field, keep it\n const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== undefined;\n if (Object.keys(field.options).length === 0) {\n delete field.options;\n } else if (pbField.type === \"select\" && hasOnlyValues) {\n // Keep options object if it only contains values for a select field\n // This ensures values are preserved for comparison\n }\n\n return field as FieldDefinition;\n}\n\n/**\n * Converts a PocketBase collection object to CollectionSchema format\n *\n * @param pbCollection - PocketBase collection object from migration file\n * @returns CollectionSchema object\n */\nexport function convertPocketBaseCollection(pbCollection: any): CollectionSchema {\n const fields: any[] = [];\n const isView = pbCollection.type === \"view\";\n\n // System field names that should always be excluded\n const systemFieldNames = [\"id\", \"created\", \"updated\", \"collectionId\", \"collectionName\", \"expand\"];\n\n // View collections have no stored fields - PocketBase derives them from the\n // view query, so anything present here is generated output, not schema\n // Convert PocketBase fields to our FieldDefinition format\n if (!isView && pbCollection.fields && Array.isArray(pbCollection.fields)) {\n for (const pbField of pbCollection.fields) {\n // Skip system fields by checking both the system flag and field name\n // Some PocketBase exports mark created/updated as system: false\n if (pbField.system || systemFieldNames.includes(pbField.name)) {\n // For auth collections, we want to keep the system fields (email, password, etc.)\n // These are marked as system: true in PocketBase, but we need them in our schema\n // to match the CLI behavior which includes them in the fields array\n const isAuthSystemField =\n pbCollection.type === \"auth\" &&\n [\"email\", \"emailVisibility\", \"verified\", \"password\", \"tokenKey\"].includes(pbField.name);\n\n if (!isAuthSystemField) {\n continue;\n }\n }\n\n const field = convertPocketBaseField(pbField);\n fields.push(field);\n }\n }\n\n const schema: CollectionSchema = {\n name: pbCollection.name,\n type: pbCollection.type || \"base\",\n fields,\n };\n\n // Preserve collection ID if present (needed for relation resolution)\n if (pbCollection.id) {\n schema.id = pbCollection.id;\n }\n\n // Preserve the SQL query backing a view collection\n // Dedented so a query indented to fit the migration file compares equal to\n // the one declared in the schema\n if (typeof pbCollection.viewQuery === \"string\") {\n schema.viewQuery = dedentSql(pbCollection.viewQuery);\n }\n\n // Add indexes if present\n if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {\n schema.indexes = pbCollection.indexes;\n }\n\n // Add rules/permissions\n // Check if any rule properties exist on the collection object\n const hasAnyRule =\n pbCollection.listRule !== undefined ||\n pbCollection.viewRule !== undefined ||\n pbCollection.createRule !== undefined ||\n pbCollection.updateRule !== undefined ||\n pbCollection.deleteRule !== undefined ||\n pbCollection.manageRule !== undefined;\n\n if (hasAnyRule) {\n const rules: any = {};\n // Include rules even if they're null (null is a valid value)\n if (pbCollection.listRule !== undefined) rules.listRule = pbCollection.listRule;\n if (pbCollection.viewRule !== undefined) rules.viewRule = pbCollection.viewRule;\n if (pbCollection.createRule !== undefined) rules.createRule = pbCollection.createRule;\n if (pbCollection.updateRule !== undefined) rules.updateRule = pbCollection.updateRule;\n if (pbCollection.deleteRule !== undefined) rules.deleteRule = pbCollection.deleteRule;\n if (pbCollection.manageRule !== undefined) rules.manageRule = pbCollection.manageRule;\n\n schema.rules = rules;\n // Also set permissions to match rules (they're the same thing)\n schema.permissions = { ...rules };\n }\n\n return schema;\n}\n\n/**\n * Converts an array of raw PocketBase-shaped collection objects (as found\n * in snapshot arrays or produced by the execution engine) to a SchemaSnapshot\n *\n * @param rawCollections - Raw PocketBase collection objects\n * @returns SchemaSnapshot with collections map\n */\nexport function rawCollectionsToSnapshot(rawCollections: any[]): SchemaSnapshot {\n const collections = new Map<string, CollectionSchema>();\n\n for (const pbCollection of rawCollections) {\n if (!pbCollection?.name) {\n console.warn(\"Skipping collection without name\");\n continue;\n }\n\n const schema = convertPocketBaseCollection(pbCollection);\n collections.set(pbCollection.name, schema);\n }\n\n return {\n version: SNAPSHOT_VERSION,\n timestamp: new Date().toISOString(),\n collections,\n };\n}\n","/**\n * CollectionStore — the in-memory database state migrations execute against\n *\n * Keyed by collection id (migrations reference collections by id, name, or\n * the `_pb_users_auth_` alias; renames must not orphan entries). Cloning\n * serializes to plain objects and rebuilds, giving transaction semantics:\n * the runner clones, applies a migration to the clone, and commits with\n * replaceWith() only on success.\n */\n\nimport { rawCollectionsToSnapshot } from \"../pocketbase-converter\";\nimport type { SchemaSnapshot } from \"../types\";\nimport { Collection } from \"./collection\";\nimport { RecordStore } from \"./records\";\nimport type { RawCollection } from \"./types\";\n\n/** PocketBase's fixed id for the default users auth collection */\nconst USERS_AUTH_ID = \"_pb_users_auth_\";\n\nexport class CollectionStore {\n private byId = new Map<string, Collection>();\n\n /**\n * Rows, when record simulation is enabled. Always present so clone/commit\n * carry data through the same transaction as the schema; empty and\n * effectively free when only schema is being replayed.\n */\n readonly records = new RecordStore();\n\n list(): Collection[] {\n return [...this.byId.values()];\n }\n\n getById(id: string): Collection | undefined {\n return this.byId.get(id);\n }\n\n getByNameOrId(nameOrId: string): Collection | undefined {\n const byId = this.byId.get(nameOrId);\n if (byId) {\n return byId;\n }\n for (const collection of this.byId.values()) {\n if (collection.name === nameOrId) {\n return collection;\n }\n }\n // The users auth collection is addressable by its fixed system id even\n // when a snapshot stored it under a different id, and vice versa\n if (nameOrId === USERS_AUTH_ID) {\n return this.getByNameOrId(\"users\");\n }\n return undefined;\n }\n\n upsert(collection: Collection): void {\n this.byId.set(collection.id, collection);\n }\n\n removeById(id: string): boolean {\n // Dropping a collection drops its table with it\n this.records.dropCollection(id);\n return this.byId.delete(id);\n }\n\n /** Deep, independent copy (rebuilds Collection/FieldsList instances) */\n clone(): CollectionStore {\n const copy = new CollectionStore();\n for (const collection of this.byId.values()) {\n copy.upsert(new Collection(structuredClone(collection.serialize())));\n }\n // Rows are rebound to the copied collections, so a record's collection()\n // sees the schema of the transaction it is running in\n copy.records.replaceWith(this.records.clone((id) => copy.getById(id)));\n return copy;\n }\n\n /** Commit: adopt another store's state */\n replaceWith(other: CollectionStore): void {\n this.byId = new Map(other.byId);\n this.records.replaceWith(other.records);\n }\n\n serialize(): RawCollection[] {\n return this.list().map((collection) => collection.serialize());\n }\n\n /** Convert to the internal schema model used by diff/compare */\n toSnapshot(): SchemaSnapshot {\n return rawCollectionsToSnapshot(this.serialize());\n }\n}\n","/**\n * Replayer — folds an ordered list of migration files into a final state\n *\n * Mirrors what PocketBase does on `migrate up`: execute each unapplied file\n * in timestamp order. State reconstruction starts from an empty store; a\n * native snapshot migration (app.importCollections) is just the first file.\n *\n * Which files that is comes from `planMigrationReplay`: by default the newest\n * snapshot plus everything after it, or — when an applied-migrations list is\n * supplied — only the files PocketBase has actually run, starting from the\n * newest applied snapshot.\n */\n\nimport { executeMigrationFile } from \"./runner\";\nimport { planMigrationReplay, type MigrationPlan, type PlanOptions } from \"./migration-plan\";\nimport { CollectionStore } from \"./store\";\nimport type { EngineOptions, EngineWarning, ReplayResult } from \"./types\";\n\nexport function replayMigrations(\n files: string[],\n options: EngineOptions & { initialStore?: CollectionStore; plan?: MigrationPlan } = {}\n): ReplayResult {\n const { initialStore, plan, ...engineOptions } = options;\n const store = initialStore ?? new CollectionStore();\n const warnings: EngineWarning[] = [];\n const filesExecuted: string[] = [];\n\n for (const file of files) {\n const result = executeMigrationFile(file, store, engineOptions);\n warnings.push(...result.warnings);\n filesExecuted.push(file);\n }\n\n return {\n snapshot: store.toSnapshot(),\n store,\n warnings,\n filesExecuted,\n plan: plan ?? null,\n };\n}\n\n/**\n * Replays a pb_migrations directory: the snapshot the state starts from,\n * then every migration after it, in timestamp order.\n *\n * Pass `applied` (from `readAppliedMigrations`) to replay only what PocketBase\n * has actually run — otherwise every file on disk is assumed applied.\n *\n * Returns null when there is nothing to replay (an empty database).\n */\nexport function replayMigrationsDirectory(\n migrationsPath: string,\n options: EngineOptions & PlanOptions = {}\n): ReplayResult | null {\n const { applied, ...engineOptions } = options;\n const plan = planMigrationReplay(migrationsPath, { applied });\n\n if (plan.filesToReplay.length === 0) {\n return null;\n }\n\n return replayMigrations(plan.filesToReplay, { ...engineOptions, plan });\n}\n","/**\n * Snapshot Manager\n * Handles saving and loading schema snapshots from JSON files\n *\n * This module provides a standalone, configurable snapshot manager that can be used\n * by consumer projects to manage schema snapshots. It focuses on JSON snapshot file\n * management, delegating migration file parsing and PocketBase format conversion\n * to specialized modules.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { MigrationExecutionError, FileSystemError, SnapshotError } from \"./errors\";\nimport type { AppliedMigrationsSource } from \"./engine/applied-migrations\";\nimport { replayMigrations, replayMigrationsDirectory } from \"./engine/replayer\";\nimport type { EngineOptions } from \"./engine/types\";\nimport type { CollectionSchema, SchemaDefinition, SchemaSnapshot } from \"./types\";\n\nconst SNAPSHOT_VERSION = \"1.0.0\";\nconst DEFAULT_SNAPSHOT_FILENAME = \".migration-snapshot.json\";\n\n/**\n * Configuration for snapshot operations\n */\nexport interface SnapshotConfig {\n /**\n * Path to the snapshot file\n * Can be absolute or relative to workspaceRoot\n */\n snapshotPath?: string;\n\n /**\n * Workspace root directory for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * Path to the migrations directory for finding PocketBase snapshots\n */\n migrationsPath?: string;\n\n /**\n * Whether to auto-migrate old snapshot formats\n * Defaults to true\n */\n autoMigrate?: boolean;\n\n /**\n * Custom snapshot version for testing\n */\n version?: string;\n\n /**\n * Options forwarded to the execution engine, which reconstructs state by\n * executing migration files in a simulated PocketBase JSVM.\n */\n engineOptions?: EngineOptions;\n\n /**\n * Migrations PocketBase has actually applied, read from its `_migrations`\n * table (see `readAppliedMigrations`). When supplied, replay starts from\n * the newest applied snapshot and stops at the applied set, so a migration\n * written but not yet run does not leak into the reconstructed state.\n */\n appliedMigrations?: AppliedMigrationsSource | string[] | null;\n}\n\n/**\n * Snapshot format versions and their migration functions\n */\ninterface SnapshotMigration {\n fromVersion: string;\n toVersion: string;\n migrate: (data: any) => any;\n}\n\n/**\n * Registry of snapshot format migrations\n */\nconst SNAPSHOT_MIGRATIONS: SnapshotMigration[] = [\n // Add migrations here as the format evolves\n // Example:\n // {\n // fromVersion: '0.9.0',\n // toVersion: '1.0.0',\n // migrate: (data) => ({ ...data, newField: 'default' })\n // }\n];\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: Omit<Required<SnapshotConfig>, \"migrationsPath\" | \"engineOptions\" | \"appliedMigrations\"> &\n Pick<SnapshotConfig, \"migrationsPath\" | \"engineOptions\" | \"appliedMigrations\"> = {\n snapshotPath: DEFAULT_SNAPSHOT_FILENAME,\n workspaceRoot: process.cwd(),\n autoMigrate: true,\n version: SNAPSHOT_VERSION,\n};\n\n/**\n * Merges user config with defaults\n */\nfunction mergeConfig(config: SnapshotConfig = {}): typeof DEFAULT_CONFIG {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n };\n}\n\n/**\n * Gets the snapshot file path from configuration\n *\n * @param config - Snapshot configuration\n * @returns Absolute path to the snapshot file\n */\nexport function getSnapshotPath(config: SnapshotConfig = {}): string {\n const mergedConfig = mergeConfig(config);\n const workspaceRoot = mergedConfig.workspaceRoot;\n const snapshotFilename = mergedConfig.snapshotPath;\n\n // If snapshotPath is absolute, use it directly\n if (path.isAbsolute(snapshotFilename)) {\n return snapshotFilename;\n }\n\n // Otherwise, resolve relative to workspaceRoot\n return path.join(workspaceRoot, snapshotFilename);\n}\n\n/**\n * Checks if snapshot file exists\n *\n * @param config - Snapshot configuration\n * @returns True if snapshot file exists\n */\nexport function snapshotExists(config: SnapshotConfig = {}): boolean {\n try {\n const snapshotPath = getSnapshotPath(config);\n return fs.existsSync(snapshotPath);\n } catch {\n // If there's any error checking existence, treat as non-existent\n return false;\n }\n}\n\n/**\n * Handles file system errors with descriptive messages\n *\n * @param error - The error object\n * @param operation - The operation being performed\n * @param filePath - The file path involved\n * @throws SnapshotError or FileSystemError with descriptive message\n */\nfunction handleFileSystemError(error: any, operation: \"read\" | \"write\", filePath: string): never {\n const fsError = error as NodeJS.ErrnoException;\n\n if (fsError.code === \"ENOENT\") {\n throw new SnapshotError(`Snapshot file not found: ${filePath}`, filePath, operation, error);\n } else if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied ${operation === \"read\" ? \"reading\" : \"writing\"} snapshot file. Check file permissions.`,\n filePath,\n operation,\n fsError.code,\n error\n );\n } else if (fsError.code === \"ENOSPC\") {\n throw new FileSystemError(\n `No space left on device when ${operation === \"read\" ? \"reading\" : \"writing\"} snapshot file.`,\n filePath,\n operation,\n fsError.code,\n error\n );\n } else {\n throw new SnapshotError(`Failed to ${operation} snapshot file: ${error.message}`, filePath, operation, error);\n }\n}\n\n/**\n * Serializes a Map to a plain object for JSON serialization\n *\n * @param map - Map to serialize\n * @returns Plain object representation\n */\nfunction serializeMap<K extends string, V>(map: Map<K, V>): Record<K, V> {\n const obj: Record<string, V> = {};\n for (const [key, value] of map.entries()) {\n obj[key] = value;\n }\n return obj as Record<K, V>;\n}\n\n/**\n * Deserializes a plain object to a Map\n *\n * @param obj - Plain object to deserialize\n * @returns Map representation\n */\nfunction deserializeMap<K extends string, V>(obj: Record<K, V>): Map<K, V> {\n const map = new Map<K, V>();\n for (const [key, value] of Object.entries(obj)) {\n map.set(key as K, value as V);\n }\n return map;\n}\n\n/**\n * Serializes SchemaDefinition to JSON format\n * Converts Map to plain object for JSON compatibility\n *\n * @param schema - Schema definition to serialize\n * @returns JSON-serializable object\n */\nfunction serializeSchemaDefinition(schema: SchemaDefinition): any {\n return {\n collections: serializeMap(schema.collections),\n };\n}\n\n/**\n * Adds version and timestamp metadata to snapshot\n *\n * @param schema - Schema definition\n * @param config - Optional configuration with custom version\n * @returns Snapshot with metadata\n */\nfunction addSnapshotMetadata(schema: SchemaDefinition, config?: SnapshotConfig): any {\n const mergedConfig = mergeConfig(config);\n return {\n version: mergedConfig.version,\n timestamp: new Date().toISOString(),\n ...serializeSchemaDefinition(schema),\n };\n}\n\n/**\n * Saves schema snapshot to file\n * Serializes SchemaDefinition to JSON with version and timestamp metadata\n * Writes with pretty printing for readability\n *\n * @param schema - Schema definition to save\n * @param config - Snapshot configuration\n */\nexport function saveSnapshot(schema: SchemaDefinition, config: SnapshotConfig = {}): void {\n const snapshotPath = getSnapshotPath(config);\n\n try {\n // Ensure directory exists\n const snapshotDir = path.dirname(snapshotPath);\n if (!fs.existsSync(snapshotDir)) {\n fs.mkdirSync(snapshotDir, { recursive: true });\n }\n\n // Add metadata and serialize\n const snapshotData = addSnapshotMetadata(schema, config);\n\n // Write with pretty printing (2 spaces indentation)\n const jsonContent = JSON.stringify(snapshotData, null, 2);\n fs.writeFileSync(snapshotPath, jsonContent, \"utf-8\");\n } catch (error) {\n handleFileSystemError(error, \"write\", snapshotPath);\n }\n}\n\n/**\n * Parses JSON and validates snapshot format\n *\n * @param jsonContent - Raw JSON content\n * @param snapshotPath - Path to snapshot file (for error messages)\n * @returns Parsed snapshot data\n */\nfunction parseAndValidateSnapshot(jsonContent: string, snapshotPath: string): any {\n try {\n const data = JSON.parse(jsonContent);\n\n // Validate required fields\n if (!data.version) {\n throw new SnapshotError(\n \"Snapshot file is missing version field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n if (!data.timestamp) {\n throw new SnapshotError(\n \"Snapshot file is missing timestamp field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n if (!data.collections) {\n throw new SnapshotError(\n \"Snapshot file is missing collections field. The snapshot may be corrupted.\",\n snapshotPath,\n \"validate\"\n );\n }\n\n return data;\n } catch (error) {\n if (error instanceof SnapshotError) {\n throw error;\n }\n\n if (error instanceof SyntaxError) {\n throw new SnapshotError(\n `Invalid JSON in snapshot file. The file may be corrupted or manually edited incorrectly.`,\n snapshotPath,\n \"parse\",\n error\n );\n }\n throw error;\n }\n}\n\n/**\n * Compares two version strings\n * Returns -1 if a < b, 0 if a == b, 1 if a > b\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const numA = partsA[i] || 0;\n const numB = partsB[i] || 0;\n\n if (numA < numB) return -1;\n if (numA > numB) return 1;\n }\n\n return 0;\n}\n\n/**\n * Migrates old snapshot formats to current version\n * Applies migrations in sequence from old version to current\n *\n * @param data - Parsed snapshot data\n * @param config - Optional configuration\n * @returns Migrated snapshot data\n */\nfunction migrateSnapshotFormat(data: any, config?: SnapshotConfig): any {\n const mergedConfig = mergeConfig(config);\n const currentVersion = data.version;\n const targetVersion = mergedConfig.version;\n\n // If versions match, no migration needed\n if (currentVersion === targetVersion) {\n return data;\n }\n\n // If auto-migrate is disabled, just return the data with a warning\n if (!mergedConfig.autoMigrate) {\n console.warn(\n `Snapshot version ${currentVersion} differs from current ${targetVersion}, but auto-migrate is disabled.`\n );\n return data;\n }\n\n // Find and apply migrations in sequence\n let migratedData = { ...data };\n let currentMigrationVersion = currentVersion;\n\n // Sort migrations by fromVersion\n const sortedMigrations = [...SNAPSHOT_MIGRATIONS].sort((a, b) => compareVersions(a.fromVersion, b.fromVersion));\n\n for (const migration of sortedMigrations) {\n if (compareVersions(currentMigrationVersion, migration.fromVersion) === 0) {\n console.log(`Migrating snapshot from ${migration.fromVersion} to ${migration.toVersion}...`);\n migratedData = migration.migrate(migratedData);\n migratedData.version = migration.toVersion;\n currentMigrationVersion = migration.toVersion;\n }\n }\n\n // If we couldn't migrate to the target version, log a warning\n if (compareVersions(currentMigrationVersion, targetVersion) !== 0) {\n console.warn(`Unknown snapshot version ${currentVersion}, attempting to load anyway...`);\n }\n\n return migratedData;\n}\n\n/**\n * Deserializes snapshot data to SchemaSnapshot\n *\n * @param data - Parsed and validated snapshot data\n * @returns SchemaSnapshot object\n */\nfunction deserializeSnapshot(data: any): SchemaSnapshot {\n return {\n version: data.version,\n timestamp: data.timestamp,\n collections: deserializeMap<string, CollectionSchema>(data.collections),\n };\n}\n\n/**\n * Loads schema snapshot from file\n * Reads snapshot file, parses JSON, validates format, and handles migrations\n *\n * @param config - Snapshot configuration\n * @returns SchemaSnapshot object\n * @throws Error if snapshot file doesn't exist or is invalid\n */\nexport function loadSnapshot(config: SnapshotConfig = {}): SchemaSnapshot {\n const snapshotPath = getSnapshotPath(config);\n\n try {\n // Read file\n const jsonContent = fs.readFileSync(snapshotPath, \"utf-8\");\n\n // Parse and validate\n const data = parseAndValidateSnapshot(jsonContent, snapshotPath);\n\n // Migrate format if needed\n const migratedData = migrateSnapshotFormat(data, config);\n\n // Deserialize to SchemaSnapshot\n return deserializeSnapshot(migratedData);\n } catch (error) {\n // If it's already a SnapshotError or FileSystemError, re-throw it\n if (error instanceof SnapshotError || error instanceof FileSystemError) {\n throw error;\n }\n\n // If file doesn't exist, throw specific error\n if ((error as any).code === \"ENOENT\") {\n throw new SnapshotError(\n `Snapshot file not found. This may be the first migration run.`,\n snapshotPath,\n \"read\",\n error as Error\n );\n }\n\n // Handle other file system errors\n handleFileSystemError(error, \"read\", snapshotPath);\n }\n}\n\n/**\n * Merges base schema with custom snapshot\n * Base schema collections are preserved, custom collections are added\n * Custom collections override base collections if they have the same name\n *\n * @param baseSnapshot - PocketBase base schema\n * @param customSnapshot - User's custom schema snapshot (may be null)\n * @returns Merged SchemaSnapshot\n */\nexport function mergeSnapshots(baseSnapshot: SchemaSnapshot, customSnapshot: SchemaSnapshot | null): SchemaSnapshot {\n // If no custom snapshot, return base snapshot\n if (!customSnapshot) {\n return baseSnapshot;\n }\n\n // Create a new collections map starting with base collections\n const mergedCollections = new Map<string, CollectionSchema>(baseSnapshot.collections);\n\n // Add or override with custom collections\n for (const [name, schema] of customSnapshot.collections.entries()) {\n mergedCollections.set(name, schema);\n }\n\n return {\n version: customSnapshot.version || baseSnapshot.version,\n timestamp: customSnapshot.timestamp || baseSnapshot.timestamp,\n collections: mergedCollections,\n };\n}\n\n/**\n * Finds the most recent snapshot file in the migrations directory\n * Identifies snapshot files by naming pattern (e.g., *_collections_snapshot.js)\n *\n * @param migrationsPath - Path to pb_migrations directory\n * @returns Path to most recent snapshot file or null if none exist\n */\nexport function findLatestSnapshot(migrationsPath: string): string | null {\n try {\n // Check if migrations directory exists\n if (!fs.existsSync(migrationsPath)) {\n return null;\n }\n\n // Read all files in migrations directory\n const files = fs.readdirSync(migrationsPath);\n\n // Filter for snapshot files (files ending with _collections_snapshot.js or _snapshot.js)\n const snapshotFiles = files.filter(\n (file) => file.endsWith(\"_collections_snapshot.js\") || file.endsWith(\"_snapshot.js\")\n );\n\n if (snapshotFiles.length === 0) {\n return null;\n }\n\n // Sort by filename (timestamp prefix) to get most recent\n // Snapshot files are named with timestamp prefix: [timestamp]_collections_snapshot.js\n snapshotFiles.sort().reverse();\n\n // Return full path to most recent snapshot\n const latestSnapshot = snapshotFiles[0];\n if (!latestSnapshot) {\n return null;\n }\n return path.join(migrationsPath, latestSnapshot);\n } catch (error) {\n // If there's any error reading directory, return null\n console.warn(`Error finding latest snapshot: ${error}`);\n return null;\n }\n}\n\n/**\n * Reconstructs the current database state: executes the snapshot migration and\n * every migration after it in a simulated PocketBase JSVM.\n *\n * A migration that cannot be executed fails hard — continuing past it would\n * silently reconstruct the wrong state and cause the generator to emit\n * incorrect diffs.\n *\n * @param config - Snapshot configuration (must include migrationsPath)\n * @returns SchemaSnapshot representing the current state, or null when there is\n * nothing to replay (an empty database)\n */\nexport function loadSnapshotWithMigrations(config: SnapshotConfig = {}): SchemaSnapshot | null {\n const migrationsPath = config.migrationsPath;\n\n if (!migrationsPath) {\n return null;\n }\n\n try {\n // File path instead of a directory (backward compatibility with tests):\n // execute just that one file\n if (fs.existsSync(migrationsPath) && fs.statSync(migrationsPath).isFile()) {\n return replayMigrations([migrationsPath], config.engineOptions).snapshot;\n }\n\n const result = replayMigrationsDirectory(migrationsPath, {\n ...config.engineOptions,\n applied: config.appliedMigrations,\n });\n return result ? result.snapshot : null;\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n throw new SnapshotError(\n `Failed to execute migration ${error.filePath ?? \"<unknown>\"}: ${error.message}`,\n error.filePath,\n \"parse\",\n error\n );\n }\n throw error;\n }\n}\n\n/**\n * Loads snapshot if it exists, returns null for first run\n * Convenience method that handles missing snapshot gracefully\n * Finds the most recent snapshot file from migrations directory\n * NOTE: This function only executes the snapshot file, not the migrations\n * after it. Use loadSnapshotWithMigrations() for the current state.\n *\n * @param config - Snapshot configuration (must include migrationsPath)\n * @returns SchemaSnapshot object or null if snapshot doesn't exist\n */\nexport function loadSnapshotIfExists(config: SnapshotConfig = {}): SchemaSnapshot | null {\n const migrationsPath = config.migrationsPath;\n\n if (!migrationsPath) {\n // No migrations path provided - return null\n return null;\n }\n\n // A file path is treated as a direct snapshot file path\n const snapshotPath =\n fs.existsSync(migrationsPath) && fs.statSync(migrationsPath).isFile()\n ? migrationsPath\n : findLatestSnapshot(migrationsPath);\n\n if (!snapshotPath) {\n // No snapshot found - return null (empty database)\n return null;\n }\n\n try {\n return replayMigrations([snapshotPath], config.engineOptions).snapshot;\n } catch (error) {\n console.warn(`Failed to load snapshot from ${snapshotPath}: ${error}`);\n return null;\n }\n}\n\n/**\n * Loads the base PocketBase schema from the initial migration file\n *\n * @param migrationPath - Path to pocketbase/pb_migrations/000000000_collections_snapshot.js\n * @returns SchemaSnapshot representing PocketBase's initial state\n * @throws SnapshotError if file not found or invalid format\n */\nexport function loadBaseMigration(migrationPath: string): SchemaSnapshot {\n try {\n // Check if file exists\n if (!fs.existsSync(migrationPath)) {\n throw new SnapshotError(\n `Base migration file not found: ${migrationPath}\\n\\n` +\n `This file should contain PocketBase's initial schema.\\n` +\n `Please ensure PocketBase is properly set up by running 'yarn setup'.\\n` +\n `If the file exists in a different location, update the configuration.`,\n migrationPath,\n \"read\"\n );\n }\n\n // Execute the migration to reconstruct the state it defines\n return replayMigrations([migrationPath]).snapshot;\n } catch (error) {\n // If it's already a SnapshotError, re-throw it\n if (error instanceof SnapshotError) {\n throw error;\n }\n\n // Handle file system errors\n if ((error as any).code === \"ENOENT\") {\n throw new SnapshotError(\n `Base migration file not found: ${migrationPath}\\n\\n` +\n `This file should contain PocketBase's initial schema.\\n` +\n `Please ensure PocketBase is properly set up by running 'yarn setup'.`,\n migrationPath,\n \"read\",\n error as Error\n );\n }\n\n if ((error as any).code === \"EACCES\" || (error as any).code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied reading base migration file. Check file permissions.`,\n migrationPath,\n \"read\",\n (error as any).code,\n error as Error\n );\n }\n\n // Other errors\n throw new SnapshotError(\n `Failed to load base migration: ${error instanceof Error ? error.message : String(error)}`,\n migrationPath,\n \"read\",\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Gets the current snapshot version\n */\nexport function getSnapshotVersion(): string {\n return SNAPSHOT_VERSION;\n}\n\n/**\n * Validates a snapshot against the current version\n * Returns validation result with any issues found\n */\nexport function validateSnapshot(snapshot: SchemaSnapshot): { valid: boolean; issues: string[] } {\n const issues: string[] = [];\n\n // Check version\n if (!snapshot.version) {\n issues.push(\"Missing version field\");\n } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION) > 0) {\n issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`);\n }\n\n // Check timestamp\n if (!snapshot.timestamp) {\n issues.push(\"Missing timestamp field\");\n }\n\n // Check collections\n if (!snapshot.collections) {\n issues.push(\"Missing collections field\");\n } else if (!(snapshot.collections instanceof Map)) {\n issues.push(\"Collections field is not a Map\");\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n\n/**\n * SnapshotManager class for object-oriented usage\n * Provides a stateful interface for snapshot management\n */\nexport class SnapshotManager {\n private config: SnapshotConfig;\n\n constructor(config: SnapshotConfig = {}) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Loads the current snapshot\n */\n loadSnapshot(): SchemaSnapshot {\n return loadSnapshot(this.config);\n }\n\n /**\n * Saves a schema as a snapshot\n */\n saveSnapshot(schema: SchemaDefinition): void {\n saveSnapshot(schema, this.config);\n }\n\n /**\n * Loads snapshot if it exists, returns null otherwise\n */\n loadSnapshotIfExists(): SchemaSnapshot | null {\n return loadSnapshotIfExists(this.config);\n }\n\n /**\n * Checks if a snapshot exists\n */\n snapshotExists(): boolean {\n return snapshotExists(this.config);\n }\n\n /**\n * Gets the snapshot file path\n */\n getSnapshotPath(): string {\n return getSnapshotPath(this.config);\n }\n\n /**\n * Validates a snapshot\n */\n validateSnapshot(snapshot: SchemaSnapshot): { valid: boolean; issues: string[] } {\n return validateSnapshot(snapshot);\n }\n}\n","/**\n * Configuration options for the diff engine\n */\nexport interface DiffEngineConfig {\n /**\n * Whether to warn on collection deletions\n * Defaults to true\n */\n warnOnDelete?: boolean;\n\n /**\n * Whether to require --force flag for destructive changes\n * Defaults to true\n */\n requireForceForDestructive?: boolean;\n\n /**\n * Severity threshold for requiring force flag\n * 'high' = only collection/field deletions and type changes\n * 'medium' = includes making fields required\n * 'low' = includes any constraint changes\n * Defaults to 'high'\n */\n severityThreshold?: \"high\" | \"medium\" | \"low\";\n\n /**\n * Custom system collections to exclude from diff\n * These collections will not be created or deleted\n */\n systemCollections?: string[];\n\n /**\n * Custom system fields to exclude from user collection diffs\n * These fields will not be included in fieldsToAdd for the users collection\n */\n usersSystemFields?: string[];\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<DiffEngineConfig> = {\n warnOnDelete: true,\n requireForceForDestructive: true,\n severityThreshold: \"high\",\n systemCollections: [\"_mfas\", \"_otps\", \"_externalAuths\", \"_authOrigins\", \"_superusers\"],\n usersSystemFields: [\"id\", \"password\", \"tokenKey\", \"email\", \"emailVisibility\", \"verified\", \"created\", \"updated\"],\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(config?: DiffEngineConfig): Required<DiffEngineConfig> {\n return {\n ...DEFAULT_CONFIG,\n ...config,\n };\n}\n","import { mergeConfig, type DiffEngineConfig } from \"./config\";\n\n/**\n * Checks if a collection is a PocketBase system collection\n * System collections are internal to PocketBase and should not be created or deleted\n *\n * @param collectionName - Name of the collection to check\n * @param config - Optional configuration with custom system collections\n * @returns True if the collection is a system collection\n */\nexport function isSystemCollection(collectionName: string, config?: DiffEngineConfig): boolean {\n const mergedConfig = mergeConfig(config);\n return mergedConfig.systemCollections.includes(collectionName);\n}\n\n/**\n * Returns the list of system field names for the users collection\n * These fields are automatically provided by PocketBase for auth collections\n * and should not be included when generating migrations for users collection extensions\n *\n * @param config - Optional configuration with custom system fields\n * @returns Set of system field names\n */\nexport function getUsersSystemFields(config?: DiffEngineConfig): Set<string> {\n const mergedConfig = mergeConfig(config);\n return new Set(mergedConfig.usersSystemFields);\n}\n\n/**\n * Compares two values for equality, handling deep object comparison\n *\n * @param a - First value\n * @param b - Second value\n * @returns True if values are equal\n */\nexport function areValuesEqual(a: any, b: any): boolean {\n // Handle null/undefined\n if (a === b) return true;\n if (a == null || b == null) return false;\n\n // Handle arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((val, idx) => areValuesEqual(val, b[idx]));\n }\n\n // Handle objects\n if (typeof a === \"object\" && typeof b === \"object\") {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) => areValuesEqual(a[key], b[key]));\n }\n\n // Primitive comparison\n return a === b;\n}\n\n/**\n * Options whose zero value carries no information: PocketBase stores them on\n * every field of the relevant type, and a schema that omits them describes the\n * same field. Keys not listed here (`min`, `max`, …) are compared literally.\n */\nconst OPTION_ZERO_VALUES: Record<string, any> = {\n autogeneratePattern: \"\",\n pattern: \"\",\n primaryKey: false,\n convertURLs: false,\n cost: 0,\n hidden: false,\n presentable: false,\n system: false,\n};\n\n/**\n * Normalizes a field option value to account for PocketBase defaults\n * Returns the normalized value, treating default values as equivalent to undefined\n *\n * @param key - Option key name\n * @param value - Option value\n * @param fieldType - Field type\n * @returns Normalized value (undefined if it's a default value)\n */\nexport function normalizeOptionValue(key: string, value: any, fieldType: string): any {\n // PocketBase writes every option a field type has, at its zero value, into\n // the migrations it authors itself. A schema that simply does not set the\n // option means the same thing, so the zero value has to compare equal to a\n // missing one — otherwise replaying a PocketBase-authored migration reports\n // a modification the generator can never settle.\n if (OPTION_ZERO_VALUES[key] !== undefined && value === OPTION_ZERO_VALUES[key]) {\n return undefined;\n }\n\n // maxSelect: 1 is the default for select and file fields\n if (key === \"maxSelect\" && value === 1 && (fieldType === \"select\" || fieldType === \"file\")) {\n return undefined; // Treat as undefined to match missing default\n }\n\n // maxSize: 0 is default for file fields\n if (key === \"maxSize\" && value === 0 && fieldType === \"file\") {\n return undefined;\n }\n\n // min: 1 can be a default for some PocketBase versions/number fields\n if (key === \"min\" && value === 1 && fieldType === \"number\") {\n return undefined;\n }\n\n // Empty arrays are defaults for file fields\n if (fieldType === \"file\") {\n if (key === \"mimeTypes\" && Array.isArray(value) && value.length === 0) {\n return undefined;\n }\n if (key === \"thumbs\" && Array.isArray(value) && value.length === 0) {\n return undefined;\n }\n if (key === \"protected\" && value === false) {\n return undefined;\n }\n }\n\n // Autodate defaults\n if (fieldType === \"autodate\") {\n if (key === \"onCreate\" && value === true) {\n return undefined;\n }\n if (key === \"onUpdate\" && value === false) {\n return undefined;\n }\n }\n\n return value;\n}\n","import type { FieldChange, FieldDefinition } from \"../types\";\nimport { areValuesEqual, normalizeOptionValue } from \"./utils\";\n\n/**\n * Identifies new fields in current collection that don't exist in previous\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of new fields\n */\nexport function findNewFields(currentFields: FieldDefinition[], previousFields: FieldDefinition[]): FieldDefinition[] {\n const newFields: FieldDefinition[] = [];\n const previousFieldNames = new Set(previousFields.map((f) => f.name));\n\n for (const currentField of currentFields) {\n if (!previousFieldNames.has(currentField.name)) {\n newFields.push(currentField);\n }\n }\n\n return newFields;\n}\n\n/**\n * Identifies fields removed from current collection (exist in previous but not in current)\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of removed fields\n */\nexport function findRemovedFields(\n currentFields: FieldDefinition[],\n previousFields: FieldDefinition[]\n): FieldDefinition[] {\n const removedFields: FieldDefinition[] = [];\n const currentFieldNames = new Set(currentFields.map((f) => f.name));\n\n for (const previousField of previousFields) {\n if (!currentFieldNames.has(previousField.name)) {\n removedFields.push(previousField);\n }\n }\n\n return removedFields;\n}\n\n/**\n * Matches fields by name between current and previous collections\n * Returns pairs of [current, previous] for fields that exist in both\n *\n * @param currentFields - Current collection fields\n * @param previousFields - Previous collection fields\n * @returns Array of matched field pairs\n */\nexport function matchFieldsByName(\n currentFields: FieldDefinition[],\n previousFields: FieldDefinition[]\n): Array<[FieldDefinition, FieldDefinition]> {\n const matches: Array<[FieldDefinition, FieldDefinition]> = [];\n\n // Create a map of previous fields by name for efficient lookup\n const previousFieldMap = new Map<string, FieldDefinition>();\n for (const previousField of previousFields) {\n previousFieldMap.set(previousField.name, previousField);\n }\n\n // Find matching fields\n for (const currentField of currentFields) {\n const previousField = previousFieldMap.get(currentField.name);\n\n if (previousField) {\n matches.push([currentField, previousField]);\n }\n }\n\n return matches;\n}\n\n/**\n * Compares field types between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns FieldChange if types differ, null otherwise\n */\nexport function compareFieldTypes(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange | null {\n if (currentField.type !== previousField.type) {\n return {\n property: \"type\",\n oldValue: previousField.type,\n newValue: currentField.type,\n };\n }\n\n return null;\n}\n\n/**\n * Compares field constraints (required, unique) between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for constraint differences\n */\nexport function compareFieldConstraints(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange[] {\n const changes: FieldChange[] = [];\n\n // Compare required constraint\n if (currentField.required !== previousField.required) {\n changes.push({\n property: \"required\",\n oldValue: previousField.required,\n newValue: currentField.required,\n });\n }\n\n // Compare unique constraint\n if (currentField.unique !== previousField.unique) {\n changes.push({\n property: \"unique\",\n oldValue: previousField.unique,\n newValue: currentField.unique,\n });\n }\n\n return changes;\n}\n\n/**\n * Compares field options (min, max, pattern, etc.) between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for option differences\n */\nexport function compareFieldOptions(currentField: FieldDefinition, previousField: FieldDefinition): FieldChange[] {\n const changes: FieldChange[] = [];\n\n const currentOptions = currentField.options || {};\n const previousOptions = previousField.options || {};\n\n // Get all unique option keys\n const allKeys = new Set([...Object.keys(currentOptions), ...Object.keys(previousOptions)]);\n\n // Compare each option\n // Use currentField.type for normalization since types should match at this point\n // (type changes are handled separately in compareFieldTypes)\n const fieldType = currentField.type;\n\n for (const key of allKeys) {\n const currentValue = currentOptions[key];\n const previousValue = previousOptions[key];\n\n // Normalize values to account for default values\n // This ensures that maxSelect: 1 (default) is treated the same as undefined (missing default)\n const normalizedCurrent = normalizeOptionValue(key, currentValue, fieldType);\n const normalizedPrevious = normalizeOptionValue(key, previousValue, fieldType);\n\n // Handle undefined values - if both are undefined (or normalized to undefined), that's not a change\n if (normalizedCurrent === undefined && normalizedPrevious === undefined) {\n continue;\n }\n\n if (!areValuesEqual(normalizedCurrent, normalizedPrevious)) {\n changes.push({\n property: `options.${key}`,\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Compares relation configurations between current and previous\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of FieldChange for relation differences\n */\nexport function compareRelationConfigurations(\n currentField: FieldDefinition,\n previousField: FieldDefinition,\n collectionIdToName?: Map<string, string>\n): FieldChange[] {\n const changes: FieldChange[] = [];\n\n const currentRelation = currentField.relation;\n const previousRelation = previousField.relation;\n\n // If one has relation and other doesn't, that's not a config change (handled elsewhere, likely type or structure)\n // But here we assume types match (both relation) or structure implies relation\n if (!currentRelation && !previousRelation) {\n return changes;\n }\n\n if (!currentRelation || !previousRelation) {\n // This shouldn't happen if types match and both are 'relation', but handle gracefully\n return changes;\n }\n\n // Compare relation properties\n // Note: collectionId should already be resolved to collection name during parsing\n // This normalization is just a safety net for edge cases\n const normalizeCollection = (collection: string): string => {\n if (!collection) return collection;\n\n // Resolve ID to name if possible\n if (collectionIdToName && collectionIdToName.has(collection)) {\n return collectionIdToName.get(collection)!;\n }\n\n // Handle expressions that might not have been parsed correctly\n const nameMatch = collection.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (nameMatch) {\n return nameMatch[1];\n }\n return collection;\n };\n\n const normalizedCurrent = normalizeCollection(currentRelation.collection);\n // We resolve the ID from the previous relation (snapshot) to its name if available\n const normalizedPrevious = normalizeCollection(previousRelation.collection);\n\n // Only report a change if the normalized values differ\n // Use case-insensitive comparison for collection names\n if (normalizedCurrent.toLowerCase() !== normalizedPrevious.toLowerCase()) {\n changes.push({\n property: \"relation.collection\",\n oldValue: previousRelation.collection,\n newValue: currentRelation.collection,\n });\n }\n\n if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {\n changes.push({\n property: \"relation.cascadeDelete\",\n oldValue: previousRelation.cascadeDelete,\n newValue: currentRelation.cascadeDelete,\n });\n }\n\n // Normalize maxSelect: 1 to undefined/null as it's often the default or treated as such\n const normalizeMax = (val: number | null | undefined) => (val === 1 ? null : val);\n const currentMax = normalizeMax(currentRelation.maxSelect);\n const previousMax = normalizeMax(previousRelation.maxSelect);\n\n // Use loose equality to handle null vs undefined\n if (currentMax != previousMax) {\n changes.push({\n property: \"relation.maxSelect\",\n oldValue: previousRelation.maxSelect,\n newValue: currentRelation.maxSelect,\n });\n }\n\n // Normalize minSelect: 0 to undefined/null\n const normalizeMin = (val: number | null | undefined) => (val === 0 ? null : val);\n const currentMin = normalizeMin(currentRelation.minSelect);\n const previousMin = normalizeMin(previousRelation.minSelect);\n\n if (currentMin != previousMin) {\n changes.push({\n property: \"relation.minSelect\",\n oldValue: previousRelation.minSelect,\n newValue: currentRelation.minSelect,\n });\n }\n\n return changes;\n}\n\n/**\n * Detects all changes between two field definitions\n * Combines type, constraint, option, and relation changes\n *\n * @param currentField - Current field definition\n * @param previousField - Previous field definition\n * @returns Array of all detected changes\n */\nexport function detectFieldChanges(\n currentField: FieldDefinition,\n previousField: FieldDefinition,\n collectionIdToName?: Map<string, string>\n): FieldChange[] {\n const changes: FieldChange[] = [];\n\n // Compare types\n const typeChange = compareFieldTypes(currentField, previousField);\n if (typeChange) {\n changes.push(typeChange);\n }\n\n // Compare constraints\n changes.push(...compareFieldConstraints(currentField, previousField));\n\n // Compare options\n changes.push(...compareFieldOptions(currentField, previousField));\n\n // Compare relation configurations (if applicable)\n if (currentField.type === \"relation\" && previousField.type === \"relation\") {\n changes.push(...compareRelationConfigurations(currentField, previousField, collectionIdToName));\n }\n\n return changes;\n}\n","/**\n * Compares indexes between current and previous collections\n *\n * @param currentIndexes - Current collection indexes\n * @param previousIndexes - Previous collection indexes\n * @returns Object with indexes to add and remove\n */\nexport function compareIndexes(\n currentIndexes: string[] = [],\n previousIndexes: string[] = []\n): { indexesToAdd: string[]; indexesToRemove: string[] } {\n const currentSet = new Set(currentIndexes);\n const previousSet = new Set(previousIndexes);\n\n const indexesToAdd = currentIndexes.filter((idx) => !previousSet.has(idx));\n const indexesToRemove = previousIndexes.filter((idx) => !currentSet.has(idx));\n\n return { indexesToAdd, indexesToRemove };\n}\n","import type { APIRuleType, CollectionSchema, PermissionChange, RuleUpdate } from \"../types\";\n\n/**\n * Compares API rules between current and previous collections\n *\n * @param currentRules - Current collection rules\n * @param previousRules - Previous collection rules\n * @returns Array of rule updates\n */\nexport function compareRules(\n currentRules: CollectionSchema[\"rules\"],\n previousRules: CollectionSchema[\"rules\"],\n currentPermissions?: CollectionSchema[\"permissions\"],\n previousPermissions?: CollectionSchema[\"permissions\"]\n): RuleUpdate[] {\n const updates: RuleUpdate[] = [];\n\n const ruleTypes: Array<keyof NonNullable<CollectionSchema[\"rules\"]>> = [\n \"listRule\",\n \"viewRule\",\n \"createRule\",\n \"updateRule\",\n \"deleteRule\",\n \"manageRule\",\n ];\n\n for (const ruleType of ruleTypes) {\n // Use rules if available, otherwise fall back to permissions (they're the same thing)\n const currentValue = currentRules?.[ruleType] ?? currentPermissions?.[ruleType] ?? null;\n const previousValue = previousRules?.[ruleType] ?? previousPermissions?.[ruleType] ?? null;\n\n if (currentValue !== previousValue) {\n updates.push({\n ruleType: ruleType as RuleUpdate[\"ruleType\"],\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return updates;\n}\n\n/**\n * Compares permissions between current and previous collections\n * Detects changes in permission rules defined in schema\n *\n * @param currentPermissions - Current collection permissions\n * @param previousPermissions - Previous collection permissions\n * @returns Array of permission changes\n */\nexport function comparePermissions(\n currentPermissions: CollectionSchema[\"permissions\"],\n previousPermissions: CollectionSchema[\"permissions\"]\n): PermissionChange[] {\n const changes: PermissionChange[] = [];\n\n const ruleTypes: APIRuleType[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\", \"manageRule\"];\n\n for (const ruleType of ruleTypes) {\n const currentValue = currentPermissions?.[ruleType] ?? null;\n const previousValue = previousPermissions?.[ruleType] ?? null;\n\n // Compare permission values\n if (currentValue !== previousValue) {\n changes.push({\n ruleType,\n oldValue: previousValue,\n newValue: currentValue,\n });\n }\n }\n\n return changes;\n}\n","import type {\n CollectionModification,\n CollectionSchema,\n FieldDefinition,\n FieldModification,\n SchemaDefinition,\n SchemaSnapshot,\n ViewQueryUpdate,\n} from \"../types\";\nimport { type DiffEngineConfig } from \"./config\";\nimport { detectFieldChanges, findNewFields, findRemovedFields, matchFieldsByName } from \"./fields\";\nimport { compareIndexes } from \"./indexes\";\nimport { comparePermissions, compareRules } from \"./rules\";\nimport { getUsersSystemFields, isSystemCollection } from \"./utils\";\n\n/**\n * Filters system collections from a schema definition\n * Returns a new SchemaDefinition with only custom (non-system) collections\n *\n * @param schema - Schema definition to filter\n * @param config - Optional configuration\n * @returns Filtered SchemaDefinition without system collections\n */\nexport function filterSystemCollections(schema: SchemaDefinition, config?: DiffEngineConfig): SchemaDefinition {\n const filteredCollections = new Map<string, CollectionSchema>();\n\n for (const [collectionName, collectionSchema] of schema.collections) {\n if (!isSystemCollection(collectionName, config)) {\n filteredCollections.set(collectionName, collectionSchema);\n }\n }\n\n return {\n collections: filteredCollections,\n };\n}\n\n/**\n * Identifies new collections in schema that don't exist in snapshot\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of new collections\n */\nexport function findNewCollections(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): CollectionSchema[] {\n const newCollections: CollectionSchema[] = [];\n\n // If no previous snapshot, all collections are new\n if (!previousSnapshot) {\n return Array.from(currentSchema.collections.values());\n }\n\n // Find collections in current schema that don't exist in snapshot\n for (const [collectionName, collectionSchema] of currentSchema.collections) {\n if (!previousSnapshot.collections.has(collectionName)) {\n newCollections.push(collectionSchema);\n }\n }\n\n return newCollections;\n}\n\n/**\n * Identifies collections removed from schema (exist in snapshot but not in current schema)\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of removed collections\n */\nexport function findRemovedCollections(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): CollectionSchema[] {\n const removedCollections: CollectionSchema[] = [];\n\n // If no previous snapshot, nothing can be removed\n if (!previousSnapshot) {\n return removedCollections;\n }\n\n // Find collections in snapshot that don't exist in current schema\n for (const [collectionName, collectionSchema] of previousSnapshot.collections) {\n if (!currentSchema.collections.has(collectionName)) {\n removedCollections.push(collectionSchema);\n }\n }\n\n return removedCollections;\n}\n\n/**\n * Matches collections by name between current schema and snapshot\n * Returns pairs of [current, previous] for collections that exist in both\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @returns Array of matched collection pairs\n */\nexport function matchCollectionsByName(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null\n): Array<[CollectionSchema, CollectionSchema]> {\n const matches: Array<[CollectionSchema, CollectionSchema]> = [];\n\n // If no previous snapshot, no matches possible\n if (!previousSnapshot) {\n return matches;\n }\n\n // Create a case-insensitive lookup map for previous collections\n const previousCollectionsLower = new Map<string, [string, CollectionSchema]>();\n for (const [name, collection] of previousSnapshot.collections) {\n previousCollectionsLower.set(name.toLowerCase(), [name, collection]);\n }\n\n // Find collections that exist in both current and previous (case-insensitive)\n for (const [collectionName, currentCollection] of currentSchema.collections) {\n const previousEntry = previousCollectionsLower.get(collectionName.toLowerCase());\n\n if (previousEntry) {\n const [, previousCollection] = previousEntry;\n matches.push([currentCollection, previousCollection]);\n }\n }\n\n return matches;\n}\n\n/**\n * Compares fields between current and previous collections\n * Identifies new, removed, and modified fields\n * For the users collection, filters out system fields from fieldsToAdd\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @param config - Optional configuration\n * @returns Object with field changes\n */\nfunction compareCollectionFields(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema,\n config?: DiffEngineConfig,\n collectionIdToName?: Map<string, string>\n): {\n fieldsToAdd: FieldDefinition[];\n fieldsToRemove: FieldDefinition[];\n fieldsToModify: FieldModification[];\n} {\n let fieldsToAdd = findNewFields(currentCollection.fields, previousCollection.fields);\n let fieldsToRemove = findRemovedFields(currentCollection.fields, previousCollection.fields);\n const fieldsToModify: FieldModification[] = [];\n\n // For users collection, filter out system fields from fieldsToAdd\n // System fields are automatically provided by PocketBase and should not be in migrations\n if (currentCollection.name === \"users\") {\n const systemFields = getUsersSystemFields(config);\n fieldsToAdd = fieldsToAdd.filter((field) => !systemFields.has(field.name));\n }\n\n // Check for modified fields\n const matchedFields = matchFieldsByName(currentCollection.fields, previousCollection.fields);\n\n for (const [currentField, previousField] of matchedFields) {\n const changes = detectFieldChanges(currentField, previousField, collectionIdToName);\n\n if (changes.length > 0) {\n fieldsToModify.push({\n fieldName: currentField.name,\n currentDefinition: previousField,\n newDefinition: currentField,\n changes,\n });\n }\n }\n\n // Detect Renames (Heuristic)\n // If we have single removed and added fields of the same type, consider it a rename\n const processedAddIndices = new Set<number>();\n const processedRemoveIndices = new Set<number>();\n\n // Helper to resolve collection name from ID/expression\n const resolveCollectionName = (val: string): string => {\n if (!val) return val;\n if (collectionIdToName && collectionIdToName.has(val)) return collectionIdToName.get(val)!;\n const match = val.match(/app\\.findCollectionByNameOrId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n return match ? match[1] : val;\n };\n\n // Group fields by type\n const addedByType = new Map<string, number[]>();\n fieldsToAdd.forEach((field, index) => {\n const type = field.type;\n if (!addedByType.has(type)) addedByType.set(type, []);\n addedByType.get(type)!.push(index);\n });\n\n const removedByType = new Map<string, number[]>();\n fieldsToRemove.forEach((field, index) => {\n const type = field.type;\n if (!removedByType.has(type)) removedByType.set(type, []);\n removedByType.get(type)!.push(index);\n });\n\n // Check each type for potential renames\n for (const [type, removedIndices] of removedByType) {\n const addedIndices = addedByType.get(type);\n\n // Heuristic: Only rename if exactly one field of this type was removed and one added\n if (addedIndices && addedIndices.length === 1 && removedIndices.length === 1) {\n const addedIndex = addedIndices[0];\n const removedIndex = removedIndices[0];\n const addedField = fieldsToAdd[addedIndex];\n const removedField = fieldsToRemove[removedIndex];\n\n // For relations, ensure target collection matches\n let isMatch = true;\n if (type === \"relation\") {\n const addedTarget = resolveCollectionName(addedField.relation?.collection || \"\");\n const removedTarget = resolveCollectionName(removedField.relation?.collection || \"\");\n if (addedTarget.toLowerCase() !== removedTarget.toLowerCase()) {\n isMatch = false;\n }\n }\n\n if (isMatch) {\n // It's a rename!\n processedAddIndices.add(addedIndex);\n processedRemoveIndices.add(removedIndex);\n\n // Calculate changes (including name change)\n const changes = detectFieldChanges(addedField, removedField, collectionIdToName);\n changes.push({\n property: \"name\",\n oldValue: removedField.name,\n newValue: addedField.name,\n });\n\n fieldsToModify.push({\n fieldName: removedField.name, // Use OLD name so generator can find it\n currentDefinition: removedField, // OLD definition\n newDefinition: addedField, // NEW definition\n changes,\n });\n }\n }\n }\n\n // Filter out processed fields\n fieldsToAdd = fieldsToAdd.filter((_, index) => !processedAddIndices.has(index));\n fieldsToRemove = fieldsToRemove.filter((_, index) => !processedRemoveIndices.has(index));\n\n return { fieldsToAdd, fieldsToRemove, fieldsToModify };\n}\n\n/**\n * Normalizes a SQL view query for comparison\n * Collapses whitespace so re-indenting or re-wrapping a query does not produce\n * a migration\n *\n * @param query - The SQL query\n * @returns Normalized query text\n */\nexport function normalizeSql(query: string | null | undefined): string {\n if (!query) {\n return \"\";\n }\n\n return query\n .split(\"\\n\")\n .map((line) => line.trim())\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Compares the SQL query of two view collections\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @returns A ViewQueryUpdate when the query changed, undefined otherwise\n */\nfunction compareViewQuery(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema\n): ViewQueryUpdate | undefined {\n const newValue = currentCollection.viewQuery;\n\n if (typeof newValue !== \"string\") {\n return undefined;\n }\n\n if (normalizeSql(newValue) === normalizeSql(previousCollection.viewQuery)) {\n return undefined;\n }\n\n return {\n oldValue: previousCollection.viewQuery ?? null,\n newValue,\n };\n}\n\n/**\n * Builds a CollectionModification for a matched collection pair\n *\n * @param currentCollection - Current collection schema\n * @param previousCollection - Previous collection schema\n * @param config - Optional configuration\n * @returns CollectionModification object\n */\nexport function buildCollectionModification(\n currentCollection: CollectionSchema,\n previousCollection: CollectionSchema,\n config?: DiffEngineConfig,\n collectionIdToName?: Map<string, string>\n): CollectionModification {\n // View collections are defined entirely by their SQL query: PocketBase\n // derives the fields from it and views cannot have indexes, so only the\n // query and the read rules are diffed\n const isView = currentCollection.type === \"view\" || previousCollection.type === \"view\";\n\n if (isView) {\n return {\n collection: currentCollection.name,\n fieldsToAdd: [],\n fieldsToRemove: [],\n fieldsToModify: [],\n indexesToAdd: [],\n indexesToRemove: [],\n rulesToUpdate: compareRules(\n currentCollection.rules,\n previousCollection.rules,\n currentCollection.permissions,\n previousCollection.permissions\n ),\n permissionsToUpdate: comparePermissions(currentCollection.permissions, previousCollection.permissions),\n viewQueryUpdate: compareViewQuery(currentCollection, previousCollection),\n };\n }\n\n // Compare fields\n const { fieldsToAdd, fieldsToRemove, fieldsToModify } = compareCollectionFields(\n currentCollection,\n previousCollection,\n config,\n collectionIdToName\n );\n\n // Compare indexes\n const { indexesToAdd, indexesToRemove } = compareIndexes(currentCollection.indexes, previousCollection.indexes);\n\n // Compare rules (also check permissions as fallback since they're the same thing)\n const rulesToUpdate = compareRules(\n currentCollection.rules,\n previousCollection.rules,\n currentCollection.permissions,\n previousCollection.permissions\n );\n\n // Compare permissions\n const permissionsToUpdate = comparePermissions(currentCollection.permissions, previousCollection.permissions);\n\n return {\n collection: currentCollection.name,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexesToAdd,\n indexesToRemove,\n rulesToUpdate,\n permissionsToUpdate,\n };\n}\n","import type { SchemaDiff } from \"../types\";\nimport { type DiffEngineConfig } from \"./config\";\nimport { detectDestructiveChanges, type DestructiveChange } from \"./destructiveness\";\n\n/**\n * Change summary for status reporting\n */\nexport interface ChangeSummary {\n totalChanges: number;\n collectionsToCreate: number;\n collectionsToDelete: number;\n collectionsToModify: number;\n fieldsToAdd: number;\n fieldsToRemove: number;\n fieldsToModify: number;\n indexChanges: number;\n ruleChanges: number;\n permissionChanges: number;\n viewQueryChanges: number;\n destructiveChanges: DestructiveChange[];\n nonDestructiveChanges: string[];\n}\n\n/**\n * Categorizes changes by severity\n * Returns object with destructive and non-destructive changes\n *\n * @param diff - Schema diff to categorize\n * @param config - Optional configuration\n * @returns Object with categorized changes\n */\nexport function categorizeChangesBySeverity(\n diff: SchemaDiff,\n _config?: DiffEngineConfig\n): {\n destructive: string[];\n nonDestructive: string[];\n} {\n const destructive: string[] = [];\n const nonDestructive: string[] = [];\n\n // Collection deletions are destructive, except for views which hold no data\n for (const collection of diff.collectionsToDelete) {\n if (collection.type === \"view\") {\n nonDestructive.push(`Delete view collection: ${collection.name}`);\n } else {\n destructive.push(`Delete collection: ${collection.name}`);\n }\n }\n\n // Collection creations are non-destructive\n for (const collection of diff.collectionsToCreate) {\n nonDestructive.push(`Create collection: ${collection.name}`);\n }\n\n // Analyze modifications\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Field deletions are destructive\n for (const field of modification.fieldsToRemove) {\n destructive.push(`Delete field: ${collectionName}.${field.name}`);\n }\n\n // Field additions are non-destructive\n for (const field of modification.fieldsToAdd) {\n nonDestructive.push(`Add field: ${collectionName}.${field.name}`);\n }\n\n // Field modifications can be destructive or non-destructive\n for (const fieldMod of modification.fieldsToModify) {\n const hasTypeChange = fieldMod.changes.some((c) => c.property === \"type\");\n const hasRequiredChange = fieldMod.changes.some((c) => c.property === \"required\" && c.newValue === true);\n\n if (hasTypeChange) {\n destructive.push(\n `Change field type: ${collectionName}.${fieldMod.fieldName} (${fieldMod.changes.find((c) => c.property === \"type\")?.oldValue} → ${fieldMod.changes.find((c) => c.property === \"type\")?.newValue})`\n );\n } else if (hasRequiredChange) {\n destructive.push(`Make field required: ${collectionName}.${fieldMod.fieldName}`);\n } else {\n nonDestructive.push(`Modify field: ${collectionName}.${fieldMod.fieldName}`);\n }\n }\n\n // Index changes are generally non-destructive\n for (const _index of modification.indexesToAdd) {\n nonDestructive.push(`Add index: ${collectionName}`);\n }\n\n for (const _index of modification.indexesToRemove) {\n nonDestructive.push(`Remove index: ${collectionName}`);\n }\n\n // Rule changes are non-destructive\n for (const rule of modification.rulesToUpdate) {\n nonDestructive.push(`Update rule: ${collectionName}.${rule.ruleType}`);\n }\n\n // View query changes are non-destructive - a view stores no data\n if (modification.viewQueryUpdate) {\n nonDestructive.push(`Update view query: ${collectionName}`);\n }\n }\n\n return { destructive, nonDestructive };\n}\n\n/**\n * Generates a summary of all changes in a diff\n * Useful for status reporting and user feedback\n *\n * @param diff - Schema diff to summarize\n * @param config - Optional configuration\n * @returns Change summary with counts and details\n */\nexport function generateChangeSummary(diff: SchemaDiff, config?: DiffEngineConfig): ChangeSummary {\n const destructiveChanges = detectDestructiveChanges(diff, config);\n const { nonDestructive } = categorizeChangesBySeverity(diff, config);\n\n let fieldsToAdd = 0;\n let fieldsToRemove = 0;\n let fieldsToModify = 0;\n let indexChanges = 0;\n let ruleChanges = 0;\n let permissionChanges = 0;\n let viewQueryChanges = 0;\n\n for (const modification of diff.collectionsToModify) {\n fieldsToAdd += modification.fieldsToAdd.length;\n fieldsToRemove += modification.fieldsToRemove.length;\n fieldsToModify += modification.fieldsToModify.length;\n indexChanges += modification.indexesToAdd.length + modification.indexesToRemove.length;\n ruleChanges += modification.rulesToUpdate.length;\n permissionChanges += modification.permissionsToUpdate.length;\n if (modification.viewQueryUpdate) {\n viewQueryChanges += 1;\n }\n }\n\n return {\n totalChanges: diff.collectionsToCreate.length + diff.collectionsToDelete.length + diff.collectionsToModify.length,\n collectionsToCreate: diff.collectionsToCreate.length,\n collectionsToDelete: diff.collectionsToDelete.length,\n collectionsToModify: diff.collectionsToModify.length,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexChanges,\n ruleChanges,\n permissionChanges,\n viewQueryChanges,\n destructiveChanges,\n nonDestructiveChanges: nonDestructive,\n };\n}\n","import type { SchemaDiff, FieldModification } from \"../types\";\n\nexport interface FilterOptions {\n patterns?: string[];\n skipDestructive?: boolean;\n}\n\nfunction matchesPattern(text: string, patterns: string[]): boolean {\n if (!patterns || patterns.length === 0) return true;\n return patterns.some(pattern => {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return text.includes(pattern);\n }\n });\n}\n\nfunction isDestructiveFieldModification(mod: FieldModification): boolean {\n const typeChange = mod.changes.find(c => c.property === \"type\");\n const requiredChange = mod.changes.find(c => c.property === \"required\" && c.newValue === true);\n return !!(typeChange || requiredChange);\n}\n\nexport function filterDiff(diff: SchemaDiff, options: FilterOptions): SchemaDiff {\n const { patterns = [], skipDestructive = false } = options;\n\n // 1. Filter Collections to Create\n const collectionsToCreate = diff.collectionsToCreate.filter(col => {\n return matchesPattern(col.name, patterns);\n });\n\n // 2. Filter Collections to Delete\n // View collections are kept even when skipping destructive changes: they\n // store no data, so dropping one loses nothing\n let collectionsToDelete = diff.collectionsToDelete;\n if (skipDestructive) {\n collectionsToDelete = collectionsToDelete.filter(col => col.type === \"view\");\n }\n collectionsToDelete = collectionsToDelete.filter(col => {\n return matchesPattern(col.name, patterns);\n });\n\n // 3. Filter Collections to Modify\n const collectionsToModify = diff.collectionsToModify.map(mod => {\n // Check if collection name itself matches\n const collectionMatches = matchesPattern(mod.collection, patterns);\n\n // Filter fields to add\n const fieldsToAdd = mod.fieldsToAdd.filter(field => {\n return collectionMatches || matchesPattern(`${mod.collection}.${field.name}`, patterns);\n });\n\n // Filter fields to remove\n let fieldsToRemove = mod.fieldsToRemove;\n if (skipDestructive) {\n fieldsToRemove = [];\n } else {\n fieldsToRemove = fieldsToRemove.filter(field => {\n return collectionMatches || matchesPattern(`${mod.collection}.${field.name}`, patterns);\n });\n }\n\n // Filter fields to modify\n let fieldsToModify = mod.fieldsToModify;\n if (skipDestructive) {\n fieldsToModify = fieldsToModify.filter(f => !isDestructiveFieldModification(f));\n }\n fieldsToModify = fieldsToModify.filter(f => {\n return collectionMatches || matchesPattern(`${mod.collection}.${f.fieldName}`, patterns);\n });\n\n // Filter collection-level changes (indexes, rules, permissions)\n // Only include them if the collection name itself matches the pattern.\n // If user targets specific fields (e.g. \"User.name\"), collectionMatches is false, so these are skipped.\n const indexesToAdd = collectionMatches ? mod.indexesToAdd : [];\n const indexesToRemove = collectionMatches ? mod.indexesToRemove : [];\n const rulesToUpdate = collectionMatches ? mod.rulesToUpdate : [];\n const permissionsToUpdate = collectionMatches ? mod.permissionsToUpdate : [];\n const viewQueryUpdate = collectionMatches ? mod.viewQueryUpdate : undefined;\n\n return {\n ...mod,\n fieldsToAdd,\n fieldsToRemove,\n fieldsToModify,\n indexesToAdd,\n indexesToRemove,\n rulesToUpdate,\n permissionsToUpdate,\n viewQueryUpdate\n };\n }).filter(mod => {\n // Keep modification object only if there is something left to modify\n return mod.fieldsToAdd.length > 0 ||\n mod.fieldsToRemove.length > 0 ||\n mod.fieldsToModify.length > 0 ||\n mod.indexesToAdd.length > 0 ||\n mod.indexesToRemove.length > 0 ||\n mod.rulesToUpdate.length > 0 ||\n mod.permissionsToUpdate.length > 0 ||\n mod.viewQueryUpdate !== undefined;\n });\n\n return {\n ...diff,\n collectionsToCreate,\n collectionsToDelete,\n collectionsToModify\n };\n}\n","/**\n * Diff Engine component\n * Compares current schema with previous snapshot and identifies changes\n *\n * This module provides a standalone, configurable diff engine that can be used\n * by consumer projects to compare schema definitions and detect changes.\n */\n\nimport type { CollectionModification, SchemaDefinition, SchemaDiff, SchemaSnapshot } from \"../types\";\nimport { CollectionIdRegistry } from \"../utils/collection-id-generator\";\nimport {\n buildCollectionModification,\n findNewCollections,\n findRemovedCollections,\n matchCollectionsByName,\n} from \"./collections\";\nimport { mergeConfig, type DiffEngineConfig } from \"./config\";\nimport {\n categorizeChangesBySeverity,\n generateChangeSummary,\n type ChangeSummary,\n} from \"./summary\";\nimport { isSystemCollection } from \"./utils\";\nimport { detectDestructiveChanges, type DestructiveChange, requiresForceFlag } from \"./destructiveness\";\n\n// Export everything from submodules\nexport * from \"./collections\";\nexport * from \"./config\";\nexport * from \"./destructiveness\";\nexport * from \"./fields\";\nexport * from \"./indexes\";\nexport * from \"./rules\";\nexport * from \"./summary\";\nexport * from \"./utils\";\n\n/**\n * Checks if a collection modification has any actual changes\n *\n * @param modification - Collection modification to check\n * @returns True if there are any changes\n */\nfunction hasChanges(modification: CollectionModification): boolean {\n return (\n modification.fieldsToAdd.length > 0 ||\n modification.fieldsToRemove.length > 0 ||\n modification.fieldsToModify.length > 0 ||\n modification.indexesToAdd.length > 0 ||\n modification.indexesToRemove.length > 0 ||\n modification.rulesToUpdate.length > 0 ||\n modification.permissionsToUpdate.length > 0 ||\n modification.viewQueryUpdate !== undefined\n );\n}\n\n/**\n * Aggregates all detected changes into a SchemaDiff\n * Main entry point for diff comparison\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot\n * @param config - Optional configuration\n * @returns Complete SchemaDiff with all changes\n */\nexport function aggregateChanges(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null,\n config?: DiffEngineConfig\n): SchemaDiff {\n // Build lookup map for ID -> Name from previous snapshot\n // This helps resolve relations where snapshot uses ID but schema uses Name\n const collectionIdToName = new Map<string, string>();\n if (previousSnapshot) {\n for (const [name, collection] of previousSnapshot.collections) {\n if (collection.id) {\n collectionIdToName.set(collection.id, name);\n }\n }\n }\n\n // Find new and removed collections\n const collectionsToCreate = findNewCollections(currentSchema, previousSnapshot);\n const collectionsToDelete = findRemovedCollections(currentSchema, previousSnapshot);\n\n // Filter out system collections from create and delete operations\n const filteredCollectionsToCreate = collectionsToCreate.filter(\n (collection) => !isSystemCollection(collection.name, config)\n );\n const filteredCollectionsToDelete = collectionsToDelete.filter(\n (collection) => !isSystemCollection(collection.name, config)\n );\n\n // Generate and assign collection IDs for new collections\n const registry = new CollectionIdRegistry();\n const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {\n // If the collection already has an ID, register it and use it\n if (collection.id) {\n registry.register(collection.id);\n return collection;\n }\n\n // Generate a new ID for the collection (pass name for special handling)\n const id = registry.generate(collection.name);\n return {\n ...collection,\n id,\n };\n });\n\n // Find modified collections\n const collectionsToModify: CollectionModification[] = [];\n const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);\n\n for (const [currentCollection, previousCollection] of matchedCollections) {\n const modification = buildCollectionModification(currentCollection, previousCollection, config, collectionIdToName);\n\n // Only include if there are actual changes\n // Note: We allow modifications to the users collection (non-system)\n if (hasChanges(modification)) {\n collectionsToModify.push(modification);\n }\n }\n\n // Build map of existing collection names to their IDs from the snapshot\n // This is used by the generator to resolve relation field references\n const existingCollectionIds = new Map<string, string>();\n if (previousSnapshot) {\n for (const [name, collection] of previousSnapshot.collections) {\n if (collection.id) {\n existingCollectionIds.set(name, collection.id);\n }\n }\n }\n\n return {\n collectionsToCreate: collectionsWithIds,\n collectionsToDelete: filteredCollectionsToDelete,\n collectionsToModify,\n existingCollectionIds,\n };\n}\n\n/**\n * Main comparison function\n * Compares current schema with previous snapshot and returns complete diff\n *\n * @param currentSchema - Current schema definition\n * @param previousSnapshot - Previous schema snapshot (null for first run)\n * @param config - Optional configuration\n * @returns Complete SchemaDiff with all detected changes\n */\nexport function compare(\n currentSchema: SchemaDefinition,\n previousSnapshot: SchemaSnapshot | null,\n config?: DiffEngineConfig\n): SchemaDiff {\n return aggregateChanges(currentSchema, previousSnapshot, config);\n}\n\n/**\n * DiffEngine class for object-oriented usage\n * Provides a stateful interface for schema comparison\n */\nexport class DiffEngine {\n private config: Required<DiffEngineConfig>;\n\n constructor(config?: DiffEngineConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Compares current schema with previous snapshot\n */\n compare(currentSchema: SchemaDefinition, previousSnapshot: SchemaSnapshot | null): SchemaDiff {\n return compare(currentSchema, previousSnapshot, this.config);\n }\n\n /**\n * Detects destructive changes in a diff\n */\n detectDestructiveChanges(diff: SchemaDiff): DestructiveChange[] {\n return detectDestructiveChanges(diff, this.config);\n }\n\n /**\n * Categorizes changes by severity\n */\n categorizeChangesBySeverity(diff: SchemaDiff): { destructive: string[]; nonDestructive: string[] } {\n return categorizeChangesBySeverity(diff, this.config);\n }\n\n /**\n * Generates a summary of changes\n */\n generateChangeSummary(diff: SchemaDiff): ChangeSummary {\n return generateChangeSummary(diff, this.config);\n }\n\n /**\n * Checks if force flag is required\n */\n requiresForceFlag(diff: SchemaDiff): boolean {\n return requiresForceFlag(diff, this.config);\n }\n}\nexport * from \"./filter.js\";\n","/**\n * Configuration options for the migration generator\n */\nexport interface MigrationGeneratorConfig {\n /**\n * Directory to write migration files\n */\n migrationDir: string;\n\n /**\n * Workspace root for resolving relative paths\n * Defaults to process.cwd()\n */\n workspaceRoot?: string;\n\n /**\n * Custom timestamp generator function\n * Defaults to Unix timestamp in seconds\n */\n timestampGenerator?: () => string;\n\n /**\n * Custom migration file template\n * Use {{UP_CODE}} and {{DOWN_CODE}} placeholders\n */\n template?: string;\n\n /**\n * Whether to include type reference comment\n * Defaults to true\n */\n includeTypeReference?: boolean;\n\n /**\n * Path to types.d.ts file for reference comment\n * Defaults to '../pb_data/types.d.ts'\n */\n typesPath?: string;\n\n /**\n * Whether to force generation even if duplicate migration exists\n * Defaults to false\n */\n force?: boolean;\n}\n\n/**\n * Default migration template\n */\nexport const DEFAULT_TEMPLATE = `/// <reference path=\"{{TYPES_PATH}}\" />\nmigrate((app) => {\n{{UP_CODE}}\n}, (app) => {\n{{DOWN_CODE}}\n});\n`;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Omit<Required<MigrationGeneratorConfig>, \"migrationDir\" | \"force\"> = {\n workspaceRoot: process.cwd(),\n timestampGenerator: () => Math.floor(Date.now() / 1000).toString(),\n template: DEFAULT_TEMPLATE,\n includeTypeReference: true,\n typesPath: \"../pb_data/types.d.ts\",\n};\n\n/**\n * Merges user config with defaults\n */\nexport function mergeConfig(config: MigrationGeneratorConfig): Required<MigrationGeneratorConfig> {\n return {\n ...DEFAULT_CONFIG,\n force: false,\n ...config,\n };\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, MigrationGenerationError } from \"../errors\";\nimport { DEFAULT_CONFIG, mergeConfig, type MigrationGeneratorConfig } from \"./config\";\n\n/**\n * Resolves the migration directory path\n */\nexport function resolveMigrationDir(config: MigrationGeneratorConfig): string {\n const workspaceRoot = config.workspaceRoot || process.cwd();\n\n if (path.isAbsolute(config.migrationDir)) {\n return config.migrationDir;\n }\n\n return path.join(workspaceRoot, config.migrationDir);\n}\n\n/**\n * Creates the migration file structure with up and down functions\n *\n * @param upCode - Code for the up migration\n * @param downCode - Code for the down migration\n * @param config - Optional configuration with custom template\n * @returns Complete migration file content\n */\nexport function createMigrationFileStructure(\n upCode: string,\n downCode: string,\n config?: MigrationGeneratorConfig\n): string {\n const mergedConfig = config ? mergeConfig(config) : DEFAULT_CONFIG;\n let template = mergedConfig.template;\n\n // Replace placeholders using functions to avoid special character expansion (like $')\n template = template.replace(\"{{TYPES_PATH}}\", () => mergedConfig.typesPath);\n template = template.replace(\"{{UP_CODE}}\", () => upCode);\n template = template.replace(\"{{DOWN_CODE}}\", () => downCode);\n\n // Remove type reference if disabled\n if (!mergedConfig.includeTypeReference) {\n template = template.replace(/\\/\\/\\/ <reference path=\"[^\"]*\" \\/>\\n?/, \"\");\n }\n\n return template;\n}\n\n/**\n * Writes migration file to the specified directory\n * Creates directory if it doesn't exist\n *\n * @param migrationDir - Directory to write migration file\n * @param filename - Migration filename\n * @param content - Migration file content\n * @returns Full path to the created migration file\n */\nexport function writeMigrationFile(migrationDir: string, filename: string, content: string): string {\n try {\n // Ensure migration directory exists\n if (!fs.existsSync(migrationDir)) {\n try {\n fs.mkdirSync(migrationDir, { recursive: true });\n } catch (error) {\n const fsError = error as NodeJS.ErrnoException;\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied creating migration directory. Check directory permissions.`,\n migrationDir,\n \"create\",\n fsError.code,\n error as Error\n );\n }\n throw new FileSystemError(\n `Failed to create migration directory: ${fsError.message}`,\n migrationDir,\n \"create\",\n fsError.code,\n error as Error\n );\n }\n }\n\n // Full path to migration file\n const filePath = path.join(migrationDir, filename);\n\n // Write migration file\n fs.writeFileSync(filePath, content, \"utf-8\");\n\n return filePath;\n } catch (error) {\n // If it's already a FileSystemError, re-throw it\n if (error instanceof FileSystemError) {\n throw error;\n }\n\n const fsError = error as NodeJS.ErrnoException;\n const filePath = path.join(migrationDir, filename);\n\n if (fsError.code === \"EACCES\" || fsError.code === \"EPERM\") {\n throw new FileSystemError(\n `Permission denied writing migration file. Check file and directory permissions.`,\n filePath,\n \"write\",\n fsError.code,\n error as Error\n );\n } else if (fsError.code === \"ENOSPC\") {\n throw new FileSystemError(\n `No space left on device when writing migration file.`,\n filePath,\n \"write\",\n fsError.code,\n error as Error\n );\n }\n\n throw new MigrationGenerationError(`Failed to write migration file: ${fsError.message}`, filePath, error as Error);\n }\n}\n","import type { FieldDefinition, FieldModification } from \"../types\";\nimport { formatValue, generateFindCollectionCode, getFieldConstructorName } from \"./utils\";\n\n/**\n * Generates field definition object for collection creation\n * Creates the field configuration object used in Collection constructor\n *\n * @param field - Field definition\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Field definition object as string\n */\nexport function generateFieldDefinitionObject(field: FieldDefinition, collectionIdMap?: Map<string, string>): string {\n const parts: string[] = [];\n\n // Add field name\n parts.push(` \"name\": \"${field.name}\"`);\n\n // Add field id\n parts.push(` \"id\": \"${field.id}\"`);\n\n // Add field type\n parts.push(` \"type\": \"${field.type}\"`);\n\n // Add required flag\n parts.push(` \"required\": ${field.required}`);\n\n // Add unique flag if present\n if (field.unique !== undefined) {\n parts.push(` \"unique\": ${field.unique}`);\n }\n\n // Add explicit defaults for select fields\n if (field.type === \"select\") {\n // Always include maxSelect (default: 1)\n const maxSelect = field.options?.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include values array (default: [])\n const values = field.options?.values ?? [];\n parts.push(` \"values\": ${formatValue(values)}`);\n }\n\n // Add options if present (excluding select-specific options already handled)\n if (field.options && Object.keys(field.options).length > 0) {\n for (const [key, value] of Object.entries(field.options)) {\n // Skip select-specific options as they're handled above\n if (field.type === \"select\" && (key === \"maxSelect\" || key === \"values\")) {\n continue;\n }\n // Skip id as it's already added explicitly above\n if (key === \"id\") {\n continue;\n }\n // Convert noDecimal to onlyInt for number fields (PocketBase uses onlyInt)\n if (field.type === \"number\" && key === \"noDecimal\") {\n parts.push(` \"onlyInt\": ${formatValue(value)}`);\n } else {\n parts.push(` \"${key}\": ${formatValue(value)}`);\n }\n }\n }\n\n // Add relation configuration if present\n if (field.relation) {\n // Use pre-generated collection ID from map if available\n // Otherwise fall back to runtime lookup (for existing collections not in the current diff)\n const isUsersCollection = field.relation.collection.toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n // Special case: users collection always uses the constant\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {\n // Use pre-generated ID from map\n collectionIdValue = `\"${collectionIdMap.get(field.relation.collection)}\"`;\n } else {\n // Fall back to runtime lookup for existing collections\n collectionIdValue = `app.findCollectionByNameOrId(\"${field.relation.collection}\").id`;\n }\n\n parts.push(` \"collectionId\": ${collectionIdValue}`);\n\n // Always include maxSelect (default: 1)\n const maxSelect = field.relation.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include minSelect (default: null)\n const minSelect = field.relation.minSelect ?? null;\n parts.push(` \"minSelect\": ${minSelect}`);\n\n // Always include cascadeDelete (default: false)\n const cascadeDelete = field.relation.cascadeDelete ?? false;\n parts.push(` \"cascadeDelete\": ${cascadeDelete}`);\n\n // `displayFields` is deliberately not emitted: PocketBase dropped it from\n // the relation field in v0.23 and silently discards it on save, so writing\n // it only makes the generated file diverge from what PocketBase stores\n }\n\n return ` {\\n${parts.join(\",\\n\")},\\n }`;\n}\n\n/**\n * Generates fields array for collection creation\n *\n * @param fields - Array of field definitions\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Fields array as string\n */\nexport function generateFieldsArray(fields: FieldDefinition[], collectionIdMap?: Map<string, string>): string {\n if (fields.length === 0) {\n return \"[]\";\n }\n\n const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));\n return `[\\n${fieldObjects.join(\",\\n\")},\\n ]`;\n}\n\n/**\n * Generates field constructor options object\n *\n * @param field - Field definition\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns Options object as string\n */\nexport function generateFieldConstructorOptions(field: FieldDefinition, collectionIdMap?: Map<string, string>): string {\n const parts: string[] = [];\n\n // Add field name\n parts.push(` \"name\": \"${field.name}\"`);\n\n // Add field id\n parts.push(` \"id\": \"${field.id}\"`);\n\n // Add required flag\n parts.push(` \"required\": ${field.required}`);\n\n // Add unique flag if present\n if (field.unique !== undefined) {\n parts.push(` \"unique\": ${field.unique}`);\n }\n\n // Add explicit defaults for select fields\n if (field.type === \"select\") {\n // Always include maxSelect (default: 1)\n const maxSelect = field.options?.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include values array (default: [])\n const values = field.options?.values ?? [];\n parts.push(` \"values\": ${formatValue(values)}`);\n }\n\n // Add options if present (excluding select-specific options already handled)\n if (field.options && Object.keys(field.options).length > 0) {\n for (const [key, value] of Object.entries(field.options)) {\n // Skip select-specific options as they're handled above\n if (field.type === \"select\" && (key === \"maxSelect\" || key === \"values\")) {\n continue;\n }\n // Skip id as it's already added explicitly above\n if (key === \"id\") {\n continue;\n }\n // Convert noDecimal to onlyInt for number fields (PocketBase uses onlyInt)\n if (field.type === \"number\" && key === \"noDecimal\") {\n parts.push(` \"onlyInt\": ${formatValue(value)}`);\n } else {\n parts.push(` \"${key}\": ${formatValue(value)}`);\n }\n }\n }\n\n // Add relation-specific options\n if (field.relation && field.type === \"relation\") {\n // Use pre-generated collection ID from map if available\n // Otherwise fall back to runtime lookup (for existing collections not in the current diff)\n const isUsersCollection = field.relation.collection.toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n // Special case: users collection always uses the constant\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {\n // Use pre-generated ID from map\n collectionIdValue = `\"${collectionIdMap.get(field.relation.collection)}\"`;\n } else {\n // Fall back to runtime lookup for existing collections\n collectionIdValue = `app.findCollectionByNameOrId(\"${field.relation.collection}\").id`;\n }\n\n parts.push(` \"collectionId\": ${collectionIdValue}`);\n\n // Always include maxSelect (default: 1)\n const maxSelect = field.relation.maxSelect ?? 1;\n parts.push(` \"maxSelect\": ${maxSelect}`);\n\n // Always include minSelect (default: null)\n const minSelect = field.relation.minSelect ?? null;\n parts.push(` \"minSelect\": ${minSelect}`);\n\n // Always include cascadeDelete (default: false)\n const cascadeDelete = field.relation.cascadeDelete ?? false;\n parts.push(` \"cascadeDelete\": ${cascadeDelete}`);\n\n // See generateFieldDefinitionObject: PocketBase has no displayFields\n // option on relation fields since v0.23\n }\n\n return parts.join(\",\\n\");\n}\n\n/**\n * Generates code for adding a field to an existing collection\n * Uses the appropriate Field constructor based on field type\n *\n * @param collectionName - Name of the collection\n * @param field - Field definition to add\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for adding the field\n */\nexport function generateFieldAddition(\n collectionName: string,\n field: FieldDefinition,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const constructorName = getFieldConstructorName(field.type);\n const collectionVar = varName || `collection_${collectionName}_${field.name}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(``);\n lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);\n lines.push(generateFieldConstructorOptions(field, collectionIdMap));\n lines.push(` }));`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for modifying an existing field\n * Updates field properties based on detected changes\n *\n * @param collectionName - Name of the collection\n * @param modification - Field modification details\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for modifying the field\n */\nexport function generateFieldModification(\n collectionName: string,\n modification: FieldModification,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;\n const fieldVar = `${collectionVar}_field`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` const ${fieldVar} = ${collectionVar}.fields.getByName(\"${modification.fieldName}\");`);\n lines.push(``);\n\n // Apply each change\n for (const change of modification.changes) {\n if (change.property.startsWith(\"options.\")) {\n // Handle nested options properties\n const optionKey = change.property.replace(\"options.\", \"\");\n // In PocketBase, field properties are set directly on the field, not in an options object\n lines.push(` ${fieldVar}.${optionKey} = ${formatValue(change.newValue)};`);\n } else if (change.property.startsWith(\"relation.\")) {\n // Handle nested relation properties\n const relationKey = change.property.replace(\"relation.\", \"\");\n\n if (relationKey === \"collection\") {\n // Special handling for collection ID\n // Use case-insensitive check for \"users\" to handle both explicit and implicit relation definitions\n const isUsersCollection = String(change.newValue).toLowerCase() === \"users\";\n let collectionIdValue: string;\n\n if (isUsersCollection) {\n collectionIdValue = '\"_pb_users_auth_\"';\n } else if (collectionIdMap && collectionIdMap.has(String(change.newValue))) {\n // Use pre-generated ID from map (for existing collections)\n collectionIdValue = `\"${collectionIdMap.get(String(change.newValue))}\"`;\n } else {\n // Fall back to runtime lookup (should not happen if snapshot is properly loaded)\n collectionIdValue = `app.findCollectionByNameOrId(\"${change.newValue}\").id`;\n }\n lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);\n } else {\n lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);\n }\n } else {\n // Handle top-level properties\n lines.push(` ${fieldVar}.${change.property} = ${formatValue(change.newValue)};`);\n }\n }\n\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for deleting a field from a collection\n *\n * @param collectionName - Name of the collection\n * @param fieldName - Name of the field to delete\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for deleting the field\n */\nexport function generateFieldDeletion(\n collectionName: string,\n fieldName: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${fieldName}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(``);\n lines.push(` ${collectionVar}.fields.removeByName(\"${fieldName}\");`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import { generateFindCollectionCode } from \"./utils\";\n\n/**\n * Generates indexes array for collection creation\n *\n * @param indexes - Array of index definitions\n * @returns Indexes array as string\n */\nexport function generateIndexesArray(indexes?: string[]): string {\n if (!indexes || indexes.length === 0) {\n return \"[]\";\n }\n\n const indexStrings = indexes.map((idx) => JSON.stringify(idx));\n return `[\\n ${indexStrings.join(\",\\n \")},\\n ]`;\n}\n\n/**\n * Generates code for adding an index to a collection\n *\n * @param collectionName - Name of the collection\n * @param index - Index SQL statement\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for adding the index\n */\nexport function generateIndexAddition(\n collectionName: string,\n index: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_idx`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for removing an index from a collection\n *\n * @param collectionName - Name of the collection\n * @param index - Index SQL statement\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for removing the index\n */\nexport function generateIndexRemoval(\n collectionName: string,\n index: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_idx`;\n const indexVar = `${collectionVar}_indexToRemove`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);\n lines.push(` if (${indexVar} !== -1) {`);\n lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);\n lines.push(` }`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionSchema } from \"../types\";\nimport { formatSqlTemplate, formatValue, generateFindCollectionCode } from \"./utils\";\n\n/**\n * Generates collection rules object\n *\n * @param rules - Collection rules\n * @returns Rules configuration as string\n */\nexport function generateCollectionRules(rules?: CollectionSchema[\"rules\"], collectionType: string = \"base\"): string {\n if (!rules) {\n return \"\";\n }\n\n // View collections are read-only: the write rules are always null and\n // manageRule is not applicable\n if (collectionType === \"view\") {\n return [\n `\"listRule\": ${formatValue(rules.listRule ?? null)}`,\n `\"viewRule\": ${formatValue(rules.viewRule ?? null)}`,\n `\"createRule\": null`,\n `\"updateRule\": null`,\n `\"deleteRule\": null`,\n ].join(\",\\n \");\n }\n\n const parts: string[] = [];\n\n if (rules.listRule !== undefined) {\n parts.push(`\"listRule\": ${formatValue(rules.listRule)}`);\n }\n\n if (rules.viewRule !== undefined) {\n parts.push(`\"viewRule\": ${formatValue(rules.viewRule)}`);\n }\n\n if (rules.createRule !== undefined) {\n parts.push(`\"createRule\": ${formatValue(rules.createRule)}`);\n }\n\n if (rules.updateRule !== undefined) {\n parts.push(`\"updateRule\": ${formatValue(rules.updateRule)}`);\n }\n\n if (rules.deleteRule !== undefined) {\n parts.push(`\"deleteRule\": ${formatValue(rules.deleteRule)}`);\n }\n\n if (collectionType === \"auth\" && rules.manageRule !== undefined) {\n parts.push(`\"manageRule\": ${formatValue(rules.manageRule)}`);\n }\n\n return parts.join(\",\\n \");\n}\n\n/**\n * Generates collection permissions object\n * Permissions are the same as rules but extracted from schema metadata\n *\n * @param permissions - Collection permissions\n * @returns Permissions configuration as string\n */\nexport function generateCollectionPermissions(\n permissions?: CollectionSchema[\"permissions\"],\n collectionType: string = \"base\"\n): string {\n if (!permissions) {\n return \"\";\n }\n\n // View collections are read-only: the write rules are always null and\n // manageRule is not applicable\n if (collectionType === \"view\") {\n return [\n `\"listRule\": ${formatValue(permissions.listRule ?? null)}`,\n `\"viewRule\": ${formatValue(permissions.viewRule ?? null)}`,\n `\"createRule\": null`,\n `\"updateRule\": null`,\n `\"deleteRule\": null`,\n ].join(\",\\n \");\n }\n\n const parts: string[] = [];\n\n if (permissions.listRule !== undefined) {\n parts.push(`\"listRule\": ${formatValue(permissions.listRule)}`);\n }\n\n if (permissions.viewRule !== undefined) {\n parts.push(`\"viewRule\": ${formatValue(permissions.viewRule)}`);\n }\n\n if (permissions.createRule !== undefined) {\n parts.push(`\"createRule\": ${formatValue(permissions.createRule)}`);\n }\n\n if (permissions.updateRule !== undefined) {\n parts.push(`\"updateRule\": ${formatValue(permissions.updateRule)}`);\n }\n\n if (permissions.deleteRule !== undefined) {\n parts.push(`\"deleteRule\": ${formatValue(permissions.deleteRule)}`);\n }\n\n if (collectionType === \"auth\" && permissions.manageRule !== undefined) {\n parts.push(`\"manageRule\": ${formatValue(permissions.manageRule)}`);\n }\n\n return parts.join(\",\\n \");\n}\n\n/**\n * Generates code for updating collection rules\n *\n * @param collectionName - Name of the collection\n * @param ruleType - Type of rule to update\n * @param newValue - New rule value\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for updating the rule\n */\nexport function generateRuleUpdate(\n collectionName: string,\n ruleType: string,\n newValue: string | null,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${ruleType}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for updating collection permissions\n * Handles permission rule updates including manageRule for auth collections\n *\n * @param collectionName - Name of the collection\n * @param ruleType - Type of permission rule to update\n * @param newValue - New permission rule value\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for updating the permission\n */\nexport function generatePermissionUpdate(\n collectionName: string,\n ruleType: string,\n newValue: string | null,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_${ruleType}`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for updating a view collection's SQL query\n *\n * Applied in place so the collection ID stays stable - PocketBase re-derives\n * the view's fields when the collection is saved.\n *\n * Uses unmarshal() rather than a direct `collection.viewQuery = ...`\n * assignment: viewQuery lives on an embedded struct in PocketBase's Go model,\n * and a direct assignment from the migration JS runtime is silently dropped.\n *\n * @param collectionName - Name of the view collection\n * @param viewQuery - The SQL query to set\n * @param varName - Variable name to use for the collection (default: auto-generated)\n * @param isLast - Whether this is the last operation (will return the result)\n * @param collectionIdMap - Map of collection names to IDs\n * @returns JavaScript code for updating the view query\n */\nexport function generateViewQueryUpdate(\n collectionName: string,\n viewQuery: string,\n varName?: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n const collectionVar = varName || `collection_${collectionName}_viewQuery`;\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` unmarshal({`);\n lines.push(` \"viewQuery\": ${formatSqlTemplate(viewQuery, \" \")},`);\n lines.push(` }, ${collectionVar})`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates a single unmarshal({...}, collection) block for multiple rule/permission changes.\n * Used when 2+ rules change at once to match PocketBase's native migration style.\n *\n * @param collectionName - Name of the collection\n * @param entries - Array of { ruleType, value } to include in the unmarshal object\n * @param varSuffix - Suffix for the variable name (e.g. \"rules\" or \"revert_rules\")\n * @param isLast - Whether this is the last operation (will use return app.save)\n * @param collectionIdMap - Map of collection names to IDs\n * @returns JavaScript code block\n */\nexport function generateGroupedRuleUpdates(\n collectionName: string,\n entries: Array<{ ruleType: string; value: string | null }>,\n varSuffix: string,\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const collectionVar = `collection_${collectionName}_${varSuffix}`;\n const lines: string[] = [];\n\n lines.push(` const ${collectionVar} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(` unmarshal({`);\n for (const entry of entries) {\n lines.push(` \"${entry.ruleType}\": ${formatValue(entry.value)},`);\n }\n lines.push(` }, ${collectionVar})`);\n lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionSchema } from \"../types\";\nimport { generateFieldsArray } from \"./fields\";\nimport { generateIndexesArray } from \"./indexes\";\nimport { generateCollectionPermissions, generateCollectionRules } from \"./rules\";\nimport {\n formatSqlTemplate,\n formatValue,\n generateFindCollectionCode,\n getAuthSystemFields,\n getAuthSystemIndexes,\n getSystemFields,\n getSystemTimestampFields,\n} from \"./utils\";\n\n/**\n * Generates Collection constructor call for creating a new collection\n *\n * @param collection - Collection schema\n * @param varName - Variable name to use for the collection (default: 'collection')\n * @returns JavaScript code for creating the collection\n */\nexport function generateCollectionCreation(\n collection: CollectionSchema,\n varName: string = \"collection\",\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n\n lines.push(` const ${varName} = new Collection({`);\n if (collection.id) {\n lines.push(` \"id\": ${formatValue(collection.id)},`);\n }\n lines.push(` \"name\": \"${collection.name}\",`);\n lines.push(` \"type\": \"${collection.type}\",`);\n lines.push(` \"system\": false,`);\n\n // Add permissions (preferred) or rules\n // Permissions take precedence if both are defined\n const permissionsCode = generateCollectionPermissions(collection.permissions, collection.type);\n const rulesCode = generateCollectionRules(collection.rules, collection.type);\n\n if (permissionsCode) {\n lines.push(` ${permissionsCode},`);\n } else if (rulesCode) {\n lines.push(` ${rulesCode},`);\n }\n\n // View collections are defined by their SQL query: PocketBase derives the\n // fields by running it, and views support neither fields nor indexes here\n if (collection.type === \"view\") {\n lines.push(` \"viewQuery\": ${formatSqlTemplate(collection.viewQuery ?? \"\")},`);\n lines.push(` });`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);\n\n return lines.join(\"\\n\");\n }\n\n // Filter out system fields (they will be added back in correct order)\n const systemFieldNames = [\"created\", \"updated\", \"id\"];\n if (collection.type === \"auth\") {\n systemFieldNames.push(...getAuthSystemFields().map((f) => f.name));\n }\n const userFields = collection.fields.filter((f) => !systemFieldNames.includes(f.name));\n\n // Build field list in correct order: id, [auth fields], user fields, created, updated\n const allFields = [...getSystemFields()];\n\n if (collection.type === \"auth\") {\n allFields.push(...getAuthSystemFields());\n }\n\n allFields.push(...userFields);\n allFields.push(...getSystemTimestampFields());\n\n // Add fields\n lines.push(` \"fields\": ${generateFieldsArray(allFields, collectionIdMap)},`);\n\n // Add indexes\n let allIndexes = [...(collection.indexes || [])];\n if (collection.type === \"auth\") {\n allIndexes = [...getAuthSystemIndexes(collection.name, collection.id), ...allIndexes];\n }\n lines.push(` \"indexes\": ${generateIndexesArray(allIndexes)},`);\n\n lines.push(` });`);\n lines.push(``);\n lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates code for deleting a collection\n *\n * @param collectionName - Name of the collection to delete\n * @param varName - Variable name to use for the collection (default: 'collection')\n * @param isLast - Whether this is the last operation (will return the result)\n * @returns JavaScript code for deleting the collection\n */\nexport function generateCollectionDeletion(\n collectionName: string,\n varName: string = \"collection\",\n isLast: boolean = false,\n collectionIdMap?: Map<string, string>\n): string {\n const lines: string[] = [];\n\n lines.push(` const ${varName} = ${generateFindCollectionCode(collectionName, collectionIdMap)};`);\n lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);\n\n return lines.join(\"\\n\");\n}\n","import type { CollectionOperation, CollectionSchema, FieldModification, SchemaDiff } from \"../types\";\nimport { generateCollectionCreation, generateCollectionDeletion } from \"./collections\";\nimport { generateFieldAddition, generateFieldDeletion, generateFieldModification } from \"./fields\";\nimport { generateIndexAddition, generateIndexRemoval } from \"./indexes\";\nimport { generateGroupedRuleUpdates, generatePermissionUpdate, generateRuleUpdate, generateViewQueryUpdate } from \"./rules\";\n\n/**\n * Generates the up migration code for a single collection operation\n * Handles create, modify, and delete operations\n *\n * @param operation - Collection operation to generate migration for\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for up migration\n */\nexport function generateOperationUpMigration(\n operation: CollectionOperation,\n collectionIdMap: Map<string, string>\n): string {\n const lines: string[] = [];\n\n if (operation.type === \"create\") {\n // Handle collection creation\n const collection = operation.collection as CollectionSchema;\n const varName = \"collection\";\n lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));\n } else if (operation.type === \"modify\") {\n // Handle collection modification\n const modification = operation.modifications!;\n const collectionName =\n typeof operation.collection === \"string\"\n ? operation.collection\n : (operation.collection?.name ?? modification.collection);\n\n let operationCount = 0;\n const totalOperations =\n modification.fieldsToAdd.length +\n modification.fieldsToModify.length +\n modification.fieldsToRemove.length +\n modification.indexesToAdd.length +\n modification.indexesToRemove.length +\n (modification.viewQueryUpdate ? 1 : 0) +\n (modification.permissionsToUpdate.length > 0 ? 1 : modification.rulesToUpdate.length > 0 ? 1 : 0);\n\n // Update the view query (view collections only)\n if (modification.viewQueryUpdate) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.newValue,\n undefined,\n isLast,\n collectionIdMap\n )\n );\n if (!isLast) lines.push(\"\");\n }\n\n // Add new fields\n for (let i = 0; i < modification.fieldsToAdd.length; i++) {\n const field = modification.fieldsToAdd[i];\n operationCount++;\n const varName = `collection_${collectionName}_add_${field.name}_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Modify existing fields\n for (const fieldMod of modification.fieldsToModify) {\n operationCount++;\n const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Remove fields\n for (const field of modification.fieldsToRemove) {\n operationCount++;\n const varName = `collection_${collectionName}_remove_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Add indexes\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n operationCount++;\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_addidx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexAddition(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Remove indexes\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n operationCount++;\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_rmidx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexRemoval(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Update permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", isLast, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n } else if (modification.rulesToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", isLast, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n }\n } else if (operation.type === \"delete\") {\n // Handle collection deletion\n const collectionName = typeof operation.collection === \"string\" ? operation.collection : operation.collection.name;\n const varName = \"collection\";\n lines.push(generateCollectionDeletion(collectionName, varName, true, collectionIdMap));\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the down migration code for a single collection operation\n * Reverts the operation (inverse of up migration)\n *\n * @param operation - Collection operation to generate rollback for\n * @param collectionIdMap - Map of collection names to their pre-generated IDs\n * @returns JavaScript code for down migration\n */\nexport function generateOperationDownMigration(\n operation: CollectionOperation,\n collectionIdMap: Map<string, string>\n): string {\n const lines: string[] = [];\n\n if (operation.type === \"create\") {\n // Rollback: delete the created collection\n const collection = operation.collection as CollectionSchema;\n const varName = \"collection\";\n lines.push(generateCollectionDeletion(collection.name, varName, true, collectionIdMap));\n } else if (operation.type === \"modify\") {\n // Rollback: revert all modifications\n const modification = operation.modifications!;\n const collectionName =\n typeof operation.collection === \"string\"\n ? operation.collection\n : (operation.collection?.name ?? modification.collection);\n\n let operationCount = 0;\n const totalOperations =\n modification.fieldsToAdd.length +\n modification.fieldsToModify.length +\n modification.fieldsToRemove.length +\n modification.indexesToAdd.length +\n modification.indexesToRemove.length +\n (modification.viewQueryUpdate ? 1 : 0) +\n (modification.permissionsToUpdate.length > 0 ? 1 : modification.rulesToUpdate.length > 0 ? 1 : 0);\n\n // Restore the previous view query (view collections only)\n if (modification.viewQueryUpdate) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.oldValue ?? \"\",\n `collection_${collectionName}_revert_viewQuery`,\n isLast,\n collectionIdMap\n )\n );\n if (!isLast) lines.push(\"\");\n }\n\n // Revert permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", isLast, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n } else if (modification.rulesToUpdate.length > 0) {\n operationCount++;\n const isLast = operationCount === totalOperations;\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", isLast, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast, collectionIdMap));\n }\n if (!isLast) lines.push(\"\");\n }\n\n // Revert index removals (add them back)\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n operationCount++;\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_restore_idx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexAddition(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert index additions (remove them)\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n operationCount++;\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_revert_idx_${i}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateIndexRemoval(collectionName, index, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field removals (add them back)\n for (const field of modification.fieldsToRemove) {\n operationCount++;\n const varName = `collection_${collectionName}_restore_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field modifications\n for (const fieldMod of modification.fieldsToModify) {\n operationCount++;\n // Create a reverse modification\n const reverseChanges = fieldMod.changes.map((change) => ({\n property: change.property,\n oldValue: change.newValue,\n newValue: change.oldValue,\n }));\n\n const reverseMod: FieldModification = {\n fieldName: fieldMod.fieldName,\n currentDefinition: fieldMod.newDefinition,\n newDefinition: fieldMod.currentDefinition,\n changes: reverseChanges,\n };\n\n const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n\n // Revert field additions (remove them)\n for (const field of modification.fieldsToAdd) {\n operationCount++;\n const varName = `collection_${collectionName}_revert_add_${field.name}`;\n const isLast = operationCount === totalOperations;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast, collectionIdMap));\n if (!isLast) lines.push(\"\");\n }\n } else if (operation.type === \"delete\") {\n // Rollback: recreate the deleted collection\n const collection = operation.collection;\n if (typeof collection !== \"string\") {\n const varName = \"collection\";\n lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));\n }\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the up migration function code\n * Applies all changes from the diff in the correct order\n *\n * @param diff - Schema diff containing all changes\n * @returns JavaScript code for up migration\n */\nexport function generateUpMigration(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Add comment header\n lines.push(` // UP MIGRATION`);\n lines.push(``);\n\n // Build collection ID map from collections being created and existing collections\n // This map will be used to resolve relation field references\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // 1. Create new collections\n if (diff.collectionsToCreate.length > 0) {\n lines.push(` // Create new collections`);\n for (let i = 0; i < diff.collectionsToCreate.length; i++) {\n const collection = diff.collectionsToCreate[i];\n const varName = `collection_${collection.name}_create`;\n lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // 2. Modify existing collections\n if (diff.collectionsToModify.length > 0) {\n lines.push(` // Modify existing collections`);\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Update the view query (view collections only)\n if (modification.viewQueryUpdate) {\n lines.push(` // Update the view query of ${collectionName}`);\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.newValue,\n undefined,\n false,\n collectionIdMap\n )\n );\n lines.push(``);\n }\n\n // Add new fields\n if (modification.fieldsToAdd.length > 0) {\n lines.push(` // Add fields to ${collectionName}`);\n for (let i = 0; i < modification.fieldsToAdd.length; i++) {\n const field = modification.fieldsToAdd[i];\n const varName = `collection_${collectionName}_add_${field.name}_${i}`;\n lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Modify existing fields\n if (modification.fieldsToModify.length > 0) {\n lines.push(` // Modify fields in ${collectionName}`);\n for (const fieldMod of modification.fieldsToModify) {\n const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;\n lines.push(generateFieldModification(collectionName, fieldMod, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Remove fields\n if (modification.fieldsToRemove.length > 0) {\n lines.push(` // Remove fields from ${collectionName}`);\n for (const field of modification.fieldsToRemove) {\n const varName = `collection_${collectionName}_remove_${field.name}`;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Add indexes\n if (modification.indexesToAdd.length > 0) {\n lines.push(` // Add indexes to ${collectionName}`);\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_addidx_${i}`;\n lines.push(generateIndexAddition(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Remove indexes\n if (modification.indexesToRemove.length > 0) {\n lines.push(` // Remove indexes from ${collectionName}`);\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_rmidx_${i}`;\n lines.push(generateIndexRemoval(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Update permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n lines.push(` // Update permissions for ${collectionName}`);\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", false, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n } else if (modification.rulesToUpdate.length > 0) {\n lines.push(` // Update rules for ${collectionName}`);\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.newValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"rules\", false, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n }\n }\n }\n\n // 3. Delete collections\n if (diff.collectionsToDelete.length > 0) {\n lines.push(` // Delete collections`);\n for (let i = 0; i < diff.collectionsToDelete.length; i++) {\n const collection = diff.collectionsToDelete[i];\n const varName = `collection_${collection.name}_delete`;\n lines.push(generateCollectionDeletion(collection.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // If no changes, add a comment\n if (lines.length === 2) {\n lines.push(` // No changes detected`);\n lines.push(``);\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n\n/**\n * Generates the down migration function code\n * Reverts all changes from the diff in reverse order\n *\n * @param diff - Schema diff containing all changes\n * @returns JavaScript code for down migration\n */\nexport function generateDownMigration(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Add comment header\n lines.push(` // DOWN MIGRATION (ROLLBACK)`);\n lines.push(``);\n\n // Build collection ID map from collections being created (for rollback)\n // This map will be used to resolve relation field references\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Also include deleted collections that might have IDs\n for (const collection of diff.collectionsToDelete) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // Reverse order: delete -> modify -> create\n\n // 1. Recreate deleted collections\n if (diff.collectionsToDelete.length > 0) {\n lines.push(` // Recreate deleted collections`);\n for (let i = 0; i < diff.collectionsToDelete.length; i++) {\n const collection = diff.collectionsToDelete[i];\n const varName = `collection_${collection.name}_recreate`;\n lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // 2. Revert modifications (in reverse order)\n if (diff.collectionsToModify.length > 0) {\n lines.push(` // Revert modifications`);\n for (const modification of diff.collectionsToModify) {\n const collectionName = modification.collection;\n\n // Restore the previous view query (view collections only)\n if (modification.viewQueryUpdate) {\n lines.push(` // Restore the view query of ${collectionName}`);\n lines.push(\n generateViewQueryUpdate(\n collectionName,\n modification.viewQueryUpdate.oldValue ?? \"\",\n `collection_${collectionName}_revert_viewQuery`,\n false,\n collectionIdMap\n )\n );\n lines.push(``);\n }\n\n // Revert permissions (preferred) or rules (fallback)\n if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {\n lines.push(` // Revert permissions for ${collectionName}`);\n if (modification.permissionsToUpdate.length >= 2) {\n const entries = modification.permissionsToUpdate.map((p) => ({ ruleType: p.ruleType, value: p.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", false, collectionIdMap));\n } else {\n const permission = modification.permissionsToUpdate[0];\n const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;\n lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n } else if (modification.rulesToUpdate.length > 0) {\n lines.push(` // Revert rules for ${collectionName}`);\n if (modification.rulesToUpdate.length >= 2) {\n const entries = modification.rulesToUpdate.map((r) => ({ ruleType: r.ruleType, value: r.oldValue }));\n lines.push(generateGroupedRuleUpdates(collectionName, entries, \"revert_rules\", false, collectionIdMap));\n } else {\n const rule = modification.rulesToUpdate[0];\n const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;\n lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, false, collectionIdMap));\n }\n lines.push(``);\n }\n\n // Revert index removals (add them back)\n if (modification.indexesToRemove.length > 0) {\n lines.push(` // Restore indexes to ${collectionName}`);\n for (let i = 0; i < modification.indexesToRemove.length; i++) {\n const index = modification.indexesToRemove[i];\n const varName = `collection_${collectionName}_restore_idx_${i}`;\n lines.push(generateIndexAddition(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert index additions (remove them)\n if (modification.indexesToAdd.length > 0) {\n lines.push(` // Remove indexes from ${collectionName}`);\n for (let i = 0; i < modification.indexesToAdd.length; i++) {\n const index = modification.indexesToAdd[i];\n const varName = `collection_${collectionName}_revert_idx_${i}`;\n lines.push(generateIndexRemoval(collectionName, index, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field removals (add them back)\n if (modification.fieldsToRemove.length > 0) {\n lines.push(` // Restore fields to ${collectionName}`);\n for (const field of modification.fieldsToRemove) {\n const varName = `collection_${collectionName}_restore_${field.name}`;\n lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field modifications\n if (modification.fieldsToModify.length > 0) {\n lines.push(` // Revert field modifications in ${collectionName}`);\n for (const fieldMod of modification.fieldsToModify) {\n // Create a reverse modification\n const reverseChanges = fieldMod.changes.map((change) => ({\n property: change.property,\n oldValue: change.newValue,\n newValue: change.oldValue,\n }));\n\n const reverseMod: FieldModification = {\n fieldName: fieldMod.fieldName,\n currentDefinition: fieldMod.newDefinition,\n newDefinition: fieldMod.currentDefinition,\n changes: reverseChanges,\n };\n\n const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;\n lines.push(generateFieldModification(collectionName, reverseMod, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // Revert field additions (remove them)\n if (modification.fieldsToAdd.length > 0) {\n lines.push(` // Remove added fields from ${collectionName}`);\n for (const field of modification.fieldsToAdd) {\n const varName = `collection_${collectionName}_revert_add_${field.name}`;\n lines.push(generateFieldDeletion(collectionName, field.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n }\n }\n\n // 3. Delete created collections\n if (diff.collectionsToCreate.length > 0) {\n lines.push(` // Delete created collections`);\n for (let i = 0; i < diff.collectionsToCreate.length; i++) {\n const collection = diff.collectionsToCreate[i];\n const varName = `collection_${collection.name}_rollback`;\n lines.push(generateCollectionDeletion(collection.name, varName, false, collectionIdMap));\n lines.push(``);\n }\n }\n\n // If no changes, add a comment\n if (lines.length === 2) {\n lines.push(` // No changes to revert`);\n lines.push(``);\n }\n\n let code = lines.join(\"\\n\");\n\n // Check if there's already a return statement in the code\n // If so, skip post-processing to avoid duplicate returns\n const hasReturnStatement = /return\\s+app\\.(save|delete)\\(/m.test(code);\n\n if (!hasReturnStatement) {\n // Find the last app.save() or app.delete() call and make it return the result\n // Match app.save(...) or app.delete(...) at the end of lines (not in comments or strings)\n const savePattern = /^(\\s*)app\\.save\\((\\w+)\\);$/gm;\n const deletePattern = /^(\\s*)app\\.delete\\((\\w+)\\);$/gm;\n\n const saveMatches = [...code.matchAll(savePattern)];\n const deleteMatches = [...code.matchAll(deletePattern)];\n\n // Combine all matches and find the last one by position\n const allMatches = [\n ...saveMatches.map((m) => ({ match: m, type: \"save\", index: m.index! })),\n ...deleteMatches.map((m) => ({ match: m, type: \"delete\", index: m.index! })),\n ].sort((a, b) => b.index - a.index); // Sort descending to get last match first\n\n if (allMatches.length > 0) {\n const lastMatch = allMatches[0];\n if (lastMatch.type === \"save\") {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.save(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n } else {\n code =\n code.substring(0, lastMatch.match.index!) +\n lastMatch.match[1] +\n \"return app.delete(\" +\n lastMatch.match[2] +\n \");\" +\n code.substring(lastMatch.match.index! + lastMatch.match[0].length);\n }\n }\n }\n\n return code;\n}\n","import type { CollectionSchema } from \"../types\";\n\n/**\n * Sorts collections based on their relationship dependencies.\n * Collections that are referenced by others should be created first.\n *\n * @param collections - List of collections to sort\n * @returns Sorted list of collections\n */\nexport function sortCollectionsByDependency(collections: CollectionSchema[]): CollectionSchema[] {\n // Map collection names to schema objects for easy lookup\n const collectionMap = new Map<string, CollectionSchema>();\n collections.forEach((col) => collectionMap.set(col.name, col));\n\n // Build dependency graph\n // Adjacency list: dependency -> [dependents]\n // In this graph, an edge A -> B means A must be created before B.\n const adjList = new Map<string, string[]>();\n // In-degree: number of dependencies a collection has that are also in the list\n const inDegree = new Map<string, number>();\n\n // Initialize graph\n collections.forEach((col) => {\n adjList.set(col.name, []);\n inDegree.set(col.name, 0);\n });\n\n // Populate graph\n collections.forEach((col) => {\n col.fields.forEach((field) => {\n // Check if field is a relation\n if (field.relation) {\n const targetName = field.relation.collection;\n\n // We only care about dependencies on collections that are currently being created.\n // If the target collection is not in the list, it's assumed to already exist.\n if (collectionMap.has(targetName)) {\n // If self-reference, ignore for topological sort (creation order doesn't matter strictly,\n // but usually we want to avoid cycles if possible. Self-ref is cycle size 1).\n if (targetName === col.name) {\n return;\n }\n\n // Edge: Target -> Collection (Target comes before Collection)\n adjList.get(targetName)?.push(col.name);\n inDegree.set(col.name, (inDegree.get(col.name) || 0) + 1);\n }\n }\n });\n });\n\n // Kahn's algorithm for topological sort\n const queue: string[] = [];\n const sortedResult: CollectionSchema[] = [];\n\n // Add all nodes with in-degree 0 to queue\n inDegree.forEach((degree, name) => {\n if (degree === 0) {\n queue.push(name);\n }\n });\n\n // Process queue\n while (queue.length > 0) {\n const currentName = queue.shift()!;\n const currentCollection = collectionMap.get(currentName);\n\n if (currentCollection) {\n sortedResult.push(currentCollection);\n }\n\n const neighbors = adjList.get(currentName) || [];\n for (const neighbor of neighbors) {\n inDegree.set(neighbor, (inDegree.get(neighbor) || 0) - 1);\n if (inDegree.get(neighbor) === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Check for cycles\n if (sortedResult.length !== collections.length) {\n const remainingCount = collections.length - sortedResult.length;\n console.warn(\n `Warning: Circular dependencies detected involving ${remainingCount} collections. ` +\n `Migrations may fail if strict foreign key checks are enabled. ` +\n `Check your schema for circular relations.`\n );\n\n // Append remaining collections (those involved in cycles)\n // We can't determine a perfect order, so we append them in their original order\n // (excluding those already sorted)\n const sortedNames = new Set(sortedResult.map((c) => c.name));\n collections.forEach((col) => {\n if (!sortedNames.has(col.name)) {\n sortedResult.push(col);\n }\n });\n }\n\n return sortedResult;\n}\n","import type { CollectionOperation, SchemaDiff } from \"../types\";\nimport { sortCollectionsByDependency } from \"../utils\";\nimport { type MigrationGeneratorConfig } from \"./config\";\nimport { generateTimestamp } from \"./utils\";\n\n/**\n * Splits a SchemaDiff into individual collection operations\n * Each operation will generate a separate migration file\n *\n * @param diff - Schema diff containing all changes\n * @param baseTimestamp - Base timestamp for the first operation\n * @returns Array of collection operations\n */\nexport function splitDiffByCollection(diff: SchemaDiff, baseTimestamp: string): CollectionOperation[] {\n const operations: CollectionOperation[] = [];\n let currentTimestamp = parseInt(baseTimestamp, 10);\n\n // Split collectionsToCreate into individual operations\n // Sort collections by dependency to ensure collections are created in the correct order\n const sortedCollections = sortCollectionsByDependency(diff.collectionsToCreate);\n for (const collection of sortedCollections) {\n operations.push({\n type: \"create\",\n collection: collection,\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n // Split collectionsToModify into individual operations\n for (const modification of diff.collectionsToModify) {\n operations.push({\n type: \"modify\",\n collection: modification.collection,\n modifications: modification,\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n // Split collectionsToDelete into individual operations\n for (const collection of diff.collectionsToDelete) {\n operations.push({\n type: \"delete\",\n collection: collection, // Handle both object and string\n timestamp: currentTimestamp.toString(),\n });\n currentTimestamp += 1; // Increment by 1 second\n }\n\n return operations;\n}\n\n/**\n * Generates migration filename for a collection operation\n * Format: {timestamp}_{operation}_{collection_name}.js\n *\n * @param operation - Collection operation\n * @returns Migration filename\n */\nexport function generateCollectionMigrationFilename(operation: CollectionOperation): string {\n const timestamp = operation.timestamp;\n const operationType = operation.type === \"modify\" ? \"updated\" : operation.type === \"create\" ? \"created\" : \"deleted\";\n\n // Get collection name\n let collectionName: string;\n if (typeof operation.collection === \"string\") {\n collectionName = operation.collection;\n } else {\n collectionName = operation.collection.name;\n }\n\n // Sanitize collection name for filename (replace spaces and special chars with underscores)\n const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\n return `${timestamp}_${operationType}_${sanitizedName}.js`;\n}\n\n/**\n * Generates a human-readable description from the diff\n * Creates a concise summary of the main changes\n *\n * @param diff - Schema diff containing all changes\n * @returns Description string for filename\n */\nexport function generateMigrationDescription(diff: SchemaDiff): string {\n const parts: string[] = [];\n\n // Summarize collection changes\n if (diff.collectionsToCreate.length > 0) {\n if (diff.collectionsToCreate.length === 1) {\n parts.push(`created_${diff.collectionsToCreate[0].name}`);\n } else {\n parts.push(`created_${diff.collectionsToCreate.length}_collections`);\n }\n }\n\n if (diff.collectionsToDelete.length > 0) {\n if (diff.collectionsToDelete.length === 1) {\n parts.push(`deleted_${diff.collectionsToDelete[0].name}`);\n } else {\n parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);\n }\n }\n\n if (diff.collectionsToModify.length > 0) {\n if (diff.collectionsToModify.length === 1) {\n parts.push(`updated_${diff.collectionsToModify[0].collection}`);\n } else {\n parts.push(`updated_${diff.collectionsToModify.length}_collections`);\n }\n }\n\n // Default description if no changes\n if (parts.length === 0) {\n return \"no_changes\";\n }\n\n // Join parts with underscores and limit length\n let description = parts.join(\"_\");\n\n // Truncate if too long (keep under 100 chars for filename)\n if (description.length > 80) {\n description = description.substring(0, 77) + \"...\";\n }\n\n return description;\n}\n\n/**\n * Generates the migration filename\n * Format: {timestamp}_{description}.js\n *\n * @param diff - Schema diff containing all changes\n * @param config - Optional configuration\n * @returns Migration filename\n */\nexport function generateMigrationFilename(diff: SchemaDiff, config?: MigrationGeneratorConfig): string {\n const timestamp = generateTimestamp(config);\n const description = generateMigrationDescription(diff);\n\n return `${timestamp}_${description}.js`;\n}\n","/**\n * Migration Generator component\n * Creates PocketBase migration files based on detected differences\n *\n * This module provides a standalone, configurable migration generator that can be used\n * by consumer projects to generate PocketBase-compatible migration files.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { FileSystemError, MigrationGenerationError } from \"../errors\";\nimport type { CollectionOperation, SchemaDiff } from \"../types\";\nimport { mergeConfig, type MigrationGeneratorConfig } from \"./config\";\nimport { createMigrationFileStructure, resolveMigrationDir, writeMigrationFile } from \"./file-writer\";\nimport {\n generateDownMigration,\n generateOperationDownMigration,\n generateOperationUpMigration,\n generateUpMigration,\n} from \"./migrator\";\nimport { generateCollectionMigrationFilename, generateMigrationFilename, splitDiffByCollection } from \"./operations\";\nimport { generateTimestamp } from \"./utils\";\n\n// Export everything from submodules\nexport * from \"./collections\";\nexport * from \"./config\";\nexport * from \"./fields\";\nexport * from \"./file-writer\";\nexport * from \"./indexes\";\nexport * from \"./migrator\";\nexport * from \"./operations\";\nexport * from \"./rules\";\nexport * from \"./utils\";\n\n/**\n * A migration file that has been generated but not yet written to disk\n */\nexport interface PlannedMigration {\n /** Filename the migration will be written as */\n filename: string;\n /** Complete migration file content */\n content: string;\n /** The collection operation this file was generated from */\n operation: CollectionOperation;\n}\n\n/**\n * Generates migration file contents from a schema diff without writing them\n *\n * Splitting planning from writing lets callers inspect or verify a migration\n * before it lands in the migrations directory — see the engine's\n * `verifyMigrationSources`, which the CLI's `generate --verify` runs over the\n * plan and aborts on.\n *\n * @param diff - Schema diff containing all changes\n * @param config - Migration generator configuration\n * @returns One planned migration per collection operation, in dependency order\n */\nexport function planMigrations(diff: SchemaDiff, config: MigrationGeneratorConfig | string): PlannedMigration[] {\n // Support legacy string-only parameter (migration directory)\n const normalizedConfig: MigrationGeneratorConfig = typeof config === \"string\" ? { migrationDir: config } : config;\n\n try {\n const migrationDir = resolveMigrationDir(normalizedConfig);\n\n // Check if there are any changes\n const hasChanges =\n diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;\n\n // If no changes, return empty array\n if (!hasChanges) {\n return [];\n }\n\n // Build collection ID map from collections being created\n const collectionIdMap = new Map<string, string>();\n for (const collection of diff.collectionsToCreate) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Also include deleted collections that might have IDs (for rollback)\n for (const collection of diff.collectionsToDelete) {\n if (collection.id) {\n collectionIdMap.set(collection.name, collection.id);\n }\n }\n // Add existing collection IDs from snapshot (for relation fields referencing existing collections)\n if (diff.existingCollectionIds) {\n for (const [name, id] of diff.existingCollectionIds) {\n collectionIdMap.set(name, id);\n }\n }\n\n // Generate base timestamp\n const baseTimestamp = generateTimestamp(normalizedConfig);\n\n // Split diff into individual collection operations\n const operations = splitDiffByCollection(diff, baseTimestamp);\n\n // Generate migration file for each operation\n const planned: PlannedMigration[] = [];\n\n // Read existing files for duplicate check\n let existingFiles: string[] = [];\n if (!normalizedConfig.force && fs.existsSync(migrationDir)) {\n existingFiles = fs\n .readdirSync(migrationDir)\n .filter((f) => f.endsWith(\".js\") || f.endsWith(\".ts\"))\n .map((f) => fs.readFileSync(path.join(migrationDir, f), \"utf-8\"));\n }\n\n for (const operation of operations) {\n // Generate up and down migration code for this operation\n const upCode = generateOperationUpMigration(operation, collectionIdMap);\n const downCode = generateOperationDownMigration(operation, collectionIdMap);\n\n // Create migration file structure\n const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);\n\n // Check for duplicates\n if (!normalizedConfig.force && existingFiles.some((existingContent) => existingContent === content)) {\n console.warn(\n `Duplicate migration detected for ${operation.type} ${\n typeof operation.collection === \"string\" ? operation.collection : operation.collection.name\n }. Skipping...`\n );\n continue;\n }\n\n // Generate filename for this operation\n const filename = generateCollectionMigrationFilename(operation);\n\n planned.push({ filename, content, operation });\n }\n\n return planned;\n } catch (error) {\n // If it's already a MigrationGenerationError or FileSystemError, re-throw it\n if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {\n throw error;\n }\n\n // Otherwise, wrap it in a MigrationGenerationError\n throw new MigrationGenerationError(\n `Failed to generate migration: ${error instanceof Error ? error.message : String(error)}`,\n normalizedConfig.migrationDir,\n error as Error\n );\n }\n}\n\n/**\n * Main generation function\n * Generates migration files from schema diff (one file per collection operation)\n *\n * @param diff - Schema diff containing all changes\n * @param config - Migration generator configuration\n * @returns Array of paths to the generated migration files\n */\nexport function generate(diff: SchemaDiff, config: MigrationGeneratorConfig | string): string[] {\n const normalizedConfig: MigrationGeneratorConfig = typeof config === \"string\" ? { migrationDir: config } : config;\n const planned = planMigrations(diff, normalizedConfig);\n\n if (planned.length === 0) {\n return [];\n }\n\n const migrationDir = resolveMigrationDir(normalizedConfig);\n return writePlannedMigrations(planned, migrationDir);\n}\n\n/**\n * Writes planned migrations to disk, in order\n *\n * @param planned - Migrations produced by planMigrations()\n * @param migrationDir - Absolute path to the migrations directory\n * @returns Array of paths to the written files\n */\nexport function writePlannedMigrations(planned: PlannedMigration[], migrationDir: string): string[] {\n return planned.map((migration) => writeMigrationFile(migrationDir, migration.filename, migration.content));\n}\n\n/**\n * MigrationGenerator class for object-oriented usage\n * Provides a stateful interface for migration generation\n */\nexport class MigrationGenerator {\n private config: Required<MigrationGeneratorConfig>;\n\n constructor(config: MigrationGeneratorConfig) {\n this.config = mergeConfig(config);\n }\n\n /**\n * Generates migration files from a schema diff\n * Returns array of file paths (one per collection operation)\n */\n generate(diff: SchemaDiff): string[] {\n return generate(diff, this.config);\n }\n\n /**\n * Generates the migration file contents without writing them, so they can\n * be inspected or verified first\n */\n plan(diff: SchemaDiff): PlannedMigration[] {\n return planMigrations(diff, this.config);\n }\n\n /**\n * Generates the up migration code without writing to file\n */\n generateUpMigration(diff: SchemaDiff): string {\n return generateUpMigration(diff);\n }\n\n /**\n * Generates the down migration code without writing to file\n */\n generateDownMigration(diff: SchemaDiff): string {\n return generateDownMigration(diff);\n }\n\n /**\n * Generates a migration filename\n */\n generateMigrationFilename(diff: SchemaDiff): string {\n return generateMigrationFilename(diff, this.config);\n }\n}\n","/**\n * goja-compatibility lint\n *\n * The engine executes migrations with Node's JavaScript, a superset of the\n * goja dialect PocketBase actually runs. That gap is silent: a migration can\n * replay perfectly here, pass verification, and still fail the moment\n * `pocketbase migrate up` reaches it — because it referenced a Node global,\n * used class fields, or awaited a promise in a runtime with no event loop.\n *\n * This pass closes the gap statically. It parses the file with acorn and\n * reports:\n *\n * - `unknown-global` — a free identifier that is neither declared in the file\n * nor part of the PocketBase JSVM surface (the sandbox globals) or the\n * ECMAScript library goja implements. `require`, `process`, `Buffer`,\n * `fetch`, `setTimeout` all land here.\n * - `unsupported-syntax` — constructs goja's parser rejects: class fields,\n * private members, static blocks, BigInt literals, `import.meta`.\n * - `module-syntax` — `import`/`export`; migrations are scripts.\n * - `async` — `async`/`await`/`Promise`. goja runs migrations synchronously,\n * so an awaited promise never settles.\n * - `unsupported-api` — folded in from execution warnings: a call that\n * resolved to an inert stub did nothing here and will do something (or\n * throw) in production.\n */\n\nimport * as acorn from \"acorn\";\nimport * as fs from \"fs\";\nimport { buildSandbox } from \"./globals\";\nimport type { EngineWarning } from \"./types\";\n\nexport type GojaLintRule =\n | \"syntax\"\n | \"unsupported-syntax\"\n | \"module-syntax\"\n | \"async\"\n | \"unknown-global\"\n | \"unsupported-api\";\n\nexport type GojaLintSeverity = \"error\" | \"warning\";\n\nexport interface GojaLintFinding {\n rule: GojaLintRule;\n severity: GojaLintSeverity;\n message: string;\n file?: string;\n line?: number;\n column?: number;\n}\n\nexport interface GojaLintResult {\n file: string;\n findings: GojaLintFinding[];\n /** No error-severity findings */\n ok: boolean;\n}\n\nexport interface GojaLintOptions {\n /** Path or name used in messages */\n file?: string;\n /**\n * Extra globals to treat as available — for a PocketBase build that\n * registers its own JSVM bindings.\n */\n allowedGlobals?: string[];\n /**\n * Engine warnings from executing the same file. `unsupported-api` entries\n * become findings, which is how a stubbed call gets surfaced prominently\n * instead of being buried in replay output.\n */\n warnings?: EngineWarning[];\n}\n\n/**\n * The ECMAScript library goja implements. Deliberately excludes the ones it\n * does not: BigInt, WeakRef, FinalizationRegistry, Atomics,\n * SharedArrayBuffer, Intl.\n */\nconst ECMASCRIPT_GLOBALS = [\n \"Array\",\n \"ArrayBuffer\",\n \"Boolean\",\n \"DataView\",\n \"Date\",\n \"Error\",\n \"EvalError\",\n \"Float32Array\",\n \"Float64Array\",\n \"Function\",\n \"Infinity\",\n \"Int16Array\",\n \"Int32Array\",\n \"Int8Array\",\n \"JSON\",\n \"Map\",\n \"Math\",\n \"NaN\",\n \"Number\",\n \"Object\",\n \"Proxy\",\n \"RangeError\",\n \"ReferenceError\",\n \"Reflect\",\n \"RegExp\",\n \"Set\",\n \"String\",\n \"Symbol\",\n \"SyntaxError\",\n \"TypeError\",\n \"URIError\",\n \"Uint16Array\",\n \"Uint32Array\",\n \"Uint8Array\",\n \"Uint8ClampedArray\",\n \"WeakMap\",\n \"WeakSet\",\n \"decodeURI\",\n \"decodeURIComponent\",\n \"encodeURI\",\n \"encodeURIComponent\",\n \"escape\",\n \"eval\",\n \"globalThis\",\n \"isFinite\",\n \"isNaN\",\n \"parseFloat\",\n \"parseInt\",\n \"undefined\",\n \"unescape\",\n];\n\n/**\n * PocketBase JSVM bindings that exist at runtime but are not part of the\n * simulation's sandbox, so referencing them is valid even though the engine\n * would stub them.\n */\nconst POCKETBASE_GLOBALS = [\n \"$apis\",\n \"$tokens\",\n \"__hooks\",\n \"arrayOf\",\n \"readerToString\",\n \"sleep\",\n \"toString\",\n \"Cookie\",\n \"DynamicModel\",\n \"FieldsList\",\n \"MailerMessage\",\n \"RequestInfo\",\n \"SubscriptionMessage\",\n \"ValidationError\",\n];\n\n/**\n * `Promise` is real in goja but useless in a migration: nothing drains the\n * job queue, so a `.then` never runs. Reported by the async rule rather than\n * as an unknown global.\n */\nconst ASYNC_GLOBALS = new Set([\"Promise\"]);\n\n/** Node/browser globals absent from goja, named so the message can say why */\nconst KNOWN_FOREIGN_GLOBALS: Record<string, string> = {\n Buffer: \"Node.js\",\n TextDecoder: \"Node.js\",\n TextEncoder: \"Node.js\",\n URL: \"Node.js/browser\",\n URLSearchParams: \"Node.js/browser\",\n __dirname: \"Node.js (CommonJS)\",\n __filename: \"Node.js (CommonJS)\",\n atob: \"browser\",\n btoa: \"browser\",\n clearInterval: \"Node.js/browser\",\n clearTimeout: \"Node.js/browser\",\n document: \"browser\",\n exports: \"Node.js (CommonJS)\",\n fetch: \"Node.js/browser\",\n global: \"Node.js\",\n localStorage: \"browser\",\n module: \"Node.js (CommonJS)\",\n process: \"Node.js\",\n queueMicrotask: \"Node.js/browser\",\n require: \"Node.js (CommonJS)\",\n setInterval: \"Node.js/browser\",\n setTimeout: \"Node.js/browser\",\n structuredClone: \"Node.js/browser\",\n window: \"browser\",\n};\n\n/** The globals the simulation itself installs — the PocketBase JSVM surface */\nlet sandboxGlobalsCache: string[] | null = null;\n\nfunction sandboxGlobals(): string[] {\n if (!sandboxGlobalsCache) {\n const { sandbox } = buildSandbox({}, () => {});\n sandboxGlobalsCache = Object.keys(sandbox);\n }\n return sandboxGlobalsCache;\n}\n\n/** The identifiers a migration may reference without declaring them */\nexport function availableGlobals(extra: string[] = []): Set<string> {\n return new Set([...ECMASCRIPT_GLOBALS, ...POCKETBASE_GLOBALS, ...sandboxGlobals(), ...extra]);\n}\n\nexport function lintMigrationSource(source: string, options: GojaLintOptions = {}): GojaLintResult {\n const file = options.file ?? \"<migration>\";\n const findings: GojaLintFinding[] = [];\n const at = (node: { loc?: acorn.SourceLocation | null }) => ({\n file,\n line: node.loc?.start.line,\n column: node.loc?.start.column,\n });\n\n const parsed = parseForLint(source);\n if (parsed.kind === \"failed\") {\n findings.push({\n rule: \"syntax\",\n severity: \"error\",\n message: `Not valid JavaScript: ${parsed.message}`,\n file,\n line: parsed.line,\n column: parsed.column,\n });\n return finish(file, findings, options.warnings);\n }\n\n if (parsed.kind === \"module\") {\n findings.push({\n rule: \"module-syntax\",\n severity: \"error\",\n message:\n \"import/export are not available in PocketBase migrations — they run as scripts in goja, not as ES modules\",\n file,\n });\n }\n\n if (parsed.kind === \"beyond-target\") {\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: `Syntax beyond what goja parses: ${parsed.message}`,\n file,\n line: parsed.line,\n column: parsed.column,\n });\n }\n\n const program = parsed.program;\n const declared = collectDeclaredNames(program);\n const allowed = availableGlobals(options.allowedGlobals);\n\n walk(program, (node, parent, key) => {\n switch (node.type) {\n case \"PropertyDefinition\":\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: \"Class fields are not supported by goja\",\n ...at(node),\n });\n break;\n case \"PrivateIdentifier\":\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: \"Private class members (#name) are not supported by goja\",\n ...at(node),\n });\n break;\n case \"StaticBlock\":\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: \"Class static initialization blocks are not supported by goja\",\n ...at(node),\n });\n break;\n case \"ImportExpression\":\n findings.push({\n rule: \"module-syntax\",\n severity: \"error\",\n message: \"Dynamic import() is not available in PocketBase migrations\",\n ...at(node),\n });\n break;\n case \"MetaProperty\":\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: \"import.meta is not available in PocketBase migrations\",\n ...at(node),\n });\n break;\n case \"AwaitExpression\":\n findings.push({\n rule: \"async\",\n severity: \"error\",\n message: \"await never settles in PocketBase migrations — goja runs them synchronously\",\n ...at(node),\n });\n break;\n case \"Literal\":\n if (typeof (node as acorn.Literal & { bigint?: string }).bigint === \"string\") {\n findings.push({\n rule: \"unsupported-syntax\",\n severity: \"error\",\n message: \"BigInt literals are not supported by goja\",\n ...at(node),\n });\n }\n break;\n case \"FunctionDeclaration\":\n case \"FunctionExpression\":\n case \"ArrowFunctionExpression\":\n if ((node as acorn.Function).async) {\n findings.push({\n rule: \"async\",\n severity: \"error\",\n message: \"async functions do not work in PocketBase migrations — goja runs them synchronously\",\n ...at(node),\n });\n }\n break;\n case \"ForOfStatement\":\n if ((node as acorn.ForOfStatement).await) {\n findings.push({\n rule: \"async\",\n severity: \"error\",\n message: \"for await...of is not supported by goja\",\n ...at(node),\n });\n }\n break;\n case \"Identifier\": {\n if (!isReference(parent, key)) {\n break;\n }\n const name = (node as acorn.Identifier).name;\n if (declared.has(name) || allowed.has(name)) {\n break;\n }\n if (ASYNC_GLOBALS.has(name)) {\n findings.push({\n rule: \"async\",\n severity: \"error\",\n message: `${name} is unusable in a PocketBase migration — nothing drains the job queue, so callbacks never run`,\n ...at(node),\n });\n break;\n }\n const origin = KNOWN_FOREIGN_GLOBALS[name];\n findings.push({\n rule: \"unknown-global\",\n severity: \"error\",\n message: origin\n ? `${name} is a ${origin} global and does not exist in PocketBase's JavaScript runtime`\n : `${name} is not declared in this file and is not part of the PocketBase JSVM surface`,\n ...at(node),\n });\n break;\n }\n default:\n break;\n }\n });\n\n return finish(file, dedupe(findings), options.warnings);\n}\n\nexport function lintMigrationFile(filePath: string, options: GojaLintOptions = {}): GojaLintResult {\n return lintMigrationSource(fs.readFileSync(filePath, \"utf-8\"), { ...options, file: options.file ?? filePath });\n}\n\nexport function lintMigrationFiles(files: string[], options: GojaLintOptions = {}): GojaLintResult[] {\n return files.map((file) => lintMigrationFile(file, { ...options, file }));\n}\n\n/** Turns engine execution warnings into findings */\nexport function gojaFindingsFromWarnings(warnings: EngineWarning[] = []): GojaLintFinding[] {\n return warnings\n .filter((warning) => warning.kind === \"unsupported-api\")\n .map((warning) => ({\n rule: \"unsupported-api\" as const,\n // The call did nothing in the simulation; in production it does\n // something the simulation did not model, which is worth reading but\n // is not by itself a goja incompatibility\n severity: \"warning\" as const,\n message: warning.message,\n file: warning.file,\n }));\n}\n\nexport function formatGojaLintFinding(finding: GojaLintFinding): string {\n const location = finding.line !== undefined ? `:${finding.line}:${(finding.column ?? 0) + 1}` : \"\";\n return `${finding.file ?? \"<migration>\"}${location} [${finding.rule}] ${finding.message}`;\n}\n\n// ---------------------------------------------------------------------------\n// Parsing\n// ---------------------------------------------------------------------------\n\n/**\n * goja's parser tracks ES2022 minus the class-member additions, which the\n * walk reports individually — so parsing at that level yields an AST for\n * almost everything and leaves genuinely newer syntax to fail here.\n */\nconst GOJA_ECMA_VERSION = 2022;\n\ntype ParseOutcome =\n | {\n kind: \"script\" | \"module\" | \"beyond-target\";\n program: acorn.Program;\n message?: string;\n line?: number;\n column?: number;\n }\n | { kind: \"failed\"; message: string; line?: number; column?: number };\n\nfunction parseForLint(source: string): ParseOutcome {\n const base: acorn.Options = { ecmaVersion: GOJA_ECMA_VERSION, locations: true, allowHashBang: true };\n\n try {\n return { kind: \"script\", program: acorn.parse(source, { ...base, sourceType: \"script\" }) };\n } catch (scriptError) {\n // import/export only parse as a module — reporting that specifically is\n // far more useful than \"unexpected token\"\n try {\n return { kind: \"module\", program: acorn.parse(source, { ...base, sourceType: \"module\" }) };\n } catch {\n // Fall through: not a module problem\n }\n\n try {\n const program = acorn.parse(source, { ecmaVersion: \"latest\", locations: true, sourceType: \"script\" });\n return { kind: \"beyond-target\", program, ...describeParseError(scriptError) };\n } catch (latestError) {\n return { kind: \"failed\", ...describeParseError(latestError) };\n }\n }\n}\n\nfunction describeParseError(error: unknown): { message: string; line?: number; column?: number } {\n const syntaxError = error as { message?: string; loc?: { line: number; column: number } };\n return {\n message: syntaxError?.message ?? String(error),\n line: syntaxError?.loc?.line,\n column: syntaxError?.loc?.column,\n };\n}\n\n// ---------------------------------------------------------------------------\n// AST traversal\n// ---------------------------------------------------------------------------\n\ntype AnyNode = acorn.Node & Record<string, any>;\n\nfunction walk(node: AnyNode, visit: (node: AnyNode, parent: AnyNode | null, key: string | null) => void): void {\n const stack: { node: AnyNode; parent: AnyNode | null; key: string | null }[] = [{ node, parent: null, key: null }];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n visit(current.node, current.parent, current.key);\n\n for (const [key, value] of Object.entries(current.node)) {\n if (key === \"loc\" || key === \"range\" || value === null || typeof value !== \"object\") {\n continue;\n }\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (isNode(entry)) {\n stack.push({ node: entry, parent: current.node, key });\n }\n }\n continue;\n }\n if (isNode(value)) {\n stack.push({ node: value, parent: current.node, key });\n }\n }\n }\n}\n\nfunction isNode(value: unknown): value is AnyNode {\n return typeof value === \"object\" && value !== null && typeof (value as AnyNode).type === \"string\";\n}\n\n/**\n * Whether an Identifier is a variable reference rather than a name in some\n * other position — a non-computed property, an object key, a label.\n */\nfunction isReference(parent: AnyNode | null, key: string | null): boolean {\n if (!parent) {\n return true;\n }\n\n switch (parent.type) {\n case \"MemberExpression\":\n return key !== \"property\" || parent.computed === true;\n case \"Property\":\n return key !== \"key\" || parent.computed === true;\n case \"MethodDefinition\":\n case \"PropertyDefinition\":\n return key !== \"key\" || parent.computed === true;\n case \"LabeledStatement\":\n case \"BreakStatement\":\n case \"ContinueStatement\":\n return key !== \"label\";\n case \"ExportSpecifier\":\n case \"ImportSpecifier\":\n return false;\n default:\n return true;\n }\n}\n\n/**\n * Every name bound anywhere in the file.\n *\n * Scopes are deliberately collapsed: over-approximating what is declared\n * cannot produce a false \"unknown global\", and the alternative — a scope\n * chain — would only matter for a migration that shadows a global in one\n * function and expects the real one in another.\n */\nfunction collectDeclaredNames(program: acorn.Program): Set<string> {\n const names = new Set<string>();\n\n const bindPattern = (pattern: AnyNode | null | undefined): void => {\n if (!pattern) {\n return;\n }\n switch (pattern.type) {\n case \"Identifier\":\n names.add(pattern.name);\n break;\n case \"ObjectPattern\":\n for (const property of pattern.properties ?? []) {\n bindPattern(property.type === \"RestElement\" ? property.argument : property.value);\n }\n break;\n case \"ArrayPattern\":\n for (const element of pattern.elements ?? []) {\n bindPattern(element);\n }\n break;\n case \"AssignmentPattern\":\n bindPattern(pattern.left);\n break;\n case \"RestElement\":\n bindPattern(pattern.argument);\n break;\n default:\n break;\n }\n };\n\n walk(program as AnyNode, (node) => {\n switch (node.type) {\n case \"VariableDeclarator\":\n bindPattern(node.id);\n break;\n case \"FunctionDeclaration\":\n case \"FunctionExpression\":\n case \"ArrowFunctionExpression\":\n bindPattern(node.id);\n for (const param of node.params ?? []) {\n bindPattern(param);\n }\n break;\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n bindPattern(node.id);\n break;\n case \"CatchClause\":\n bindPattern(node.param);\n break;\n case \"ImportDefaultSpecifier\":\n case \"ImportNamespaceSpecifier\":\n case \"ImportSpecifier\":\n bindPattern(node.local);\n break;\n default:\n break;\n }\n });\n\n return names;\n}\n\n/**\n * One finding per issue. A missing global is usually referenced many times;\n * reporting it once, at its first use, is what a reader needs. Syntax\n * findings keep their location, because each occurrence is a separate edit.\n */\nfunction dedupe(findings: GojaLintFinding[]): GojaLintFinding[] {\n const seen = new Set<string>();\n const unique: GojaLintFinding[] = [];\n const collapsedRules = new Set<GojaLintRule>([\"unknown-global\", \"async\"]);\n\n // Sorted before collapsing so a rule reported once keeps its earliest use;\n // the AST walk does not visit nodes in source order\n const ordered = [...findings].sort((a, b) => (a.line ?? 0) - (b.line ?? 0) || (a.column ?? 0) - (b.column ?? 0));\n\n for (const finding of ordered) {\n const key = collapsedRules.has(finding.rule)\n ? `${finding.rule}|${finding.message}`\n : `${finding.rule}|${finding.message}|${finding.line ?? \"\"}|${finding.column ?? \"\"}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n unique.push(finding);\n }\n\n return unique;\n}\n\nfunction finish(file: string, findings: GojaLintFinding[], warnings?: EngineWarning[]): GojaLintResult {\n const all = [...findings, ...gojaFindingsFromWarnings(warnings)];\n return { file, findings: all, ok: all.every((finding) => finding.severity !== \"error\") };\n}\n","/**\n * Structural comparison of two engine states\n *\n * Down-migration verification asks one question — \"is the state after\n * up() + down() the state we started from?\" — and needs an answer precise\n * enough to name what drifted. This compares the raw PocketBase-shaped\n * collections of two stores directly, rather than routing through the diff\n * engine, because a rollback that leaves the schema semantically equal but\n * structurally different (a restored field carrying a different id, an index\n * re-added in a different form) is exactly the kind of drift verification\n * exists to catch.\n *\n * Normalization is limited to differences PocketBase itself does not\n * distinguish:\n *\n * - An option a migration never declared and one set to its Go zero value\n * (`\"\"`, `0`, `false`, `[]`, `null`) express the same constraint, so an\n * absent key equals a zero-valued one. Two *declared* values are always\n * compared (`min: 0` vs `min: 5` is a real difference).\n * - API rules are exempt from that rule: `null` (superuser only) and `\"\"`\n * (public) are different permissions, so only absent ≡ `null` holds.\n * - Index order is not meaningful; index lists are compared as sets.\n * - Field order is not compared unless `strictFieldOrder` is set.\n */\n\nimport type { CollectionStore } from \"./store\";\nimport type { RawCollection } from \"./types\";\n\nexport interface StateDifference {\n kind:\n | \"collection-added\"\n | \"collection-removed\"\n | \"collection-property\"\n | \"field-added\"\n | \"field-removed\"\n | \"field-property\"\n | \"field-order\"\n | \"indexes\";\n /** Collection name (baseline name when the collection exists on both sides) */\n collection: string;\n field?: string;\n property?: string;\n expected?: unknown;\n actual?: unknown;\n /** Human-readable one-liner, suitable for CLI output */\n message: string;\n}\n\nexport interface StateCompareOptions {\n /**\n * Collection and field properties to skip.\n * Defaults to PocketBase's own bookkeeping timestamps.\n */\n ignoreKeys?: string[];\n /** Also compare the position of each field within its collection */\n strictFieldOrder?: boolean;\n /** Labels used in messages; defaults to \"baseline\" / \"actual\" */\n labels?: { expected: string; actual: string };\n}\n\nconst DEFAULT_IGNORED_KEYS = [\"created\", \"updated\"];\n\n/** Rules where absent means \"superuser only\" and \"\" means \"public\" */\nconst RULE_KEYS = new Set([\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\", \"manageRule\", \"authRule\"]);\n\n/** Handled structurally rather than as plain properties */\nconst STRUCTURAL_KEYS = new Set([\"fields\", \"indexes\"]);\n\n/**\n * Compares two stores. An empty result means the two states are the same\n * schema; every entry names one concrete divergence.\n */\nexport function compareStores(\n expected: CollectionStore,\n actual: CollectionStore,\n options: StateCompareOptions = {}\n): StateDifference[] {\n return compareRawCollections(expected.serialize(), actual.serialize(), options);\n}\n\nexport function compareRawCollections(\n expected: RawCollection[],\n actual: RawCollection[],\n options: StateCompareOptions = {}\n): StateDifference[] {\n const ignored = new Set(options.ignoreKeys ?? DEFAULT_IGNORED_KEYS);\n const labels = options.labels ?? { expected: \"baseline\", actual: \"actual\" };\n const differences: StateDifference[] = [];\n\n const remaining = [...actual];\n const matched = new Map<RawCollection, RawCollection>();\n\n for (const expectedCollection of expected) {\n const index = findCollectionIndex(remaining, expectedCollection);\n if (index === -1) {\n differences.push({\n kind: \"collection-removed\",\n collection: collectionLabel(expectedCollection),\n message: `collection \"${collectionLabel(expectedCollection)}\" is missing from ${labels.actual}`,\n });\n continue;\n }\n matched.set(expectedCollection, remaining[index]);\n remaining.splice(index, 1);\n }\n\n for (const extra of remaining) {\n differences.push({\n kind: \"collection-added\",\n collection: collectionLabel(extra),\n message: `collection \"${collectionLabel(extra)}\" exists in ${labels.actual} but not in ${labels.expected}`,\n });\n }\n\n for (const [expectedCollection, actualCollection] of matched) {\n differences.push(...compareCollection(expectedCollection, actualCollection, ignored, options, labels));\n }\n\n return differences;\n}\n\n/** One line per difference, e.g. for CLI output */\nexport function describeStateDifferences(differences: StateDifference[]): string[] {\n return differences.map((difference) => difference.message);\n}\n\nfunction compareCollection(\n expected: RawCollection,\n actual: RawCollection,\n ignored: Set<string>,\n options: StateCompareOptions,\n labels: { expected: string; actual: string }\n): StateDifference[] {\n const differences: StateDifference[] = [];\n const name = collectionLabel(expected);\n\n for (const key of unionKeys(expected, actual)) {\n if (ignored.has(key) || STRUCTURAL_KEYS.has(key)) {\n continue;\n }\n if (valuesAgree(key, expected[key], actual[key])) {\n continue;\n }\n differences.push({\n kind: \"collection-property\",\n collection: name,\n property: key,\n expected: expected[key],\n actual: actual[key],\n message:\n `[${name}] ${key} differs (${labels.expected}=${format(expected[key])}, ` +\n `${labels.actual}=${format(actual[key])})`,\n });\n }\n\n differences.push(...compareFields(name, expected, actual, ignored, options, labels));\n differences.push(...compareIndexes(name, expected, actual, labels));\n\n return differences;\n}\n\nfunction compareFields(\n collection: string,\n expected: RawCollection,\n actual: RawCollection,\n ignored: Set<string>,\n options: StateCompareOptions,\n labels: { expected: string; actual: string }\n): StateDifference[] {\n const differences: StateDifference[] = [];\n const expectedFields: RawCollection[] = Array.isArray(expected.fields) ? expected.fields : [];\n const actualFields: RawCollection[] = Array.isArray(actual.fields) ? actual.fields : [];\n\n const actualByName = new Map<string, RawCollection>();\n for (const field of actualFields) {\n actualByName.set(String(field?.name ?? \"\"), field);\n }\n\n for (const expectedField of expectedFields) {\n const fieldName = String(expectedField?.name ?? \"\");\n const actualField = actualByName.get(fieldName);\n\n if (!actualField) {\n differences.push({\n kind: \"field-removed\",\n collection,\n field: fieldName,\n message: `[${collection}] field \"${fieldName}\" is missing from ${labels.actual}`,\n });\n continue;\n }\n\n for (const key of unionKeys(expectedField, actualField)) {\n if (ignored.has(key)) {\n continue;\n }\n if (valuesAgree(key, expectedField[key], actualField[key])) {\n continue;\n }\n differences.push({\n kind: \"field-property\",\n collection,\n field: fieldName,\n property: key,\n expected: expectedField[key],\n actual: actualField[key],\n message:\n `[${collection}] field \"${fieldName}\" ${key} differs ` +\n `(${labels.expected}=${format(expectedField[key])}, ${labels.actual}=${format(actualField[key])})`,\n });\n }\n }\n\n const expectedNames = new Set(expectedFields.map((field) => String(field?.name ?? \"\")));\n for (const actualField of actualFields) {\n const fieldName = String(actualField?.name ?? \"\");\n if (!expectedNames.has(fieldName)) {\n differences.push({\n kind: \"field-added\",\n collection,\n field: fieldName,\n message: `[${collection}] field \"${fieldName}\" exists in ${labels.actual} but not in ${labels.expected}`,\n });\n }\n }\n\n if (options.strictFieldOrder) {\n const expectedOrder = expectedFields.map((field) => String(field?.name ?? \"\"));\n const actualOrder = actualFields.map((field) => String(field?.name ?? \"\"));\n if (expectedOrder.length === actualOrder.length && !arraysEqual(expectedOrder, actualOrder)) {\n differences.push({\n kind: \"field-order\",\n collection,\n expected: expectedOrder,\n actual: actualOrder,\n message:\n `[${collection}] field order differs (${labels.expected}=${expectedOrder.join(\", \")}, ` +\n `${labels.actual}=${actualOrder.join(\", \")})`,\n });\n }\n }\n\n return differences;\n}\n\nfunction compareIndexes(\n collection: string,\n expected: RawCollection,\n actual: RawCollection,\n labels: { expected: string; actual: string }\n): StateDifference[] {\n const expectedIndexes = normalizeIndexes(expected.indexes);\n const actualIndexes = normalizeIndexes(actual.indexes);\n const differences: StateDifference[] = [];\n\n for (const index of expectedIndexes) {\n if (!actualIndexes.includes(index)) {\n differences.push({\n kind: \"indexes\",\n collection,\n expected: index,\n message: `[${collection}] index missing from ${labels.actual}: ${index}`,\n });\n }\n }\n for (const index of actualIndexes) {\n if (!expectedIndexes.includes(index)) {\n differences.push({\n kind: \"indexes\",\n collection,\n actual: index,\n message: `[${collection}] index only in ${labels.actual}: ${index}`,\n });\n }\n }\n\n return differences;\n}\n\nfunction findCollectionIndex(candidates: RawCollection[], target: RawCollection): number {\n const byId = candidates.findIndex((candidate) => candidate.id && candidate.id === target.id);\n if (byId !== -1) {\n return byId;\n }\n return candidates.findIndex((candidate) => candidate.name && candidate.name === target.name);\n}\n\nfunction collectionLabel(collection: RawCollection): string {\n return String(collection?.name || collection?.id || \"<unnamed>\");\n}\n\nfunction unionKeys(left: RawCollection, right: RawCollection): string[] {\n return [...new Set([...Object.keys(left ?? {}), ...Object.keys(right ?? {})])];\n}\n\n/**\n * Whether two values for the same property describe the same thing —\n * see the normalization rules in the module comment.\n */\nfunction valuesAgree(key: string, expected: unknown, actual: unknown): boolean {\n if (RULE_KEYS.has(key)) {\n return deepEqual(expected ?? null, actual ?? null);\n }\n if (expected === undefined || actual === undefined) {\n return isUnset(expected) && isUnset(actual);\n }\n return deepEqual(expected, actual);\n}\n\n/** Values that carry no constraint; an undeclared option means the same */\nfunction isUnset(value: unknown): boolean {\n return (\n value === undefined ||\n value === null ||\n value === \"\" ||\n value === 0 ||\n value === false ||\n (Array.isArray(value) && value.length === 0)\n );\n}\n\nfunction normalizeIndexes(indexes: unknown): string[] {\n if (!Array.isArray(indexes)) {\n return [];\n }\n return indexes.map((index) => String(index).replace(/\\s+/g, \" \").trim());\n}\n\nfunction arraysEqual(left: string[], right: string[]): boolean {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction deepEqual(left: unknown, right: unknown): boolean {\n if (left === right) {\n return true;\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n return left.length === right.length && left.every((value, index) => deepEqual(value, right[index]));\n }\n if (left && right && typeof left === \"object\" && typeof right === \"object\") {\n const leftKeys = Object.keys(left as object);\n const rightKeys = Object.keys(right as object);\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n return leftKeys.every((key) =>\n deepEqual((left as Record<string, unknown>)[key], (right as Record<string, unknown>)[key])\n );\n }\n return false;\n}\n\nfunction format(value: unknown): string {\n if (value === undefined) {\n return \"unset\";\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * Down-migration verification\n *\n * A generated `down()` is never exercised by state reconstruction — the\n * replayer only runs `up()` — so a rollback that does not actually roll back\n * stays invisible until someone runs `pocketbase migrate down` in anger.\n * This module closes that gap: for each migration it executes `up()` against\n * a baseline, then `down()` against the result, and asserts the state came\n * back to the baseline.\n *\n * `down()` runs from a fresh evaluation of the file, the way PocketBase runs\n * it — a separate invocation that cannot observe anything `up()` left in the\n * file's module scope.\n *\n * Failures are returned, not thrown: a verification pass reports on every\n * migration it was given, and the caller decides whether an unreversible\n * migration is fatal.\n */\n\nimport * as fs from \"fs\";\nimport { MigrationExecutionError } from \"../errors\";\nimport { executeMigrationDownSource, executeMigrationSource } from \"./runner\";\nimport { compareStores, type StateCompareOptions, type StateDifference } from \"./state-compare\";\nimport { CollectionStore } from \"./store\";\nimport type { EngineOptions, EngineWarning, MigrationDirection } from \"./types\";\n\nexport interface MigrationSourceRef {\n source: string;\n /** Path or name used in messages */\n file?: string;\n}\n\nexport interface MigrationRoundTripResult {\n file: string;\n /** The file registered an up() closure and it committed */\n upApplied: boolean;\n /** The file registered a down() closure and it committed */\n downApplied: boolean;\n /** up() changed the state but the file has no down() to undo it */\n missingDown: boolean;\n /** up() followed by down() returned to the baseline */\n reversible: boolean;\n /** What the rollback failed to restore (empty when reversible) */\n differences: StateDifference[];\n warnings: EngineWarning[];\n /** Set when a phase failed to execute at all */\n error?: { phase: MigrationDirection | \"evaluate\"; message: string };\n /** State after up() — what the next migration in a sequence starts from */\n storeAfterUp: CollectionStore;\n}\n\nexport interface MigrationVerificationReport {\n results: MigrationRoundTripResult[];\n /** Every migration executed and reversed cleanly */\n ok: boolean;\n /** State after every up() — the state the migrations leave behind */\n store: CollectionStore;\n /** Only the results that failed, in input order */\n failures: MigrationRoundTripResult[];\n}\n\nexport interface VerifyOptions extends EngineOptions {\n /** State the first migration is applied to. Defaults to an empty store. */\n initialStore?: CollectionStore;\n /** Forwarded to the state comparison */\n compare?: StateCompareOptions;\n}\n\n/**\n * Verifies one migration against a baseline. The baseline store is left\n * untouched; the state after up() is returned on the result.\n */\nexport function verifyMigrationRoundTrip(\n migration: MigrationSourceRef,\n baseline: CollectionStore = new CollectionStore(),\n options: VerifyOptions = {}\n): MigrationRoundTripResult {\n const { initialStore: _initialStore, compare: compareOptions, ...engineOptions } = options;\n const file = migration.file ?? \"<migration>\";\n const warnings: EngineWarning[] = [];\n\n const afterUp = baseline.clone();\n let upApplied = false;\n try {\n const upResult = executeMigrationSource(migration.source, afterUp, { ...engineOptions, filename: file });\n upApplied = upResult.applied;\n warnings.push(...upResult.warnings);\n } catch (error) {\n return {\n file,\n upApplied: false,\n downApplied: false,\n missingDown: false,\n reversible: false,\n differences: [],\n warnings,\n error: toPhaseError(error, \"up\"),\n // up() is transactional: a failure leaves the baseline state intact\n storeAfterUp: baseline.clone(),\n };\n }\n\n const afterDown = afterUp.clone();\n let downApplied = false;\n try {\n const downResult = executeMigrationDownSource(migration.source, afterDown, { ...engineOptions, filename: file });\n downApplied = downResult.applied;\n warnings.push(...downResult.warnings);\n } catch (error) {\n return {\n file,\n upApplied,\n downApplied: false,\n missingDown: false,\n reversible: false,\n differences: [],\n warnings,\n error: toPhaseError(error, \"down\"),\n storeAfterUp: afterUp,\n };\n }\n\n const differences = compareStores(baseline, afterDown, {\n labels: { expected: \"pre-migration state\", actual: \"state after down()\" },\n ...compareOptions,\n });\n\n return {\n file,\n upApplied,\n downApplied,\n // A file with no down() is only a problem if up() actually changed\n // something — which the differences below will show\n missingDown: upApplied && !downApplied,\n reversible: differences.length === 0,\n differences,\n warnings,\n storeAfterUp: afterUp,\n };\n}\n\nexport function verifyMigrationFileRoundTrip(\n filePath: string,\n baseline: CollectionStore = new CollectionStore(),\n options: VerifyOptions = {}\n): MigrationRoundTripResult {\n return verifyMigrationRoundTrip({ source: fs.readFileSync(filePath, \"utf-8\"), file: filePath }, baseline, options);\n}\n\n/**\n * Verifies a sequence of migrations the way they will be applied: each one\n * is round-tripped against the state its predecessors leave behind, and its\n * up() is then committed before moving on.\n */\nexport function verifyMigrationSources(\n migrations: MigrationSourceRef[],\n options: VerifyOptions = {}\n): MigrationVerificationReport {\n let store = options.initialStore ?? new CollectionStore();\n const results: MigrationRoundTripResult[] = [];\n\n for (const migration of migrations) {\n const result = verifyMigrationRoundTrip(migration, store, options);\n results.push(result);\n store = result.storeAfterUp;\n\n // Continuing past a migration that could not be applied would verify\n // every later migration against a state that will never exist\n if (result.error?.phase === \"up\" || result.error?.phase === \"evaluate\") {\n break;\n }\n }\n\n const failures = results.filter((result) => !result.reversible || result.error !== undefined);\n\n return { results, ok: failures.length === 0, store, failures };\n}\n\nexport function verifyMigrationFiles(files: string[], options: VerifyOptions = {}): MigrationVerificationReport {\n return verifyMigrationSources(\n files.map((file) => ({ source: fs.readFileSync(file, \"utf-8\"), file })),\n options\n );\n}\n\nfunction toPhaseError(error: unknown, fallbackPhase: MigrationDirection): MigrationRoundTripResult[\"error\"] {\n if (error instanceof MigrationExecutionError) {\n return { phase: error.phase ?? fallbackPhase, message: error.message };\n }\n return { phase: fallbackPhase, message: error instanceof Error ? error.message : String(error) };\n}\n","/**\n * Validation and warning utilities for migration tool\n * Detects destructive changes and provides warnings\n */\n\nimport type { SchemaDiff } from \"./types\";\n\n/**\n * Types of destructive changes\n */\nexport enum DestructiveChangeType {\n COLLECTION_DELETION = \"collection_deletion\",\n FIELD_DELETION = \"field_deletion\",\n FIELD_TYPE_CHANGE = \"field_type_change\",\n FIELD_REQUIRED_CHANGE = \"field_required_change\",\n}\n\n/**\n * Represents a destructive change with details\n */\nexport interface DestructiveChange {\n type: DestructiveChangeType;\n description: string;\n collection: string;\n field?: string;\n details?: {\n oldValue?: any;\n newValue?: any;\n };\n severity: \"high\" | \"medium\" | \"low\";\n warning: string;\n}\n\n/**\n * Detects collection deletions\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for collection deletions\n */\nfunction detectCollectionDeletions(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const collection of diff.collectionsToDelete) {\n // View collections store no data, so dropping one is not destructive\n if (collection.type === \"view\") {\n continue;\n }\n\n changes.push({\n type: DestructiveChangeType.COLLECTION_DELETION,\n description: `Delete collection: ${collection.name}`,\n collection: collection.name,\n severity: \"high\",\n warning: `All data in the \"${collection.name}\" collection will be permanently deleted.`,\n });\n }\n\n return changes;\n}\n\n/**\n * Detects field deletions\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for field deletions\n */\nfunction detectFieldDeletions(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const field of modification.fieldsToRemove) {\n changes.push({\n type: DestructiveChangeType.FIELD_DELETION,\n description: `Delete field: ${modification.collection}.${field.name}`,\n collection: modification.collection,\n field: field.name,\n severity: \"high\",\n warning: `All data in the \"${field.name}\" field of \"${modification.collection}\" will be permanently deleted.`,\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Detects field type changes\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for field type changes\n */\nfunction detectFieldTypeChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const fieldMod of modification.fieldsToModify) {\n const typeChange = fieldMod.changes.find((c) => c.property === \"type\");\n\n if (typeChange) {\n changes.push({\n type: DestructiveChangeType.FIELD_TYPE_CHANGE,\n description: `Change field type: ${modification.collection}.${fieldMod.fieldName}`,\n collection: modification.collection,\n field: fieldMod.fieldName,\n details: {\n oldValue: typeChange.oldValue,\n newValue: typeChange.newValue,\n },\n severity: \"high\",\n warning: `Changing field type from \"${typeChange.oldValue}\" to \"${typeChange.newValue}\" may cause data loss or conversion errors.`,\n });\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Detects field required changes (making optional field required)\n *\n * @param diff - Schema diff\n * @returns Array of destructive changes for required field changes\n */\nfunction detectFieldRequiredChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n for (const modification of diff.collectionsToModify) {\n for (const fieldMod of modification.fieldsToModify) {\n const requiredChange = fieldMod.changes.find(\n (c) => c.property === \"required\" && c.newValue === true && c.oldValue === false\n );\n\n if (requiredChange) {\n changes.push({\n type: DestructiveChangeType.FIELD_REQUIRED_CHANGE,\n description: `Make field required: ${modification.collection}.${fieldMod.fieldName}`,\n collection: modification.collection,\n field: fieldMod.fieldName,\n details: {\n oldValue: false,\n newValue: true,\n },\n severity: \"medium\",\n warning: `Making \"${fieldMod.fieldName}\" required may cause issues with existing records that have null/empty values.`,\n });\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Detects all destructive changes in a schema diff\n *\n * @param diff - Schema diff to analyze\n * @returns Array of all destructive changes\n */\nexport function detectDestructiveChanges(diff: SchemaDiff): DestructiveChange[] {\n const changes: DestructiveChange[] = [];\n\n // Detect collection deletions\n changes.push(...detectCollectionDeletions(diff));\n\n // Detect field deletions\n changes.push(...detectFieldDeletions(diff));\n\n // Detect field type changes\n changes.push(...detectFieldTypeChanges(diff));\n\n // Detect field required changes\n changes.push(...detectFieldRequiredChanges(diff));\n\n return changes;\n}\n\n/**\n * Checks if a diff contains any destructive changes\n *\n * @param diff - Schema diff to check\n * @returns True if there are destructive changes\n */\nexport function hasDestructiveChanges(diff: SchemaDiff): boolean {\n const changes = detectDestructiveChanges(diff);\n return changes.length > 0;\n}\n\n/**\n * Formats destructive changes for display\n * Groups changes by severity and provides clear warnings\n *\n * @param changes - Array of destructive changes\n * @returns Formatted string for display\n */\nexport function formatDestructiveChanges(changes: DestructiveChange[]): string {\n if (changes.length === 0) {\n return \"No destructive changes detected.\";\n }\n\n const lines: string[] = [];\n\n // Group by severity\n const highSeverity = changes.filter((c) => c.severity === \"high\");\n const mediumSeverity = changes.filter((c) => c.severity === \"medium\");\n const lowSeverity = changes.filter((c) => c.severity === \"low\");\n\n // Display high severity changes\n if (highSeverity.length > 0) {\n lines.push(\"🔴 HIGH SEVERITY CHANGES (Data Loss Risk):\");\n lines.push(\"\");\n for (const change of highSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ⚠️ ${change.warning}`);\n if (change.details) {\n if (change.details.oldValue !== undefined && change.details.newValue !== undefined) {\n lines.push(` Old: ${change.details.oldValue} → New: ${change.details.newValue}`);\n }\n }\n lines.push(\"\");\n }\n }\n\n // Display medium severity changes\n if (mediumSeverity.length > 0) {\n lines.push(\"🟡 MEDIUM SEVERITY CHANGES (Potential Issues):\");\n lines.push(\"\");\n for (const change of mediumSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ⚠️ ${change.warning}`);\n if (change.details) {\n if (change.details.oldValue !== undefined && change.details.newValue !== undefined) {\n lines.push(` Old: ${change.details.oldValue} → New: ${change.details.newValue}`);\n }\n }\n lines.push(\"\");\n }\n }\n\n // Display low severity changes\n if (lowSeverity.length > 0) {\n lines.push(\"🟢 LOW SEVERITY CHANGES:\");\n lines.push(\"\");\n for (const change of lowSeverity) {\n lines.push(` • ${change.description}`);\n lines.push(` ℹ️ ${change.warning}`);\n lines.push(\"\");\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates a summary of destructive changes\n *\n * @param changes - Array of destructive changes\n * @returns Summary object with counts by severity\n */\nexport function summarizeDestructiveChanges(changes: DestructiveChange[]): {\n total: number;\n high: number;\n medium: number;\n low: number;\n} {\n return {\n total: changes.length,\n high: changes.filter((c) => c.severity === \"high\").length,\n medium: changes.filter((c) => c.severity === \"medium\").length,\n low: changes.filter((c) => c.severity === \"low\").length,\n };\n}\n\n/**\n * Checks if force flag is required for the given changes\n * Force is required if there are any high or medium severity changes\n *\n * @param changes - Array of destructive changes\n * @returns True if force flag should be required\n */\nexport function requiresForceFlag(changes: DestructiveChange[]): boolean {\n return changes.some((c) => c.severity === \"high\" || c.severity === \"medium\");\n}\n","/**\n * Configuration loader for migration tool\n * Handles loading and merging configuration from various sources\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { defaultDataDirectory } from \"../../migration/engine/applied-migrations.js\";\nimport { ConfigurationError } from \"../../migration/errors.js\";\n\n/**\n * Migration tool configuration\n */\nexport interface MigrationConfig {\n schema: {\n directory: string;\n exclude: string[];\n };\n migrations: {\n directory: string;\n format: string;\n /**\n * Whether `generate` executes each new migration's up() and down() in the\n * simulation before writing it, and refuses to write one that does not\n * roll back cleanly. Off by default.\n */\n verify: boolean;\n /**\n * PocketBase's data directory (or a data.db file), used to read the\n * `_migrations` table so replay can stop at what has actually been\n * applied. Empty means \"the pb_data directory next to the migrations\n * directory\".\n */\n dataDirectory: string;\n };\n diff: {\n warnOnDelete: boolean;\n requireForceForDestructive: boolean;\n };\n typeGen: {\n outPath: string;\n };\n}\n\n/**\n * Partial configuration for merging\n */\nexport type PartialMigrationConfig = {\n schema?: Partial<MigrationConfig[\"schema\"]>;\n migrations?: Partial<MigrationConfig[\"migrations\"]>;\n diff?: Partial<MigrationConfig[\"diff\"]>;\n typeGen?: Partial<MigrationConfig[\"typeGen\"]>;\n};\n\n/**\n * Configuration file names to search for\n */\nconst CONFIG_FILE_NAMES = [\n \"pocketbase-migrate.config.js\",\n \"pocketbase-migrate.config.mjs\",\n \"pocketbase-migrate.config.json\",\n \"migrate.config.js\",\n \"migrate.config.mjs\",\n \"migrate.config.json\",\n];\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: MigrationConfig = {\n schema: {\n directory: \"src/schema\",\n exclude: [\"base.ts\", \"index.ts\", \"permissions.ts\", \"permission-templates.ts\"],\n },\n migrations: {\n directory: \"pocketbase/pb_migrations\",\n format: \"timestamp_description\",\n verify: false,\n dataDirectory: \"\",\n },\n diff: {\n warnOnDelete: true,\n requireForceForDestructive: true,\n },\n typeGen: {\n outPath: \"pocketbase-types.ts\",\n },\n};\n\n/**\n * Finds a configuration file in the given directory\n */\nfunction findConfigFile(directory: string): string | null {\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = path.join(directory, fileName);\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n }\n return null;\n}\n\n/**\n * Loads configuration from a JSON file\n */\nfunction loadJsonConfig(configPath: string): PartialMigrationConfig {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n return JSON.parse(content);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConfigurationError(\"Invalid JSON syntax in configuration file\", configPath, undefined, error);\n }\n throw new ConfigurationError(\n \"Failed to read configuration file\",\n configPath,\n undefined,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Loads configuration from a JavaScript file\n */\nasync function loadJsConfig(configPath: string): Promise<PartialMigrationConfig> {\n try {\n const fileUrl = `file://${configPath}`;\n const module = await import(fileUrl);\n return module.default || module;\n } catch (error) {\n throw new ConfigurationError(\n \"Failed to load JavaScript configuration file\",\n configPath,\n undefined,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Loads configuration from file if it exists\n */\nasync function loadConfigFile(configPath: string): Promise<PartialMigrationConfig | null> {\n if (!fs.existsSync(configPath)) {\n return null;\n }\n\n const ext = path.extname(configPath).toLowerCase();\n\n if (ext === \".json\") {\n return loadJsonConfig(configPath);\n } else if (ext === \".js\" || ext === \".mjs\") {\n return loadJsConfig(configPath);\n } else {\n throw new ConfigurationError(`Unsupported configuration file format: ${ext}`, configPath, undefined);\n }\n}\n\n/**\n * Merges configuration objects with deep merge\n */\nfunction mergeConfig(base: MigrationConfig, override: PartialMigrationConfig): MigrationConfig {\n return {\n schema: { ...base.schema, ...override.schema },\n migrations: { ...base.migrations, ...override.migrations },\n diff: { ...base.diff, ...override.diff },\n typeGen: { ...base.typeGen, ...override.typeGen },\n };\n}\n\n/**\n * Loads configuration from environment variables\n */\nfunction loadConfigFromEnv(): PartialMigrationConfig {\n const config: PartialMigrationConfig = {};\n\n if (process.env.MIGRATION_SCHEMA_DIR) {\n config.schema = { directory: process.env.MIGRATION_SCHEMA_DIR };\n }\n\n if (process.env.MIGRATION_SCHEMA_EXCLUDE) {\n config.schema = {\n ...config.schema,\n exclude: process.env.MIGRATION_SCHEMA_EXCLUDE.split(\",\").map((s) => s.trim()),\n };\n }\n\n if (process.env.MIGRATION_OUTPUT_DIR) {\n config.migrations = { directory: process.env.MIGRATION_OUTPUT_DIR };\n }\n\n if (process.env.MIGRATION_VERIFY !== undefined) {\n config.migrations = {\n ...config.migrations,\n verify: process.env.MIGRATION_VERIFY === \"true\",\n };\n }\n\n if (process.env.MIGRATION_DATA_DIR) {\n config.migrations = {\n ...config.migrations,\n dataDirectory: process.env.MIGRATION_DATA_DIR,\n };\n }\n\n if (process.env.MIGRATION_REQUIRE_FORCE !== undefined) {\n config.diff = { requireForceForDestructive: process.env.MIGRATION_REQUIRE_FORCE === \"true\" };\n }\n\n return config;\n}\n\n/**\n * Loads configuration from CLI arguments\n */\nexport function loadConfigFromArgs(options: any): PartialMigrationConfig {\n const config: PartialMigrationConfig = {};\n\n if (options.output) {\n config.migrations = { directory: options.output };\n }\n\n if (options.schemaDir) {\n config.schema = { directory: options.schemaDir };\n }\n\n if (options.pbData) {\n config.migrations = { ...config.migrations, dataDirectory: options.pbData };\n }\n\n // Commander sets verify to false for --no-verify, so only an explicit\n // boolean overrides the config file\n if (typeof options.verify === \"boolean\") {\n config.migrations = { ...config.migrations, verify: options.verify };\n }\n\n return config;\n}\n\n/**\n * Validates configuration values\n */\nfunction validateConfig(config: MigrationConfig, configPath?: string): void {\n const invalidFields: string[] = [];\n\n if (typeof config.schema.directory !== \"string\" || config.schema.directory.trim() === \"\") {\n invalidFields.push(\"schema.directory (must be a non-empty string)\");\n }\n\n if (!Array.isArray(config.schema.exclude)) {\n invalidFields.push(\"schema.exclude (must be an array of strings)\");\n }\n\n if (typeof config.migrations.directory !== \"string\" || config.migrations.directory.trim() === \"\") {\n invalidFields.push(\"migrations.directory (must be a non-empty string)\");\n }\n\n if (typeof config.migrations.verify !== \"boolean\") {\n invalidFields.push(\"migrations.verify (must be a boolean)\");\n }\n\n if (typeof config.migrations.dataDirectory !== \"string\") {\n invalidFields.push(\"migrations.dataDirectory (must be a string)\");\n }\n\n if (typeof config.diff.warnOnDelete !== \"boolean\") {\n invalidFields.push(\"diff.warnOnDelete (must be a boolean)\");\n }\n\n if (typeof config.diff.requireForceForDestructive !== \"boolean\") {\n invalidFields.push(\"diff.requireForceForDestructive (must be a boolean)\");\n }\n\n if (typeof config.typeGen.outPath !== \"string\" || config.typeGen.outPath.trim() === \"\") {\n invalidFields.push(\"typeGen.outPath (must be a non-empty string)\");\n }\n\n if (invalidFields.length > 0) {\n throw new ConfigurationError(\"Invalid configuration values\", configPath, invalidFields);\n }\n\n // Validate schema directory exists - try multiple locations\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.schema.directory),\n path.resolve(cwd, \"shared\", config.schema.directory),\n ];\n\n const schemaDir = possiblePaths.find((p) => fs.existsSync(p));\n\n if (!schemaDir) {\n throw new ConfigurationError(`Schema directory not found. Tried: ${possiblePaths.join(\", \")}`, configPath, [\n \"schema.directory\",\n ]);\n }\n}\n\n/**\n * Loads and merges configuration from all sources\n * Priority: CLI args > Environment variables > Config file > Defaults\n */\nexport async function loadConfig(options: any = {}): Promise<MigrationConfig> {\n let config: MigrationConfig = { ...DEFAULT_CONFIG };\n let configFilePath: string | undefined;\n\n const cwd = process.cwd();\n\n // Check for explicit config path from CLI\n if (options.config) {\n const explicitPath = path.resolve(cwd, options.config);\n if (!fs.existsSync(explicitPath)) {\n throw new ConfigurationError(`Configuration file not found: ${explicitPath}`, explicitPath);\n }\n configFilePath = explicitPath;\n } else {\n // Search for config file in current directory and shared directory\n const searchDirs = [cwd, path.join(cwd, \"shared\")];\n\n for (const dir of searchDirs) {\n if (fs.existsSync(dir)) {\n const found = findConfigFile(dir);\n if (found) {\n configFilePath = found;\n break;\n }\n }\n }\n }\n\n // Load config file if found\n if (configFilePath) {\n const fileConfig = await loadConfigFile(configFilePath);\n if (fileConfig) {\n config = mergeConfig(config, fileConfig);\n }\n }\n\n // Merge environment variables\n const envConfig = loadConfigFromEnv();\n if (Object.keys(envConfig).length > 0) {\n config = mergeConfig(config, envConfig);\n }\n\n // Merge CLI arguments (highest priority)\n const argsConfig = loadConfigFromArgs(options);\n if (Object.keys(argsConfig).length > 0) {\n config = mergeConfig(config, argsConfig);\n }\n\n // Validate final configuration\n validateConfig(config, configFilePath);\n\n return config;\n}\n\n/**\n * Gets the absolute path to the schema directory\n */\nexport function getSchemaDirectory(config: MigrationConfig): string {\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.schema.directory),\n path.resolve(cwd, \"shared\", config.schema.directory),\n ];\n\n return possiblePaths.find((p) => fs.existsSync(p)) || possiblePaths[0];\n}\n\n/**\n * Gets the absolute path to the migrations directory\n */\nexport function getMigrationsDirectory(config: MigrationConfig): string {\n const cwd = process.cwd();\n const possiblePaths = [\n path.resolve(cwd, config.migrations.directory),\n path.resolve(cwd, \"shared\", config.migrations.directory),\n ];\n\n return possiblePaths.find((p) => fs.existsSync(p)) || possiblePaths[0];\n}\n\n/**\n * Gets the absolute path to PocketBase's data directory (or data.db file).\n *\n * Falls back to the pb_data directory next to the migrations directory, which\n * is where PocketBase puts it by default.\n */\nexport function getDataDirectory(config: MigrationConfig): string {\n const configured = config.migrations.dataDirectory.trim();\n if (configured !== \"\") {\n return path.resolve(process.cwd(), configured);\n }\n return defaultDataDirectory(getMigrationsDirectory(config));\n}\n\n/**\n * Gets the default configuration\n */\nexport function getDefaultConfig(): MigrationConfig {\n return { ...DEFAULT_CONFIG };\n}\n\n/**\n * Creates a sample configuration file content\n */\nexport function getSampleConfig(format: \"json\" | \"js\"): string {\n if (format === \"json\") {\n return JSON.stringify(DEFAULT_CONFIG, null, 2);\n }\n\n return `/**\n * PocketBase Zod Migration Configuration\n * @type {import('pocketbase-zod-schema/cli').MigrationConfig}\n */\nexport default {\n schema: {\n directory: \"/src/schema\",\n exclude: [\"base.ts\", \"index.ts\", \"permissions.ts\", \"permission-templates.ts\"],\n },\n migrations: {\n directory: \"pocketbase/pb_migrations\",\n format: \"timestamp_description\",\n verify: false,\n dataDirectory: \"\",\n },\n diff: {\n warnOnDelete: true,\n requireForceForDestructive: true,\n },\n typeGen: {\n outPath: \"pocketbase-types.ts\",\n },\n};\n`;\n}\n","/**\n * Logging utilities for CLI output\n * Provides colored console output and formatting helpers\n */\n\nimport chalk from \"chalk\";\nimport ora, { type Ora } from \"ora\";\nimport type { FieldChange, SchemaDiff } from \"../../migration/types.js\";\n\n/**\n * Verbosity levels for logging\n */\nexport type VerbosityLevel = \"quiet\" | \"normal\" | \"verbose\";\n\n/**\n * Current verbosity level\n */\nlet currentVerbosity: VerbosityLevel = \"normal\";\n\n/**\n * Sets the verbosity level for logging\n *\n * @param level - Verbosity level to set\n */\nexport function setVerbosity(level: VerbosityLevel): void {\n currentVerbosity = level;\n}\n\n/**\n * Gets the current verbosity level\n *\n * @returns Current verbosity level\n */\nexport function getVerbosity(): VerbosityLevel {\n return currentVerbosity;\n}\n\n/**\n * Checks if output should be shown based on verbosity\n *\n * @param requiredLevel - Minimum verbosity level required\n * @returns True if output should be shown\n */\nfunction shouldLog(requiredLevel: VerbosityLevel): boolean {\n const levels: VerbosityLevel[] = [\"quiet\", \"normal\", \"verbose\"];\n const currentIndex = levels.indexOf(currentVerbosity);\n const requiredIndex = levels.indexOf(requiredLevel);\n return currentIndex >= requiredIndex;\n}\n\n/**\n * Creates a spinner for long-running operations\n *\n * @param text - Initial spinner text\n * @returns Ora spinner instance\n */\nexport function createSpinner(text: string): Ora {\n // In quiet mode, create a silent spinner\n if (currentVerbosity === \"quiet\") {\n return ora({ text, isSilent: true });\n }\n return ora(text);\n}\n\n/**\n * Logs a success message in green\n *\n * @param message - Message to log\n */\nexport function logSuccess(message: string): void {\n if (shouldLog(\"normal\")) {\n console.log(chalk.green(\"✓\"), message);\n }\n}\n\n/**\n * Logs an error message in red\n * Always shown regardless of verbosity level\n *\n * @param message - Message to log\n */\nexport function logError(message: string): void {\n console.error(chalk.red(\"✗\"), message);\n}\n\n/**\n * Logs a warning message in yellow\n *\n * @param message - Message to log\n */\nexport function logWarning(message: string): void {\n if (shouldLog(\"normal\")) {\n console.warn(chalk.yellow(\"⚠\"), message);\n }\n}\n\n/**\n * Logs an info message in blue\n *\n * @param message - Message to log\n */\nexport function logInfo(message: string): void {\n if (shouldLog(\"normal\")) {\n console.log(chalk.blue(\"ℹ\"), message);\n }\n}\n\n/**\n * Logs a debug message in gray\n * Only shown in verbose mode\n *\n * @param message - Message to log\n */\nexport function logDebug(message: string): void {\n if (shouldLog(\"verbose\")) {\n console.log(chalk.gray(\"⚙\"), chalk.gray(message));\n }\n}\n\n/**\n * Logs a section header\n *\n * @param title - Section title\n */\nexport function logSection(title: string): void {\n if (shouldLog(\"normal\")) {\n console.log();\n console.log(chalk.bold.cyan(title));\n console.log(chalk.cyan(\"─\".repeat(title.length)));\n }\n}\n\n/**\n * Formats a field change for display\n *\n * @param change - Field change object\n * @returns Formatted string\n */\nfunction formatFieldChange(change: FieldChange): string {\n const oldValue = change.oldValue === null ? \"null\" : JSON.stringify(change.oldValue);\n const newValue = change.newValue === null ? \"null\" : JSON.stringify(change.newValue);\n\n return `${change.property}: ${chalk.red(oldValue)} → ${chalk.green(newValue)}`;\n}\n\n/**\n * Formats a change summary for display\n * Creates a formatted, colored summary of detected changes\n *\n * @param diff - Schema diff containing all changes\n * @returns Formatted summary string\n */\nexport function formatChangeSummary(diff: SchemaDiff): string {\n const lines: string[] = [];\n\n // Count total changes\n const totalCollectionsToCreate = diff.collectionsToCreate.length;\n const totalCollectionsToDelete = diff.collectionsToDelete.length;\n const totalCollectionsToModify = diff.collectionsToModify.length;\n\n const totalChanges = totalCollectionsToCreate + totalCollectionsToDelete + totalCollectionsToModify;\n\n if (totalChanges === 0) {\n return chalk.gray(\"No changes detected\");\n }\n\n lines.push(chalk.bold(`Found ${totalChanges} collection change(s):`));\n lines.push(\"\");\n\n // New collections\n if (totalCollectionsToCreate > 0) {\n lines.push(chalk.green.bold(`✓ ${totalCollectionsToCreate} collection(s) to create:`));\n for (const collection of diff.collectionsToCreate) {\n lines.push(chalk.green(` + ${collection.name} (${collection.type})`));\n if (collection.type === \"view\") {\n // A view's fields are derived by PocketBase from its SQL query\n lines.push(chalk.gray(` fields derived from the view query`));\n } else {\n lines.push(chalk.gray(` ${collection.fields.length} field(s)`));\n }\n }\n lines.push(\"\");\n }\n\n // Deleted collections\n if (totalCollectionsToDelete > 0) {\n lines.push(chalk.red.bold(`✗ ${totalCollectionsToDelete} collection(s) to delete:`));\n for (const collection of diff.collectionsToDelete) {\n lines.push(chalk.red(` - ${collection.name}`));\n }\n lines.push(\"\");\n }\n\n // Modified collections\n if (totalCollectionsToModify > 0) {\n lines.push(chalk.yellow.bold(`⚡ ${totalCollectionsToModify} collection(s) to modify:`));\n\n for (const modification of diff.collectionsToModify) {\n lines.push(chalk.yellow(` ~ ${modification.collection}`));\n\n // Fields to add\n if (modification.fieldsToAdd.length > 0) {\n lines.push(chalk.green(` + ${modification.fieldsToAdd.length} field(s) to add:`));\n for (const field of modification.fieldsToAdd) {\n lines.push(chalk.green(` + ${field.name} (${field.type})`));\n }\n }\n\n // Fields to remove\n if (modification.fieldsToRemove.length > 0) {\n lines.push(chalk.red(` - ${modification.fieldsToRemove.length} field(s) to remove:`));\n for (const field of modification.fieldsToRemove) {\n lines.push(chalk.red(` - ${field.name}`));\n }\n }\n\n // Fields to modify\n if (modification.fieldsToModify.length > 0) {\n lines.push(chalk.yellow(` ~ ${modification.fieldsToModify.length} field(s) to modify:`));\n for (const fieldMod of modification.fieldsToModify) {\n lines.push(chalk.yellow(` ~ ${fieldMod.fieldName}`));\n for (const change of fieldMod.changes) {\n lines.push(chalk.gray(` ${formatFieldChange(change)}`));\n }\n }\n }\n\n // Indexes\n if (modification.indexesToAdd.length > 0) {\n lines.push(chalk.green(` + ${modification.indexesToAdd.length} index(es) to add`));\n }\n\n if (modification.indexesToRemove.length > 0) {\n lines.push(chalk.red(` - ${modification.indexesToRemove.length} index(es) to remove`));\n }\n\n // Rules\n if (modification.rulesToUpdate.length > 0) {\n lines.push(chalk.yellow(` ~ ${modification.rulesToUpdate.length} rule(s) to update`));\n }\n\n // View query\n if (modification.viewQueryUpdate) {\n lines.push(chalk.yellow(` ~ view query to update`));\n }\n\n lines.push(\"\");\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Displays a progress indicator for a long operation\n *\n * @param message - Progress message\n * @param operation - Async operation to perform\n * @returns Result of the operation\n */\nexport async function withProgress<T>(message: string, operation: () => Promise<T>): Promise<T> {\n const spinner = createSpinner(message).start();\n\n try {\n const result = await operation();\n spinner.succeed();\n return result;\n } catch (error) {\n spinner.fail();\n throw error;\n }\n}\n\n/**\n * Logs a step in a multi-step process\n *\n * @param step - Current step number\n * @param total - Total number of steps\n * @param message - Step description\n */\nexport function logStep(step: number, total: number, message: string): void {\n if (shouldLog(\"normal\")) {\n const progress = chalk.gray(`[${step}/${total}]`);\n console.log(progress, message);\n }\n}\n\n/**\n * Logs a list of items with bullet points\n *\n * @param items - Items to list\n * @param indent - Indentation level (default: 2)\n */\nexport function logList(items: string[], indent: number = 2): void {\n if (shouldLog(\"normal\")) {\n const padding = \" \".repeat(indent);\n for (const item of items) {\n console.log(`${padding}• ${item}`);\n }\n }\n}\n\n/**\n * Logs a key-value pair\n *\n * @param key - Key name\n * @param value - Value to display\n * @param indent - Indentation level (default: 2)\n */\nexport function logKeyValue(key: string, value: string, indent: number = 2): void {\n if (shouldLog(\"normal\")) {\n const padding = \" \".repeat(indent);\n console.log(`${padding}${chalk.gray(key + \":\")} ${value}`);\n }\n}\n\n/**\n * Logs a table of data\n *\n * @param headers - Column headers\n * @param rows - Data rows\n */\nexport function logTable(headers: string[], rows: string[][]): void {\n if (!shouldLog(\"normal\")) return;\n\n // Calculate column widths\n const widths = headers.map((h, i) => {\n const maxRowWidth = Math.max(...rows.map((r) => (r[i] || \"\").length));\n return Math.max(h.length, maxRowWidth);\n });\n\n // Print header\n const headerLine = headers.map((h, i) => h.padEnd(widths[i])).join(\" \");\n console.log(chalk.bold(headerLine));\n console.log(chalk.gray(\"─\".repeat(headerLine.length)));\n\n // Print rows\n for (const row of rows) {\n const rowLine = row.map((cell, i) => (cell || \"\").padEnd(widths[i])).join(\" \");\n console.log(rowLine);\n }\n}\n\n/**\n * Logs a box with a title and content\n *\n * @param title - Box title\n * @param content - Box content (array of lines)\n */\nexport function logBox(title: string, content: string[]): void {\n if (!shouldLog(\"normal\")) return;\n\n const maxWidth = Math.max(title.length, ...content.map((c) => c.length));\n const border = \"─\".repeat(maxWidth + 2);\n\n console.log();\n console.log(chalk.cyan(`┌${border}┐`));\n console.log(chalk.cyan(\"│ \") + chalk.bold(title.padEnd(maxWidth)) + chalk.cyan(\" │\"));\n console.log(chalk.cyan(`├${border}┤`));\n for (const line of content) {\n console.log(chalk.cyan(\"│ \") + line.padEnd(maxWidth) + chalk.cyan(\" │\"));\n }\n console.log(chalk.cyan(`└${border}┘`));\n}\n\n/**\n * Creates a progress bar string\n *\n * @param current - Current progress value\n * @param total - Total value\n * @param width - Bar width in characters (default: 20)\n * @returns Formatted progress bar string\n */\nexport function createProgressBar(current: number, total: number, width: number = 20): string {\n const percentage = Math.min(100, Math.round((current / total) * 100));\n const filled = Math.round((percentage / 100) * width);\n const empty = width - filled;\n\n const bar = chalk.green(\"█\".repeat(filled)) + chalk.gray(\"░\".repeat(empty));\n return `${bar} ${percentage}%`;\n}\n\n/**\n * Logs a timestamp with a message\n *\n * @param message - Message to log\n */\nexport function logTimestamp(message: string): void {\n if (shouldLog(\"verbose\")) {\n const timestamp = new Date().toISOString();\n console.log(chalk.gray(`[${timestamp}]`), message);\n }\n}\n\n/**\n * Formats a duration in milliseconds to a human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns Formatted duration string\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n }\n}\n\n/**\n * Logs a timed operation result\n *\n * @param message - Operation description\n * @param startTime - Start time from Date.now()\n */\nexport function logTimed(message: string, startTime: number): void {\n if (shouldLog(\"normal\")) {\n const duration = Date.now() - startTime;\n console.log(chalk.green(\"✓\"), message, chalk.gray(`(${formatDuration(duration)})`));\n }\n}\n\n/**\n * Status output interface for JSON output mode\n */\nexport interface StatusOutput {\n status: \"up-to-date\" | \"changes-pending\" | \"first-time-setup\";\n collections: {\n current: number;\n snapshot: number;\n };\n changes: {\n create: number;\n delete: number;\n modify: number;\n };\n destructive: boolean;\n /**\n * Disk vs. PocketBase's `_migrations` table. Present only when an applied\n * migrations list was read (`--verify` / `--pb-data`).\n */\n migrations?: {\n source: string;\n applied: number;\n /** On disk, not yet applied */\n pending: string[];\n /** Applied, no longer on disk */\n missing: string[];\n /** Pending files that sit behind an already-applied migration */\n outOfOrder: string[];\n inSync: boolean;\n /**\n * What the database still lacks compared to the schema — the changes the\n * pending files carry. Distinct from `changes`, which counts what has no\n * migration file at all. Absent when disk and the database agree.\n */\n unapplied?: {\n create: number;\n delete: number;\n modify: number;\n };\n };\n}\n\n/**\n * Formats status output as JSON\n *\n * @param output - Status output object\n * @returns JSON string\n */\nexport function formatStatusJson(output: StatusOutput): string {\n return JSON.stringify(output, null, 2);\n}\n","/**\n * Generate command implementation\n * Generates migrations from schema changes\n */\n\nimport { Command } from \"commander\";\nimport * as path from \"path\";\nimport {\n ConfigurationError,\n FileSystemError,\n MigrationExecutionError,\n MigrationGenerationError,\n SchemaParsingError,\n SnapshotError,\n} from \"../../migration/errors.js\";\nimport {\n CollectionStore,\n compare,\n detectDestructiveChangesValidation as detectDestructiveChanges,\n filterDiff,\n formatDestructiveChanges,\n formatGojaLintFinding,\n lintMigrationSource,\n parseSchemaFiles,\n planMigrations,\n replayMigrationsDirectory,\n requiresForceFlagValidation as requiresForceFlag,\n summarizeDestructiveChanges,\n verifyMigrationSources,\n writePlannedMigrations,\n type GojaLintResult,\n type MigrationRoundTripResult,\n type PlannedMigration,\n} from \"../../migration/index.js\";\nimport { loadSnapshotWithMigrations } from \"../../migration/snapshot.js\";\nimport type { SchemaDefinition } from \"../../migration/types.js\";\nimport { getMigrationsDirectory, getSchemaDirectory, loadConfig, type MigrationConfig } from \"../utils/config.js\";\nimport {\n formatChangeSummary,\n logDebug,\n logError,\n logInfo,\n logSection,\n logSuccess,\n logWarning,\n setVerbosity,\n withProgress,\n} from \"../utils/logger.js\";\n\n/**\n * Checks if there are any changes in the diff\n *\n * @param diff - Schema diff to check\n * @returns True if there are changes\n */\nfunction hasChanges(diff: any): boolean {\n return (\n diff.collectionsToCreate.length > 0 || diff.collectionsToDelete.length > 0 || diff.collectionsToModify.length > 0\n );\n}\n\n/**\n * Handles destructive changes with warnings and force flag\n *\n * @param diff - Schema diff containing changes\n * @param config - Migration configuration\n * @param force - Force flag from CLI\n * @returns True if should proceed, false otherwise\n */\nfunction handleDestructiveChanges(diff: any, config: MigrationConfig, force: boolean): boolean {\n // Detect destructive changes\n const destructiveChanges = detectDestructiveChanges(diff);\n\n if (destructiveChanges.length === 0) {\n return true; // No destructive changes, proceed\n }\n\n // Display destructive changes warning\n logSection(\"⚠️ Destructive Changes Detected\");\n console.log();\n\n // Format and display destructive changes\n console.log(formatDestructiveChanges(destructiveChanges));\n\n // Display summary\n const summary = summarizeDestructiveChanges(destructiveChanges);\n console.log(\"Summary:\");\n console.log(` Total: ${summary.total} destructive change(s)`);\n if (summary.high > 0) {\n console.log(` High Severity: ${summary.high}`);\n }\n if (summary.medium > 0) {\n console.log(` Medium Severity: ${summary.medium}`);\n }\n if (summary.low > 0) {\n console.log(` Low Severity: ${summary.low}`);\n }\n console.log();\n\n // Check if force flag is required\n const forceRequired = config.diff.requireForceForDestructive && requiresForceFlag(destructiveChanges);\n\n if (forceRequired && !force) {\n // This path should technically be unreachable if we filtered destructive changes when !force\n // But keeping it as a safety net\n logError(\"Destructive changes require the --force flag to proceed.\");\n console.log();\n logInfo(\"To proceed with these changes, run the command again with --force:\");\n console.log(\" yarn migrate:generate --force\");\n console.log();\n logWarning(\"⚠️ WARNING: Using --force will apply these changes and may result in data loss!\");\n return false;\n }\n\n if (force) {\n logWarning(\"Proceeding with destructive changes (--force flag provided)\");\n console.log();\n }\n\n return true;\n}\n\n/**\n * Outcome of the pre-write verification pass\n */\ntype VerificationOutcome =\n | { status: \"verified\"; count: number }\n /** The existing migrations could not be executed, so there is no baseline */\n | { status: \"baseline-unexecutable\"; error: MigrationExecutionError }\n | { status: \"failed\"; failures: MigrationRoundTripResult[] }\n /** The migration would not run in PocketBase's goja runtime */\n | { status: \"incompatible\"; results: GojaLintResult[] };\n\n/**\n * Executes each planned migration's up() and down() in the simulated\n * PocketBase JSVM, starting from the state the existing migrations\n * reconstruct, and reports anything that does not roll back cleanly.\n *\n * @param planned - Migrations generated but not yet written\n * @param migrationsDir - Directory holding the existing migrations\n * @returns What the verification found (rendered by reportVerification)\n */\nfunction verifyPlannedMigrations(planned: PlannedMigration[], migrationsDir: string): VerificationOutcome {\n // Executing in the engine proves nothing about goja, which is what will\n // actually run the file — so check compatibility before round-tripping\n const lintResults = planned.map((migration) => lintMigrationSource(migration.content, { file: migration.filename }));\n const incompatible = lintResults.filter((result) => !result.ok);\n if (incompatible.length > 0) {\n return { status: \"incompatible\", results: incompatible };\n }\n\n let baseline: CollectionStore;\n try {\n baseline = replayMigrationsDirectory(migrationsDir)?.store ?? new CollectionStore();\n } catch (error) {\n if (error instanceof MigrationExecutionError) {\n return { status: \"baseline-unexecutable\", error };\n }\n throw error;\n }\n\n const report = verifyMigrationSources(\n planned.map((migration) => ({ file: migration.filename, source: migration.content })),\n { initialStore: baseline }\n );\n\n return report.ok\n ? { status: \"verified\", count: report.results.length }\n : { status: \"failed\", failures: report.failures };\n}\n\n/**\n * Prints a verification outcome\n *\n * @returns True if generation should proceed\n */\nfunction reportVerification(outcome: VerificationOutcome): boolean {\n if (outcome.status === \"verified\") {\n logSuccess(`Verified ${outcome.count} migration(s): up and down both apply and the state round-trips`);\n return true;\n }\n\n if (outcome.status === \"incompatible\") {\n logError(\"Generated migration uses JavaScript PocketBase cannot run - no files were written.\");\n console.log();\n for (const result of outcome.results) {\n for (const finding of result.findings.filter((entry) => entry.severity === \"error\")) {\n console.log(` ${formatGojaLintFinding(finding)}`);\n }\n }\n console.log();\n logInfo(\"This is a bug in the generator - please report it with the schema that produced it.\");\n return false;\n }\n\n if (outcome.status === \"baseline-unexecutable\") {\n logError(\"Cannot verify: an existing migration could not be executed.\");\n console.error();\n console.error(outcome.error.getDetailedMessage());\n console.error();\n logInfo(\"Fix the migration above, or run without --verify.\");\n return false;\n }\n\n logError(\"Migration verification failed - no files were written.\");\n console.log();\n\n for (const failure of outcome.failures) {\n if (failure.error) {\n console.log(` ${failure.file}: ${failure.error.phase}() failed`);\n console.log(` ${failure.error.message}`);\n continue;\n }\n\n const reason = failure.missingDown ? \"no down() to undo it\" : \"down() did not restore the previous state\";\n console.log(` ${failure.file}: ${reason}`);\n for (const difference of failure.differences) {\n console.log(` ${difference.message}`);\n }\n }\n\n console.log();\n logInfo(\"Suggestions:\");\n console.log(\" • Re-run with --no-verify to write the migration(s) anyway\");\n console.log(\" • Report the differences above if the migration was generated from a Zod schema\");\n return false;\n}\n\n/**\n * Executes the generate command\n *\n * @param filters - Optional filters for collection/field names\n * @param options - Command options\n */\nexport async function executeGenerate(filters: string[], options: any): Promise<void> {\n try {\n // Set verbosity based on global options\n const parentOpts = options.parent?.opts?.() || {};\n if (parentOpts.verbose) {\n setVerbosity(\"verbose\");\n } else if (parentOpts.quiet) {\n setVerbosity(\"quiet\");\n }\n\n logDebug(\"Starting migration generation...\");\n logDebug(`Options: ${JSON.stringify(options, null, 2)}`);\n if (filters && filters.length > 0) {\n logDebug(`Filters: ${JSON.stringify(filters)}`);\n }\n\n // Load configuration\n const config = await loadConfig(options);\n\n // Get paths\n const schemaDir = getSchemaDirectory(config);\n const migrationsDir = getMigrationsDirectory(config);\n\n logSection(\"🔍 Analyzing Schema\");\n\n // Parse schema files with full config (including exclude patterns)\n const analyzerConfig = {\n schemaDir,\n excludePatterns: config.schema.exclude,\n useCompiledFiles: false, // Use source files since we're in development/testing\n };\n const currentSchema: SchemaDefinition = await withProgress(\"Parsing Zod schemas...\", () =>\n parseSchemaFiles(analyzerConfig)\n );\n\n logSuccess(`Found ${currentSchema.collections.size} collection(s)`);\n\n // Load previous snapshot from migrations directory and apply subsequent migrations\n logInfo(\"Loading previous snapshot...\");\n const previousSnapshot = loadSnapshotWithMigrations({\n migrationsPath: migrationsDir,\n workspaceRoot: process.cwd(),\n });\n\n if (!previousSnapshot) {\n logInfo(\"No previous snapshot found - treating as empty database (first-time generation)\");\n } else {\n logSuccess(\"Loaded previous snapshot as base reference\");\n }\n\n // Compare schemas\n logSection(\"📊 Comparing Schemas\");\n let diff = compare(currentSchema, previousSnapshot);\n\n // Apply filtering (patterns and destructive skipping)\n const skipDestructive = !options.force;\n\n // Check for destructive changes BEFORE filtering if we are going to skip them (for logging)\n // Only if we are NOT forcing.\n if (skipDestructive) {\n const destructive = detectDestructiveChanges(diff);\n if (destructive.length > 0) {\n logInfo(`ℹ️ Omitting ${destructive.length} destructive change(s) because --force is not set.`);\n }\n }\n\n // Apply filter\n diff = filterDiff(diff, {\n patterns: filters,\n skipDestructive: skipDestructive,\n });\n\n // Check if there are any changes\n if (!hasChanges(diff)) {\n logInfo(\"No changes detected\");\n console.log();\n logSuccess(\"Schema is up to date!\");\n return;\n }\n\n // Display change summary\n console.log();\n console.log(formatChangeSummary(diff));\n\n // Handle destructive changes\n // If skipDestructive was true, diff shouldn't have any destructive changes, so this will pass.\n // If force was true, skipDestructive was false, diff might have destructive changes, this will warn and proceed.\n if (!handleDestructiveChanges(diff, config, options.force)) {\n process.exit(1);\n }\n\n // Generate migration\n logSection(\"📝 Generating Migration\");\n\n const planned = await withProgress(\"Creating migration file...\", () =>\n Promise.resolve(planMigrations(diff, { migrationDir: migrationsDir, force: options.force }))\n );\n\n if (planned.length === 0) {\n logWarning(\"No migration files were generated (no changes detected or duplicate migration).\");\n return;\n }\n\n // Self-verify before writing: execute up() and down() in the simulated\n // PocketBase JSVM and confirm the state round-trips\n if (config.migrations.verify) {\n logSection(\"🔁 Verifying Migration\");\n\n const outcome = await withProgress(\"Executing up() and down()...\", () =>\n Promise.resolve(verifyPlannedMigrations(planned, migrationsDir))\n );\n\n if (!reportVerification(outcome)) {\n console.error();\n process.exit(1);\n }\n }\n\n const migrationPaths = writePlannedMigrations(planned, migrationsDir);\n\n if (migrationPaths.length === 1) {\n logSuccess(`Migration file created: ${path.basename(migrationPaths[0])}`);\n } else {\n logSuccess(`Created ${migrationPaths.length} migration files`);\n }\n\n // Note: Snapshot is embedded in the generated migration file\n // No separate snapshot file needed\n\n // Display next steps\n logSection(\"✅ Next Steps\");\n console.log();\n console.log(\" 1. Review the generated migration file(s):\");\n migrationPaths.forEach((migrationPath: string) => {\n console.log(` ${migrationPath}`);\n });\n console.log();\n console.log(\" 2. Apply the migration by running PocketBase:\");\n console.log(\" yarn pb\");\n console.log();\n console.log(\" Or apply migrations manually:\");\n console.log(\" cd pb && ./pocketbase migrate up\");\n console.log();\n } catch (error) {\n // Handle specific error types with helpful messages\n if (error instanceof SchemaParsingError) {\n logError(\"Schema Parsing Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Make sure your schema files are valid Zod schemas\");\n console.log(' • Run \"yarn build\" in the shared workspace to compile TypeScript files');\n console.log(' • Check that schema files export schemas ending with \"Schema\" or \"InputSchema\"');\n } else if (error instanceof SnapshotError) {\n logError(\"Snapshot Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the snapshot file is not corrupted\");\n console.log(\" • Verify file permissions for the snapshot file\");\n console.log(\" • If this is the first run, this error should not occur\");\n } else if (error instanceof MigrationGenerationError) {\n logError(\"Migration Generation Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the migration directory exists and is writable\");\n console.log(\" • Verify you have sufficient disk space\");\n console.log(\" • Check file permissions for the migration directory\");\n } else if (error instanceof FileSystemError) {\n logError(\"File System Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check file and directory permissions\");\n console.log(\" • Verify you have sufficient disk space\");\n console.log(\" • Ensure the paths are correct and accessible\");\n } else if (error instanceof ConfigurationError) {\n logError(\"Configuration Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check your configuration file syntax\");\n console.log(\" • Verify all paths are correct and accessible\");\n console.log(\" • Run with --verbose flag for more details\");\n } else {\n // Generic error handling\n logError(`Failed to generate migration: ${error}`);\n if (error instanceof Error && error.stack) {\n console.error();\n console.error(error.stack);\n }\n }\n\n console.error();\n process.exit(1);\n }\n}\n\n/**\n * Creates the generate command\n *\n * @returns Commander command instance\n */\nexport function createGenerateCommand(): Command {\n return new Command(\"generate\")\n .description(\"Generate a migration from schema changes\")\n .argument(\"[filters...]\", \"Filter migrations by collection or field name (regex supported)\")\n .option(\"-o, --output <directory>\", \"Output directory for migration files\")\n .option(\"-f, --force\", \"Force generation even with destructive changes or duplicates\", false)\n .option(\"--dry-run\", \"Show what would be generated without creating files\", false)\n .option(\"--schema-dir <directory>\", \"Directory containing Zod schema files\")\n .option(\"--verify\", \"Execute up() and down() before writing, and refuse migrations that do not roll back\")\n .option(\"--no-verify\", \"Skip round-trip verification even when it is enabled in the configuration\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ pocketbase-migrate generate Generate migration from schema changes\n $ pocketbase-migrate generate User Generate migration only for User collection\n $ pocketbase-migrate generate User.name Generate migration only for User.name field\n $ pocketbase-migrate generate --force Force generation with destructive changes\n $ pocketbase-migrate generate --dry-run Preview changes without generating files\n $ pocketbase-migrate generate --verify Verify up() and down() round-trip before writing\n $ pocketbase-migrate generate -o ./migrations Specify output directory\n`\n )\n .action(executeGenerate);\n}\n","/**\n * Status command implementation\n * Shows current migration status without generating files\n */\n\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport {\n AppliedMigrationsError,\n categorizeChangesBySeverity,\n compare,\n parseSchemaFiles,\n planMigrationReplay,\n readAppliedMigrationsIfPresent,\n type AppliedMigrationsSource,\n type MigrationPlan,\n} from \"../../migration/index.js\";\nimport { ConfigurationError, SchemaParsingError, SnapshotError } from \"../../migration/errors.js\";\nimport { loadSnapshotWithMigrations } from \"../../migration/snapshot.js\";\nimport type { SchemaDefinition, SchemaDiff, SchemaSnapshot } from \"../../migration/types.js\";\nimport { getDataDirectory, getMigrationsDirectory, getSchemaDirectory, loadConfig } from \"../utils/config.js\";\nimport {\n formatChangeSummary,\n formatStatusJson,\n logDebug,\n logError,\n logInfo,\n logKeyValue,\n logSection,\n logSuccess,\n logTable,\n setVerbosity,\n withProgress,\n type StatusOutput,\n} from \"../utils/logger.js\";\n\n/**\n * Checks if there are any changes in the diff\n *\n * @param diff - Schema diff to check\n * @returns True if there are changes\n */\nfunction hasChanges(diff: SchemaDiff): boolean {\n return (\n diff.collectionsToCreate.length > 0 || diff.collectionsToDelete.length > 0 || diff.collectionsToModify.length > 0\n );\n}\n\n/**\n * Checks if there are any destructive changes\n *\n * @param diff - Schema diff to check\n * @returns True if there are destructive changes\n */\nfunction hasDestructiveChanges(diff: SchemaDiff): boolean {\n const { destructive } = categorizeChangesBySeverity(diff);\n return destructive.length > 0;\n}\n\n/**\n * Creates a status output object for JSON mode\n *\n * @param status - Status type\n * @param currentCount - Current schema collection count\n * @param snapshotCount - Snapshot collection count\n * @param diff - Schema diff (optional)\n * @returns Status output object\n */\nfunction createStatusOutput(\n status: StatusOutput[\"status\"],\n currentCount: number,\n snapshotCount: number,\n diff?: SchemaDiff,\n plan?: MigrationPlan | null,\n appliedDiff?: SchemaDiff | null\n): StatusOutput {\n return {\n status,\n collections: {\n current: currentCount,\n snapshot: snapshotCount,\n },\n changes: {\n create: diff?.collectionsToCreate.length ?? 0,\n delete: diff?.collectionsToDelete.length ?? 0,\n modify: diff?.collectionsToModify.length ?? 0,\n },\n destructive: diff ? hasDestructiveChanges(diff) : false,\n ...(plan?.appliedKnown\n ? {\n migrations: {\n source: plan.appliedOrigin ?? \"\",\n applied: plan.appliedCount,\n pending: plan.pending,\n missing: plan.missing,\n outOfOrder: plan.outOfOrder,\n inSync: plan.inSync,\n ...(appliedDiff\n ? {\n unapplied: {\n create: appliedDiff.collectionsToCreate.length,\n delete: appliedDiff.collectionsToDelete.length,\n modify: appliedDiff.collectionsToModify.length,\n },\n }\n : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * What the applied-migrations lookup produced. `unavailable` is not an error\n * by itself — most checkouts have never run PocketBase — but it does mean\n * `--verify` has nothing to compare against.\n */\ntype AppliedLookup =\n | { status: \"found\"; applied: AppliedMigrationsSource; plan: MigrationPlan }\n | { status: \"unavailable\"; dataPath: string }\n | { status: \"failed\"; dataPath: string; message: string };\n\n/**\n * Reads PocketBase's `_migrations` table and plans the replay against it.\n *\n * @param migrationsDir - Directory holding the migration files\n * @param dataPath - pb_data directory or data.db file\n */\nfunction lookupAppliedMigrations(migrationsDir: string, dataPath: string): AppliedLookup {\n try {\n const applied = readAppliedMigrationsIfPresent(dataPath);\n if (!applied) {\n return { status: \"unavailable\", dataPath };\n }\n return { status: \"found\", applied, plan: planMigrationReplay(migrationsDir, { applied }) };\n } catch (error) {\n if (error instanceof AppliedMigrationsError) {\n return { status: \"failed\", dataPath, message: error.message };\n }\n throw error;\n }\n}\n\n/**\n * The two states `status` compares the schema against.\n */\nexport interface StatusBaselines {\n /** What every migration file on disk describes — the baseline `generate` uses */\n previousSnapshot: SchemaSnapshot | null;\n /**\n * The schema compared against the state PocketBase is actually in, i.e. the\n * changes the pending files still owe the database. Null when no database\n * was read or when disk and the database agree, in which case it would be\n * identical to the schema comparison.\n */\n appliedDiff: SchemaDiff | null;\n}\n\n/**\n * Reconstructs both baselines.\n *\n * Two baselines, two questions, and mixing them up is what makes `status\n * --verify` contradict `generate`:\n *\n * - every file on disk answers \"does my schema still need a migration\n * written?\". Diffing against the applied-only state instead reports\n * collections that already have a migration file waiting, and then tells the\n * user to run `generate` — which correctly writes nothing.\n * - the applied-only state answers \"is the database behind its files?\", which\n * is reported next to the drift, not as a schema change.\n *\n * @param currentSchema - Schema parsed from the Zod files\n * @param migrationsDir - Directory holding the migration files\n * @param workspaceRoot - Root used to resolve migration imports\n * @param applied - Result of the `_migrations` lookup, if one was made\n */\nexport function loadStatusBaselines(\n currentSchema: SchemaDefinition,\n migrationsDir: string,\n workspaceRoot: string,\n applied: AppliedLookup | null\n): StatusBaselines {\n const previousSnapshot = loadSnapshotWithMigrations({\n migrationsPath: migrationsDir,\n workspaceRoot,\n });\n\n if (applied?.status !== \"found\" || applied.plan.inSync) {\n return { previousSnapshot, appliedDiff: null };\n }\n\n const appliedSnapshot = loadSnapshotWithMigrations({\n migrationsPath: migrationsDir,\n workspaceRoot,\n appliedMigrations: applied.applied,\n });\n\n return { previousSnapshot, appliedDiff: compare(currentSchema, appliedSnapshot) };\n}\n\n/**\n * Prints what the pending migration files will do to the database once\n * applied — the difference between the schema and the state PocketBase is\n * actually in.\n *\n * This is deliberately kept out of the Schema Comparison section: a collection\n * that already has a migration file waiting needs PocketBase to run, not\n * another `generate`.\n *\n * @param appliedDiff - Current schema compared against the applied-only state\n */\nfunction reportUnappliedChanges(appliedDiff: SchemaDiff): void {\n if (!hasChanges(appliedDiff)) {\n return;\n }\n\n console.log(chalk.gray(\" The database is behind those files. Applying them will:\"));\n\n for (const collection of appliedDiff.collectionsToCreate) {\n console.log(chalk.gray(` + create ${collection.name} (${collection.type})`));\n }\n for (const mod of appliedDiff.collectionsToModify) {\n console.log(chalk.gray(` ~ modify ${mod.collection}`));\n }\n for (const collection of appliedDiff.collectionsToDelete) {\n console.log(chalk.gray(` - delete ${collection.name}`));\n }\n\n console.log();\n console.log(chalk.gray(\" Start PocketBase to apply them; no new migration is needed.\"));\n console.log();\n}\n\n/**\n * Prints the disk vs. `_migrations` comparison.\n *\n * @returns True when disk and database agree\n */\nfunction reportAppliedMigrations(plan: MigrationPlan): boolean {\n logSection(\"🧾 Applied Migrations\");\n console.log();\n logKeyValue(\"Database\", plan.appliedOrigin ?? \"unknown\");\n logKeyValue(\"Applied\", String(plan.appliedCount));\n logKeyValue(\"Replaying\", String(plan.filesToReplay.length));\n console.log();\n\n if (plan.inSync) {\n logSuccess(\"✓ Every migration file on disk is applied\");\n return true;\n }\n\n if (plan.pending.length > 0) {\n console.log(chalk.yellow(` ${plan.pending.length} migration(s) on disk not applied to the database:`));\n for (const file of plan.pending) {\n console.log(chalk.yellow(` + ${file}`));\n }\n console.log();\n }\n\n if (plan.missing.length > 0) {\n console.log(chalk.red(` ${plan.missing.length} applied migration(s) missing from disk:`));\n for (const file of plan.missing) {\n console.log(chalk.red(` - ${file}`));\n }\n console.log();\n }\n\n if (plan.outOfOrder.length > 0) {\n console.log(chalk.yellow(\" Pending migrations authored before an already-applied one:\"));\n for (const file of plan.outOfOrder) {\n console.log(chalk.yellow(` ! ${file}`));\n }\n console.log(chalk.gray(\" They will be applied after migrations with later timestamps.\"));\n console.log();\n }\n\n return false;\n}\n\n/**\n * Displays destructive changes summary\n *\n * @param diff - Schema diff containing changes\n */\nfunction displayDestructiveChangesSummary(diff: SchemaDiff): void {\n const { destructive, nonDestructive } = categorizeChangesBySeverity(diff);\n\n if (destructive.length > 0) {\n logSection(\"⚠️ Destructive Changes\");\n console.log();\n for (const change of destructive) {\n console.log(chalk.red(` ${change}`));\n }\n console.log();\n }\n\n if (nonDestructive.length > 0) {\n logSection(\"✓ Non-Destructive Changes\");\n console.log();\n for (const change of nonDestructive) {\n console.log(chalk.green(` ${change}`));\n }\n console.log();\n }\n}\n\n/**\n * Displays a detailed change table\n *\n * @param diff - Schema diff containing changes\n */\nfunction displayChangeTable(diff: SchemaDiff): void {\n const rows: string[][] = [];\n\n // Add collections to create\n for (const collection of diff.collectionsToCreate) {\n rows.push([\n chalk.green(\"+\"),\n collection.name,\n collection.type,\n `${collection.fields.length} fields`,\n chalk.green(\"Create\"),\n ]);\n }\n\n // Add collections to delete\n for (const collection of diff.collectionsToDelete) {\n rows.push([chalk.red(\"-\"), collection.name, collection.type || \"base\", \"-\", chalk.red(\"Delete\")]);\n }\n\n // Add collections to modify\n for (const mod of diff.collectionsToModify) {\n const changes: string[] = [];\n if (mod.fieldsToAdd.length > 0) changes.push(`+${mod.fieldsToAdd.length} fields`);\n if (mod.fieldsToRemove.length > 0) changes.push(`-${mod.fieldsToRemove.length} fields`);\n if (mod.fieldsToModify.length > 0) changes.push(`~${mod.fieldsToModify.length} fields`);\n if (mod.indexesToAdd.length > 0) changes.push(`+${mod.indexesToAdd.length} indexes`);\n if (mod.indexesToRemove.length > 0) changes.push(`-${mod.indexesToRemove.length} indexes`);\n if (mod.rulesToUpdate.length > 0) changes.push(`~${mod.rulesToUpdate.length} rules`);\n\n rows.push([chalk.yellow(\"~\"), mod.collection, \"-\", changes.join(\", \") || \"No changes\", chalk.yellow(\"Modify\")]);\n }\n\n if (rows.length > 0) {\n logTable([\"\", \"Collection\", \"Type\", \"Changes\", \"Action\"], rows);\n }\n}\n\n/**\n * Executes the status command\n *\n * @param options - Command options\n */\nexport async function executeStatus(options: any): Promise<void> {\n const isJsonMode = options.json === true;\n\n try {\n // Set verbosity based on global options (quiet in JSON mode)\n if (isJsonMode) {\n setVerbosity(\"quiet\");\n } else {\n const parentOpts = options.parent?.opts?.() || {};\n if (parentOpts.verbose) {\n setVerbosity(\"verbose\");\n } else if (parentOpts.quiet) {\n setVerbosity(\"quiet\");\n }\n }\n\n logDebug(\"Checking migration status...\");\n logDebug(`Options: ${JSON.stringify(options, null, 2)}`);\n\n // Load configuration\n const config = await loadConfig(options);\n\n // Get paths\n const schemaDir = getSchemaDirectory(config);\n const migrationsDir = getMigrationsDirectory(config);\n\n logSection(\"🔍 Checking Migration Status\");\n\n // Parse schema files with full config (including exclude patterns)\n const analyzerConfig = {\n schemaDir,\n excludePatterns: config.schema.exclude,\n useCompiledFiles: false, // Use source files since we're in development/testing\n };\n const currentSchema: SchemaDefinition = await withProgress(\"Parsing Zod schemas...\", () => parseSchemaFiles(analyzerConfig));\n\n logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);\n\n // Reconstruct state from what PocketBase has actually applied, rather\n // than from every file on disk, when a database is available to ask\n const useAppliedMigrations = options.verify === true || typeof options.pbData === \"string\";\n const applied: AppliedLookup | null = useAppliedMigrations\n ? lookupAppliedMigrations(migrationsDir, getDataDirectory(config))\n : null;\n\n if (applied?.status === \"failed\") {\n logError(`Could not read applied migrations: ${applied.message}`);\n process.exit(1);\n }\n\n if (applied?.status === \"unavailable\") {\n logError(`No PocketBase database found at ${applied.dataPath}`);\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Start PocketBase once so it creates pb_data/data.db\");\n console.log(\" • Point at another location with --pb-data <path>\");\n process.exit(1);\n }\n\n logInfo(\"Loading previous snapshot...\");\n const { previousSnapshot, appliedDiff } = loadStatusBaselines(currentSchema, migrationsDir, process.cwd(), applied);\n\n // Drift is reported before the schema comparison, and fails the command\n // when it was explicitly asked for — but the rest of the status still\n // prints, because knowing what else changed is the point of running it\n if (applied?.status === \"found\" && !isJsonMode) {\n const inSync = reportAppliedMigrations(applied.plan);\n if (!inSync) {\n if (appliedDiff) {\n reportUnappliedChanges(appliedDiff);\n }\n if (options.verify === true) {\n process.exitCode = 1;\n }\n }\n } else if (applied?.status === \"found\" && !applied.plan.inSync && options.verify === true) {\n process.exitCode = 1;\n }\n\n // Handle first-time setup\n if (!previousSnapshot) {\n if (isJsonMode) {\n const output = createStatusOutput(\n \"first-time-setup\",\n currentSchema.collections.size,\n 0,\n undefined,\n applied?.status === \"found\" ? applied.plan : null,\n appliedDiff\n );\n console.log(formatStatusJson(output));\n return;\n }\n\n logSection(\"🆕 First-Time Setup Detected\");\n console.log();\n logInfo(\"No previous snapshot found. This appears to be a first-time setup.\");\n console.log();\n logKeyValue(\"Collections in schema\", String(currentSchema.collections.size));\n console.log();\n logInfo('Run \"pocketbase-migrate generate\" to create the initial migration.');\n return;\n }\n\n logSuccess(`Loaded snapshot with ${previousSnapshot.collections.size} collection(s)`);\n\n // Compare schemas against the migration files, not against the database:\n // this section answers \"what still needs a migration written?\"\n logSection(\"📊 Schema Comparison\");\n if (appliedDiff && !isJsonMode) {\n console.log(chalk.gray(\" Compared against the migration files on disk, the same baseline generate uses.\"));\n }\n const diff = compare(currentSchema, previousSnapshot);\n\n // Check if there are any changes\n if (!hasChanges(diff)) {\n if (isJsonMode) {\n const output = createStatusOutput(\n \"up-to-date\",\n currentSchema.collections.size,\n previousSnapshot.collections.size,\n diff,\n applied?.status === \"found\" ? applied.plan : null,\n appliedDiff\n );\n console.log(formatStatusJson(output));\n return;\n }\n\n console.log();\n logSuccess(\"✓ Schema is in sync with the migration files\");\n logInfo(\"No pending changes detected\");\n console.log();\n logKeyValue(\"Collections\", String(currentSchema.collections.size));\n\n if (appliedDiff && hasChanges(appliedDiff)) {\n console.log();\n logInfo(\"The database is still behind those files — see Applied Migrations above.\");\n }\n return;\n }\n\n // Handle JSON output mode\n if (isJsonMode) {\n const output = createStatusOutput(\n \"changes-pending\",\n currentSchema.collections.size,\n previousSnapshot.collections.size,\n diff,\n applied?.status === \"found\" ? applied.plan : null,\n appliedDiff\n );\n console.log(formatStatusJson(output));\n return;\n }\n\n // Display change summary\n console.log();\n console.log(formatChangeSummary(diff));\n\n // Display change table in verbose mode\n logDebug(\"Detailed change table:\");\n displayChangeTable(diff);\n\n // Display categorized changes\n displayDestructiveChangesSummary(diff);\n\n // Display next steps\n logSection(\"📝 Next Steps\");\n console.log();\n console.log(\" To generate a migration for these changes, run:\");\n console.log(chalk.cyan(\" pocketbase-migrate generate\"));\n console.log();\n\n const { destructive } = categorizeChangesBySeverity(diff);\n if (destructive.length > 0) {\n console.log(chalk.yellow(\" ⚠️ Destructive changes detected. Use --force flag when generating:\"));\n console.log(chalk.cyan(\" pocketbase-migrate generate --force\"));\n console.log();\n }\n } catch (error) {\n // Handle specific error types with helpful messages\n if (error instanceof SchemaParsingError) {\n logError(\"Schema Parsing Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Make sure your schema files are valid Zod schemas\");\n console.log(' • Check that schema files export schemas ending with \"Schema\" or \"InputSchema\"');\n } else if (error instanceof SnapshotError) {\n logError(\"Snapshot Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check that the snapshot file is not corrupted\");\n console.log(\" • Verify file permissions for the snapshot file\");\n } else if (error instanceof ConfigurationError) {\n logError(\"Configuration Error\");\n console.error();\n console.error(error.getDetailedMessage());\n console.error();\n logInfo(\"Suggestions:\");\n console.log(\" • Check your configuration file syntax\");\n console.log(\" • Verify all paths are correct and accessible\");\n } else {\n logError(`Failed to check status: ${error}`);\n if (error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n }\n process.exit(1);\n }\n}\n\n/**\n * Creates the status command\n *\n * @returns Commander command instance\n */\nexport function createStatusCommand(): Command {\n return new Command(\"status\")\n .description(\"Show current migration status without generating files\")\n .option(\"--schema-dir <directory>\", \"Directory containing Zod schema files\")\n .option(\"--json\", \"Output status as JSON for programmatic use\", false)\n .option(\n \"--verify\",\n \"Compare the migration files on disk against PocketBase's _migrations table and fail on any drift\"\n )\n .option(\"--pb-data <path>\", \"PocketBase data directory or data.db file (defaults to pb_data next to migrations)\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ pocketbase-migrate status Check for pending schema changes\n $ pocketbase-migrate status --json Output status as JSON\n $ pocketbase-migrate status --verbose Show detailed status information\n $ pocketbase-migrate status --verify Fail if disk and the database disagree on applied migrations\n`\n )\n .action(executeStatus);\n}\n"]}
|