@famgia/omnify-core 0.0.113 → 0.0.115

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors/omnify-error.ts","../src/errors/formatter.ts","../src/errors/factories.ts","../src/schema/loader.ts","../src/validation/validator.ts","../src/validation/types/base.ts","../src/validation/types/registry.ts","../src/validation/types/primitives.ts","../src/validation/types/text.ts","../src/validation/types/numeric.ts","../src/validation/types/temporal.ts","../src/validation/types/special.ts","../src/validation/types/enum.ts","../src/validation/types/relations.ts","../src/validation/types/index.ts","../src/plugins/generator-runner.ts","../src/plugins/manager.ts","../src/plugins/expander.ts","../src/api/omnify.ts","../src/api/metadata.ts","../src/history/version-store.ts"],"sourcesContent":["/**\n * @famgia/omnify-core\n * Schema loading, validation, and transformation\n *\n * This package provides the core functionality for omnify-schema:\n * - Error handling with file:line:message:suggestion format\n * - Schema loading and validation (coming soon)\n * - Plugin management (coming soon)\n * - Configuration loading (coming soon)\n */\n\n// ============================================================================\n// Re-export types from @famgia/omnify-types for convenience\n// ============================================================================\n\nexport type {\n // Schema types\n SchemaDefinition,\n PropertyDefinition,\n PropertyType,\n AssociationRelation,\n SchemaOptions,\n LoadedSchema,\n SchemaCollection,\n // Config types\n OmnifyConfig,\n DatabaseConfig,\n OutputConfig,\n // Plugin types\n OmnifyPlugin,\n CustomTypeDefinition,\n // Error types\n ErrorCode,\n ErrorLocation,\n OmnifyErrorInfo,\n Result,\n} from '@famgia/omnify-types';\n\nexport { ok, err } from '@famgia/omnify-types';\n\n// ============================================================================\n// Error handling\n// ============================================================================\n\nexport {\n // Error class\n OmnifyError,\n // Formatter\n formatError,\n formatErrorSummary,\n formatErrorPlain,\n getExitCode,\n type FormatOptions,\n // Factory functions - Config errors\n configError,\n configNotFoundError,\n invalidConfigError,\n missingConfigFieldError,\n // Factory functions - Schema parsing errors\n schemaParseError,\n schemaNotFoundError,\n yamlSyntaxError,\n jsonSyntaxError,\n // Factory functions - Validation errors\n validationError,\n invalidPropertyTypeError,\n missingFieldError,\n invalidAssociationTargetError,\n circularReferenceError,\n duplicateSchemaError,\n // Factory functions - Plugin errors\n pluginError,\n pluginNotFoundError,\n pluginTypeConflictError,\n // Factory functions - Atlas errors\n atlasError,\n atlasNotFoundError,\n // Factory functions - Generation errors\n generationError,\n outputWriteError,\n // Factory functions - Internal errors\n internalError,\n notImplementedError,\n} from './errors/index.js';\n\n// ============================================================================\n// Schema loading\n// ============================================================================\n\nexport {\n // Loader functions\n loadSchema,\n loadSchemas,\n // Parser utilities\n parseYamlSchema,\n parseJsonSchema,\n fileNameToSchemaName,\n // File schema utilities\n FILE_SCHEMA_NAME,\n schemasHaveFileProperties,\n createFileSchemaDefinition,\n createFileLoadedSchema,\n generateFileSchemaYaml,\n ensureFileSchema,\n // Types\n type LoadSchemaOptions,\n type LoadSchemasOptions,\n} from './schema/index.js';\n\n// ============================================================================\n// Schema validation\n// ============================================================================\n\nexport {\n // Main validation functions\n validateSchema,\n validateSchemas,\n // Individual validators\n validateProperties,\n validatePropertyType,\n validateAssociations,\n validateOptions,\n validateEnumSchema,\n // Default value validation\n validateDefaultValue,\n // Types\n type SchemaValidationResult,\n type ValidationResult,\n type ValidationOptions,\n type DefaultValueValidationResult,\n} from './validation/index.js';\n\n// ============================================================================\n// Plugin management\n// ============================================================================\n\nexport {\n // Plugin Manager\n PluginManager,\n createPluginManager,\n // Compound Type Expansion\n expandProperty,\n expandSchemaProperties,\n expandSchema,\n expandSchemas,\n getTypeInfo,\n isCompoundType,\n getCustomTypeNames,\n // Types\n type RegisteredType,\n type PluginRegistry,\n type PluginManagerOptions,\n type PluginRegistrationResult,\n type ExpandedProperty,\n} from './plugins/index.js';\n\n// ============================================================================\n// Programmatic API\n// ============================================================================\n\nexport {\n // Main API\n Omnify,\n createOmnify,\n // Types\n type OmnifyOptions,\n type OmnifyLogger,\n type LoadResult,\n type DiffOperationResult,\n type GenerateOptions,\n type GenerateResult,\n type GeneratedFile,\n type SchemaError,\n type SchemaWarning,\n type SchemaMetadata,\n type PropertyMetadata,\n type AssociationMetadata,\n type SchemaIntrospection,\n // Metadata utilities\n getSchemaMetadata,\n getPropertyMetadata,\n getAssociationMetadata,\n introspectSchema,\n introspectSchemas,\n getSchemaNames,\n getSchemasByKind,\n getEntitySchemas,\n getEnumSchemas,\n getSchemasByGroup,\n getGroups,\n findReferencingSchemas,\n findReferencedSchemas,\n getRelationshipGraph,\n hasCircularReferences,\n getTopologicalOrder,\n} from './api/index.js';\n\n// ============================================================================\n// Version history\n// ============================================================================\n\nexport {\n // Version Store\n VersionStore,\n createVersionStore,\n // Types\n type VersionFile,\n type VersionSchemaSnapshot,\n type VersionPropertySnapshot,\n type VersionIndexSnapshot,\n type VersionChange,\n type ChangeAction,\n type VersionSummary,\n type VersionDiff,\n type CreateVersionOptions,\n type VersionStoreConfig,\n} from './history/index.js';\n// test auto publish\n","/**\n * @famgia/omnify-core - OmnifyError Class\n *\n * Base error class for all omnify errors with file:line:message:suggestion format.\n */\n\nimport type { ErrorCode, ErrorLocation, OmnifyErrorInfo } from '@famgia/omnify-types';\n\n/**\n * Base error class for omnify-schema.\n * Provides consistent error formatting with source location and suggestions.\n *\n * @example\n * ```typescript\n * throw new OmnifyError(\n * \"Invalid property type 'Stringg'\",\n * 'E201',\n * { file: 'schemas/User.yaml', line: 15, column: 10 },\n * \"Did you mean 'String'?\"\n * );\n * ```\n */\nexport class OmnifyError extends Error {\n /** Error code (e.g., 'E201') */\n readonly code: ErrorCode;\n\n /** Source location where the error occurred */\n readonly location?: ErrorLocation;\n\n /** Suggested fix for the error */\n readonly suggestion?: string;\n\n /** Additional context or details */\n readonly details?: Record<string, unknown>;\n\n /** Original error if this wraps another error */\n override readonly cause?: Error;\n\n constructor(\n message: string,\n code: ErrorCode,\n location?: ErrorLocation,\n suggestion?: string,\n options?: {\n details?: Record<string, unknown>;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = 'OmnifyError';\n this.code = code;\n\n // Only assign optional properties when they have values\n // (required for exactOptionalPropertyTypes)\n if (location !== undefined) {\n this.location = location;\n }\n if (suggestion !== undefined) {\n this.suggestion = suggestion;\n }\n if (options?.details !== undefined) {\n this.details = options.details;\n }\n if (options?.cause !== undefined) {\n this.cause = options.cause;\n }\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, OmnifyError);\n }\n }\n\n /**\n * Creates an OmnifyError from an OmnifyErrorInfo object.\n */\n static fromInfo(info: OmnifyErrorInfo): OmnifyError {\n const options: { details?: Record<string, unknown>; cause?: Error } = {};\n if (info.details !== undefined) {\n options.details = info.details;\n }\n if (info.cause !== undefined) {\n options.cause = info.cause;\n }\n\n return new OmnifyError(\n info.message,\n info.code,\n info.location,\n info.suggestion,\n Object.keys(options).length > 0 ? options : undefined\n );\n }\n\n /**\n * Wraps an unknown error as an OmnifyError.\n * Useful for catching and re-throwing with context.\n */\n static wrap(\n error: unknown,\n code: ErrorCode = 'E901',\n location?: ErrorLocation\n ): OmnifyError {\n if (error instanceof OmnifyError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n\n if (error instanceof Error) {\n return new OmnifyError(message, code, location, undefined, { cause: error });\n }\n return new OmnifyError(message, code, location);\n }\n\n /**\n * Converts to OmnifyErrorInfo for serialization.\n */\n toInfo(): OmnifyErrorInfo {\n const info: OmnifyErrorInfo = {\n code: this.code,\n message: this.message,\n };\n\n // Only include optional properties if they have values\n if (this.location !== undefined) {\n (info as { location: ErrorLocation }).location = this.location;\n }\n if (this.suggestion !== undefined) {\n (info as { suggestion: string }).suggestion = this.suggestion;\n }\n if (this.details !== undefined) {\n (info as { details: Record<string, unknown> }).details = this.details;\n }\n if (this.cause !== undefined) {\n (info as { cause: Error }).cause = this.cause;\n }\n\n return info;\n }\n\n /**\n * Returns a formatted string representation.\n * Format: \"Error [CODE]: message\\n --> file:line:column\"\n */\n override toString(): string {\n const parts: string[] = [];\n\n // Header: Error [E201]: message\n parts.push(`Error [${this.code}]: ${this.message}`);\n\n // Location: --> file:line:column\n if (this.location?.file) {\n const loc = this.location;\n let locationStr = ` --> ${loc.file}`;\n if (loc.line !== undefined) {\n locationStr += `:${loc.line}`;\n if (loc.column !== undefined) {\n locationStr += `:${loc.column}`;\n }\n }\n parts.push(locationStr);\n }\n\n // Suggestion\n if (this.suggestion) {\n parts.push(` Suggestion: ${this.suggestion}`);\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Returns the file path from location, if available.\n */\n get file(): string | undefined {\n return this.location?.file;\n }\n\n /**\n * Returns the line number from location, if available.\n */\n get line(): number | undefined {\n return this.location?.line;\n }\n\n /**\n * Returns the column number from location, if available.\n */\n get column(): number | undefined {\n return this.location?.column;\n }\n}\n","/**\n * @famgia/omnify-core - Error Formatter\n *\n * Formats errors for CLI output with optional ANSI colors.\n */\n\nimport type { OmnifyError } from './omnify-error.js';\n\n/**\n * ANSI color codes for terminal output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n} as const;\n\n/**\n * Options for error formatting.\n */\nexport interface FormatOptions {\n /** Enable ANSI color codes */\n readonly color?: boolean;\n /** Show source context lines */\n readonly showContext?: boolean;\n /** Number of context lines to show */\n readonly contextLines?: number;\n /** Source file content (for showing context) */\n readonly sourceContent?: string;\n}\n\n/**\n * Applies color if enabled, otherwise returns the text as-is.\n */\nfunction colorize(\n text: string,\n colorCode: string,\n enabled: boolean\n): string {\n return enabled ? `${colorCode}${text}${colors.reset}` : text;\n}\n\n/**\n * Formats an OmnifyError for CLI output.\n *\n * @example Output:\n * ```\n * error[E201]: Invalid property type 'Stringg'\n * --> schemas/User.yaml:15:10\n * |\n * 15 | type: Stringg\n * | ^^^^^^^ Did you mean 'String'?\n * |\n * = suggestion: Use one of: String, Int, Boolean, Text, ...\n * ```\n */\nexport function formatError(\n error: OmnifyError,\n options: FormatOptions = {}\n): string {\n const {\n color = true,\n showContext = true,\n contextLines = 2,\n sourceContent,\n } = options;\n\n const lines: string[] = [];\n\n // Header: error[E201]: message\n const errorLabel = colorize('error', colors.red + colors.bold, color);\n const code = colorize(`[${error.code}]`, colors.red, color);\n const message = colorize(error.message, colors.bold, color);\n lines.push(`${errorLabel}${code}: ${message}`);\n\n // Location: --> file:line:column\n const locFile = error.location?.file;\n if (locFile !== undefined) {\n const loc = error.location;\n let locationStr = colorize(' --> ', colors.blue, color);\n locationStr += colorize(locFile, colors.cyan, color);\n if (loc?.line !== undefined) {\n locationStr += `:${loc.line}`;\n if (loc.column !== undefined) {\n locationStr += `:${loc.column}`;\n }\n }\n lines.push(locationStr);\n }\n\n // Source context\n if (\n showContext &&\n sourceContent &&\n error.location?.line !== undefined\n ) {\n const contextOutput = formatSourceContext(\n sourceContent,\n error.location.line,\n error.location.column,\n error.suggestion,\n contextLines,\n color\n );\n lines.push(contextOutput);\n }\n\n // Suggestion (if no source context shown)\n if (error.suggestion && (!showContext || !sourceContent)) {\n const suggestionLabel = colorize(' = suggestion:', colors.cyan, color);\n lines.push(`${suggestionLabel} ${error.suggestion}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats source context around the error location.\n */\nfunction formatSourceContext(\n source: string,\n errorLine: number,\n errorColumn: number | undefined,\n suggestion: string | undefined,\n contextCount: number,\n colorEnabled: boolean\n): string {\n const sourceLines = source.split('\\n');\n const startLine = Math.max(1, errorLine - contextCount);\n const endLine = Math.min(sourceLines.length, errorLine + contextCount);\n const gutterWidth = String(endLine).length;\n\n const output: string[] = [];\n\n // Empty gutter line\n output.push(colorize(`${' '.repeat(gutterWidth)} |`, colors.blue, colorEnabled));\n\n for (let i = startLine; i <= endLine; i++) {\n const lineContent = sourceLines[i - 1] ?? '';\n const lineNum = String(i).padStart(gutterWidth, ' ');\n const gutter = colorize(`${lineNum} |`, colors.blue, colorEnabled);\n\n output.push(`${gutter} ${lineContent}`);\n\n // Add underline on error line\n if (i === errorLine && errorColumn !== undefined) {\n const underlineGutter = colorize(\n `${' '.repeat(gutterWidth)} |`,\n colors.blue,\n colorEnabled\n );\n const spaces = ' '.repeat(errorColumn - 1);\n const underline = colorize('^', colors.red, colorEnabled);\n let underlineLine = `${underlineGutter} ${spaces}${underline}`;\n\n if (suggestion) {\n underlineLine += ` ${colorize(suggestion, colors.yellow, colorEnabled)}`;\n }\n\n output.push(underlineLine);\n }\n }\n\n // Empty gutter line\n output.push(colorize(`${' '.repeat(gutterWidth)} |`, colors.blue, colorEnabled));\n\n return output.join('\\n');\n}\n\n/**\n * Formats multiple errors as a summary.\n */\nexport function formatErrorSummary(\n errors: readonly OmnifyError[],\n options: FormatOptions = {}\n): string {\n const { color = true } = options;\n\n if (errors.length === 0) {\n return '';\n }\n\n const formattedErrors = errors.map((e) => formatError(e, options));\n const summary = colorize(\n `\\nFound ${errors.length} error${errors.length === 1 ? '' : 's'}`,\n colors.red + colors.bold,\n color\n );\n\n return formattedErrors.join('\\n\\n') + summary;\n}\n\n/**\n * Formats an error for plain text output (no colors).\n */\nexport function formatErrorPlain(error: OmnifyError): string {\n return formatError(error, { color: false, showContext: false });\n}\n\n/**\n * Gets the exit code for an error based on its code category.\n */\nexport function getExitCode(error: OmnifyError): number {\n const category = error.code.charAt(1);\n\n switch (category) {\n case '0': // Configuration errors\n return 3;\n case '2': // Validation errors\n return 2;\n default: // All other errors\n return 1;\n }\n}\n","/**\n * @famgia/omnify-core - Error Factory Functions\n *\n * Convenient factory functions for creating common error types.\n */\n\nimport type { ErrorCode, ErrorLocation } from '@famgia/omnify-types';\nimport { OmnifyError } from './omnify-error.js';\n\n/**\n * Helper to build ErrorLocation objects safely with exactOptionalPropertyTypes.\n */\nfunction buildLocation(\n file: string,\n line?: number,\n column?: number\n): ErrorLocation {\n const loc: ErrorLocation = { file };\n if (line !== undefined) {\n (loc as { line: number }).line = line;\n }\n if (column !== undefined) {\n (loc as { column: number }).column = column;\n }\n return loc;\n}\n\n/**\n * Helper to build options object safely.\n */\nfunction buildOptions(cause?: Error): { cause: Error } | undefined {\n return cause !== undefined ? { cause } : undefined;\n}\n\n// ============================================================================\n// Configuration Errors (E0xx)\n// ============================================================================\n\n/**\n * Creates a configuration error.\n */\nexport function configError(\n message: string,\n code: ErrorCode = 'E002',\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, code, undefined, suggestion);\n}\n\n/**\n * Config file not found error.\n */\nexport function configNotFoundError(configPath: string): OmnifyError {\n return new OmnifyError(\n `Configuration file not found: ${configPath}`,\n 'E001',\n { file: configPath },\n 'Run `omnify init` to create a configuration file'\n );\n}\n\n/**\n * Invalid config format error.\n */\nexport function invalidConfigError(\n message: string,\n configPath: string\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E002',\n { file: configPath },\n 'Check your omnify.config.ts for syntax errors'\n );\n}\n\n/**\n * Missing required config field error.\n */\nexport function missingConfigFieldError(\n field: string,\n configPath: string\n): OmnifyError {\n return new OmnifyError(\n `Missing required configuration field: ${field}`,\n 'E003',\n { file: configPath },\n `Add '${field}' to your configuration file`\n );\n}\n\n// ============================================================================\n// Schema Parsing Errors (E1xx)\n// ============================================================================\n\n/**\n * Creates a schema parsing error.\n */\nexport function schemaParseError(\n message: string,\n location: ErrorLocation,\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, 'E102', location, suggestion);\n}\n\n/**\n * Schema file not found error.\n */\nexport function schemaNotFoundError(schemaPath: string): OmnifyError {\n return new OmnifyError(\n `Schema file not found: ${schemaPath}`,\n 'E101',\n { file: schemaPath },\n 'Check that the file exists and the path is correct'\n );\n}\n\n/**\n * Invalid YAML syntax error.\n */\nexport function yamlSyntaxError(\n message: string,\n file: string,\n line?: number,\n column?: number\n): OmnifyError {\n return new OmnifyError(\n `Invalid YAML syntax: ${message}`,\n 'E102',\n buildLocation(file, line, column),\n 'Check for proper indentation and YAML syntax'\n );\n}\n\n/**\n * Invalid JSON syntax error.\n */\nexport function jsonSyntaxError(\n message: string,\n file: string,\n line?: number,\n column?: number\n): OmnifyError {\n return new OmnifyError(\n `Invalid JSON syntax: ${message}`,\n 'E103',\n buildLocation(file, line, column),\n 'Check for proper JSON syntax (quotes, commas, brackets)'\n );\n}\n\n// ============================================================================\n// Schema Validation Errors (E2xx)\n// ============================================================================\n\n/**\n * Creates a schema validation error.\n */\nexport function validationError(\n message: string,\n location: ErrorLocation,\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, 'E202', location, suggestion);\n}\n\n/**\n * Invalid property type error.\n */\nexport function invalidPropertyTypeError(\n typeName: string,\n location: ErrorLocation,\n validTypes?: readonly string[]\n): OmnifyError {\n const suggestion = validTypes\n ? `Use one of: ${validTypes.slice(0, 5).join(', ')}${validTypes.length > 5 ? ', ...' : ''}`\n : undefined;\n\n return new OmnifyError(\n `Invalid property type '${typeName}'`,\n 'E201',\n location,\n suggestion\n );\n}\n\n/**\n * Missing required field error.\n */\nexport function missingFieldError(\n field: string,\n location: ErrorLocation\n): OmnifyError {\n return new OmnifyError(\n `Missing required field: ${field}`,\n 'E202',\n location,\n `Add '${field}' to the schema definition`\n );\n}\n\n/**\n * Invalid association target error.\n */\nexport function invalidAssociationTargetError(\n target: string,\n location: ErrorLocation,\n availableSchemas?: readonly string[]\n): OmnifyError {\n const suggestion = availableSchemas\n ? `Available schemas: ${availableSchemas.slice(0, 5).join(', ')}${availableSchemas.length > 5 ? ', ...' : ''}`\n : 'Check that the target schema exists';\n\n return new OmnifyError(\n `Invalid association target '${target}'`,\n 'E203',\n location,\n suggestion\n );\n}\n\n/**\n * Circular reference error.\n */\nexport function circularReferenceError(\n path: readonly string[],\n location: ErrorLocation\n): OmnifyError {\n return new OmnifyError(\n `Circular reference detected: ${path.join(' -> ')}`,\n 'E204',\n location,\n 'Remove the circular dependency or use a unidirectional relationship'\n );\n}\n\n/**\n * Duplicate schema name error.\n */\nexport function duplicateSchemaError(\n name: string,\n location: ErrorLocation,\n existingLocation?: ErrorLocation\n): OmnifyError {\n const suggestion = existingLocation?.file\n ? `Schema already defined in ${existingLocation.file}`\n : 'Rename one of the schemas to avoid the conflict';\n\n return new OmnifyError(\n `Duplicate schema name '${name}'`,\n 'E205',\n location,\n suggestion\n );\n}\n\n// ============================================================================\n// Plugin Errors (E3xx)\n// ============================================================================\n\n/**\n * Creates a plugin error.\n */\nexport function pluginError(\n message: string,\n pluginName: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E302',\n undefined,\n `Check the plugin '${pluginName}' for issues`,\n buildOptions(cause)\n );\n}\n\n/**\n * Plugin not found error.\n */\nexport function pluginNotFoundError(pluginName: string): OmnifyError {\n return new OmnifyError(\n `Plugin not found: ${pluginName}`,\n 'E301',\n undefined,\n `Install the plugin with: npm install ${pluginName}`\n );\n}\n\n/**\n * Plugin type conflict error.\n */\nexport function pluginTypeConflictError(\n typeName: string,\n pluginA: string,\n pluginB: string\n): OmnifyError {\n return new OmnifyError(\n `Type '${typeName}' is defined by multiple plugins: ${pluginA}, ${pluginB}`,\n 'E304',\n undefined,\n 'Remove one of the conflicting plugins or rename the type'\n );\n}\n\n// ============================================================================\n// Atlas/Database Errors (E4xx)\n// ============================================================================\n\n/**\n * Creates an Atlas error.\n */\nexport function atlasError(\n message: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E402',\n undefined,\n 'Check Atlas CLI output for details',\n buildOptions(cause)\n );\n}\n\n/**\n * Atlas CLI not found error.\n */\nexport function atlasNotFoundError(): OmnifyError {\n return new OmnifyError(\n 'Atlas CLI not found',\n 'E401',\n undefined,\n 'Install Atlas CLI: https://atlasgo.io/getting-started'\n );\n}\n\n// ============================================================================\n// Generation Errors (E5xx)\n// ============================================================================\n\n/**\n * Creates a generation error.\n */\nexport function generationError(\n message: string,\n outputPath?: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E501',\n outputPath ? { file: outputPath } : undefined,\n undefined,\n buildOptions(cause)\n );\n}\n\n/**\n * Output write error.\n */\nexport function outputWriteError(\n outputPath: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n `Failed to write output file: ${outputPath}`,\n 'E503',\n { file: outputPath },\n 'Check file permissions and disk space',\n buildOptions(cause)\n );\n}\n\n// ============================================================================\n// Internal Errors (E9xx)\n// ============================================================================\n\n/**\n * Creates an internal/unexpected error.\n */\nexport function internalError(\n message: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E901',\n undefined,\n 'This is a bug. Please report it at https://github.com/omnify/omnify-schema/issues',\n buildOptions(cause)\n );\n}\n\n/**\n * Not implemented error.\n */\nexport function notImplementedError(feature: string): OmnifyError {\n return new OmnifyError(\n `Feature not implemented: ${feature}`,\n 'E902',\n undefined,\n 'This feature is planned for a future release'\n );\n}\n","/**\n * @famgia/omnify-core - Schema Loader\n *\n * Load and parse YAML/JSON schema files into internal representation.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport yaml from 'js-yaml';\nimport type {\n SchemaDefinition,\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n SchemaOptions,\n LocalizedString,\n} from '@famgia/omnify-types';\nimport { isLocalizedString } from '@famgia/omnify-types';\nimport {\n schemaNotFoundError,\n yamlSyntaxError,\n jsonSyntaxError,\n duplicateSchemaError,\n} from '../errors/index.js';\n\n/**\n * Options for loading schemas.\n */\nexport interface LoadSchemaOptions {\n /** Base directory for calculating relative paths */\n readonly baseDir?: string;\n}\n\n/**\n * Options for loading a directory of schemas.\n */\nexport interface LoadSchemasOptions {\n /** File extensions to include (default: ['.yaml', '.yml']) */\n readonly extensions?: readonly string[];\n /** Whether to load recursively from subdirectories (default: true) */\n readonly recursive?: boolean;\n}\n\n/**\n * Converts a file name to a schema name (PascalCase).\n * Preserves original casing if already PascalCase.\n *\n * @example\n * fileNameToSchemaName('user-profile.yaml') // 'UserProfile'\n * fileNameToSchemaName('User.yaml') // 'User'\n * fileNameToSchemaName('ExportJob.yaml') // 'ExportJob' (preserved)\n * fileNameToSchemaName('order_item.yml') // 'OrderItem'\n */\nexport function fileNameToSchemaName(fileName: string): string {\n const baseName = path.basename(fileName, path.extname(fileName));\n\n // If no separators, preserve original casing (already PascalCase)\n if (!baseName.includes('-') && !baseName.includes('_')) {\n return baseName.charAt(0).toUpperCase() + baseName.slice(1);\n }\n\n // Convert kebab-case or snake_case to PascalCase\n return baseName\n .split(/[-_]/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Parses YAML content into a SchemaDefinition.\n *\n * @param content - Raw YAML content\n * @param filePath - File path for error reporting\n * @returns Parsed schema definition\n * @throws OmnifyError if YAML is invalid\n */\nexport function parseYamlSchema(\n content: string,\n filePath: string\n): SchemaDefinition {\n try {\n const parsed = yaml.load(content) as Record<string, unknown> | null;\n\n if (parsed === null || typeof parsed !== 'object') {\n throw yamlSyntaxError('Schema must be a YAML object', filePath);\n }\n\n return buildSchemaDefinition(parsed);\n } catch (error) {\n if (error instanceof yaml.YAMLException) {\n const line = error.mark?.line !== undefined ? error.mark.line + 1 : undefined;\n const column = error.mark?.column !== undefined ? error.mark.column + 1 : undefined;\n throw yamlSyntaxError(error.reason || error.message, filePath, line, column);\n }\n throw error;\n }\n}\n\n/**\n * Parses JSON content into a SchemaDefinition.\n *\n * @param content - Raw JSON content\n * @param filePath - File path for error reporting\n * @returns Parsed schema definition\n * @throws OmnifyError if JSON is invalid\n */\nexport function parseJsonSchema(\n content: string,\n filePath: string\n): SchemaDefinition {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown> | null;\n\n if (parsed === null || typeof parsed !== 'object') {\n throw jsonSyntaxError('Schema must be a JSON object', filePath);\n }\n\n return buildSchemaDefinition(parsed);\n } catch (error) {\n if (error instanceof SyntaxError) {\n // Try to extract line/column from error message\n const match = error.message.match(/position (\\d+)/);\n const positionStr = match?.[1];\n const position = positionStr !== undefined ? parseInt(positionStr, 10) : undefined;\n let line: number | undefined;\n let column: number | undefined;\n\n if (position !== undefined) {\n // Calculate line and column from position\n const beforeError = content.substring(0, position);\n const lines = beforeError.split('\\n');\n line = lines.length;\n const lastLine = lines[lines.length - 1];\n column = (lastLine !== undefined ? lastLine.length : 0) + 1;\n }\n\n throw jsonSyntaxError(error.message, filePath, line, column);\n }\n throw error;\n }\n}\n\n/**\n * Valid fields for schema definition (used for validation).\n */\nconst VALID_SCHEMA_FIELDS = new Set([\n 'kind',\n 'displayName',\n 'titleIndex',\n 'group',\n 'options',\n 'properties',\n 'values',\n]);\n\n/**\n * Valid fields for schema options (used for validation).\n */\nconst VALID_SCHEMA_OPTIONS_FIELDS = new Set([\n 'id',\n 'idType',\n 'timestamps',\n 'softDelete',\n 'unique',\n 'indexes',\n 'translations',\n 'tableName',\n 'hidden',\n 'authenticatable',\n 'authenticatableLoginIdField',\n 'authenticatablePasswordField',\n 'authenticatableGuardName',\n]);\n\n/**\n * Error for invalid property format.\n */\nexport interface InvalidPropertyFormat {\n propertyName: string;\n value: unknown;\n expectedFormat: string;\n}\n\n/**\n * Schema with raw field tracking for validation.\n */\nexport interface SchemaWithRawFields extends SchemaDefinition {\n /** Unknown fields found in raw YAML (for validation) */\n readonly _unknownFields?: readonly string[];\n /** Unknown options fields found in raw YAML (for validation) */\n readonly _unknownOptionsFields?: readonly string[];\n /** Properties with invalid format (not objects) */\n readonly _invalidProperties?: readonly InvalidPropertyFormat[];\n}\n\n/**\n * Builds a SchemaDefinition from parsed YAML data.\n * Handles exactOptionalPropertyTypes correctly.\n * Tracks unknown fields for validation.\n */\nfunction buildSchemaDefinition(\n data: Record<string, unknown>\n): SchemaWithRawFields {\n const schema: SchemaWithRawFields = {};\n\n // Track unknown fields for validation\n const unknownFields: string[] = [];\n for (const key of Object.keys(data)) {\n if (!VALID_SCHEMA_FIELDS.has(key)) {\n unknownFields.push(key);\n }\n }\n if (unknownFields.length > 0) {\n (schema as { _unknownFields: readonly string[] })._unknownFields = unknownFields;\n }\n\n // Handle optional properties with conditional assignment\n if (data.kind !== undefined) {\n (schema as { kind: 'object' | 'enum' }).kind = data.kind as 'object' | 'enum';\n }\n\n if (data.displayName !== undefined && isLocalizedString(data.displayName)) {\n (schema as { displayName: LocalizedString }).displayName = data.displayName;\n }\n\n if (data.titleIndex !== undefined && typeof data.titleIndex === 'string') {\n (schema as { titleIndex: string }).titleIndex = data.titleIndex;\n }\n\n if (data.group !== undefined && typeof data.group === 'string') {\n (schema as { group: string }).group = data.group;\n }\n\n // Parse options and track unknown options fields\n if (data.options !== undefined && typeof data.options === 'object') {\n const optionsData = data.options as Record<string, unknown>;\n const unknownOptionsFields: string[] = [];\n for (const key of Object.keys(optionsData)) {\n if (!VALID_SCHEMA_OPTIONS_FIELDS.has(key)) {\n unknownOptionsFields.push(key);\n }\n }\n if (unknownOptionsFields.length > 0) {\n (schema as { _unknownOptionsFields: readonly string[] })._unknownOptionsFields = unknownOptionsFields;\n }\n\n const options = buildSchemaOptions(optionsData);\n if (Object.keys(options).length > 0) {\n (schema as { options: SchemaOptions }).options = options;\n }\n }\n\n // Parse properties\n if (data.properties !== undefined && typeof data.properties === 'object') {\n const { properties, invalidProperties } = buildProperties(data.properties as Record<string, unknown>);\n if (Object.keys(properties).length > 0) {\n (schema as { properties: Record<string, PropertyDefinition> }).properties = properties;\n }\n if (invalidProperties.length > 0) {\n (schema as { _invalidProperties: readonly InvalidPropertyFormat[] })._invalidProperties = invalidProperties;\n }\n }\n\n // Parse enum values\n if (data.values !== undefined && Array.isArray(data.values)) {\n (schema as { values: readonly string[] }).values = data.values as string[];\n }\n\n return schema;\n}\n\n/**\n * Builds SchemaOptions from parsed data.\n */\nfunction buildSchemaOptions(data: Record<string, unknown>): SchemaOptions {\n const options: SchemaOptions = {};\n\n if (data.timestamps !== undefined && typeof data.timestamps === 'boolean') {\n (options as { timestamps: boolean }).timestamps = data.timestamps;\n }\n\n if (data.softDelete !== undefined && typeof data.softDelete === 'boolean') {\n (options as { softDelete: boolean }).softDelete = data.softDelete;\n }\n\n if (data.unique !== undefined) {\n (options as { unique: readonly string[] | readonly (readonly string[])[] }).unique =\n data.unique as readonly string[] | readonly (readonly string[])[];\n }\n\n if (data.indexes !== undefined && Array.isArray(data.indexes)) {\n (options as { indexes: SchemaOptions['indexes'] }).indexes =\n data.indexes as SchemaOptions['indexes'];\n }\n\n if (data.translations !== undefined && typeof data.translations === 'boolean') {\n (options as { translations: boolean }).translations = data.translations;\n }\n\n if (data.tableName !== undefined && typeof data.tableName === 'string') {\n (options as { tableName: string }).tableName = data.tableName;\n }\n\n // New id options\n if (data.id !== undefined && typeof data.id === 'boolean') {\n (options as { id: boolean }).id = data.id;\n }\n\n if (data.idType !== undefined) {\n (options as { idType: 'Int' | 'BigInt' | 'Uuid' | 'String' }).idType =\n data.idType as 'Int' | 'BigInt' | 'Uuid' | 'String';\n }\n\n if (data.authenticatable !== undefined && typeof data.authenticatable === 'boolean') {\n (options as { authenticatable: boolean }).authenticatable = data.authenticatable;\n }\n\n if (data.authenticatableLoginIdField !== undefined && typeof data.authenticatableLoginIdField === 'string') {\n (options as { authenticatableLoginIdField: string }).authenticatableLoginIdField =\n data.authenticatableLoginIdField;\n }\n\n if (data.authenticatablePasswordField !== undefined && typeof data.authenticatablePasswordField === 'string') {\n (options as { authenticatablePasswordField: string }).authenticatablePasswordField =\n data.authenticatablePasswordField;\n }\n\n if (data.authenticatableGuardName !== undefined && typeof data.authenticatableGuardName === 'string') {\n (options as { authenticatableGuardName: string }).authenticatableGuardName =\n data.authenticatableGuardName;\n }\n\n // Hidden option - skip model generation when true\n if (data.hidden !== undefined && typeof data.hidden === 'boolean') {\n (options as { hidden: boolean }).hidden = data.hidden;\n }\n\n return options;\n}\n\n/**\n * Builds property definitions from parsed data.\n * Validates that all properties are in object format.\n * Tracks invalid properties for validation error reporting.\n */\nfunction buildProperties(\n data: Record<string, unknown>\n): { properties: Record<string, PropertyDefinition>; invalidProperties: InvalidPropertyFormat[] } {\n const properties: Record<string, PropertyDefinition> = {};\n const invalidProperties: InvalidPropertyFormat[] = [];\n\n for (const [name, value] of Object.entries(data)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (typeof value === 'object') {\n // Valid object format: { type: \"String\", nullable: true, ... }\n properties[name] = buildPropertyDefinition(value as Record<string, unknown>);\n } else {\n // Invalid format - track for error reporting\n invalidProperties.push({\n propertyName: name,\n value,\n expectedFormat: `Property '${name}' must be an object with 'type' field. Example:\\n ${name}:\\n type: String\\n nullable: true`,\n });\n }\n }\n\n return { properties, invalidProperties };\n}\n\n/**\n * All valid property fields (for unknown field tracking).\n */\nconst VALID_PROPERTY_FIELDS = new Set([\n 'type',\n 'displayName',\n 'nullable',\n 'default',\n 'unique',\n 'primary',\n 'description',\n 'renamedFrom',\n // Placeholder for form inputs (multi-language)\n 'placeholder',\n // String properties\n 'length',\n // Numeric properties\n 'unsigned',\n 'precision',\n 'scale',\n // Enum properties\n 'enum',\n // Association properties\n 'relation',\n 'target',\n 'targets',\n 'morphName',\n 'inversedBy',\n 'mappedBy',\n 'onDelete',\n 'onUpdate',\n 'owning',\n 'joinTable',\n 'pivotFields',\n // File properties\n 'multiple',\n 'maxFiles',\n 'accept',\n 'maxSize',\n // Validation rules (application-level only)\n 'rules',\n // Laravel-specific properties\n 'hidden',\n 'fillable',\n // Per-field settings for compound types\n 'fields',\n // Timestamp-specific properties\n 'useCurrent',\n 'useCurrentOnUpdate',\n]);\n\n/**\n * Builds a single PropertyDefinition from parsed data.\n * Uses a generic record to avoid exactOptionalPropertyTypes issues.\n * Tracks unknown fields for validation.\n */\nfunction buildPropertyDefinition(\n data: Record<string, unknown>\n): PropertyDefinition {\n // Build as a generic record first, then cast at the end\n const prop: Record<string, unknown> = {\n type: (data.type as string) || 'String',\n };\n\n // Track unknown fields for validation\n const unknownFields: string[] = [];\n for (const key of Object.keys(data)) {\n if (!VALID_PROPERTY_FIELDS.has(key)) {\n unknownFields.push(key);\n }\n }\n if (unknownFields.length > 0) {\n prop._unknownFields = unknownFields;\n }\n\n // Common properties (supports LocalizedString - string or locale map)\n if (data.displayName !== undefined && isLocalizedString(data.displayName)) {\n prop.displayName = data.displayName;\n }\n\n if (data.nullable !== undefined && typeof data.nullable === 'boolean') {\n prop.nullable = data.nullable;\n }\n\n if (data.default !== undefined) {\n prop.default = data.default;\n }\n\n if (data.unique !== undefined && typeof data.unique === 'boolean') {\n prop.unique = data.unique;\n }\n\n // Primary key (for custom primary keys with id: false)\n if (data.primary !== undefined && typeof data.primary === 'boolean') {\n prop.primary = data.primary;\n }\n\n // Description also supports LocalizedString\n if (data.description !== undefined && isLocalizedString(data.description)) {\n prop.description = data.description;\n }\n\n // Placeholder also supports LocalizedString\n if (data.placeholder !== undefined && isLocalizedString(data.placeholder)) {\n prop.placeholder = data.placeholder;\n }\n\n // Rename tracking for migrations\n if (data.renamedFrom !== undefined && typeof data.renamedFrom === 'string') {\n prop.renamedFrom = data.renamedFrom;\n }\n\n // String properties\n if (data.length !== undefined && typeof data.length === 'number') {\n prop.length = data.length;\n }\n\n // Numeric properties\n if (data.unsigned !== undefined && typeof data.unsigned === 'boolean') {\n prop.unsigned = data.unsigned;\n }\n\n if (data.precision !== undefined && typeof data.precision === 'number') {\n prop.precision = data.precision;\n }\n\n if (data.scale !== undefined && typeof data.scale === 'number') {\n prop.scale = data.scale;\n }\n\n // Enum properties\n if (data.enum !== undefined) {\n prop.enum = data.enum;\n }\n\n // Association properties\n if (data.relation !== undefined && typeof data.relation === 'string') {\n prop.relation = data.relation;\n }\n\n if (data.target !== undefined && typeof data.target === 'string') {\n prop.target = data.target;\n }\n\n if (data.inversedBy !== undefined && typeof data.inversedBy === 'string') {\n prop.inversedBy = data.inversedBy;\n }\n\n if (data.mappedBy !== undefined && typeof data.mappedBy === 'string') {\n prop.mappedBy = data.mappedBy;\n }\n\n if (data.onDelete !== undefined && typeof data.onDelete === 'string') {\n prop.onDelete = data.onDelete;\n }\n\n if (data.onUpdate !== undefined && typeof data.onUpdate === 'string') {\n prop.onUpdate = data.onUpdate;\n }\n\n if (data.owning !== undefined && typeof data.owning === 'boolean') {\n prop.owning = data.owning;\n }\n\n if (data.joinTable !== undefined && typeof data.joinTable === 'string') {\n prop.joinTable = data.joinTable;\n }\n\n // Polymorphic association properties\n if (data.targets !== undefined && Array.isArray(data.targets)) {\n prop.targets = data.targets;\n }\n\n if (data.morphName !== undefined && typeof data.morphName === 'string') {\n prop.morphName = data.morphName;\n }\n\n // Pivot fields for ManyToMany\n if (data.pivotFields !== undefined && typeof data.pivotFields === 'object') {\n prop.pivotFields = data.pivotFields;\n }\n\n // File type properties\n if (data.multiple !== undefined && typeof data.multiple === 'boolean') {\n prop.multiple = data.multiple;\n }\n\n if (data.maxFiles !== undefined && typeof data.maxFiles === 'number') {\n prop.maxFiles = data.maxFiles;\n }\n\n if (data.accept !== undefined && Array.isArray(data.accept)) {\n prop.accept = data.accept;\n }\n\n if (data.maxSize !== undefined && typeof data.maxSize === 'number') {\n prop.maxSize = data.maxSize;\n }\n\n // Validation rules (application-level only)\n if (data.rules !== undefined && typeof data.rules === 'object') {\n prop.rules = data.rules;\n }\n\n // Laravel-specific: hidden field for $hidden array\n if (data.hidden !== undefined && typeof data.hidden === 'boolean') {\n prop.hidden = data.hidden;\n }\n\n // Laravel-specific: fillable field for $fillable array\n if (data.fillable !== undefined && typeof data.fillable === 'boolean') {\n prop.fillable = data.fillable;\n }\n\n // Timestamp-specific: useCurrent for default CURRENT_TIMESTAMP\n if (data.useCurrent !== undefined && typeof data.useCurrent === 'boolean') {\n prop.useCurrent = data.useCurrent;\n }\n\n // Timestamp-specific: useCurrentOnUpdate for ON UPDATE CURRENT_TIMESTAMP\n if (data.useCurrentOnUpdate !== undefined && typeof data.useCurrentOnUpdate === 'boolean') {\n prop.useCurrentOnUpdate = data.useCurrentOnUpdate;\n }\n\n // Per-field settings for compound types\n if (data.fields !== undefined && typeof data.fields === 'object' && data.fields !== null) {\n prop.fields = data.fields;\n }\n\n return prop as unknown as PropertyDefinition;\n}\n\n/**\n * Loads a single schema file.\n * Supports both YAML (.yaml, .yml) and JSON (.json) formats.\n *\n * @param filePath - Path to the schema file\n * @param options - Loading options\n * @returns Loaded schema with metadata\n * @throws OmnifyError if file not found or invalid syntax\n */\nexport async function loadSchema(\n filePath: string,\n options: LoadSchemaOptions = {}\n): Promise<LoadedSchema> {\n const absolutePath = path.resolve(filePath);\n const baseDir = options.baseDir ? path.resolve(options.baseDir) : path.dirname(absolutePath);\n\n // Check if file exists\n try {\n await fs.access(absolutePath);\n } catch {\n throw schemaNotFoundError(filePath);\n }\n\n // Read file content\n const content = await fs.readFile(absolutePath, 'utf-8');\n\n // Parse based on file extension\n const ext = path.extname(absolutePath).toLowerCase();\n const schemaDefinition = ext === '.json'\n ? parseJsonSchema(content, filePath)\n : parseYamlSchema(content, filePath);\n\n // Build LoadedSchema\n const name = fileNameToSchemaName(absolutePath);\n const relativePath = path.relative(baseDir, absolutePath);\n\n const loadedSchema: LoadedSchema = {\n ...schemaDefinition,\n name,\n filePath: absolutePath,\n relativePath,\n };\n\n return loadedSchema;\n}\n\n/**\n * Recursively finds all schema files in a directory.\n */\nasync function findSchemaFiles(\n dirPath: string,\n extensions: readonly string[],\n recursive: boolean\n): Promise<string[]> {\n const files: string[] = [];\n\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory() && recursive) {\n const subFiles = await findSchemaFiles(fullPath, extensions, recursive);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (extensions.includes(ext)) {\n files.push(fullPath);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Loads all schemas from a directory.\n *\n * @param directoryPath - Path to the schemas directory\n * @param options - Loading options\n * @returns Collection of loaded schemas indexed by name\n * @throws OmnifyError if duplicate schema names or invalid files\n */\nexport async function loadSchemas(\n directoryPath: string,\n options: LoadSchemasOptions = {}\n): Promise<SchemaCollection> {\n const {\n extensions = ['.yaml', '.yml', '.json'],\n recursive = true,\n } = options;\n\n const absoluteDir = path.resolve(directoryPath);\n\n // Check if directory exists\n try {\n const stat = await fs.stat(absoluteDir);\n if (!stat.isDirectory()) {\n throw schemaNotFoundError(directoryPath);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw schemaNotFoundError(directoryPath);\n }\n throw error;\n }\n\n // Find all schema files\n const schemaFiles = await findSchemaFiles(absoluteDir, extensions, recursive);\n\n // Load each schema\n const schemas: Record<string, LoadedSchema> = {};\n const schemaLocations: Record<string, string> = {};\n\n for (const filePath of schemaFiles) {\n const schema = await loadSchema(filePath, { baseDir: absoluteDir });\n\n // Check for duplicate names\n const existingLocation = schemaLocations[schema.name];\n if (existingLocation !== undefined) {\n throw duplicateSchemaError(\n schema.name,\n { file: filePath },\n { file: existingLocation }\n );\n }\n\n schemas[schema.name] = schema;\n schemaLocations[schema.name] = filePath;\n }\n\n return schemas;\n}\n\n/**\n * The reserved name for the File schema (polymorphic file storage).\n */\nexport const FILE_SCHEMA_NAME = 'File';\n\n/**\n * Checks if any schema in the collection has File type properties.\n */\nexport function schemasHaveFileProperties(schemas: SchemaCollection): boolean {\n for (const schema of Object.values(schemas)) {\n if (!schema.properties) continue;\n for (const prop of Object.values(schema.properties)) {\n if (prop.type === 'File') {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Creates the File schema definition for polymorphic file storage.\n * This schema represents files stored with morphOne/morphMany relationships.\n */\nexport function createFileSchemaDefinition(): SchemaDefinition {\n return {\n displayName: 'File',\n options: {\n timestamps: true,\n tableName: 'files',\n indexes: [\n {\n columns: ['fileableType', 'fileableId', 'fileableField'],\n name: 'files_fileable_index',\n },\n ],\n },\n properties: {\n path: {\n type: 'String',\n displayName: 'Storage Path',\n },\n disk: {\n type: 'String',\n displayName: 'Storage Disk',\n default: 'local',\n },\n size: {\n type: 'BigInt',\n displayName: 'File Size (bytes)',\n unsigned: true,\n },\n mimeType: {\n type: 'String',\n displayName: 'MIME Type',\n },\n fileableType: {\n type: 'String',\n displayName: 'Fileable Type',\n },\n fileableId: {\n type: 'BigInt',\n displayName: 'Fileable ID',\n unsigned: true,\n },\n fileableField: {\n type: 'String',\n displayName: 'Fileable Field',\n },\n },\n };\n}\n\n/**\n * Creates a LoadedSchema for the File schema.\n * Used when auto-generating File schema in memory.\n */\nexport function createFileLoadedSchema(schemasDir: string): LoadedSchema {\n const definition = createFileSchemaDefinition();\n const filePath = path.join(schemasDir, 'File.yaml');\n\n return {\n ...definition,\n name: FILE_SCHEMA_NAME,\n filePath,\n relativePath: 'File.yaml',\n };\n}\n\n/**\n * Generates YAML content for File.yaml schema.\n * Can be written to disk for user customization.\n */\nexport function generateFileSchemaYaml(): string {\n return `# File Schema - Polymorphic file storage\n# Auto-generated by Omnify when File type is detected\n# You can customize this schema as needed\n\ndisplayName: File\n\noptions:\n timestamps: true\n tableName: files\n indexes:\n - columns: [fileableType, fileableId, fileableField]\n name: files_fileable_index\n\nproperties:\n path:\n type: String\n displayName: Storage Path\n\n disk:\n type: String\n displayName: Storage Disk\n default: local\n\n size:\n type: BigInt\n displayName: File Size (bytes)\n unsigned: true\n\n mimeType:\n type: String\n displayName: MIME Type\n\n fileableType:\n type: String\n displayName: Fileable Type\n\n fileableId:\n type: BigInt\n displayName: Fileable ID\n unsigned: true\n\n fileableField:\n type: String\n displayName: Fileable Field\n`;\n}\n\n/**\n * Ensures File schema exists when File type is used.\n * Returns the schema collection with File schema added if needed.\n *\n * @param schemas - Existing schema collection\n * @param schemasDir - Directory where schemas are stored\n * @param autoCreate - If true, creates File.yaml on disk; if false, adds in-memory only\n * @returns Updated schema collection\n */\nexport async function ensureFileSchema(\n schemas: SchemaCollection,\n schemasDir: string,\n autoCreate: boolean = false\n): Promise<SchemaCollection> {\n // Check if File type is used\n if (!schemasHaveFileProperties(schemas)) {\n return schemas;\n }\n\n // Check if File schema already exists\n if (schemas[FILE_SCHEMA_NAME]) {\n return schemas;\n }\n\n // Create File schema\n const fileSchema = createFileLoadedSchema(schemasDir);\n\n // Optionally write to disk\n if (autoCreate) {\n const filePath = path.join(schemasDir, 'File.yaml');\n const yamlContent = generateFileSchemaYaml();\n await fs.writeFile(filePath, yamlContent, 'utf-8');\n }\n\n // Return updated collection\n return {\n [FILE_SCHEMA_NAME]: fileSchema,\n ...schemas,\n };\n}\n","/**\n * @famgia/omnify-core - Schema Validator\n *\n * Validates schema definitions for correctness and consistency.\n * Uses class-based type system for extensible validation.\n */\n\nimport type {\n SchemaDefinition,\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n BuiltInPropertyType,\n LocalizedString,\n LocaleConfig,\n} from '@famgia/omnify-types';\nimport { isLocaleMap } from '@famgia/omnify-types';\nimport {\n OmnifyError,\n validationError,\n invalidPropertyTypeError,\n missingFieldError,\n invalidAssociationTargetError,\n} from '../errors/index.js';\nimport type {\n SchemaValidationResult,\n ValidationResult,\n ValidationOptions,\n DatabaseDriver,\n} from './types.js';\nimport {\n typeRegistry,\n VALID_RELATIONS,\n VALID_REFERENTIAL_ACTIONS,\n BASE_PROPERTY_FIELDS,\n VALID_RULES_FIELDS,\n} from './types/index.js';\n\n/**\n * Valid ID types for auto-generated primary key.\n */\nconst VALID_ID_TYPES = ['Int', 'BigInt', 'Uuid', 'String'] as const;\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string, line?: number, column?: number) {\n const loc: { file: string; line?: number; column?: number } = { file };\n if (line !== undefined) {\n loc.line = line;\n }\n if (column !== undefined) {\n loc.column = column;\n }\n return loc;\n}\n\n/**\n * Validates unknown fields at the schema root level.\n * Returns errors for fields that are not part of the schema spec.\n * Uses _unknownFields populated by the loader.\n */\nexport function validateUnknownSchemaFields(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for unknown fields tracked by the loader\n const unknownFields = (schema as { _unknownFields?: readonly string[] })._unknownFields;\n if (!unknownFields || unknownFields.length === 0) {\n return errors;\n }\n\n for (const field of unknownFields) {\n // Provide specific suggestions based on common mistakes\n let suggestion = `Valid schema fields: kind, displayName, titleIndex, group, options, properties, values`;\n\n if (field === 'associations') {\n suggestion = `Associations should be defined inside 'properties' with type: Association.\nExample:\n properties:\n author:\n type: Association\n relation: ManyToOne\n target: User\n onDelete: CASCADE`;\n } else if (field === 'indexes') {\n suggestion = `Indexes should be inside 'options.indexes'.\nExample:\n options:\n indexes:\n - columns: [email]\n unique: true`;\n } else if (field === 'required') {\n suggestion = `'required' is not a valid field. Use 'nullable: false' on properties (default is not nullable).\nExample:\n properties:\n email:\n type: String\n # not nullable by default, explicitly use nullable: true to make optional`;\n } else if (field === 'hidden') {\n suggestion = `'hidden' is not a schema-level field. Hidden fields should be handled by your framework.\nFor Laravel, the model generator can handle this, but you need to use a custom property.`;\n }\n\n errors.push(\n validationError(\n `Unknown schema field '${field}'`,\n buildLocation(filePath),\n suggestion\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates unknown fields in schema options.\n * Returns errors for option fields that are not recognized.\n * Uses _unknownOptionsFields populated by the loader.\n */\nexport function validateUnknownOptionsFields(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for unknown options fields tracked by the loader\n const unknownOptionsFields = (schema as { _unknownOptionsFields?: readonly string[] })._unknownOptionsFields;\n if (!unknownOptionsFields || unknownOptionsFields.length === 0) {\n return errors;\n }\n\n for (const field of unknownOptionsFields) {\n errors.push(\n validationError(\n `Unknown option field '${field}'`,\n buildLocation(filePath),\n `Valid option fields: id, idType, timestamps, softDelete, unique, indexes, translations, tableName, authenticatable, authenticatableLoginIdField, authenticatablePasswordField, authenticatableGuardName`\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Invalid property format info from loader.\n */\ninterface InvalidPropertyFormat {\n propertyName: string;\n value: unknown;\n expectedFormat: string;\n}\n\n/**\n * Validates that all properties are in correct object format.\n * Returns errors for properties that are not objects (e.g., shorthand strings).\n * Uses _invalidProperties populated by the loader.\n */\nexport function validatePropertyFormat(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for invalid properties tracked by the loader\n const invalidProperties = (schema as { _invalidProperties?: readonly InvalidPropertyFormat[] })._invalidProperties;\n if (!invalidProperties || invalidProperties.length === 0) {\n return errors;\n }\n\n for (const invalid of invalidProperties) {\n const valueType = typeof invalid.value;\n const valuePreview = valueType === 'string'\n ? `\"${invalid.value}\"`\n : String(invalid.value);\n\n errors.push(\n validationError(\n `Property '${invalid.propertyName}' has invalid format: got ${valueType} (${valuePreview})`,\n buildLocation(filePath),\n invalid.expectedFormat\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates database compatibility for a property type.\n * Returns warnings for types with limited support, errors for unsupported types.\n */\nexport function validateDbCompatibility(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n databaseDriver?: DatabaseDriver\n): { errors: OmnifyError[]; warnings: OmnifyError[] } {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n\n if (!databaseDriver || !property.type) {\n return { errors, warnings };\n }\n\n const compatibility = typeRegistry.getDbCompatibility(property.type, databaseDriver);\n\n if (compatibility === 'unsupported') {\n errors.push(\n validationError(\n `Property '${propertyName}' uses type '${property.type}' which is not supported in ${databaseDriver}`,\n buildLocation(filePath),\n `Consider using a different type or database driver`\n )\n );\n } else if (compatibility === 'limited') {\n warnings.push(\n validationError(\n `Property '${propertyName}' uses type '${property.type}' which has limited support in ${databaseDriver}`,\n buildLocation(filePath),\n `The type will work but may have precision or feature limitations`\n )\n );\n }\n\n return { errors, warnings };\n}\n\n/**\n * Result of unknown field validation.\n */\nexport interface UnknownFieldsResult {\n /** Errors: fields valid for other types but not this type */\n readonly errors: OmnifyError[];\n /** Warnings: completely unknown fields */\n readonly warnings: OmnifyError[];\n}\n\n/**\n * Validates unknown fields in a property definition.\n * Checks:\n * 1. Fields tracked by loader as unknown (_unknownFields) → warnings\n * 2. Fields that are valid for other types but not this type → errors\n */\nexport function validateUnknownFields(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n): OmnifyError[] {\n const result = validateUnknownFieldsDetailed(propertyName, property, filePath);\n // For backwards compatibility, return combined errors (warnings become errors)\n // But the detailed version separates them properly\n return [...result.errors, ...result.warnings];\n}\n\n/**\n * Validates unknown fields with detailed separation of errors and warnings.\n */\nexport function validateUnknownFieldsDetailed(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n customTypeDefinitions?: ReadonlyMap<string, import('@famgia/omnify-types').CustomTypeDefinition>\n): UnknownFieldsResult {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n\n // Skip if no type\n if (!property.type) {\n return { errors, warnings };\n }\n\n // Get valid fields for this type\n let validFields: readonly string[];\n const isBuiltIn = typeRegistry.has(property.type);\n\n if (isBuiltIn) {\n // Built-in type - use registry\n validFields = typeRegistry.getValidFields(property.type);\n } else {\n // Custom type - check if we have full definition\n const customTypeDef = customTypeDefinitions?.get(property.type);\n if (customTypeDef?.validFields) {\n // Custom type with validFields - use base fields + custom validFields\n validFields = [...BASE_PROPERTY_FIELDS, ...customTypeDef.validFields];\n } else {\n // Custom type without validFields - only allow base fields\n validFields = [...BASE_PROPERTY_FIELDS];\n }\n }\n\n const validFieldsSet = new Set(validFields);\n\n // Check each field in the property (except internal fields)\n for (const field of Object.keys(property)) {\n if (field.startsWith('_')) continue; // Skip internal fields\n if (validFieldsSet.has(field)) continue; // Field is valid for this type\n\n // Field is not valid for this type - determine if it's an error or warning\n // Error: field is valid for SOME other type (user likely made a mistake)\n // Warning: field is completely unknown (might be intentional extension)\n const isValidForOtherType = typeRegistry.isFieldValidForAnyType(field);\n\n if (isValidForOtherType) {\n // Field is valid for another type - this is an error\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${property.type}' has invalid field '${field}'`,\n buildLocation(filePath),\n `'${field}' is not valid for type '${property.type}'. Valid fields: ${validFields.join(', ')}`\n )\n );\n } else {\n // Field is completely unknown - this is an ERROR (not warning)\n // Unknown fields should not be silently ignored\n errors.push(\n validationError(\n `Property '${propertyName}' has unknown field '${field}'`,\n buildLocation(filePath),\n getSuggestionForUnknownField(field)\n )\n );\n }\n }\n\n return { errors, warnings };\n}\n\n/**\n * Get suggestion message for unknown field.\n */\nfunction getSuggestionForUnknownField(field: string): string {\n if (field === 'required') {\n return `'required' should be inside 'rules' field.\nExample:\n name:\n type: String\n rules:\n required: true\nNote: rules.required is for validation only, does NOT affect database nullable.\nRecommended: set 'nullable: false' if required: true.`;\n }\n\n if (field === 'maxLength' || field === 'minLength') {\n return `'${field}' should be inside 'rules' field.\nExample:\n name:\n type: String\n length: 255 # Database column size\n rules:\n minLength: 5\n maxLength: 100\nNote: 'length' is for database column size, 'rules.maxLength' is for validation only.`;\n }\n\n // 'hidden' is now a valid base field - no suggestion needed\n\n if (field === 'foreignKey') {\n return `'foreignKey' is not needed. Omnify auto-generates foreign keys from Association properties.\nThe foreign key name is derived from the property name + '_id'.\nExample:\n author:\n type: Association\n relation: ManyToOne\n target: User\n # Creates author_id column automatically`;\n }\n\n return `Unknown field '${field}'. Valid property fields: type, displayName, placeholder, nullable, default, unique, primary, description, length, unsigned, precision, scale, enum, relation, target, onDelete, onUpdate, joinTable, rules, hidden, fillable, fields`;\n}\n\n/**\n * Types that allow minLength/maxLength in rules.\n */\nconst STRING_TYPES_WITH_LENGTH_RULES = ['String', 'Email', 'Password'] as const;\n\n/**\n * Validates the rules field in a property definition.\n * Checks:\n * 1. Unknown fields in rules object\n * 2. minLength/maxLength only allowed for String, Email, Password types\n * 3. maxLength <= length (database column size)\n * 4. minLength <= maxLength\n */\nexport function validateRules(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n const rules = (property as { rules?: Record<string, unknown> }).rules;\n\n if (!rules || typeof rules !== 'object') {\n return errors;\n }\n\n // Check for unknown fields in rules\n const validRulesSet = new Set(VALID_RULES_FIELDS as readonly string[]);\n for (const field of Object.keys(rules)) {\n if (!validRulesSet.has(field)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has unknown field in rules: '${field}'`,\n buildLocation(filePath),\n `Valid rules fields: ${VALID_RULES_FIELDS.join(', ')}`\n )\n );\n }\n }\n\n const { required, minLength, maxLength } = rules as {\n required?: unknown;\n minLength?: unknown;\n maxLength?: unknown;\n };\n\n // Validate required is boolean\n if (required !== undefined && typeof required !== 'boolean') {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.required value`,\n buildLocation(filePath),\n 'rules.required must be a boolean (true or false)'\n )\n );\n }\n\n // Validate minLength/maxLength only for String, Email, Password types\n const propertyType = property.type;\n const allowsLengthRules = STRING_TYPES_WITH_LENGTH_RULES.includes(\n propertyType as typeof STRING_TYPES_WITH_LENGTH_RULES[number]\n );\n\n if (minLength !== undefined && !allowsLengthRules) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${propertyType}' cannot use rules.minLength`,\n buildLocation(filePath),\n `rules.minLength is only valid for types: ${STRING_TYPES_WITH_LENGTH_RULES.join(', ')}`\n )\n );\n }\n\n if (maxLength !== undefined && !allowsLengthRules) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${propertyType}' cannot use rules.maxLength`,\n buildLocation(filePath),\n `rules.maxLength is only valid for types: ${STRING_TYPES_WITH_LENGTH_RULES.join(', ')}`\n )\n );\n }\n\n // Validate minLength value\n if (minLength !== undefined && allowsLengthRules) {\n if (typeof minLength !== 'number' || minLength < 0 || minLength > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.minLength '${minLength}'`,\n buildLocation(filePath),\n 'rules.minLength must be a non-negative number between 0 and 65535'\n )\n );\n }\n }\n\n // Validate maxLength value and compare with length\n if (maxLength !== undefined && allowsLengthRules) {\n if (typeof maxLength !== 'number' || maxLength < 1 || maxLength > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.maxLength '${maxLength}'`,\n buildLocation(filePath),\n 'rules.maxLength must be a positive number between 1 and 65535'\n )\n );\n } else {\n // Check maxLength <= length (database column size)\n const dbLength = (property as { length?: number }).length;\n if (dbLength !== undefined && typeof dbLength === 'number' && maxLength > dbLength) {\n errors.push(\n validationError(\n `Property '${propertyName}' has rules.maxLength (${maxLength}) greater than length (${dbLength})`,\n buildLocation(filePath),\n 'rules.maxLength must be less than or equal to length (database column size)'\n )\n );\n }\n }\n }\n\n // Validate minLength <= maxLength\n if (minLength !== undefined && maxLength !== undefined &&\n typeof minLength === 'number' && typeof maxLength === 'number' &&\n minLength > maxLength) {\n errors.push(\n validationError(\n `Property '${propertyName}' has rules.minLength (${minLength}) greater than rules.maxLength (${maxLength})`,\n buildLocation(filePath),\n 'rules.minLength must be less than or equal to rules.maxLength'\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates a property type.\n */\nexport function validatePropertyType(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n customTypes: readonly string[] = []\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!property.type) {\n errors.push(\n missingFieldError('type', buildLocation(filePath))\n );\n return errors;\n }\n\n // Check if type exists (built-in or custom)\n const isBuiltIn = typeRegistry.has(property.type);\n const isCustom = customTypes.includes(property.type);\n\n if (!isBuiltIn && !isCustom) {\n errors.push(\n invalidPropertyTypeError(\n property.type,\n buildLocation(filePath),\n typeRegistry.getAllTypeNames() as readonly BuiltInPropertyType[]\n )\n );\n return errors;\n }\n\n // Run type-specific validation for built-in types\n if (isBuiltIn) {\n const typeErrors = typeRegistry.validateProperty(propertyName, property, filePath);\n errors.push(...typeErrors);\n }\n\n return errors;\n}\n\n/**\n * Validates all properties in a schema.\n */\nexport function validateProperties(\n schema: SchemaDefinition,\n filePath: string,\n customTypes: readonly string[] = []\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!schema.properties) {\n // No properties is valid for enum schemas\n if (schema.kind !== 'enum') {\n // Warning: object schema without properties\n }\n return errors;\n }\n\n for (const [name, property] of Object.entries(schema.properties)) {\n const propErrors = validatePropertyType(name, property, filePath, customTypes);\n errors.push(...propErrors);\n }\n\n return errors;\n}\n\n/**\n * Polymorphic relation types that use 'targets' instead of 'target'.\n */\nconst MORPH_TO_RELATIONS = ['MorphTo'] as const;\n\n/**\n * Polymorphic relation types that require 'morphName' pointing to MorphTo on target.\n * Note: MorphedByMany also uses morphName but for pivot table name, not property reference.\n */\nconst MORPH_INVERSE_RELATIONS = ['MorphOne', 'MorphMany'] as const;\n\n/**\n * Validates associations in a schema against available schemas.\n */\nexport function validateAssociations(\n schema: LoadedSchema,\n allSchemas: SchemaCollection\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!schema.properties) {\n return errors;\n }\n\n const availableSchemas = Object.keys(allSchemas);\n\n for (const [name, property] of Object.entries(schema.properties)) {\n if (property.type !== 'Association') {\n continue;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n targets?: readonly string[];\n morphName?: string;\n inversedBy?: string;\n mappedBy?: string;\n onDelete?: string;\n onUpdate?: string;\n };\n\n // Validate relation type\n if (assocProp.relation && !VALID_RELATIONS.includes(assocProp.relation as typeof VALID_RELATIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid relation '${assocProp.relation}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_RELATIONS.join(', ')}`\n )\n );\n }\n\n const relation = assocProp.relation as typeof VALID_RELATIONS[number] | undefined;\n\n // Validate targets for MorphTo\n if (relation && MORPH_TO_RELATIONS.includes(relation as typeof MORPH_TO_RELATIONS[number])) {\n if (assocProp.targets) {\n for (const target of assocProp.targets) {\n if (!availableSchemas.includes(target)) {\n errors.push(\n invalidAssociationTargetError(\n target,\n buildLocation(schema.filePath),\n availableSchemas\n )\n );\n }\n }\n }\n }\n // Validate target for standard relations and inverse polymorphic\n else if (assocProp.target && !availableSchemas.includes(assocProp.target)) {\n errors.push(\n invalidAssociationTargetError(\n assocProp.target,\n buildLocation(schema.filePath),\n availableSchemas\n )\n );\n }\n\n // Validate morphName matches a MorphTo property on target schema\n if (relation && MORPH_INVERSE_RELATIONS.includes(relation as typeof MORPH_INVERSE_RELATIONS[number])) {\n if (assocProp.morphName && assocProp.target) {\n const targetSchema = allSchemas[assocProp.target];\n if (targetSchema?.properties) {\n const morphProperty = targetSchema.properties[assocProp.morphName];\n if (!morphProperty) {\n errors.push(\n validationError(\n `Property '${name}' references non-existent morphName '${assocProp.morphName}' on '${assocProp.target}'`,\n buildLocation(schema.filePath),\n `Add a MorphTo property '${assocProp.morphName}' to ${assocProp.target} schema`\n )\n );\n } else if (morphProperty.type === 'Association') {\n const morphAssoc = morphProperty as { relation?: string };\n if (morphAssoc.relation !== 'MorphTo') {\n errors.push(\n validationError(\n `Property '${name}' morphName '${assocProp.morphName}' on '${assocProp.target}' must be a MorphTo relation`,\n buildLocation(schema.filePath),\n `Change ${assocProp.target}.${assocProp.morphName} relation to MorphTo`\n )\n );\n }\n }\n }\n }\n }\n\n // Validate inversedBy/mappedBy references exist (for standard relations)\n if (assocProp.inversedBy && assocProp.target) {\n const targetSchema = allSchemas[assocProp.target];\n if (targetSchema?.properties) {\n const inverseProperty = targetSchema.properties[assocProp.inversedBy];\n if (!inverseProperty) {\n errors.push(\n validationError(\n `Property '${name}' references non-existent inverse property '${assocProp.inversedBy}' on '${assocProp.target}'`,\n buildLocation(schema.filePath),\n `Add property '${assocProp.inversedBy}' to ${assocProp.target} schema`\n )\n );\n }\n }\n }\n\n // Validate referential actions\n if (assocProp.onDelete && !VALID_REFERENTIAL_ACTIONS.includes(assocProp.onDelete as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid onDelete action '${assocProp.onDelete}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n\n if (assocProp.onUpdate && !VALID_REFERENTIAL_ACTIONS.includes(assocProp.onUpdate as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid onUpdate action '${assocProp.onUpdate}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n return errors;\n}\n\n/**\n * Validates schema options.\n */\nexport function validateOptions(\n schema: SchemaDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n const options = schema.options;\n\n if (!options) {\n return errors;\n }\n\n // Validate idType\n if (options.idType !== undefined) {\n if (!VALID_ID_TYPES.includes(options.idType as typeof VALID_ID_TYPES[number])) {\n errors.push(\n validationError(\n `Invalid idType '${options.idType}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_ID_TYPES.join(', ')}`\n )\n );\n }\n }\n\n // Validate unique constraints reference existing properties\n if (options.unique && schema.properties) {\n const propertyNames = Object.keys(schema.properties);\n const uniqueConstraints = Array.isArray(options.unique[0])\n ? (options.unique as readonly (readonly string[])[])\n : [options.unique as readonly string[]];\n\n for (const constraint of uniqueConstraints) {\n for (const column of constraint) {\n if (!propertyNames.includes(column)) {\n errors.push(\n validationError(\n `Unique constraint references non-existent property '${column}'`,\n buildLocation(filePath),\n `Available properties: ${propertyNames.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n // Validate indexes reference existing properties\n if (options.indexes && schema.properties) {\n const propertyNames = Object.keys(schema.properties);\n\n for (const index of options.indexes) {\n // Handle both shorthand (string) and full object format\n const columns = typeof index === 'string' ? [index] : index.columns;\n for (const column of columns) {\n if (!propertyNames.includes(column)) {\n errors.push(\n validationError(\n `Index references non-existent property '${column}'`,\n buildLocation(filePath),\n `Available properties: ${propertyNames.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n // Validate authenticatable options\n if (options.authenticatable) {\n if (options.authenticatableLoginIdField && schema.properties) {\n if (!schema.properties[options.authenticatableLoginIdField]) {\n errors.push(\n validationError(\n `authenticatableLoginIdField references non-existent property '${options.authenticatableLoginIdField}'`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n if (options.authenticatablePasswordField && schema.properties) {\n if (!schema.properties[options.authenticatablePasswordField]) {\n errors.push(\n validationError(\n `authenticatablePasswordField references non-existent property '${options.authenticatablePasswordField}'`,\n buildLocation(filePath)\n )\n );\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Validates an enum schema.\n */\nexport function validateEnumSchema(\n schema: SchemaDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (schema.kind !== 'enum') {\n return errors;\n }\n\n if (!schema.values || schema.values.length === 0) {\n errors.push(\n validationError(\n 'Enum schema requires at least one value',\n buildLocation(filePath),\n 'Add values: [value1, value2, ...]'\n )\n );\n }\n\n // Check for duplicate values\n if (schema.values) {\n const seen = new Set<string>();\n for (const value of schema.values) {\n if (seen.has(value)) {\n errors.push(\n validationError(\n `Duplicate enum value '${value}'`,\n buildLocation(filePath)\n )\n );\n }\n seen.add(value);\n }\n }\n\n return errors;\n}\n\n/**\n * Result of localized string validation.\n */\nexport interface LocalizedStringValidationResult {\n /** Warnings for locales not in config */\n readonly warnings: OmnifyError[];\n}\n\n/**\n * Validates a localized string against locale configuration.\n * Returns warnings for locales used but not in the configured list.\n *\n * @param fieldName - Name of the field being validated (e.g., 'displayName', 'description')\n * @param value - The localized string value\n * @param filePath - File path for error location\n * @param localeConfig - Optional locale configuration\n * @param context - Optional context (e.g., property name)\n * @returns Validation warnings\n */\nexport function validateLocalizedString(\n fieldName: string,\n value: LocalizedString | undefined,\n filePath: string,\n localeConfig?: LocaleConfig,\n context?: string\n): LocalizedStringValidationResult {\n const warnings: OmnifyError[] = [];\n\n // Skip if no value or not a locale map\n if (value === undefined || !isLocaleMap(value)) {\n return { warnings };\n }\n\n // Skip if no locale config provided\n if (!localeConfig) {\n return { warnings };\n }\n\n // Check each locale in the value\n const configuredLocales = new Set(localeConfig.locales);\n const usedLocales = Object.keys(value);\n\n for (const locale of usedLocales) {\n if (!configuredLocales.has(locale)) {\n const contextStr = context ? ` (property '${context}')` : '';\n warnings.push(\n validationError(\n `${fieldName}${contextStr} uses locale '${locale}' which is not in configured locales`,\n buildLocation(filePath),\n `Configured locales: ${localeConfig.locales.join(', ')}. Add '${locale}' to your locale configuration or remove it from the schema.`\n )\n );\n }\n }\n\n return { warnings };\n}\n\n/**\n * Validates all localized strings in a schema.\n * Checks displayName and description fields at schema and property levels.\n */\nexport function validateLocalizedStrings(\n schema: LoadedSchema,\n localeConfig?: LocaleConfig\n): OmnifyError[] {\n const warnings: OmnifyError[] = [];\n\n // Validate schema-level displayName\n const schemaDisplayNameResult = validateLocalizedString(\n 'displayName',\n schema.displayName,\n schema.filePath,\n localeConfig\n );\n warnings.push(...schemaDisplayNameResult.warnings);\n\n // Validate property-level displayName and description\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Validate property displayName\n const propDisplayNameResult = validateLocalizedString(\n 'displayName',\n property.displayName,\n schema.filePath,\n localeConfig,\n propName\n );\n warnings.push(...propDisplayNameResult.warnings);\n\n // Validate property description (cast to access optional field)\n const propDescription = (property as { description?: LocalizedString }).description;\n const propDescriptionResult = validateLocalizedString(\n 'description',\n propDescription,\n schema.filePath,\n localeConfig,\n propName\n );\n warnings.push(...propDescriptionResult.warnings);\n }\n }\n\n return warnings;\n}\n\n/**\n * Validates a single schema.\n */\nexport function validateSchema(\n schema: LoadedSchema,\n options: ValidationOptions = {}\n): SchemaValidationResult {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n const customTypes = options.customTypes ?? [];\n\n // Validate unknown fields at schema root level\n const unknownSchemaFieldErrors = validateUnknownSchemaFields(schema, schema.filePath);\n errors.push(...unknownSchemaFieldErrors);\n\n // Validate unknown fields in options\n const unknownOptionsErrors = validateUnknownOptionsFields(schema, schema.filePath);\n errors.push(...unknownOptionsErrors);\n\n // Validate property format (must be objects, not strings)\n const propertyFormatErrors = validatePropertyFormat(schema, schema.filePath);\n errors.push(...propertyFormatErrors);\n\n // Validate properties\n const propErrors = validateProperties(schema, schema.filePath, customTypes);\n errors.push(...propErrors);\n\n // Validate options\n const optErrors = validateOptions(schema, schema.filePath);\n errors.push(...optErrors);\n\n // Validate enum schema\n if (schema.kind === 'enum') {\n const enumErrors = validateEnumSchema(schema, schema.filePath);\n errors.push(...enumErrors);\n }\n\n // Validate titleIndex references existing property\n if (schema.titleIndex && schema.properties) {\n if (!schema.properties[schema.titleIndex]) {\n errors.push(\n validationError(\n `titleIndex references non-existent property '${schema.titleIndex}'`,\n buildLocation(schema.filePath),\n `Available properties: ${Object.keys(schema.properties).join(', ')}`\n )\n );\n }\n }\n\n // Validate properties for unknown fields and DB compatibility\n if (schema.properties) {\n for (const [name, property] of Object.entries(schema.properties)) {\n // Check for unknown fields tracked by loader (stripped from property but saved in _unknownFields)\n const propertyUnknownFields = (property as { _unknownFields?: readonly string[] })._unknownFields;\n if (propertyUnknownFields && propertyUnknownFields.length > 0) {\n for (const field of propertyUnknownFields) {\n errors.push(\n validationError(\n `Property '${name}' has unknown field '${field}'`,\n buildLocation(schema.filePath),\n getSuggestionForUnknownField(field)\n )\n );\n }\n }\n\n // Check for unknown fields (errors for wrong type, warnings for completely unknown)\n const unknownFieldResult = validateUnknownFieldsDetailed(\n name,\n property,\n schema.filePath,\n options.customTypeDefinitions\n );\n errors.push(...unknownFieldResult.errors);\n warnings.push(...unknownFieldResult.warnings);\n\n // Check DB compatibility (errors and warnings)\n const dbCompat = validateDbCompatibility(name, property, schema.filePath, options.databaseDriver);\n errors.push(...dbCompat.errors);\n warnings.push(...dbCompat.warnings);\n\n // Validate rules field (if present)\n const rulesErrors = validateRules(name, property, schema.filePath);\n errors.push(...rulesErrors);\n }\n }\n\n // Validate localized strings (displayName, description)\n const localizedStringWarnings = validateLocalizedStrings(schema, options.localeConfig);\n warnings.push(...localizedStringWarnings);\n\n return {\n schemaName: schema.name,\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validates a collection of schemas.\n */\nexport function validateSchemas(\n schemas: SchemaCollection,\n options: ValidationOptions = {}\n): ValidationResult {\n const schemaResults: SchemaValidationResult[] = [];\n const allErrors: OmnifyError[] = [];\n const allWarnings: OmnifyError[] = [];\n const validateAssocs = options.validateAssociations ?? true;\n\n // First pass: validate each schema individually\n for (const schema of Object.values(schemas)) {\n const result = validateSchema(schema, options);\n schemaResults.push(result);\n allErrors.push(...result.errors);\n allWarnings.push(...result.warnings);\n }\n\n // Second pass: validate associations across schemas\n if (validateAssocs) {\n for (const schema of Object.values(schemas)) {\n const assocErrors = validateAssociations(schema, schemas);\n allErrors.push(...assocErrors);\n\n // Update the schema result\n const existingResult = schemaResults.find(r => r.schemaName === schema.name);\n if (existingResult && assocErrors.length > 0) {\n const updatedResult: SchemaValidationResult = {\n ...existingResult,\n valid: false,\n errors: [...existingResult.errors, ...assocErrors],\n };\n const index = schemaResults.indexOf(existingResult);\n schemaResults[index] = updatedResult;\n }\n }\n }\n\n return {\n valid: allErrors.length === 0,\n errorCount: allErrors.length,\n warningCount: allWarnings.length,\n schemas: schemaResults,\n errors: allErrors,\n warnings: allWarnings,\n };\n}\n","/**\n * @famgia/omnify-core - Property Type Definition Base\n *\n * Base interface for all property type definitions.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport type { OmnifyError } from '../../errors/index.js';\nimport type { DatabaseDriver } from '../types.js';\n\n/**\n * Database compatibility level for a type.\n */\nexport type DbCompatibilityLevel = 'full' | 'limited' | 'unsupported';\n\n/**\n * Property type category for grouping.\n */\nexport type PropertyTypeCategory =\n | 'primitive'\n | 'text'\n | 'numeric'\n | 'temporal'\n | 'special'\n | 'enum'\n | 'relation';\n\n/**\n * Base fields valid for all property types.\n */\nexport const BASE_PROPERTY_FIELDS = [\n 'type',\n 'displayName',\n 'placeholder', // Placeholder for form inputs (supports multi-language)\n 'nullable',\n 'default',\n 'unique',\n 'primary', // Custom primary key (use with options.id: false)\n 'description',\n 'renamedFrom',\n 'rules', // Validation rules (application-level only)\n 'hidden', // Laravel: $hidden array\n 'fillable', // Laravel: $fillable array (default true)\n 'fields', // Per-field settings for compound types\n] as const;\n\n/**\n * Valid fields inside the 'rules' object.\n */\nexport const VALID_RULES_FIELDS = [\n 'required',\n 'minLength',\n 'maxLength',\n] as const;\n\n/**\n * Result of default value validation.\n */\nexport interface DefaultValueValidationResult {\n /** Whether the value is valid */\n readonly valid: boolean;\n /** Error message if invalid */\n readonly error?: string;\n}\n\n/**\n * Definition interface for a property type.\n * Each type implements this to self-describe its validation rules.\n */\nexport interface PropertyTypeDefinition {\n /** Type name (e.g., 'String', 'Decimal') */\n readonly name: string;\n\n /** Category for grouping */\n readonly category: PropertyTypeCategory;\n\n /** Fields valid for this type (includes BASE_PROPERTY_FIELDS) */\n readonly validFields: readonly string[];\n\n /** Fields required for this type */\n readonly requiredFields?: readonly string[];\n\n /** Database compatibility per driver */\n readonly dbCompatibility: Readonly<Record<DatabaseDriver, DbCompatibilityLevel>>;\n\n /** Default values for optional fields */\n readonly defaults?: Partial<PropertyDefinition>;\n\n /**\n * Validate type-specific rules.\n * Should not check type name or base fields - registry handles that.\n */\n validate(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n ): OmnifyError[];\n\n /**\n * Validate that a default value is appropriate for this type.\n * Returns validation result with error message if invalid.\n */\n validateDefaultValue?(\n value: unknown,\n property?: PropertyDefinition\n ): DefaultValueValidationResult;\n}\n\n/**\n * Helper to create valid fields array with base fields included.\n */\nexport function createValidFields(\n additionalFields: readonly string[]\n): readonly string[] {\n return [...BASE_PROPERTY_FIELDS, ...additionalFields];\n}\n\n/**\n * Helper to create full DB compatibility (supported on all drivers).\n */\nexport function fullDbCompatibility(): Readonly<Record<DatabaseDriver, DbCompatibilityLevel>> {\n return {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'full',\n sqlserver: 'full',\n };\n}\n","/**\n * @famgia/omnify-core - Type Registry\n *\n * Registry for property type definitions.\n * Provides centralized type lookup and validation.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport type { OmnifyError } from '../../errors/index.js';\nimport type { DatabaseDriver } from '../types.js';\nimport type {\n PropertyTypeDefinition,\n DbCompatibilityLevel,\n} from './base.js';\nimport { BASE_PROPERTY_FIELDS } from './base.js';\n\n/**\n * Registry for property type definitions.\n * Allows built-in and custom types to be registered and looked up.\n */\nexport class TypeRegistry {\n private readonly types = new Map<string, PropertyTypeDefinition>();\n\n /**\n * Register a type definition.\n */\n register(type: PropertyTypeDefinition): void {\n if (this.types.has(type.name)) {\n throw new Error(`Type '${type.name}' is already registered`);\n }\n this.types.set(type.name, type);\n }\n\n /**\n * Register multiple type definitions.\n */\n registerAll(types: readonly PropertyTypeDefinition[]): void {\n for (const type of types) {\n this.register(type);\n }\n }\n\n /**\n * Get a type definition by name.\n */\n get(name: string): PropertyTypeDefinition | undefined {\n return this.types.get(name);\n }\n\n /**\n * Check if a type is registered.\n */\n has(name: string): boolean {\n return this.types.has(name);\n }\n\n /**\n * Get valid fields for a type.\n * Returns base fields if type not found.\n */\n getValidFields(name: string): readonly string[] {\n const type = this.types.get(name);\n return type?.validFields ?? BASE_PROPERTY_FIELDS;\n }\n\n /**\n * Get database compatibility for a type.\n * Returns 'full' if type not found (custom types assumed compatible).\n */\n getDbCompatibility(\n name: string,\n driver: DatabaseDriver\n ): DbCompatibilityLevel {\n const type = this.types.get(name);\n return type?.dbCompatibility[driver] ?? 'full';\n }\n\n /**\n * Get default values for a type.\n */\n getDefaults(name: string): Partial<PropertyDefinition> | undefined {\n return this.types.get(name)?.defaults;\n }\n\n /**\n * Validate a property using its type's validator.\n * Returns empty array if type not found (validation handled elsewhere).\n */\n validateProperty(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n ): OmnifyError[] {\n const type = this.types.get(property.type);\n if (!type) {\n return [];\n }\n return type.validate(propertyName, property, filePath);\n }\n\n /**\n * Get all registered type names.\n */\n getAllTypeNames(): readonly string[] {\n return [...this.types.keys()];\n }\n\n /**\n * Get all valid fields across ALL types.\n * Used to determine if a field is valid for any type.\n */\n getAllValidFields(): ReadonlySet<string> {\n const allFields = new Set<string>();\n for (const type of this.types.values()) {\n for (const field of type.validFields) {\n allFields.add(field);\n }\n }\n return allFields;\n }\n\n /**\n * Check if a field is valid for any registered type.\n */\n isFieldValidForAnyType(field: string): boolean {\n for (const type of this.types.values()) {\n if (type.validFields.includes(field)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get count of registered types.\n */\n get size(): number {\n return this.types.size;\n }\n\n /**\n * Clear all registered types.\n * Useful for testing.\n */\n clear(): void {\n this.types.clear();\n }\n}\n\n/**\n * Global type registry instance.\n * Pre-populated with built-in types.\n */\nexport const typeRegistry = new TypeRegistry();\n","/**\n * @famgia/omnify-core - Primitive Types\n *\n * Boolean type definition.\n */\n\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate boolean default value.\n */\nfunction validateBooleanDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value).toLowerCase();\n if (!['true', 'false', '1', '0'].includes(strValue)) {\n return { valid: false, error: 'Must be true or false' };\n }\n return { valid: true };\n}\n\n/**\n * Boolean type - true/false values.\n */\nexport const BooleanType: PropertyTypeDefinition = {\n name: 'Boolean',\n category: 'primitive',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n // Boolean has no type-specific validation\n return [];\n },\n\n validateDefaultValue: validateBooleanDefault,\n};\n\n/**\n * All primitive types.\n */\nexport const primitiveTypes: readonly PropertyTypeDefinition[] = [\n BooleanType,\n];\n","/**\n * @famgia/omnify-core - Text Types\n *\n * String, Text, LongText, Email, Password type definitions.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * No validation needed for text default values (any string is valid).\n */\nfunction validateTextDefault(): DefaultValueValidationResult {\n return { valid: true };\n}\n\n/**\n * Validate email default value.\n */\nfunction validateEmailDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return { valid: false, error: 'Must be a valid email address' };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Validate length field (database column size only).\n * minLength/maxLength are now in rules field, validated separately.\n */\nfunction validateLength(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n) {\n const errors = [];\n const { length } = property as { length?: unknown };\n\n // Validate length (database column size)\n if (length !== undefined) {\n if (typeof length !== 'number' || length < 1 || length > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid length '${length}'`,\n buildLocation(filePath),\n 'length must be a positive number between 1 and 65535'\n )\n );\n }\n }\n\n return errors;\n}\n\n/**\n * String type - variable length text with optional length constraint.\n */\nexport const StringType: PropertyTypeDefinition = {\n name: 'String',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n defaults: {\n // Default length depends on database, handled by generator\n },\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * Text type - longer text without length constraint.\n */\nexport const TextType: PropertyTypeDefinition = {\n name: 'Text',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * MediumText type - medium length text (MEDIUMTEXT in MySQL, TEXT in PostgreSQL).\n */\nexport const MediumTextType: PropertyTypeDefinition = {\n name: 'MediumText',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * LongText type - very long text (LONGTEXT in MySQL, TEXT in PostgreSQL).\n */\nexport const LongTextType: PropertyTypeDefinition = {\n name: 'LongText',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'full',\n sqlserver: 'limited', // Uses NVARCHAR(MAX)\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * Email type - string with email format validation.\n */\nexport const EmailType: PropertyTypeDefinition = {\n name: 'Email',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateEmailDefault,\n};\n\n/**\n * Password type - string for password storage (hashed).\n */\nexport const PasswordType: PropertyTypeDefinition = {\n name: 'Password',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * All text types.\n */\nexport const textTypes: readonly PropertyTypeDefinition[] = [\n StringType,\n TextType,\n MediumTextType,\n LongTextType,\n EmailType,\n PasswordType,\n];\n","/**\n * @famgia/omnify-core - Numeric Types\n *\n * Int, BigInt, Float, Decimal type definitions.\n */\n\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate integer default value.\n */\nfunction validateIntegerDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^-?\\d+$/.test(strValue)) {\n return { valid: false, error: 'Must be an integer' };\n }\n return { valid: true };\n}\n\n/**\n * Validate float/decimal default value.\n */\nfunction validateNumberDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^-?\\d+(\\.\\d+)?$/.test(strValue)) {\n return { valid: false, error: 'Must be a number' };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * TinyInt type - 8-bit integer (-128 to 127, or 0 to 255 if unsigned).\n */\nexport const TinyIntType: PropertyTypeDefinition = {\n name: 'TinyInt',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * Int type - 32-bit integer.\n */\nexport const IntType: PropertyTypeDefinition = {\n name: 'Int',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * BigInt type - 64-bit integer.\n */\nexport const BigIntType: PropertyTypeDefinition = {\n name: 'BigInt',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * Float type - floating point number.\n */\nexport const FloatType: PropertyTypeDefinition = {\n name: 'Float',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateNumberDefault,\n};\n\n/**\n * Decimal type - precise decimal number with precision and scale.\n */\nexport const DecimalType: PropertyTypeDefinition = {\n name: 'Decimal',\n category: 'numeric',\n validFields: createValidFields(['precision', 'scale', 'unsigned']),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as REAL, loses precision\n sqlserver: 'full',\n },\n defaults: {\n // precision: 8, scale: 2 - handled by generator\n },\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { precision, scale } = property as { precision?: unknown; scale?: unknown };\n\n // Validate precision\n if (precision !== undefined) {\n if (typeof precision !== 'number' || precision < 1 || precision > 65) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid precision '${precision}'`,\n buildLocation(filePath),\n 'precision must be a number between 1 and 65'\n )\n );\n }\n }\n\n // Validate scale\n if (scale !== undefined) {\n if (typeof scale !== 'number' || scale < 0 || scale > 30) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid scale '${scale}'`,\n buildLocation(filePath),\n 'scale must be a number between 0 and 30'\n )\n );\n }\n\n // Scale cannot be greater than precision\n const effectivePrecision = typeof precision === 'number' ? precision : 8;\n if (typeof scale === 'number' && scale > effectivePrecision) {\n errors.push(\n validationError(\n `Property '${propertyName}' has scale (${scale}) greater than precision (${effectivePrecision})`,\n buildLocation(filePath),\n 'scale cannot be greater than precision'\n )\n );\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateNumberDefault,\n};\n\n/**\n * All numeric types.\n */\nexport const numericTypes: readonly PropertyTypeDefinition[] = [\n TinyIntType,\n IntType,\n BigIntType,\n FloatType,\n DecimalType,\n];\n","/**\n * @famgia/omnify-core - Temporal Types\n *\n * Date, Time, DateTime, Timestamp type definitions.\n */\n\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate date default value (YYYY-MM-DD format).\n */\nfunction validateDateDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(strValue)) {\n return { valid: false, error: 'Must be in YYYY-MM-DD format' };\n }\n return { valid: true };\n}\n\n/**\n * Validate time default value (HH:MM or HH:MM:SS format).\n */\nfunction validateTimeDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^\\d{2}:\\d{2}(:\\d{2})?$/.test(strValue)) {\n return { valid: false, error: 'Must be in HH:MM or HH:MM:SS format' };\n }\n return { valid: true };\n}\n\n/**\n * Validate datetime/timestamp default value (YYYY-MM-DD HH:MM:SS format).\n */\nfunction validateTimestampDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n // Accept ISO format (T separator) or space separator\n if (!/^\\d{4}-\\d{2}-\\d{2}(T|\\s)\\d{2}:\\d{2}(:\\d{2})?/.test(strValue)) {\n return { valid: false, error: 'Must be in YYYY-MM-DD HH:MM:SS format' };\n }\n return { valid: true };\n}\n\n/**\n * Date type - date without time.\n */\nexport const DateType: PropertyTypeDefinition = {\n name: 'Date',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateDateDefault,\n};\n\n/**\n * Time type - time without date.\n */\nexport const TimeType: PropertyTypeDefinition = {\n name: 'Time',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as TEXT\n sqlserver: 'full',\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimeDefault,\n};\n\n/**\n * DateTime type - date with time.\n */\nexport const DateTimeType: PropertyTypeDefinition = {\n name: 'DateTime',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimestampDefault,\n};\n\n/**\n * Timestamp type - Unix timestamp or database timestamp.\n */\nexport const TimestampType: PropertyTypeDefinition = {\n name: 'Timestamp',\n category: 'temporal',\n validFields: createValidFields(['useCurrent', 'useCurrentOnUpdate']),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as INTEGER or TEXT\n sqlserver: 'full',\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimestampDefault,\n};\n\n/**\n * All temporal types.\n */\nexport const temporalTypes: readonly PropertyTypeDefinition[] = [\n DateType,\n TimeType,\n DateTimeType,\n TimestampType,\n];\n","/**\n * @famgia/omnify-core - Special Types\n *\n * Json, Uuid, File type definitions.\n */\n\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Valid fields for File type.\n */\nconst FILE_VALID_FIELDS = ['multiple', 'maxFiles', 'accept', 'maxSize'] as const;\n\n/**\n * Validate JSON default value.\n */\nfunction validateJsonDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n try {\n JSON.parse(strValue);\n return { valid: true };\n } catch {\n return { valid: false, error: 'Must be valid JSON' };\n }\n}\n\n/**\n * Validate UUID default value.\n */\nfunction validateUuidDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n // UUID v4 format\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(strValue)) {\n return { valid: false, error: 'Must be a valid UUID' };\n }\n return { valid: true };\n}\n\n/**\n * No validation needed for file default values.\n */\nfunction validateFileDefault(): DefaultValueValidationResult {\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Json type - JSON data stored as text.\n */\nexport const JsonType: PropertyTypeDefinition = {\n name: 'Json',\n category: 'special',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full', // Native JSON type\n postgres: 'full', // Native JSONB type\n sqlite: 'limited', // Stored as TEXT\n sqlserver: 'limited', // Stored as NVARCHAR(MAX)\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateJsonDefault,\n};\n\n/**\n * Uuid type - UUID/GUID string.\n */\nexport const UuidType: PropertyTypeDefinition = {\n name: 'Uuid',\n category: 'special',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateUuidDefault,\n};\n\n/**\n * File type - polymorphic file attachment.\n * Creates morphOne (single) or morphMany (multiple) relationship to files table.\n */\nexport const FileType: PropertyTypeDefinition = {\n name: 'File',\n category: 'special',\n validFields: createValidFields(FILE_VALID_FIELDS),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const {\n multiple,\n maxFiles,\n accept,\n maxSize,\n } = property as {\n multiple?: unknown;\n maxFiles?: unknown;\n accept?: unknown;\n maxSize?: unknown;\n };\n\n // Validate multiple\n if (multiple !== undefined && typeof multiple !== 'boolean') {\n errors.push(\n validationError(\n `Property '${propertyName}' multiple must be a boolean`,\n buildLocation(filePath)\n )\n );\n }\n\n // Validate maxFiles\n if (maxFiles !== undefined) {\n if (!multiple) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxFiles is only valid when multiple=true`,\n buildLocation(filePath),\n 'Add multiple: true or remove maxFiles'\n )\n );\n } else if (typeof maxFiles !== 'number' || maxFiles < 1 || !Number.isInteger(maxFiles)) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxFiles must be a positive integer`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n // Validate accept\n if (accept !== undefined) {\n if (!Array.isArray(accept)) {\n errors.push(\n validationError(\n `Property '${propertyName}' accept must be an array of file extensions`,\n buildLocation(filePath),\n 'Example: accept: [jpg, png, pdf]'\n )\n );\n } else {\n for (const ext of accept) {\n if (typeof ext !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' accept array contains non-string value`,\n buildLocation(filePath)\n )\n );\n break;\n }\n }\n }\n }\n\n // Validate maxSize\n if (maxSize !== undefined) {\n if (typeof maxSize !== 'number' || maxSize < 1 || !Number.isInteger(maxSize)) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxSize must be a positive integer (KB)`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateFileDefault,\n};\n\n/**\n * All special types.\n */\nexport const specialTypes: readonly PropertyTypeDefinition[] = [\n JsonType,\n UuidType,\n FileType,\n];\n","/**\n * @famgia/omnify-core - Enum Types\n *\n * Enum, EnumRef type definitions.\n */\n\nimport type { PropertyDefinition, InlineEnumValue } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Type guard for InlineEnumValue object.\n */\nfunction isInlineEnumValue(value: unknown): value is InlineEnumValue {\n return typeof value === 'object' && value !== null && 'value' in value;\n}\n\n/**\n * Extracts the string value from an enum value (string or object).\n */\nfunction getEnumStringValue(value: string | InlineEnumValue): string {\n return typeof value === 'string' ? value : value.value;\n}\n\n/**\n * Validate enum default value.\n */\nfunction validateEnumDefault(\n value: unknown,\n property?: PropertyDefinition\n): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const enumValues = (property as { enum?: readonly (string | InlineEnumValue)[] })?.enum;\n if (!enumValues || !Array.isArray(enumValues)) {\n return { valid: true }; // No enum values to validate against\n }\n const strValue = String(value);\n const validValues = enumValues.map(getEnumStringValue);\n if (!validValues.includes(strValue)) {\n return {\n valid: false,\n error: `Must be one of: ${validValues.join(', ')}`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Enum type - fixed set of string values.\n */\nexport const EnumType: PropertyTypeDefinition = {\n name: 'Enum',\n category: 'enum',\n validFields: createValidFields(['enum']),\n requiredFields: ['enum'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { enum: enumValues } = property as { enum?: unknown };\n\n if (enumValues === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Enum' requires 'enum' field`,\n buildLocation(filePath),\n 'Add enum values: enum: [value1, value2]'\n )\n );\n } else if (!Array.isArray(enumValues)) {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field must be an array`,\n buildLocation(filePath),\n 'enum: [value1, value2]'\n )\n );\n } else if (enumValues.length === 0) {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field cannot be empty`,\n buildLocation(filePath),\n 'Add at least one enum value'\n )\n );\n } else {\n // Check for duplicate values - supports both string and object format\n const seen = new Set<string>();\n for (const value of enumValues) {\n // Accept both string and object with value field\n if (typeof value === 'string') {\n if (seen.has(value)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has duplicate enum value '${value}'`,\n buildLocation(filePath)\n )\n );\n } else {\n seen.add(value);\n }\n } else if (isInlineEnumValue(value)) {\n // Object format: { value, label?, extra? }\n if (typeof value.value !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum value.value must be a string`,\n buildLocation(filePath),\n 'Use format: { value: \"string\", label: \"Display Label\" }'\n )\n );\n } else if (seen.has(value.value)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has duplicate enum value '${value.value}'`,\n buildLocation(filePath)\n )\n );\n } else {\n seen.add(value.value);\n }\n } else {\n errors.push(\n validationError(\n `Property '${propertyName}' enum values must be strings or objects with 'value' field`,\n buildLocation(filePath),\n 'Use: \"value\" or { value: \"value\", label: \"Label\" }'\n )\n );\n }\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateEnumDefault,\n};\n\n/**\n * EnumRef type - reference to shared enum schema.\n */\nexport const EnumRefType: PropertyTypeDefinition = {\n name: 'EnumRef',\n category: 'enum',\n validFields: createValidFields(['enum']),\n requiredFields: ['enum'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { enum: enumRef } = property as { enum?: unknown };\n\n if (enumRef === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'EnumRef' requires 'enum' field`,\n buildLocation(filePath),\n 'Add enum schema reference: enum: EnumSchemaName'\n )\n );\n } else if (typeof enumRef !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field must be a string (enum schema name)`,\n buildLocation(filePath),\n 'enum: EnumSchemaName'\n )\n );\n } else if (enumRef.trim() === '') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field cannot be empty`,\n buildLocation(filePath),\n 'Add enum schema name'\n )\n );\n }\n\n return errors;\n },\n\n // EnumRef default value validation requires schema context\n // This is handled at a higher level (validator.ts) where schemas are available\n validateDefaultValue: () => ({ valid: true }),\n};\n\n/**\n * All enum types.\n */\nexport const enumTypes: readonly PropertyTypeDefinition[] = [\n EnumType,\n EnumRefType,\n];\n","/**\n * @famgia/omnify-core - Relation Types\n *\n * Association, Polymorphic type definitions.\n */\n\nimport type { AssociationRelation } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Valid association relation types.\n */\nconst VALID_RELATIONS: readonly AssociationRelation[] = [\n 'OneToOne',\n 'OneToMany',\n 'ManyToOne',\n 'ManyToMany',\n // Polymorphic relations\n 'MorphTo',\n 'MorphOne',\n 'MorphMany',\n 'MorphToMany',\n 'MorphedByMany',\n];\n\n/**\n * Polymorphic relation types that use 'targets' instead of 'target'.\n */\nconst MORPH_TO_RELATIONS: readonly AssociationRelation[] = ['MorphTo'];\n\n/**\n * Polymorphic relation types that require 'morphName' pointing to MorphTo on target.\n * Note: MorphedByMany uses optional morphName for pivot table naming only.\n */\nconst MORPH_INVERSE_RELATIONS: readonly AssociationRelation[] = [\n 'MorphOne',\n 'MorphMany',\n];\n\n/**\n * Valid referential actions for foreign keys.\n */\nconst VALID_REFERENTIAL_ACTIONS = [\n 'CASCADE',\n 'SET NULL',\n 'SET DEFAULT',\n 'RESTRICT',\n 'NO ACTION',\n] as const;\n\n/**\n * Relation types that support pivot tables (and thus pivot fields).\n */\nconst PIVOT_TABLE_RELATIONS: readonly AssociationRelation[] = [\n 'ManyToMany',\n 'MorphToMany',\n];\n\n/**\n * Valid types for pivot fields (basic types only, no Association).\n */\nconst VALID_PIVOT_FIELD_TYPES = [\n 'String',\n 'Int',\n 'BigInt',\n 'Float',\n 'Decimal',\n 'Boolean',\n 'Text',\n 'Date',\n 'Time',\n 'Timestamp',\n 'Json',\n] as const;\n\n/**\n * Association fields.\n */\nconst ASSOCIATION_FIELDS = [\n 'relation',\n 'target',\n 'targets', // For MorphTo: array of target schema names\n 'morphName', // For MorphOne/MorphMany/MorphedByMany: polymorphic name\n 'inversedBy',\n 'mappedBy',\n 'onDelete',\n 'onUpdate',\n 'owning',\n 'joinTable',\n 'pivotFields', // For ManyToMany/MorphToMany: additional fields on pivot table\n] as const;\n\n/**\n * Association type - relationship to another schema.\n */\nexport const AssociationType: PropertyTypeDefinition = {\n name: 'Association',\n category: 'relation',\n validFields: createValidFields(ASSOCIATION_FIELDS),\n requiredFields: ['relation'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const {\n relation,\n target,\n targets,\n morphName,\n onDelete,\n onUpdate,\n } = property as {\n relation?: unknown;\n target?: unknown;\n targets?: unknown;\n morphName?: unknown;\n onDelete?: unknown;\n onUpdate?: unknown;\n };\n\n // Validate required field: relation\n if (relation === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Association' requires 'relation' field`,\n buildLocation(filePath),\n 'Add relation: OneToOne, OneToMany, ManyToOne, ManyToMany, MorphTo, MorphOne, MorphMany, MorphToMany, or MorphedByMany'\n )\n );\n return errors;\n }\n\n if (typeof relation !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' relation field must be a string`,\n buildLocation(filePath)\n )\n );\n return errors;\n }\n\n if (!VALID_RELATIONS.includes(relation as AssociationRelation)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid relation '${relation}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_RELATIONS.join(', ')}`\n )\n );\n return errors;\n }\n\n const relationTyped = relation as AssociationRelation;\n\n // Validate based on relation type\n if (MORPH_TO_RELATIONS.includes(relationTyped)) {\n // MorphTo: requires 'targets' array, not 'target'\n if (targets === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphTo' requires 'targets' field`,\n buildLocation(filePath),\n 'Add targets: [Post, Video, Image]'\n )\n );\n } else if (!Array.isArray(targets)) {\n errors.push(\n validationError(\n `Property '${propertyName}' targets field must be an array of schema names`,\n buildLocation(filePath),\n 'Example: targets: [Post, Video, Image]'\n )\n );\n } else if (targets.length === 0) {\n errors.push(\n validationError(\n `Property '${propertyName}' targets array cannot be empty`,\n buildLocation(filePath),\n 'Add at least one target schema'\n )\n );\n } else {\n // Validate each target is a string\n for (const t of targets) {\n if (typeof t !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' targets array contains non-string value`,\n buildLocation(filePath)\n )\n );\n }\n }\n }\n\n // MorphTo should not have 'target'\n if (target !== undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphTo' should use 'targets' (plural) not 'target'`,\n buildLocation(filePath),\n 'Change target to targets array'\n )\n );\n }\n } else if (MORPH_INVERSE_RELATIONS.includes(relationTyped)) {\n // MorphOne/MorphMany: requires 'target' and 'morphName' pointing to MorphTo property\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Comment'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n\n if (morphName === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' requires 'morphName' field`,\n buildLocation(filePath),\n 'Add morphName to match the MorphTo property name (e.g., morphName: commentable)'\n )\n );\n } else if (typeof morphName !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' morphName field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else if (relationTyped === 'MorphToMany') {\n // MorphToMany: requires 'target', optional 'joinTable'\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphToMany' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Tag'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else if (relationTyped === 'MorphedByMany') {\n // MorphedByMany: requires 'target', optional 'morphName' for pivot table naming\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphedByMany' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Post'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n // morphName is optional for MorphedByMany (used for pivot table naming)\n if (morphName !== undefined && typeof morphName !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' morphName field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else {\n // Standard relations: OneToOne, OneToMany, ManyToOne, ManyToMany\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Association' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: User'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n // Validate referential actions (only for owning side relations)\n if (onDelete !== undefined && typeof onDelete === 'string') {\n if (!VALID_REFERENTIAL_ACTIONS.includes(onDelete as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid onDelete action '${onDelete}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n if (onUpdate !== undefined && typeof onUpdate === 'string') {\n if (!VALID_REFERENTIAL_ACTIONS.includes(onUpdate as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid onUpdate action '${onUpdate}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n // Validate pivotFields (only for ManyToMany and MorphToMany)\n const pivotFields = (property as { pivotFields?: unknown }).pivotFields;\n if (pivotFields !== undefined) {\n if (!PIVOT_TABLE_RELATIONS.includes(relationTyped)) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' cannot have pivotFields`,\n buildLocation(filePath),\n 'pivotFields is only allowed for ManyToMany and MorphToMany relations'\n )\n );\n } else if (typeof pivotFields !== 'object' || pivotFields === null || Array.isArray(pivotFields)) {\n errors.push(\n validationError(\n `Property '${propertyName}' pivotFields must be an object`,\n buildLocation(filePath),\n 'Example: pivotFields: { assigned_at: { type: \"Timestamp\" } }'\n )\n );\n } else {\n // Validate each pivot field\n for (const [fieldName, fieldDef] of Object.entries(pivotFields)) {\n if (typeof fieldDef !== 'object' || fieldDef === null) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' must be an object`,\n buildLocation(filePath)\n )\n );\n continue;\n }\n\n const { type: fieldType } = fieldDef as { type?: unknown };\n if (fieldType === undefined) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' requires 'type' field`,\n buildLocation(filePath),\n `Example: ${fieldName}: { type: \"String\" }`\n )\n );\n } else if (typeof fieldType !== 'string') {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' type must be a string`,\n buildLocation(filePath)\n )\n );\n } else if (fieldType === 'Association') {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' cannot be of type 'Association'`,\n buildLocation(filePath),\n 'Pivot fields only support basic types like String, Int, Boolean, Timestamp, etc.'\n )\n );\n } else if (!VALID_PIVOT_FIELD_TYPES.includes(fieldType as typeof VALID_PIVOT_FIELD_TYPES[number])) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' has unsupported type '${fieldType}'`,\n buildLocation(filePath),\n `Supported types: ${VALID_PIVOT_FIELD_TYPES.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n return errors;\n },\n};\n\n/**\n * All relation types.\n */\nexport const relationTypes: readonly PropertyTypeDefinition[] = [\n AssociationType,\n];\n\n/**\n * Export constants for use in cross-schema validation.\n */\nexport { VALID_RELATIONS, VALID_REFERENTIAL_ACTIONS };\n","/**\n * @famgia/omnify-core - Property Type Definitions\n *\n * Exports all property type definitions and the type registry.\n */\n\n// Base interface and helpers\nexport type {\n PropertyTypeDefinition,\n PropertyTypeCategory,\n DbCompatibilityLevel,\n DefaultValueValidationResult,\n} from './base.js';\nexport { BASE_PROPERTY_FIELDS, VALID_RULES_FIELDS, createValidFields, fullDbCompatibility } from './base.js';\n\n// Registry\nexport { TypeRegistry, typeRegistry } from './registry.js';\n\n// Type definitions by category\nexport { BooleanType, primitiveTypes } from './primitives.js';\nexport {\n StringType,\n TextType,\n MediumTextType,\n LongTextType,\n EmailType,\n PasswordType,\n textTypes,\n} from './text.js';\nexport {\n TinyIntType,\n IntType,\n BigIntType,\n FloatType,\n DecimalType,\n numericTypes,\n} from './numeric.js';\nexport {\n DateType,\n TimeType,\n DateTimeType,\n TimestampType,\n temporalTypes,\n} from './temporal.js';\nexport {\n JsonType,\n UuidType,\n FileType,\n specialTypes,\n} from './special.js';\nexport {\n EnumType,\n EnumRefType,\n enumTypes,\n} from './enum.js';\nexport {\n AssociationType,\n relationTypes,\n VALID_RELATIONS,\n VALID_REFERENTIAL_ACTIONS,\n} from './relations.js';\n\n// Import for registration\nimport { typeRegistry } from './registry.js';\nimport { primitiveTypes } from './primitives.js';\nimport { textTypes } from './text.js';\nimport { numericTypes } from './numeric.js';\nimport { temporalTypes } from './temporal.js';\nimport { specialTypes } from './special.js';\nimport { enumTypes } from './enum.js';\nimport { relationTypes } from './relations.js';\n\n/**\n * All built-in types grouped by category.\n */\nexport const allBuiltInTypes = [\n ...primitiveTypes,\n ...textTypes,\n ...numericTypes,\n ...temporalTypes,\n ...specialTypes,\n ...enumTypes,\n ...relationTypes,\n] as const;\n\n/**\n * Register all built-in types with the global registry.\n */\nfunction registerBuiltInTypes(): void {\n for (const type of allBuiltInTypes) {\n if (!typeRegistry.has(type.name)) {\n typeRegistry.register(type);\n }\n }\n}\n\n// Auto-register on import\nregisterBuiltInTypes();\n\n/**\n * Validate a default value for a given type.\n *\n * @param typeName - The type name (e.g., 'Int', 'String', 'Enum')\n * @param value - The default value to validate\n * @param property - Optional property definition for context (needed for Enum/Select)\n * @returns Validation result with valid flag and optional error message\n */\nexport function validateDefaultValue(\n typeName: string,\n value: unknown,\n property?: { enum?: readonly string[]; options?: unknown[] }\n): { valid: boolean; error?: string } {\n const typeDef = typeRegistry.get(typeName);\n if (!typeDef) {\n return { valid: true }; // Unknown type, skip validation\n }\n\n if (typeDef.validateDefaultValue) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeDef.validateDefaultValue(value, property as any);\n }\n\n return { valid: true }; // No validator for this type\n}\n","/**\n * @famgia/omnify-core - Generator Runner\n *\n * Executes generators in topological order based on dependencies (DAG).\n */\n\nimport type { SchemaCollection, PluginLogger, GeneratorOutput, CustomTypeDefinition, PluginEnumDefinition, SchemaChange, LocaleConfig } from '@famgia/omnify-types';\nimport type { RegisteredGenerator, GeneratorContext } from './types.js';\n\n/**\n * Result of running all generators.\n */\nexport interface GeneratorRunResult {\n /** Whether all generators succeeded */\n success: boolean;\n /** All generated outputs */\n outputs: GeneratorOutput[];\n /** Outputs grouped by generator name */\n outputsByGenerator: ReadonlyMap<string, GeneratorOutput[]>;\n /** Execution order (topological) */\n executionOrder: string[];\n /** Errors if any */\n errors: GeneratorError[];\n}\n\n/**\n * Error from generator execution.\n */\nexport interface GeneratorError {\n /** Generator name */\n generatorName: string;\n /** Error message */\n message: string;\n /** Original error */\n cause?: unknown;\n}\n\n/**\n * Options for generator runner.\n */\nexport interface GeneratorRunnerOptions {\n /** Current working directory */\n cwd: string;\n /** Logger for output */\n logger: PluginLogger;\n /** Custom types registered by all plugins */\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>;\n /** Enums registered by all plugins */\n pluginEnums?: ReadonlyMap<string, PluginEnumDefinition>;\n /** Locale configuration for multi-language support */\n localeConfig?: LocaleConfig;\n}\n\n/**\n * Generator Runner - executes generators in DAG order.\n */\nexport class GeneratorRunner {\n private generators = new Map<string, RegisteredGenerator>();\n private readonly options: GeneratorRunnerOptions;\n\n constructor(options: GeneratorRunnerOptions) {\n this.options = options;\n }\n\n /**\n * Register a generator.\n */\n register(generator: RegisteredGenerator): void {\n const name = generator.definition.name;\n if (this.generators.has(name)) {\n throw new Error(`Generator \"${name}\" is already registered`);\n }\n this.generators.set(name, generator);\n }\n\n /**\n * Register multiple generators.\n */\n registerAll(generators: RegisteredGenerator[]): void {\n for (const gen of generators) {\n this.register(gen);\n }\n }\n\n /**\n * Clear all registered generators.\n */\n clear(): void {\n this.generators.clear();\n }\n\n /**\n * Get all registered generator names.\n */\n getGeneratorNames(): string[] {\n return Array.from(this.generators.keys());\n }\n\n /**\n * Check if a generator is registered.\n */\n hasGenerator(name: string): boolean {\n return this.generators.has(name);\n }\n\n /**\n * Run all generators in topological order.\n * @param schemas - The schemas to generate from\n * @param changes - Schema changes detected from lock file comparison\n */\n async runAll(\n schemas: SchemaCollection,\n changes?: readonly SchemaChange[]\n ): Promise<GeneratorRunResult> {\n const errors: GeneratorError[] = [];\n const outputs: GeneratorOutput[] = [];\n const outputsByGenerator = new Map<string, GeneratorOutput[]>();\n\n // Get topological order\n let executionOrder: string[];\n try {\n executionOrder = this.topologicalSort();\n } catch (error) {\n return {\n success: false,\n outputs: [],\n outputsByGenerator: new Map(),\n executionOrder: [],\n errors: [{\n generatorName: '',\n message: error instanceof Error ? error.message : String(error),\n cause: error,\n }],\n };\n }\n\n // Track outputs from each generator for dependencies\n const previousOutputs = new Map<string, readonly GeneratorOutput[]>();\n\n // Run generators in order\n for (const name of executionOrder) {\n const generator = this.generators.get(name)!;\n const { definition, pluginConfig } = generator;\n\n try {\n this.options.logger.debug(`Running generator: ${name}`);\n\n // Build context\n const ctx: GeneratorContext = {\n schemas,\n changes,\n pluginConfig,\n cwd: this.options.cwd,\n logger: this.options.logger,\n previousOutputs,\n customTypes: this.options.customTypes ?? new Map(),\n pluginEnums: this.options.pluginEnums ?? new Map(),\n localeConfig: this.options.localeConfig,\n };\n\n // Execute generator\n const result = await definition.generate(ctx);\n const generatorOutputs = Array.isArray(result) ? result : [result];\n\n // Store outputs\n outputsByGenerator.set(name, generatorOutputs);\n previousOutputs.set(name, generatorOutputs);\n outputs.push(...generatorOutputs);\n\n this.options.logger.debug(`Generator ${name} produced ${generatorOutputs.length} outputs`);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.options.logger.error(`Generator ${name} failed: ${message}`);\n errors.push({\n generatorName: name,\n message,\n cause: error,\n });\n }\n }\n\n return {\n success: errors.length === 0,\n outputs,\n outputsByGenerator,\n executionOrder,\n errors,\n };\n }\n\n /**\n * Topological sort using Kahn's algorithm.\n * Returns generators in execution order (dependencies first).\n * Throws if circular dependencies detected.\n */\n private topologicalSort(): string[] {\n const names = Array.from(this.generators.keys());\n\n // Build adjacency list and in-degree count\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n // Initialize\n for (const name of names) {\n inDegree.set(name, 0);\n adjacency.set(name, []);\n }\n\n // Build graph\n for (const name of names) {\n const generator = this.generators.get(name)!;\n const deps = generator.definition.dependsOn ?? [];\n\n for (const dep of deps) {\n if (!this.generators.has(dep)) {\n throw new Error(\n `Generator \"${name}\" depends on \"${dep}\" which is not registered`\n );\n }\n // dep -> name (dep must run before name)\n adjacency.get(dep)!.push(name);\n inDegree.set(name, inDegree.get(name)! + 1);\n }\n }\n\n // Kahn's algorithm\n const queue: string[] = [];\n const result: string[] = [];\n\n // Start with generators that have no dependencies\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n result.push(current);\n\n for (const neighbor of adjacency.get(current)!) {\n const newDegree = inDegree.get(neighbor)! - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Check for cycles\n if (result.length !== names.length) {\n const remaining = names.filter(n => !result.includes(n));\n throw new Error(\n `Circular dependency detected among generators: ${remaining.join(', ')}`\n );\n }\n\n return result;\n }\n}\n","/**\n * @famgia/omnify-core - Plugin Manager\n *\n * Manages plugin registration and type resolution.\n */\n\nimport type {\n OmnifyPlugin,\n CustomTypeDefinition,\n PluginEnumDefinition,\n PluginContext,\n PluginLogger,\n SchemaCollection,\n SchemaChange,\n} from '@famgia/omnify-types';\nimport type {\n RegisteredType,\n RegisteredGenerator,\n PluginRegistry,\n PluginManagerOptions,\n PluginRegistrationResult,\n} from './types.js';\nimport { pluginError, pluginTypeConflictError, pluginNotFoundError } from '../errors/index.js';\nimport { GeneratorRunner, type GeneratorRunResult } from './generator-runner.js';\n\n/**\n * Default logger that does nothing.\n */\nconst nullLogger: PluginLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\n/**\n * Console logger for verbose mode.\n */\nconst consoleLogger: PluginLogger = {\n debug: (msg) => console.log(`[plugin:debug] ${msg}`),\n info: (msg) => console.log(`[plugin:info] ${msg}`),\n warn: (msg) => console.warn(`[plugin:warn] ${msg}`),\n error: (msg) => console.error(`[plugin:error] ${msg}`),\n};\n\n/**\n * Plugin Manager class for managing plugin lifecycle.\n */\nexport class PluginManager {\n private readonly _plugins: Map<string, OmnifyPlugin> = new Map();\n private readonly _types: Map<string, RegisteredType> = new Map();\n private readonly _enums: Map<string, PluginEnumDefinition> = new Map();\n private readonly _generators: Map<string, RegisteredGenerator> = new Map();\n private readonly _pluginConfigs: Map<string, Record<string, unknown>> = new Map();\n private readonly _cwd: string;\n private readonly _verbose: boolean;\n private readonly _logger: PluginLogger;\n\n constructor(options: PluginManagerOptions = {}) {\n this._cwd = options.cwd ?? process.cwd();\n this._verbose = options.verbose ?? false;\n this._logger = options.logger ?? (this._verbose ? consoleLogger : nullLogger);\n }\n\n /**\n * Creates a plugin context for plugin setup.\n */\n private createContext(): PluginContext {\n return {\n cwd: this._cwd,\n verbose: this._verbose,\n logger: this._logger,\n };\n }\n\n /**\n * Registers a single plugin.\n * @param plugin - The plugin to register\n * @param pluginConfig - Optional configuration passed to plugin generators\n */\n async register(\n plugin: OmnifyPlugin,\n pluginConfig: Record<string, unknown> = {}\n ): Promise<PluginRegistrationResult> {\n const warnings: string[] = [];\n const registeredTypes: RegisteredType[] = [];\n\n // Check for duplicate plugin\n if (this._plugins.has(plugin.name)) {\n return {\n success: false,\n types: [],\n warnings: [],\n error: `Plugin '${plugin.name}' is already registered`,\n };\n }\n\n this._logger.debug(`Registering plugin: ${plugin.name}@${plugin.version}`);\n\n // Store plugin config\n this._pluginConfigs.set(plugin.name, pluginConfig);\n\n // Run setup if provided\n if (plugin.setup) {\n try {\n await plugin.setup(this.createContext());\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n types: [],\n warnings: [],\n error: `Plugin setup failed: ${message}`,\n };\n }\n }\n\n // Register types\n if (plugin.types) {\n for (const typeDef of plugin.types) {\n // Check for type conflicts\n const existing = this._types.get(typeDef.name);\n if (existing) {\n throw pluginTypeConflictError(\n typeDef.name,\n existing.pluginName,\n plugin.name\n );\n }\n\n // Validate type definition\n const validationError = this.validateTypeDefinition(typeDef);\n if (validationError) {\n warnings.push(`Type '${typeDef.name}': ${validationError}`);\n continue;\n }\n\n const registeredType: RegisteredType = {\n ...typeDef,\n pluginName: plugin.name,\n pluginVersion: plugin.version,\n };\n\n this._types.set(typeDef.name, registeredType);\n registeredTypes.push(registeredType);\n\n this._logger.debug(` Registered type: ${typeDef.name}`);\n }\n }\n\n // Register enums\n if (plugin.enums) {\n for (const enumDef of plugin.enums) {\n // Check for enum conflicts\n const existing = this._enums.get(enumDef.name);\n if (existing) {\n warnings.push(\n `Enum '${enumDef.name}' already registered by another plugin`\n );\n continue;\n }\n\n this._enums.set(enumDef.name, enumDef);\n this._logger.debug(` Registered enum: ${enumDef.name}`);\n }\n }\n\n // Register generators\n if (plugin.generators) {\n for (const genDef of plugin.generators) {\n // Check for generator conflicts\n const existing = this._generators.get(genDef.name);\n if (existing) {\n warnings.push(\n `Generator '${genDef.name}' already registered by plugin '${existing.pluginName}'`\n );\n continue;\n }\n\n const registeredGenerator: RegisteredGenerator = {\n definition: genDef,\n pluginName: plugin.name,\n pluginVersion: plugin.version,\n pluginConfig,\n };\n\n this._generators.set(genDef.name, registeredGenerator);\n this._logger.debug(` Registered generator: ${genDef.name}`);\n }\n }\n\n // Store plugin\n this._plugins.set(plugin.name, plugin);\n\n const genCount = plugin.generators?.length ?? 0;\n const enumCount = plugin.enums?.length ?? 0;\n this._logger.info(\n `Plugin registered: ${plugin.name} (${registeredTypes.length} types, ${enumCount} enums, ${genCount} generators)`\n );\n\n return {\n success: true,\n types: registeredTypes,\n warnings,\n };\n }\n\n /**\n * Registers multiple plugins.\n */\n async registerAll(plugins: readonly OmnifyPlugin[]): Promise<void> {\n for (const plugin of plugins) {\n const result = await this.register(plugin);\n if (!result.success) {\n throw pluginError(result.error ?? 'Unknown error', plugin.name);\n }\n }\n }\n\n /**\n * Validates a type definition.\n */\n private validateTypeDefinition(typeDef: CustomTypeDefinition): string | undefined {\n if (!typeDef.name || typeDef.name.length === 0) {\n return 'Type name is required';\n }\n\n if (typeDef.compound) {\n if (!typeDef.expand || typeDef.expand.length === 0) {\n return 'Compound type must have expand definitions';\n }\n\n for (const field of typeDef.expand) {\n if (!field.suffix) {\n return 'Expanded field must have a suffix';\n }\n // Field must have either sql definition OR enumRef\n const hasSql = field.sql && field.sql.sqlType;\n const hasEnumRef = 'enumRef' in field && typeof field.enumRef === 'string';\n if (!hasSql && !hasEnumRef) {\n return `Expanded field '${field.suffix}' must have SQL type or enumRef`;\n }\n // TypeScript type is optional when using enumRef (will be derived from enum)\n if (!hasEnumRef && (!field.typescript || !field.typescript.type)) {\n return `Expanded field '${field.suffix}' must have TypeScript type`;\n }\n }\n } else {\n if (!typeDef.sql || !typeDef.sql.sqlType) {\n return 'Non-compound type must have SQL definition';\n }\n if (!typeDef.typescript || !typeDef.typescript.type) {\n return 'Non-compound type must have TypeScript type';\n }\n }\n\n return undefined;\n }\n\n /**\n * Unregisters a plugin and its types/generators.\n */\n async unregister(pluginName: string): Promise<void> {\n const plugin = this._plugins.get(pluginName);\n if (!plugin) {\n throw pluginNotFoundError(pluginName);\n }\n\n // Run teardown if provided\n if (plugin.teardown) {\n try {\n await plugin.teardown();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this._logger.warn(`Plugin teardown failed: ${message}`);\n }\n }\n\n // Remove types from this plugin\n for (const [typeName, type] of this._types) {\n if (type.pluginName === pluginName) {\n this._types.delete(typeName);\n }\n }\n\n // Remove generators from this plugin\n for (const [genName, gen] of this._generators) {\n if (gen.pluginName === pluginName) {\n this._generators.delete(genName);\n }\n }\n\n // Remove plugin config\n this._pluginConfigs.delete(pluginName);\n\n // Remove plugin\n this._plugins.delete(pluginName);\n\n this._logger.info(`Plugin unregistered: ${pluginName}`);\n }\n\n /**\n * Gets a registered type by name.\n */\n getType(typeName: string): RegisteredType | undefined {\n return this._types.get(typeName);\n }\n\n /**\n * Checks if a type is registered.\n */\n hasType(typeName: string): boolean {\n return this._types.has(typeName);\n }\n\n /**\n * Gets all registered types.\n */\n getAllTypes(): ReadonlyMap<string, RegisteredType> {\n return this._types;\n }\n\n /**\n * Gets all registered type names.\n */\n getTypeNames(): readonly string[] {\n return Array.from(this._types.keys());\n }\n\n /**\n * Gets a registered plugin by name.\n */\n getPlugin(pluginName: string): OmnifyPlugin | undefined {\n return this._plugins.get(pluginName);\n }\n\n /**\n * Gets all registered plugins.\n */\n getAllPlugins(): ReadonlyMap<string, OmnifyPlugin> {\n return this._plugins;\n }\n\n /**\n * Gets a registered generator by name.\n */\n getGenerator(generatorName: string): RegisteredGenerator | undefined {\n return this._generators.get(generatorName);\n }\n\n /**\n * Checks if a generator is registered.\n */\n hasGenerator(generatorName: string): boolean {\n return this._generators.has(generatorName);\n }\n\n /**\n * Gets all registered generators.\n */\n getAllGenerators(): ReadonlyMap<string, RegisteredGenerator> {\n return this._generators;\n }\n\n /**\n * Gets all registered generator names.\n */\n getGeneratorNames(): readonly string[] {\n return Array.from(this._generators.keys());\n }\n\n /**\n * Gets the current registry state.\n */\n getRegistry(): PluginRegistry {\n return {\n plugins: this._plugins,\n types: this._types,\n generators: this._generators,\n };\n }\n\n /**\n * Runs all registered generators in topological order.\n * @param schemas - The schemas to generate from\n * @param changes - Schema changes detected from lock file comparison\n * @returns Result with all generated outputs\n */\n async runGenerators(\n schemas: SchemaCollection,\n changes?: readonly SchemaChange[]\n ): Promise<GeneratorRunResult> {\n // Build customTypes map from registered types (convert RegisteredType to CustomTypeDefinition)\n const customTypes = new Map<string, CustomTypeDefinition>();\n for (const [name, registeredType] of this._types) {\n // Extract CustomTypeDefinition fields (exclude pluginName, pluginVersion)\n const { pluginName, pluginVersion, ...typeDefinition } = registeredType;\n customTypes.set(name, typeDefinition as CustomTypeDefinition);\n }\n\n const runner = new GeneratorRunner({\n cwd: this._cwd,\n logger: this._logger,\n customTypes,\n pluginEnums: this._enums,\n });\n\n // Register all generators\n for (const gen of this._generators.values()) {\n runner.register(gen);\n }\n\n // Run all generators with changes\n return runner.runAll(schemas, changes);\n }\n\n /**\n * Clears all registered plugins, types, and generators.\n */\n async clear(): Promise<void> {\n // Teardown all plugins\n for (const plugin of this._plugins.values()) {\n if (plugin.teardown) {\n try {\n await plugin.teardown();\n } catch {\n // Ignore teardown errors during clear\n }\n }\n }\n\n this._plugins.clear();\n this._types.clear();\n this._enums.clear();\n this._generators.clear();\n this._pluginConfigs.clear();\n\n this._logger.debug('Plugin registry cleared');\n }\n}\n\n/**\n * Creates a new plugin manager instance.\n */\nexport function createPluginManager(options?: PluginManagerOptions): PluginManager {\n return new PluginManager(options);\n}\n","/**\n * @famgia/omnify-core - Compound Type Expander\n *\n * Expands compound types into multiple fields.\n */\n\nimport type {\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n} from '@famgia/omnify-types';\nimport type { RegisteredType, PluginRegistry } from './types.js';\n\n/**\n * Expanded property with original property name.\n */\nexport interface ExpandedProperty {\n /** Original property name */\n originalName: string;\n /** Expanded column name (originalName + suffix) */\n expandedName: string;\n /** The expanded field definition */\n property: PropertyDefinition;\n /** Whether this is from a compound type */\n isCompound: boolean;\n /** Source type name if from plugin */\n sourceType?: string;\n}\n\n/**\n * Expands a single property if it's a compound type.\n */\nexport function expandProperty(\n propertyName: string,\n property: PropertyDefinition,\n registry: PluginRegistry\n): ExpandedProperty[] {\n const typeName = property.type;\n const registeredType = registry.types.get(typeName);\n\n // If not a registered type or not compound, return as-is\n if (!registeredType || !registeredType.compound || !registeredType.expand) {\n return [{\n originalName: propertyName,\n expandedName: propertyName,\n property,\n isCompound: false,\n }];\n }\n\n // Expand compound type\n const expanded: ExpandedProperty[] = [];\n\n for (const field of registeredType.expand) {\n const expandedName = `${propertyName}${field.suffix}`;\n\n // Create property definition for expanded field\n const expandedProperty: PropertyDefinition = {\n type: 'String', // Use String as placeholder, actual SQL type is in field.sql\n // Copy nullable from original property\n ...((property as { nullable?: boolean }).nullable !== undefined\n ? { nullable: (property as { nullable?: boolean }).nullable }\n : {}),\n };\n\n expanded.push({\n originalName: propertyName,\n expandedName,\n property: expandedProperty,\n isCompound: true,\n sourceType: typeName,\n });\n }\n\n return expanded;\n}\n\n/**\n * Expands all compound types in a schema's properties.\n */\nexport function expandSchemaProperties(\n schema: LoadedSchema,\n registry: PluginRegistry\n): Map<string, ExpandedProperty[]> {\n const expandedMap = new Map<string, ExpandedProperty[]>();\n\n if (!schema.properties) {\n return expandedMap;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n const expanded = expandProperty(propName, property, registry);\n expandedMap.set(propName, expanded);\n }\n\n return expandedMap;\n}\n\n/**\n * Creates a new schema with compound types expanded.\n */\nexport function expandSchema(\n schema: LoadedSchema,\n registry: PluginRegistry\n): LoadedSchema {\n if (!schema.properties || schema.kind === 'enum') {\n return schema;\n }\n\n const expandedProperties: Record<string, PropertyDefinition> = {};\n let hasExpansion = false;\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n const expanded = expandProperty(propName, property, registry);\n\n const firstExpanded = expanded[0];\n if (expanded.length === 1 && firstExpanded && !firstExpanded.isCompound) {\n // Not a compound type, keep original\n expandedProperties[propName] = property;\n } else {\n // Compound type expanded\n hasExpansion = true;\n for (const exp of expanded) {\n expandedProperties[exp.expandedName] = exp.property;\n }\n }\n }\n\n if (!hasExpansion) {\n return schema;\n }\n\n return {\n ...schema,\n properties: expandedProperties,\n };\n}\n\n/**\n * Expands compound types in all schemas.\n */\nexport function expandSchemas(\n schemas: SchemaCollection,\n registry: PluginRegistry\n): SchemaCollection {\n const expanded: Record<string, LoadedSchema> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n expanded[name] = expandSchema(schema, registry);\n }\n\n return expanded;\n}\n\n/**\n * Gets the registered type info for a property type.\n */\nexport function getTypeInfo(\n typeName: string,\n registry: PluginRegistry\n): RegisteredType | undefined {\n return registry.types.get(typeName);\n}\n\n/**\n * Checks if a type is a compound type.\n */\nexport function isCompoundType(\n typeName: string,\n registry: PluginRegistry\n): boolean {\n const type = registry.types.get(typeName);\n return type?.compound === true;\n}\n\n/**\n * Gets all custom type names from the registry.\n */\nexport function getCustomTypeNames(registry: PluginRegistry): string[] {\n return Array.from(registry.types.keys());\n}\n","/**\n * @famgia/omnify-core - Omnify Programmatic API\n *\n * Main entry point for using omnify-schema programmatically.\n */\n\nimport { resolve } from 'node:path';\nimport type { SchemaCollection, OmnifyPlugin } from '@famgia/omnify-types';\nimport type {\n OmnifyOptions,\n OmnifyLogger,\n LoadResult,\n SchemaError,\n SchemaIntrospection,\n} from './types.js';\nimport { loadSchemas } from '../schema/index.js';\nimport { validateSchemas } from '../validation/index.js';\nimport { PluginManager, createPluginManager } from '../plugins/index.js';\nimport type { PluginRegistry } from '../plugins/types.js';\nimport { OmnifyError } from '../errors/index.js';\nimport {\n introspectSchema,\n introspectSchemas,\n getSchemaNames,\n getEntitySchemas,\n getEnumSchemas,\n getSchemasByGroup,\n getGroups,\n findReferencingSchemas,\n findReferencedSchemas,\n hasCircularReferences,\n getTopologicalOrder,\n} from './metadata.js';\n\n/**\n * Default logger that does nothing.\n */\nconst nullLogger: OmnifyLogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Console logger for verbose mode.\n */\nconst consoleLogger: OmnifyLogger = {\n debug: (msg, ...args) => console.debug(`[omnify] ${msg}`, ...args),\n info: (msg, ...args) => console.info(`[omnify] ${msg}`, ...args),\n warn: (msg, ...args) => console.warn(`[omnify] ${msg}`, ...args),\n error: (msg, ...args) => console.error(`[omnify] ${msg}`, ...args),\n};\n\n/**\n * Main Omnify API class for programmatic usage.\n *\n * @example\n * ```typescript\n * import { Omnify } from '@famgia/omnify-core';\n *\n * const omnify = new Omnify({\n * schemaDir: './schemas',\n * plugins: [japanTypesPlugin],\n * });\n *\n * // Load and validate schemas\n * const { schemas, errors } = await omnify.load();\n *\n * // Get schema metadata\n * const users = omnify.getSchema('User');\n *\n * // Introspect schema\n * const introspection = omnify.introspect('User');\n * ```\n */\nexport class Omnify {\n private readonly options: OmnifyOptions;\n private readonly logger: OmnifyLogger;\n private readonly pluginManager: PluginManager;\n private schemas: SchemaCollection | null = null;\n private loaded = false;\n\n constructor(options: OmnifyOptions) {\n this.options = {\n ...options,\n schemaDir: resolve(options.schemaDir),\n };\n this.logger = options.logger ?? (options.verbose ? consoleLogger : nullLogger);\n this.pluginManager = createPluginManager({ logger: this.logger });\n }\n\n /**\n * Registers plugins with the plugin manager.\n */\n async registerPlugins(plugins: OmnifyPlugin[]): Promise<void> {\n for (const plugin of plugins) {\n this.logger.debug(`Registering plugin: ${plugin.name}`);\n const result = await this.pluginManager.register(plugin);\n if (!result.success) {\n throw new Error(`Failed to register plugin ${plugin.name}: ${result.error}`);\n }\n if (result.warnings.length > 0) {\n for (const warning of result.warnings) {\n this.logger.warn(warning);\n }\n }\n }\n }\n\n /**\n * Loads and validates schemas from the configured directory.\n */\n async load(): Promise<LoadResult> {\n this.logger.info(`Loading schemas from: ${this.options.schemaDir}`);\n\n // Register plugins if provided\n if (this.options.plugins?.length) {\n await this.registerPlugins(this.options.plugins);\n }\n\n const errors: SchemaError[] = [];\n const warnings: { file: string; message: string }[] = [];\n\n try {\n // Load schemas\n const schemas = await loadSchemas(this.options.schemaDir, {\n recursive: true,\n });\n this.logger.debug(`Loaded ${Object.keys(schemas).length} schemas`);\n\n // Get custom type names from plugin registry\n const customTypeNames = Array.from(this.pluginManager.getRegistry().types.keys());\n\n // Validate schemas\n const validationResult = validateSchemas(schemas, {\n customTypes: customTypeNames,\n });\n\n // Collect errors and warnings\n for (const error of validationResult.errors) {\n const schemaError: SchemaError = {\n file: error.file ?? 'unknown',\n message: error.message,\n };\n if (error.line !== undefined) {\n schemaError.line = error.line;\n }\n if (error.suggestion !== undefined) {\n schemaError.suggestion = error.suggestion;\n }\n errors.push(schemaError);\n }\n\n for (const warning of validationResult.warnings) {\n warnings.push({\n file: warning.file ?? 'unknown',\n message: warning.message,\n });\n }\n\n if (validationResult.valid) {\n this.schemas = schemas;\n this.loaded = true;\n }\n\n return {\n success: validationResult.valid,\n schemas: schemas,\n errors,\n warnings,\n };\n } catch (error) {\n if (error instanceof OmnifyError) {\n const schemaError: SchemaError = {\n file: error.file ?? 'unknown',\n message: error.message,\n };\n if (error.line !== undefined) {\n schemaError.line = error.line;\n }\n if (error.suggestion !== undefined) {\n schemaError.suggestion = error.suggestion;\n }\n errors.push(schemaError);\n } else {\n errors.push({\n file: 'unknown',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n\n return {\n success: false,\n schemas: {},\n errors,\n warnings,\n };\n }\n }\n\n /**\n * Gets loaded schemas. Throws if not loaded.\n */\n getSchemas(): SchemaCollection {\n if (!this.loaded || !this.schemas) {\n throw new Error('Schemas not loaded. Call load() first.');\n }\n return this.schemas;\n }\n\n /**\n * Gets a single schema by name.\n */\n getSchema(name: string): SchemaIntrospection | undefined {\n const schemas = this.getSchemas();\n const schema = schemas[name];\n if (!schema) return undefined;\n return introspectSchema(schema, this.pluginManager.getRegistry());\n }\n\n /**\n * Gets all schema names.\n */\n getSchemaNames(): string[] {\n return getSchemaNames(this.getSchemas());\n }\n\n /**\n * Gets entity schemas (non-enum).\n */\n getEntitySchemas(): SchemaIntrospection[] {\n const schemas = getEntitySchemas(this.getSchemas());\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets enum schemas.\n */\n getEnumSchemas(): SchemaIntrospection[] {\n const schemas = getEnumSchemas(this.getSchemas());\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets schemas by group.\n */\n getSchemasByGroup(group: string): SchemaIntrospection[] {\n const schemas = getSchemasByGroup(this.getSchemas(), group);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets all unique group names.\n */\n getGroups(): string[] {\n return getGroups(this.getSchemas());\n }\n\n /**\n * Introspects a specific schema.\n */\n introspect(name: string): SchemaIntrospection | undefined {\n return this.getSchema(name);\n }\n\n /**\n * Introspects all schemas.\n */\n introspectAll(): Map<string, SchemaIntrospection> {\n return introspectSchemas(this.getSchemas(), this.pluginManager.getRegistry());\n }\n\n /**\n * Finds schemas that reference a target schema.\n */\n findReferencingSchemas(targetName: string): SchemaIntrospection[] {\n const schemas = findReferencingSchemas(this.getSchemas(), targetName);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Finds schemas referenced by a source schema.\n */\n findReferencedSchemas(sourceName: string): SchemaIntrospection[] {\n const schemas = findReferencedSchemas(this.getSchemas(), sourceName);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Checks if schemas have circular references.\n */\n hasCircularReferences(): boolean {\n return hasCircularReferences(this.getSchemas());\n }\n\n /**\n * Gets topological order of schemas (dependencies first).\n */\n getTopologicalOrder(): string[] {\n return getTopologicalOrder(this.getSchemas());\n }\n\n /**\n * Gets the plugin registry.\n */\n getPluginRegistry(): PluginRegistry {\n return this.pluginManager.getRegistry();\n }\n\n /**\n * Checks if a type is registered (from plugin).\n */\n hasType(typeName: string): boolean {\n return this.pluginManager.hasType(typeName);\n }\n\n /**\n * Gets custom type names from all registered plugins.\n */\n getCustomTypeNames(): string[] {\n return Array.from(this.pluginManager.getRegistry().types.keys());\n }\n}\n\n/**\n * Creates an Omnify instance.\n *\n * @example\n * ```typescript\n * const omnify = createOmnify({\n * schemaDir: './schemas',\n * });\n *\n * const { schemas } = await omnify.load();\n * ```\n */\nexport function createOmnify(options: OmnifyOptions): Omnify {\n return new Omnify(options);\n}\n","/**\n * @famgia/omnify-core - Schema Metadata Access\n *\n * Utilities for accessing schema metadata programmatically.\n */\n\nimport type {\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n AssociationDefinition,\n} from '@famgia/omnify-types';\nimport type {\n SchemaMetadata,\n PropertyMetadata,\n AssociationMetadata,\n SchemaIntrospection,\n} from './types.js';\nimport type { PluginRegistry } from '../plugins/types.js';\n\n/**\n * Type guard to check if a property is an association.\n */\nfunction isAssociation(prop: PropertyDefinition): prop is AssociationDefinition {\n return prop.type === 'Association';\n}\n\n/**\n * Extracts metadata from a loaded schema.\n */\nexport function getSchemaMetadata(schema: LoadedSchema): SchemaMetadata {\n const propertyNames: string[] = [];\n const associationNames: string[] = [];\n\n if (schema.properties) {\n for (const [name, prop] of Object.entries(schema.properties)) {\n if (isAssociation(prop)) {\n associationNames.push(name);\n } else {\n propertyNames.push(name);\n }\n }\n }\n\n // Map 'object' to 'entity' for our API\n const kind = schema.kind === 'enum' ? 'enum' : 'entity';\n\n const result: SchemaMetadata = {\n name: schema.name,\n kind,\n filePath: schema.filePath,\n propertyNames,\n associationNames,\n hasTimestamps: schema.options?.timestamps ?? false,\n hasSoftDelete: schema.options?.softDelete ?? false,\n idType: schema.options?.idType ?? 'BigInt',\n };\n\n if (schema.displayName !== undefined) {\n result.displayName = schema.displayName;\n }\n if (schema.group !== undefined) {\n result.group = schema.group;\n }\n\n return result;\n}\n\n/**\n * Extracts property metadata.\n */\nexport function getPropertyMetadata(\n name: string,\n property: PropertyDefinition,\n registry?: PluginRegistry\n): PropertyMetadata {\n // Associations are handled separately\n if (isAssociation(property)) {\n return {\n name,\n type: 'Association',\n nullable: false,\n unique: false,\n hasDefault: false,\n isPluginType: false,\n };\n }\n\n const isPluginType = registry?.types.has(property.type) ?? false;\n const pluginType = registry?.types.get(property.type);\n\n const result: PropertyMetadata = {\n name,\n type: property.type,\n nullable: (property as { nullable?: boolean }).nullable ?? false,\n unique: (property as { unique?: boolean }).unique ?? false,\n hasDefault: 'default' in property && (property as { default?: unknown }).default !== undefined,\n isPluginType,\n };\n\n if ('default' in property && (property as { default?: unknown }).default !== undefined) {\n result.defaultValue = (property as { default?: unknown }).default;\n }\n\n if (pluginType?.pluginName !== undefined) {\n result.pluginName = pluginType.pluginName;\n }\n\n return result;\n}\n\n/**\n * Extracts association metadata.\n */\nexport function getAssociationMetadata(\n name: string,\n association: AssociationDefinition\n): AssociationMetadata {\n const result: AssociationMetadata = {\n name,\n relation: association.relation,\n };\n\n // Handle target (for standard and inverse polymorphic relations)\n if (association.target !== undefined) {\n result.target = association.target;\n }\n\n // Handle targets (for MorphTo)\n if (association.targets !== undefined) {\n result.targets = association.targets;\n }\n\n // Handle morphName (for MorphOne/MorphMany/MorphedByMany)\n if (association.morphName !== undefined) {\n result.morphName = association.morphName;\n }\n\n if (association.inversedBy !== undefined) {\n result.inversedBy = association.inversedBy;\n }\n if (association.mappedBy !== undefined) {\n result.mappedBy = association.mappedBy;\n }\n if (association.onDelete !== undefined) {\n result.onDelete = association.onDelete;\n }\n if (association.onUpdate !== undefined) {\n result.onUpdate = association.onUpdate;\n }\n\n return result;\n}\n\n/**\n * Full schema introspection.\n */\nexport function introspectSchema(\n schema: LoadedSchema,\n registry?: PluginRegistry\n): SchemaIntrospection {\n const metadata = getSchemaMetadata(schema);\n\n const properties: PropertyMetadata[] = [];\n const associations: AssociationMetadata[] = [];\n\n if (schema.properties) {\n for (const [name, prop] of Object.entries(schema.properties)) {\n if (isAssociation(prop)) {\n associations.push(getAssociationMetadata(name, prop));\n } else {\n properties.push(getPropertyMetadata(name, prop, registry));\n }\n }\n }\n\n return {\n metadata,\n properties,\n associations,\n schema,\n };\n}\n\n/**\n * Introspects all schemas in a collection.\n */\nexport function introspectSchemas(\n schemas: SchemaCollection,\n registry?: PluginRegistry\n): Map<string, SchemaIntrospection> {\n const result = new Map<string, SchemaIntrospection>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n result.set(name, introspectSchema(schema, registry));\n }\n\n return result;\n}\n\n/**\n * Gets all schema names from a collection.\n */\nexport function getSchemaNames(schemas: SchemaCollection): string[] {\n return Object.keys(schemas);\n}\n\n/**\n * Gets schemas by kind.\n */\nexport function getSchemasByKind(\n schemas: SchemaCollection,\n kind: 'entity' | 'enum'\n): LoadedSchema[] {\n return Object.values(schemas).filter((schema) => {\n const schemaKind = schema.kind === 'enum' ? 'enum' : 'entity';\n return schemaKind === kind;\n });\n}\n\n/**\n * Gets entity schemas (non-enum).\n */\nexport function getEntitySchemas(schemas: SchemaCollection): LoadedSchema[] {\n return getSchemasByKind(schemas, 'entity');\n}\n\n/**\n * Gets enum schemas.\n */\nexport function getEnumSchemas(schemas: SchemaCollection): LoadedSchema[] {\n return getSchemasByKind(schemas, 'enum');\n}\n\n/**\n * Gets schemas by group.\n */\nexport function getSchemasByGroup(\n schemas: SchemaCollection,\n group: string\n): LoadedSchema[] {\n return Object.values(schemas).filter((schema) => schema.group === group);\n}\n\n/**\n * Gets all unique group names.\n */\nexport function getGroups(schemas: SchemaCollection): string[] {\n const groups = new Set<string>();\n\n for (const schema of Object.values(schemas)) {\n if (schema.group) {\n groups.add(schema.group);\n }\n }\n\n return Array.from(groups).sort();\n}\n\n/**\n * Gets associations from a schema.\n */\nfunction getSchemaAssociations(schema: LoadedSchema): AssociationDefinition[] {\n if (!schema.properties) return [];\n\n const associations: AssociationDefinition[] = [];\n for (const prop of Object.values(schema.properties)) {\n if (isAssociation(prop)) {\n associations.push(prop);\n }\n }\n return associations;\n}\n\n/**\n * Finds schemas that reference a target schema.\n */\nexport function findReferencingSchemas(\n schemas: SchemaCollection,\n targetName: string\n): LoadedSchema[] {\n const result: LoadedSchema[] = [];\n\n for (const schema of Object.values(schemas)) {\n const associations = getSchemaAssociations(schema);\n for (const association of associations) {\n if (association.target === targetName) {\n result.push(schema);\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Finds schemas referenced by a source schema.\n */\nexport function findReferencedSchemas(\n schemas: SchemaCollection,\n sourceName: string\n): LoadedSchema[] {\n const source = schemas[sourceName];\n if (!source) return [];\n\n const associations = getSchemaAssociations(source);\n const targetNames = new Set(associations.map((a) => a.target));\n\n return Object.values(schemas).filter((s) => targetNames.has(s.name));\n}\n\n/**\n * Gets the relationship graph as adjacency list.\n */\nexport function getRelationshipGraph(\n schemas: SchemaCollection\n): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const schema of Object.values(schemas)) {\n const targets: string[] = [];\n const associations = getSchemaAssociations(schema);\n\n for (const association of associations) {\n // Handle MorphTo with multiple targets\n if (association.targets) {\n for (const target of association.targets) {\n if (!targets.includes(target)) {\n targets.push(target);\n }\n }\n }\n // Handle standard and inverse polymorphic with single target\n else if (association.target && !targets.includes(association.target)) {\n targets.push(association.target);\n }\n }\n\n graph.set(schema.name, targets);\n }\n\n return graph;\n}\n\n/**\n * Checks if schemas form a valid DAG (no circular references).\n */\nexport function hasCircularReferences(schemas: SchemaCollection): boolean {\n const graph = getRelationshipGraph(schemas);\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n function hasCycle(node: string): boolean {\n if (recursionStack.has(node)) return true;\n if (visited.has(node)) return false;\n\n visited.add(node);\n recursionStack.add(node);\n\n const neighbors = graph.get(node) ?? [];\n for (const neighbor of neighbors) {\n if (hasCycle(neighbor)) return true;\n }\n\n recursionStack.delete(node);\n return false;\n }\n\n for (const schemaName of graph.keys()) {\n if (hasCycle(schemaName)) return true;\n }\n\n return false;\n}\n\n/**\n * Gets topological sort order for schemas (dependencies first).\n */\nexport function getTopologicalOrder(schemas: SchemaCollection): string[] {\n const graph = getRelationshipGraph(schemas);\n const result: string[] = [];\n const visited = new Set<string>();\n\n function visit(node: string): void {\n if (visited.has(node)) return;\n visited.add(node);\n\n const neighbors = graph.get(node) ?? [];\n for (const neighbor of neighbors) {\n visit(neighbor);\n }\n\n result.push(node);\n }\n\n for (const schemaName of graph.keys()) {\n visit(schemaName);\n }\n\n // Post-order DFS already gives correct dependency order\n // (dependencies/referenced schemas come first)\n return result;\n}\n","/**\n * @famgia/omnify-core - Version Store\n *\n * Manages version history files for schema tracking.\n */\n\nimport { readdir, readFile, writeFile, mkdir, rm, access } from 'fs/promises';\nimport { join } from 'path';\nimport yaml from 'js-yaml';\nimport type {\n VersionFile,\n VersionSummary,\n VersionSchemaSnapshot,\n VersionChange,\n VersionDiff,\n CreateVersionOptions,\n VersionStoreConfig,\n} from './types.js';\n\n/**\n * Directory name for omnify data.\n */\nconst OMNIFY_DIR = '.omnify';\n\n/**\n * Subdirectory for version files.\n */\nconst VERSIONS_DIR = 'versions';\n\n/**\n * Deep equality comparison that ignores property order.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return a === b;\n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n if (typeof a === 'object' && typeof b === 'object') {\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;\n if (!deepEqual(aObj[key], bObj[key])) return false;\n }\n return true;\n }\n\n return false;\n}\n\n/**\n * Current version symlink/file name.\n */\nconst CURRENT_FILE = 'current.lock';\n\n/**\n * Version file name pattern.\n */\nconst VERSION_FILE_PATTERN = /^(\\d{4})(?:_(.+))?\\.lock$/;\n\n/**\n * Format version number to 4-digit string.\n */\nfunction formatVersionNumber(version: number): string {\n return version.toString().padStart(4, '0');\n}\n\n/**\n * Parse version number from filename.\n */\nfunction parseVersionFilename(filename: string): { version: number; name?: string | undefined } | null {\n const match = filename.match(VERSION_FILE_PATTERN);\n if (!match || !match[1]) return null;\n const result: { version: number; name?: string | undefined } = {\n version: parseInt(match[1], 10),\n };\n if (match[2] !== undefined) {\n result.name = match[2];\n }\n return result;\n}\n\n/**\n * Generate version filename.\n */\nfunction generateVersionFilename(version: number, migration?: string): string {\n const versionStr = formatVersionNumber(version);\n if (migration) {\n // Extract name from migration file (e.g., \"0001_create_users.sql\" -> \"create_users\")\n const name = migration.replace(/^\\d+_/, '').replace(/\\.sql$/, '');\n return `${versionStr}_${name}.lock`;\n }\n return `${versionStr}.lock`;\n}\n\n/**\n * Check if directory exists.\n */\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Version Store class for managing schema version history.\n */\nexport class VersionStore {\n private readonly omnifyDir: string;\n private readonly versionsDir: string;\n private readonly maxVersions: number;\n\n constructor(config: VersionStoreConfig) {\n this.omnifyDir = join(config.baseDir, OMNIFY_DIR);\n this.versionsDir = join(this.omnifyDir, VERSIONS_DIR);\n this.maxVersions = config.maxVersions ?? 0;\n }\n\n /**\n * Initialize the version store directory structure.\n */\n async initialize(): Promise<void> {\n await mkdir(this.versionsDir, { recursive: true });\n }\n\n /**\n * Get the path to the versions directory.\n */\n getVersionsDir(): string {\n return this.versionsDir;\n }\n\n /**\n * Get the path to a specific version file.\n */\n getVersionPath(version: number, migration?: string): string {\n const filename = generateVersionFilename(version, migration);\n return join(this.versionsDir, filename);\n }\n\n /**\n * List all available versions.\n */\n async listVersions(): Promise<VersionSummary[]> {\n if (!(await dirExists(this.versionsDir))) {\n return [];\n }\n\n const files = await readdir(this.versionsDir);\n const versions: VersionSummary[] = [];\n\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (!parsed) continue;\n\n try {\n const filePath = join(this.versionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const versionFile = yaml.load(content) as VersionFile;\n\n const summary: VersionSummary = {\n version: versionFile.version,\n timestamp: versionFile.timestamp,\n ...(versionFile.migration !== undefined && { migration: versionFile.migration }),\n ...(versionFile.description !== undefined && { description: versionFile.description }),\n schemaCount: Object.keys(versionFile.snapshot).length,\n changeCount: versionFile.changes.length,\n };\n versions.push(summary);\n } catch {\n // Skip invalid files\n }\n }\n\n return versions.sort((a, b) => a.version - b.version);\n }\n\n /**\n * Get the latest version number.\n */\n async getLatestVersion(): Promise<number> {\n const versions = await this.listVersions();\n if (versions.length === 0) return 0;\n const lastVersion = versions[versions.length - 1];\n return lastVersion?.version ?? 0;\n }\n\n /**\n * Read a specific version file.\n */\n async readVersion(version: number): Promise<VersionFile | null> {\n if (!(await dirExists(this.versionsDir))) {\n return null;\n }\n\n const files = await readdir(this.versionsDir);\n\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (parsed?.version === version) {\n const filePath = join(this.versionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n return yaml.load(content) as VersionFile;\n }\n }\n\n return null;\n }\n\n /**\n * Read the latest version file.\n */\n async readLatestVersion(): Promise<VersionFile | null> {\n const latestVersion = await this.getLatestVersion();\n if (latestVersion === 0) return null;\n return this.readVersion(latestVersion);\n }\n\n /**\n * Create a new version.\n */\n async createVersion(\n snapshot: Record<string, VersionSchemaSnapshot>,\n changes: readonly VersionChange[],\n options: CreateVersionOptions\n ): Promise<VersionFile> {\n await this.initialize();\n\n const latestVersion = await this.getLatestVersion();\n const newVersion = latestVersion + 1;\n\n const versionFile: VersionFile = {\n version: newVersion,\n timestamp: new Date().toISOString(),\n driver: options.driver,\n ...(options.migration !== undefined && { migration: options.migration }),\n ...(options.description !== undefined && { description: options.description }),\n changes,\n snapshot,\n };\n\n const filePath = this.getVersionPath(newVersion, options.migration);\n const content = yaml.dump(versionFile, {\n lineWidth: -1, // Disable line wrapping\n noRefs: true,\n quotingType: '\"',\n });\n\n await writeFile(filePath, content, 'utf-8');\n\n // Update current.lock symlink/copy\n await this.updateCurrentLink(versionFile);\n\n // Cleanup old versions if maxVersions is set\n if (this.maxVersions > 0) {\n await this.cleanupOldVersions();\n }\n\n return versionFile;\n }\n\n /**\n * Update the current.lock file to point to latest version.\n */\n private async updateCurrentLink(versionFile: VersionFile): Promise<void> {\n const currentPath = join(this.omnifyDir, CURRENT_FILE);\n const content = yaml.dump(versionFile, {\n lineWidth: -1,\n noRefs: true,\n quotingType: '\"',\n });\n await writeFile(currentPath, content, 'utf-8');\n }\n\n /**\n * Cleanup old versions beyond maxVersions limit.\n */\n private async cleanupOldVersions(): Promise<void> {\n const versions = await this.listVersions();\n if (versions.length <= this.maxVersions) return;\n\n const toDelete = versions.slice(0, versions.length - this.maxVersions);\n for (const v of toDelete) {\n const files = await readdir(this.versionsDir);\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (parsed?.version === v.version) {\n await rm(join(this.versionsDir, file));\n break;\n }\n }\n }\n }\n\n /**\n * Get diff between two versions.\n */\n async diffVersions(fromVersion: number, toVersion: number): Promise<VersionDiff | null> {\n const fromFile = await this.readVersion(fromVersion);\n const toFile = await this.readVersion(toVersion);\n\n if (!fromFile || !toFile) return null;\n\n // Collect all changes between versions\n const allChanges: VersionChange[] = [];\n\n if (fromVersion < toVersion) {\n // Forward diff: collect changes from fromVersion+1 to toVersion\n for (let v = fromVersion + 1; v <= toVersion; v++) {\n const vFile = await this.readVersion(v);\n if (vFile) {\n allChanges.push(...vFile.changes);\n }\n }\n } else {\n // Backward diff: compute changes needed to go FROM current TO target\n // e.g., v5 -> v2 means what's in v5 but not in v2 needs to be removed\n const changes = this.computeSnapshotDiff(fromFile.snapshot, toFile.snapshot);\n allChanges.push(...changes);\n }\n\n return {\n fromVersion,\n toVersion,\n changes: allChanges,\n };\n }\n\n /**\n * Compute changes between two snapshots.\n */\n computeSnapshotDiff(\n from: Record<string, VersionSchemaSnapshot>,\n to: Record<string, VersionSchemaSnapshot>\n ): VersionChange[] {\n const changes: VersionChange[] = [];\n const fromNames = new Set(Object.keys(from));\n const toNames = new Set(Object.keys(to));\n\n // Added schemas\n for (const name of toNames) {\n if (!fromNames.has(name)) {\n changes.push({ action: 'schema_added', schema: name });\n }\n }\n\n // Removed schemas\n for (const name of fromNames) {\n if (!toNames.has(name)) {\n changes.push({ action: 'schema_removed', schema: name });\n }\n }\n\n // Modified schemas\n for (const name of fromNames) {\n if (!toNames.has(name)) continue;\n\n const fromSchema = from[name];\n const toSchema = to[name];\n if (!fromSchema || !toSchema) continue;\n\n // Compare properties\n const fromProps = fromSchema.properties ?? {};\n const toProps = toSchema.properties ?? {};\n const fromPropNames = new Set(Object.keys(fromProps));\n const toPropNames = new Set(Object.keys(toProps));\n\n for (const prop of toPropNames) {\n if (!fromPropNames.has(prop)) {\n changes.push({\n action: 'property_added',\n schema: name,\n property: prop,\n to: toProps[prop],\n });\n }\n }\n\n for (const prop of fromPropNames) {\n if (!toPropNames.has(prop)) {\n changes.push({\n action: 'property_removed',\n schema: name,\n property: prop,\n from: fromProps[prop],\n });\n }\n }\n\n for (const prop of fromPropNames) {\n if (!toPropNames.has(prop)) continue;\n if (!deepEqual(fromProps[prop], toProps[prop])) {\n changes.push({\n action: 'property_modified',\n schema: name,\n property: prop,\n from: fromProps[prop],\n to: toProps[prop],\n });\n }\n }\n\n // Compare options granularly\n const fromOpts = fromSchema.options ?? {};\n const toOpts = toSchema.options ?? {};\n\n // Default values for options - used to normalize undefined values\n const optionDefaults: Record<string, unknown> = {\n id: true,\n idType: 'BigInt',\n timestamps: true,\n softDelete: false,\n tableName: undefined, // no default\n translations: false,\n authenticatable: false,\n };\n\n // Helper to get normalized option value (undefined → default)\n const getNormalizedOption = (opts: Record<string, unknown>, key: string): unknown => {\n const value = opts[key];\n if (value === undefined) {\n return optionDefaults[key];\n }\n return value;\n };\n\n // Compare simple options with normalization\n const simpleOptions = ['timestamps', 'softDelete', 'id', 'idType', 'tableName', 'translations', 'authenticatable'] as const;\n for (const opt of simpleOptions) {\n const fromVal = getNormalizedOption(fromOpts, opt);\n const toVal = getNormalizedOption(toOpts, opt);\n if (!deepEqual(fromVal, toVal)) {\n changes.push({\n action: 'option_changed',\n schema: name,\n property: opt,\n from: fromOpts[opt], // Keep original value for display\n to: toOpts[opt],\n });\n }\n }\n\n // Compare indexes specifically - match by columns (unique identifier)\n const fromIndexes = (fromOpts.indexes ?? []) as Array<{ columns: string[]; unique?: boolean; name?: string; type?: string }>;\n const toIndexes = (toOpts.indexes ?? []) as Array<{ columns: string[]; unique?: boolean; name?: string; type?: string }>;\n\n // Helper to check if columns match\n const columnsMatch = (a: string[], b: string[]): boolean => {\n if (a.length !== b.length) return false;\n return a.every((col, i) => col === b[i]);\n };\n\n const matchedFromIndexes = new Set<number>();\n\n // Check each \"to\" index\n for (const toIdx of toIndexes) {\n // Find matching \"from\" index by columns\n const fromIndex = fromIndexes.findIndex((fromIdx, i) =>\n !matchedFromIndexes.has(i) && columnsMatch(fromIdx.columns, toIdx.columns)\n );\n\n if (fromIndex === -1) {\n // No match by columns → new index\n changes.push({\n action: 'index_added',\n schema: name,\n to: toIdx,\n });\n } else {\n matchedFromIndexes.add(fromIndex);\n const fromIdx = fromIndexes[fromIndex];\n // Check if other properties changed\n if (!deepEqual(fromIdx, toIdx)) {\n changes.push({\n action: 'index_modified',\n schema: name,\n from: fromIdx,\n to: toIdx,\n });\n }\n }\n }\n\n // Any unmatched \"from\" indexes are removed\n for (let i = 0; i < fromIndexes.length; i++) {\n if (!matchedFromIndexes.has(i)) {\n changes.push({\n action: 'index_removed',\n schema: name,\n from: fromIndexes[i],\n });\n }\n }\n }\n\n return changes;\n }\n\n /**\n * Get snapshot at a specific version (for rollback).\n */\n async getSnapshotAt(version: number): Promise<Record<string, VersionSchemaSnapshot> | null> {\n const versionFile = await this.readVersion(version);\n return versionFile?.snapshot ?? null;\n }\n}\n\n/**\n * Create a new VersionStore instance.\n */\nexport function createVersionStore(config: VersionStoreConfig): VersionStore {\n return new VersionStore(config);\n}\n"],"mappings":"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","names":["import_omnify_types","path","yaml","stat","import_omnify_types","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","MORPH_TO_RELATIONS","MORPH_INVERSE_RELATIONS","validationError","nullLogger","consoleLogger","import_js_yaml","path","yaml"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors/omnify-error.ts","../src/errors/formatter.ts","../src/errors/factories.ts","../src/schema/loader.ts","../src/validation/validator.ts","../src/validation/types/base.ts","../src/validation/types/registry.ts","../src/validation/types/primitives.ts","../src/validation/types/text.ts","../src/validation/types/numeric.ts","../src/validation/types/temporal.ts","../src/validation/types/special.ts","../src/validation/types/enum.ts","../src/validation/types/relations.ts","../src/validation/types/index.ts","../src/plugins/generator-runner.ts","../src/plugins/manager.ts","../src/plugins/expander.ts","../src/api/omnify.ts","../src/api/metadata.ts","../src/history/version-store.ts"],"sourcesContent":["/**\n * @famgia/omnify-core\n * Schema loading, validation, and transformation\n *\n * This package provides the core functionality for omnify-schema:\n * - Error handling with file:line:message:suggestion format\n * - Schema loading and validation (coming soon)\n * - Plugin management (coming soon)\n * - Configuration loading (coming soon)\n */\n\n// ============================================================================\n// Re-export types from @famgia/omnify-types for convenience\n// ============================================================================\n\nexport type {\n // Schema types\n SchemaDefinition,\n PropertyDefinition,\n PropertyType,\n AssociationRelation,\n SchemaOptions,\n LoadedSchema,\n SchemaCollection,\n // Config types\n OmnifyConfig,\n DatabaseConfig,\n OutputConfig,\n // Plugin types\n OmnifyPlugin,\n CustomTypeDefinition,\n // Error types\n ErrorCode,\n ErrorLocation,\n OmnifyErrorInfo,\n Result,\n} from '@famgia/omnify-types';\n\nexport { ok, err } from '@famgia/omnify-types';\n\n// ============================================================================\n// Error handling\n// ============================================================================\n\nexport {\n // Error class\n OmnifyError,\n // Formatter\n formatError,\n formatErrorSummary,\n formatErrorPlain,\n getExitCode,\n type FormatOptions,\n // Factory functions - Config errors\n configError,\n configNotFoundError,\n invalidConfigError,\n missingConfigFieldError,\n // Factory functions - Schema parsing errors\n schemaParseError,\n schemaNotFoundError,\n yamlSyntaxError,\n jsonSyntaxError,\n // Factory functions - Validation errors\n validationError,\n invalidPropertyTypeError,\n missingFieldError,\n invalidAssociationTargetError,\n circularReferenceError,\n duplicateSchemaError,\n // Factory functions - Plugin errors\n pluginError,\n pluginNotFoundError,\n pluginTypeConflictError,\n // Factory functions - Atlas errors\n atlasError,\n atlasNotFoundError,\n // Factory functions - Generation errors\n generationError,\n outputWriteError,\n // Factory functions - Internal errors\n internalError,\n notImplementedError,\n} from './errors/index.js';\n\n// ============================================================================\n// Schema loading\n// ============================================================================\n\nexport {\n // Loader functions\n loadSchema,\n loadSchemas,\n // Parser utilities\n parseYamlSchema,\n parseJsonSchema,\n fileNameToSchemaName,\n // File schema utilities\n FILE_SCHEMA_NAME,\n schemasHaveFileProperties,\n createFileSchemaDefinition,\n createFileLoadedSchema,\n generateFileSchemaYaml,\n ensureFileSchema,\n // Types\n type LoadSchemaOptions,\n type LoadSchemasOptions,\n} from './schema/index.js';\n\n// ============================================================================\n// Schema validation\n// ============================================================================\n\nexport {\n // Main validation functions\n validateSchema,\n validateSchemas,\n // Individual validators\n validateProperties,\n validatePropertyType,\n validateAssociations,\n validateOptions,\n validateEnumSchema,\n // Default value validation\n validateDefaultValue,\n // Types\n type SchemaValidationResult,\n type ValidationResult,\n type ValidationOptions,\n type DefaultValueValidationResult,\n} from './validation/index.js';\n\n// ============================================================================\n// Plugin management\n// ============================================================================\n\nexport {\n // Plugin Manager\n PluginManager,\n createPluginManager,\n // Compound Type Expansion\n expandProperty,\n expandSchemaProperties,\n expandSchema,\n expandSchemas,\n getTypeInfo,\n isCompoundType,\n getCustomTypeNames,\n // Types\n type RegisteredType,\n type PluginRegistry,\n type PluginManagerOptions,\n type PluginRegistrationResult,\n type ExpandedProperty,\n} from './plugins/index.js';\n\n// ============================================================================\n// Programmatic API\n// ============================================================================\n\nexport {\n // Main API\n Omnify,\n createOmnify,\n // Types\n type OmnifyOptions,\n type OmnifyLogger,\n type LoadResult,\n type DiffOperationResult,\n type GenerateOptions,\n type GenerateResult,\n type GeneratedFile,\n type SchemaError,\n type SchemaWarning,\n type SchemaMetadata,\n type PropertyMetadata,\n type AssociationMetadata,\n type SchemaIntrospection,\n // Metadata utilities\n getSchemaMetadata,\n getPropertyMetadata,\n getAssociationMetadata,\n introspectSchema,\n introspectSchemas,\n getSchemaNames,\n getSchemasByKind,\n getEntitySchemas,\n getEnumSchemas,\n getSchemasByGroup,\n getGroups,\n findReferencingSchemas,\n findReferencedSchemas,\n getRelationshipGraph,\n hasCircularReferences,\n getTopologicalOrder,\n} from './api/index.js';\n\n// ============================================================================\n// Version history\n// ============================================================================\n\nexport {\n // Version Store\n VersionStore,\n createVersionStore,\n // Types\n type VersionFile,\n type VersionSchemaSnapshot,\n type VersionPropertySnapshot,\n type VersionIndexSnapshot,\n type VersionChange,\n type ChangeAction,\n type VersionSummary,\n type VersionDiff,\n type CreateVersionOptions,\n type VersionStoreConfig,\n} from './history/index.js';\n// test auto publish\n","/**\n * @famgia/omnify-core - OmnifyError Class\n *\n * Base error class for all omnify errors with file:line:message:suggestion format.\n */\n\nimport type { ErrorCode, ErrorLocation, OmnifyErrorInfo } from '@famgia/omnify-types';\n\n/**\n * Base error class for omnify-schema.\n * Provides consistent error formatting with source location and suggestions.\n *\n * @example\n * ```typescript\n * throw new OmnifyError(\n * \"Invalid property type 'Stringg'\",\n * 'E201',\n * { file: 'schemas/User.yaml', line: 15, column: 10 },\n * \"Did you mean 'String'?\"\n * );\n * ```\n */\nexport class OmnifyError extends Error {\n /** Error code (e.g., 'E201') */\n readonly code: ErrorCode;\n\n /** Source location where the error occurred */\n readonly location?: ErrorLocation;\n\n /** Suggested fix for the error */\n readonly suggestion?: string;\n\n /** Additional context or details */\n readonly details?: Record<string, unknown>;\n\n /** Original error if this wraps another error */\n override readonly cause?: Error;\n\n constructor(\n message: string,\n code: ErrorCode,\n location?: ErrorLocation,\n suggestion?: string,\n options?: {\n details?: Record<string, unknown>;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = 'OmnifyError';\n this.code = code;\n\n // Only assign optional properties when they have values\n // (required for exactOptionalPropertyTypes)\n if (location !== undefined) {\n this.location = location;\n }\n if (suggestion !== undefined) {\n this.suggestion = suggestion;\n }\n if (options?.details !== undefined) {\n this.details = options.details;\n }\n if (options?.cause !== undefined) {\n this.cause = options.cause;\n }\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, OmnifyError);\n }\n }\n\n /**\n * Creates an OmnifyError from an OmnifyErrorInfo object.\n */\n static fromInfo(info: OmnifyErrorInfo): OmnifyError {\n const options: { details?: Record<string, unknown>; cause?: Error } = {};\n if (info.details !== undefined) {\n options.details = info.details;\n }\n if (info.cause !== undefined) {\n options.cause = info.cause;\n }\n\n return new OmnifyError(\n info.message,\n info.code,\n info.location,\n info.suggestion,\n Object.keys(options).length > 0 ? options : undefined\n );\n }\n\n /**\n * Wraps an unknown error as an OmnifyError.\n * Useful for catching and re-throwing with context.\n */\n static wrap(\n error: unknown,\n code: ErrorCode = 'E901',\n location?: ErrorLocation\n ): OmnifyError {\n if (error instanceof OmnifyError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n\n if (error instanceof Error) {\n return new OmnifyError(message, code, location, undefined, { cause: error });\n }\n return new OmnifyError(message, code, location);\n }\n\n /**\n * Converts to OmnifyErrorInfo for serialization.\n */\n toInfo(): OmnifyErrorInfo {\n const info: OmnifyErrorInfo = {\n code: this.code,\n message: this.message,\n };\n\n // Only include optional properties if they have values\n if (this.location !== undefined) {\n (info as { location: ErrorLocation }).location = this.location;\n }\n if (this.suggestion !== undefined) {\n (info as { suggestion: string }).suggestion = this.suggestion;\n }\n if (this.details !== undefined) {\n (info as { details: Record<string, unknown> }).details = this.details;\n }\n if (this.cause !== undefined) {\n (info as { cause: Error }).cause = this.cause;\n }\n\n return info;\n }\n\n /**\n * Returns a formatted string representation.\n * Format: \"Error [CODE]: message\\n --> file:line:column\"\n */\n override toString(): string {\n const parts: string[] = [];\n\n // Header: Error [E201]: message\n parts.push(`Error [${this.code}]: ${this.message}`);\n\n // Location: --> file:line:column\n if (this.location?.file) {\n const loc = this.location;\n let locationStr = ` --> ${loc.file}`;\n if (loc.line !== undefined) {\n locationStr += `:${loc.line}`;\n if (loc.column !== undefined) {\n locationStr += `:${loc.column}`;\n }\n }\n parts.push(locationStr);\n }\n\n // Suggestion\n if (this.suggestion) {\n parts.push(` Suggestion: ${this.suggestion}`);\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Returns the file path from location, if available.\n */\n get file(): string | undefined {\n return this.location?.file;\n }\n\n /**\n * Returns the line number from location, if available.\n */\n get line(): number | undefined {\n return this.location?.line;\n }\n\n /**\n * Returns the column number from location, if available.\n */\n get column(): number | undefined {\n return this.location?.column;\n }\n}\n","/**\n * @famgia/omnify-core - Error Formatter\n *\n * Formats errors for CLI output with optional ANSI colors.\n */\n\nimport type { OmnifyError } from './omnify-error.js';\n\n/**\n * ANSI color codes for terminal output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n} as const;\n\n/**\n * Options for error formatting.\n */\nexport interface FormatOptions {\n /** Enable ANSI color codes */\n readonly color?: boolean;\n /** Show source context lines */\n readonly showContext?: boolean;\n /** Number of context lines to show */\n readonly contextLines?: number;\n /** Source file content (for showing context) */\n readonly sourceContent?: string;\n}\n\n/**\n * Applies color if enabled, otherwise returns the text as-is.\n */\nfunction colorize(\n text: string,\n colorCode: string,\n enabled: boolean\n): string {\n return enabled ? `${colorCode}${text}${colors.reset}` : text;\n}\n\n/**\n * Formats an OmnifyError for CLI output.\n *\n * @example Output:\n * ```\n * error[E201]: Invalid property type 'Stringg'\n * --> schemas/User.yaml:15:10\n * |\n * 15 | type: Stringg\n * | ^^^^^^^ Did you mean 'String'?\n * |\n * = suggestion: Use one of: String, Int, Boolean, Text, ...\n * ```\n */\nexport function formatError(\n error: OmnifyError,\n options: FormatOptions = {}\n): string {\n const {\n color = true,\n showContext = true,\n contextLines = 2,\n sourceContent,\n } = options;\n\n const lines: string[] = [];\n\n // Header: error[E201]: message\n const errorLabel = colorize('error', colors.red + colors.bold, color);\n const code = colorize(`[${error.code}]`, colors.red, color);\n const message = colorize(error.message, colors.bold, color);\n lines.push(`${errorLabel}${code}: ${message}`);\n\n // Location: --> file:line:column\n const locFile = error.location?.file;\n if (locFile !== undefined) {\n const loc = error.location;\n let locationStr = colorize(' --> ', colors.blue, color);\n locationStr += colorize(locFile, colors.cyan, color);\n if (loc?.line !== undefined) {\n locationStr += `:${loc.line}`;\n if (loc.column !== undefined) {\n locationStr += `:${loc.column}`;\n }\n }\n lines.push(locationStr);\n }\n\n // Source context\n if (\n showContext &&\n sourceContent &&\n error.location?.line !== undefined\n ) {\n const contextOutput = formatSourceContext(\n sourceContent,\n error.location.line,\n error.location.column,\n error.suggestion,\n contextLines,\n color\n );\n lines.push(contextOutput);\n }\n\n // Suggestion (if no source context shown)\n if (error.suggestion && (!showContext || !sourceContent)) {\n const suggestionLabel = colorize(' = suggestion:', colors.cyan, color);\n lines.push(`${suggestionLabel} ${error.suggestion}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats source context around the error location.\n */\nfunction formatSourceContext(\n source: string,\n errorLine: number,\n errorColumn: number | undefined,\n suggestion: string | undefined,\n contextCount: number,\n colorEnabled: boolean\n): string {\n const sourceLines = source.split('\\n');\n const startLine = Math.max(1, errorLine - contextCount);\n const endLine = Math.min(sourceLines.length, errorLine + contextCount);\n const gutterWidth = String(endLine).length;\n\n const output: string[] = [];\n\n // Empty gutter line\n output.push(colorize(`${' '.repeat(gutterWidth)} |`, colors.blue, colorEnabled));\n\n for (let i = startLine; i <= endLine; i++) {\n const lineContent = sourceLines[i - 1] ?? '';\n const lineNum = String(i).padStart(gutterWidth, ' ');\n const gutter = colorize(`${lineNum} |`, colors.blue, colorEnabled);\n\n output.push(`${gutter} ${lineContent}`);\n\n // Add underline on error line\n if (i === errorLine && errorColumn !== undefined) {\n const underlineGutter = colorize(\n `${' '.repeat(gutterWidth)} |`,\n colors.blue,\n colorEnabled\n );\n const spaces = ' '.repeat(errorColumn - 1);\n const underline = colorize('^', colors.red, colorEnabled);\n let underlineLine = `${underlineGutter} ${spaces}${underline}`;\n\n if (suggestion) {\n underlineLine += ` ${colorize(suggestion, colors.yellow, colorEnabled)}`;\n }\n\n output.push(underlineLine);\n }\n }\n\n // Empty gutter line\n output.push(colorize(`${' '.repeat(gutterWidth)} |`, colors.blue, colorEnabled));\n\n return output.join('\\n');\n}\n\n/**\n * Formats multiple errors as a summary.\n */\nexport function formatErrorSummary(\n errors: readonly OmnifyError[],\n options: FormatOptions = {}\n): string {\n const { color = true } = options;\n\n if (errors.length === 0) {\n return '';\n }\n\n const formattedErrors = errors.map((e) => formatError(e, options));\n const summary = colorize(\n `\\nFound ${errors.length} error${errors.length === 1 ? '' : 's'}`,\n colors.red + colors.bold,\n color\n );\n\n return formattedErrors.join('\\n\\n') + summary;\n}\n\n/**\n * Formats an error for plain text output (no colors).\n */\nexport function formatErrorPlain(error: OmnifyError): string {\n return formatError(error, { color: false, showContext: false });\n}\n\n/**\n * Gets the exit code for an error based on its code category.\n */\nexport function getExitCode(error: OmnifyError): number {\n const category = error.code.charAt(1);\n\n switch (category) {\n case '0': // Configuration errors\n return 3;\n case '2': // Validation errors\n return 2;\n default: // All other errors\n return 1;\n }\n}\n","/**\n * @famgia/omnify-core - Error Factory Functions\n *\n * Convenient factory functions for creating common error types.\n */\n\nimport type { ErrorCode, ErrorLocation } from '@famgia/omnify-types';\nimport { OmnifyError } from './omnify-error.js';\n\n/**\n * Helper to build ErrorLocation objects safely with exactOptionalPropertyTypes.\n */\nfunction buildLocation(\n file: string,\n line?: number,\n column?: number\n): ErrorLocation {\n const loc: ErrorLocation = { file };\n if (line !== undefined) {\n (loc as { line: number }).line = line;\n }\n if (column !== undefined) {\n (loc as { column: number }).column = column;\n }\n return loc;\n}\n\n/**\n * Helper to build options object safely.\n */\nfunction buildOptions(cause?: Error): { cause: Error } | undefined {\n return cause !== undefined ? { cause } : undefined;\n}\n\n// ============================================================================\n// Configuration Errors (E0xx)\n// ============================================================================\n\n/**\n * Creates a configuration error.\n */\nexport function configError(\n message: string,\n code: ErrorCode = 'E002',\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, code, undefined, suggestion);\n}\n\n/**\n * Config file not found error.\n */\nexport function configNotFoundError(configPath: string): OmnifyError {\n return new OmnifyError(\n `Configuration file not found: ${configPath}`,\n 'E001',\n { file: configPath },\n 'Run `omnify init` to create a configuration file'\n );\n}\n\n/**\n * Invalid config format error.\n */\nexport function invalidConfigError(\n message: string,\n configPath: string\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E002',\n { file: configPath },\n 'Check your omnify.config.ts for syntax errors'\n );\n}\n\n/**\n * Missing required config field error.\n */\nexport function missingConfigFieldError(\n field: string,\n configPath: string\n): OmnifyError {\n return new OmnifyError(\n `Missing required configuration field: ${field}`,\n 'E003',\n { file: configPath },\n `Add '${field}' to your configuration file`\n );\n}\n\n// ============================================================================\n// Schema Parsing Errors (E1xx)\n// ============================================================================\n\n/**\n * Creates a schema parsing error.\n */\nexport function schemaParseError(\n message: string,\n location: ErrorLocation,\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, 'E102', location, suggestion);\n}\n\n/**\n * Schema file not found error.\n */\nexport function schemaNotFoundError(schemaPath: string): OmnifyError {\n return new OmnifyError(\n `Schema file not found: ${schemaPath}`,\n 'E101',\n { file: schemaPath },\n 'Check that the file exists and the path is correct'\n );\n}\n\n/**\n * Invalid YAML syntax error.\n */\nexport function yamlSyntaxError(\n message: string,\n file: string,\n line?: number,\n column?: number\n): OmnifyError {\n return new OmnifyError(\n `Invalid YAML syntax: ${message}`,\n 'E102',\n buildLocation(file, line, column),\n 'Check for proper indentation and YAML syntax'\n );\n}\n\n/**\n * Invalid JSON syntax error.\n */\nexport function jsonSyntaxError(\n message: string,\n file: string,\n line?: number,\n column?: number\n): OmnifyError {\n return new OmnifyError(\n `Invalid JSON syntax: ${message}`,\n 'E103',\n buildLocation(file, line, column),\n 'Check for proper JSON syntax (quotes, commas, brackets)'\n );\n}\n\n// ============================================================================\n// Schema Validation Errors (E2xx)\n// ============================================================================\n\n/**\n * Creates a schema validation error.\n */\nexport function validationError(\n message: string,\n location: ErrorLocation,\n suggestion?: string\n): OmnifyError {\n return new OmnifyError(message, 'E202', location, suggestion);\n}\n\n/**\n * Invalid property type error.\n */\nexport function invalidPropertyTypeError(\n typeName: string,\n location: ErrorLocation,\n validTypes?: readonly string[]\n): OmnifyError {\n const suggestion = validTypes\n ? `Use one of: ${validTypes.slice(0, 5).join(', ')}${validTypes.length > 5 ? ', ...' : ''}`\n : undefined;\n\n return new OmnifyError(\n `Invalid property type '${typeName}'`,\n 'E201',\n location,\n suggestion\n );\n}\n\n/**\n * Missing required field error.\n */\nexport function missingFieldError(\n field: string,\n location: ErrorLocation\n): OmnifyError {\n return new OmnifyError(\n `Missing required field: ${field}`,\n 'E202',\n location,\n `Add '${field}' to the schema definition`\n );\n}\n\n/**\n * Invalid association target error.\n */\nexport function invalidAssociationTargetError(\n target: string,\n location: ErrorLocation,\n availableSchemas?: readonly string[]\n): OmnifyError {\n const suggestion = availableSchemas\n ? `Available schemas: ${availableSchemas.slice(0, 5).join(', ')}${availableSchemas.length > 5 ? ', ...' : ''}`\n : 'Check that the target schema exists';\n\n return new OmnifyError(\n `Invalid association target '${target}'`,\n 'E203',\n location,\n suggestion\n );\n}\n\n/**\n * Circular reference error.\n */\nexport function circularReferenceError(\n path: readonly string[],\n location: ErrorLocation\n): OmnifyError {\n return new OmnifyError(\n `Circular reference detected: ${path.join(' -> ')}`,\n 'E204',\n location,\n 'Remove the circular dependency or use a unidirectional relationship'\n );\n}\n\n/**\n * Duplicate schema name error.\n */\nexport function duplicateSchemaError(\n name: string,\n location: ErrorLocation,\n existingLocation?: ErrorLocation\n): OmnifyError {\n const suggestion = existingLocation?.file\n ? `Schema already defined in ${existingLocation.file}`\n : 'Rename one of the schemas to avoid the conflict';\n\n return new OmnifyError(\n `Duplicate schema name '${name}'`,\n 'E205',\n location,\n suggestion\n );\n}\n\n// ============================================================================\n// Plugin Errors (E3xx)\n// ============================================================================\n\n/**\n * Creates a plugin error.\n */\nexport function pluginError(\n message: string,\n pluginName: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E302',\n undefined,\n `Check the plugin '${pluginName}' for issues`,\n buildOptions(cause)\n );\n}\n\n/**\n * Plugin not found error.\n */\nexport function pluginNotFoundError(pluginName: string): OmnifyError {\n return new OmnifyError(\n `Plugin not found: ${pluginName}`,\n 'E301',\n undefined,\n `Install the plugin with: npm install ${pluginName}`\n );\n}\n\n/**\n * Plugin type conflict error.\n */\nexport function pluginTypeConflictError(\n typeName: string,\n pluginA: string,\n pluginB: string\n): OmnifyError {\n return new OmnifyError(\n `Type '${typeName}' is defined by multiple plugins: ${pluginA}, ${pluginB}`,\n 'E304',\n undefined,\n 'Remove one of the conflicting plugins or rename the type'\n );\n}\n\n// ============================================================================\n// Atlas/Database Errors (E4xx)\n// ============================================================================\n\n/**\n * Creates an Atlas error.\n */\nexport function atlasError(\n message: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E402',\n undefined,\n 'Check Atlas CLI output for details',\n buildOptions(cause)\n );\n}\n\n/**\n * Atlas CLI not found error.\n */\nexport function atlasNotFoundError(): OmnifyError {\n return new OmnifyError(\n 'Atlas CLI not found',\n 'E401',\n undefined,\n 'Install Atlas CLI: https://atlasgo.io/getting-started'\n );\n}\n\n// ============================================================================\n// Generation Errors (E5xx)\n// ============================================================================\n\n/**\n * Creates a generation error.\n */\nexport function generationError(\n message: string,\n outputPath?: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E501',\n outputPath ? { file: outputPath } : undefined,\n undefined,\n buildOptions(cause)\n );\n}\n\n/**\n * Output write error.\n */\nexport function outputWriteError(\n outputPath: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n `Failed to write output file: ${outputPath}`,\n 'E503',\n { file: outputPath },\n 'Check file permissions and disk space',\n buildOptions(cause)\n );\n}\n\n// ============================================================================\n// Internal Errors (E9xx)\n// ============================================================================\n\n/**\n * Creates an internal/unexpected error.\n */\nexport function internalError(\n message: string,\n cause?: Error\n): OmnifyError {\n return new OmnifyError(\n message,\n 'E901',\n undefined,\n 'This is a bug. Please report it at https://github.com/omnify/omnify-schema/issues',\n buildOptions(cause)\n );\n}\n\n/**\n * Not implemented error.\n */\nexport function notImplementedError(feature: string): OmnifyError {\n return new OmnifyError(\n `Feature not implemented: ${feature}`,\n 'E902',\n undefined,\n 'This feature is planned for a future release'\n );\n}\n","/**\n * @famgia/omnify-core - Schema Loader\n *\n * Load and parse YAML/JSON schema files into internal representation.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport yaml from 'js-yaml';\nimport type {\n SchemaDefinition,\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n SchemaOptions,\n LocalizedString,\n} from '@famgia/omnify-types';\nimport { isLocalizedString } from '@famgia/omnify-types';\nimport {\n schemaNotFoundError,\n yamlSyntaxError,\n jsonSyntaxError,\n duplicateSchemaError,\n} from '../errors/index.js';\n\n/**\n * Options for loading schemas.\n */\nexport interface LoadSchemaOptions {\n /** Base directory for calculating relative paths */\n readonly baseDir?: string;\n}\n\n/**\n * Options for loading a directory of schemas.\n */\nexport interface LoadSchemasOptions {\n /** File extensions to include (default: ['.yaml', '.yml']) */\n readonly extensions?: readonly string[];\n /** Whether to load recursively from subdirectories (default: true) */\n readonly recursive?: boolean;\n}\n\n/**\n * Converts a file name to a schema name (PascalCase).\n * Preserves original casing if already PascalCase.\n *\n * @example\n * fileNameToSchemaName('user-profile.yaml') // 'UserProfile'\n * fileNameToSchemaName('User.yaml') // 'User'\n * fileNameToSchemaName('ExportJob.yaml') // 'ExportJob' (preserved)\n * fileNameToSchemaName('order_item.yml') // 'OrderItem'\n */\nexport function fileNameToSchemaName(fileName: string): string {\n const baseName = path.basename(fileName, path.extname(fileName));\n\n // If no separators, preserve original casing (already PascalCase)\n if (!baseName.includes('-') && !baseName.includes('_')) {\n return baseName.charAt(0).toUpperCase() + baseName.slice(1);\n }\n\n // Convert kebab-case or snake_case to PascalCase\n return baseName\n .split(/[-_]/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Parses YAML content into a SchemaDefinition.\n *\n * @param content - Raw YAML content\n * @param filePath - File path for error reporting\n * @returns Parsed schema definition\n * @throws OmnifyError if YAML is invalid\n */\nexport function parseYamlSchema(\n content: string,\n filePath: string\n): SchemaDefinition {\n try {\n const parsed = yaml.load(content) as Record<string, unknown> | null;\n\n if (parsed === null || typeof parsed !== 'object') {\n throw yamlSyntaxError('Schema must be a YAML object', filePath);\n }\n\n return buildSchemaDefinition(parsed);\n } catch (error) {\n if (error instanceof yaml.YAMLException) {\n const line = error.mark?.line !== undefined ? error.mark.line + 1 : undefined;\n const column = error.mark?.column !== undefined ? error.mark.column + 1 : undefined;\n throw yamlSyntaxError(error.reason || error.message, filePath, line, column);\n }\n throw error;\n }\n}\n\n/**\n * Parses JSON content into a SchemaDefinition.\n *\n * @param content - Raw JSON content\n * @param filePath - File path for error reporting\n * @returns Parsed schema definition\n * @throws OmnifyError if JSON is invalid\n */\nexport function parseJsonSchema(\n content: string,\n filePath: string\n): SchemaDefinition {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown> | null;\n\n if (parsed === null || typeof parsed !== 'object') {\n throw jsonSyntaxError('Schema must be a JSON object', filePath);\n }\n\n return buildSchemaDefinition(parsed);\n } catch (error) {\n if (error instanceof SyntaxError) {\n // Try to extract line/column from error message\n const match = error.message.match(/position (\\d+)/);\n const positionStr = match?.[1];\n const position = positionStr !== undefined ? parseInt(positionStr, 10) : undefined;\n let line: number | undefined;\n let column: number | undefined;\n\n if (position !== undefined) {\n // Calculate line and column from position\n const beforeError = content.substring(0, position);\n const lines = beforeError.split('\\n');\n line = lines.length;\n const lastLine = lines[lines.length - 1];\n column = (lastLine !== undefined ? lastLine.length : 0) + 1;\n }\n\n throw jsonSyntaxError(error.message, filePath, line, column);\n }\n throw error;\n }\n}\n\n/**\n * Valid fields for schema definition (used for validation).\n */\nconst VALID_SCHEMA_FIELDS = new Set([\n 'kind',\n 'target', // For partial schemas\n 'displayName',\n 'titleIndex',\n 'group',\n 'options',\n 'properties',\n 'values',\n]);\n\n/**\n * Valid fields for schema options (used for validation).\n */\nconst VALID_SCHEMA_OPTIONS_FIELDS = new Set([\n 'id',\n 'idType',\n 'timestamps',\n 'softDelete',\n 'unique',\n 'indexes',\n 'translations',\n 'tableName',\n 'hidden',\n 'authenticatable',\n 'authenticatableLoginIdField',\n 'authenticatablePasswordField',\n 'authenticatableGuardName',\n]);\n\n/**\n * Error for invalid property format.\n */\nexport interface InvalidPropertyFormat {\n propertyName: string;\n value: unknown;\n expectedFormat: string;\n}\n\n/**\n * Schema with raw field tracking for validation.\n */\nexport interface SchemaWithRawFields extends SchemaDefinition {\n /** Unknown fields found in raw YAML (for validation) */\n readonly _unknownFields?: readonly string[];\n /** Unknown options fields found in raw YAML (for validation) */\n readonly _unknownOptionsFields?: readonly string[];\n /** Properties with invalid format (not objects) */\n readonly _invalidProperties?: readonly InvalidPropertyFormat[];\n}\n\n/**\n * Builds a SchemaDefinition from parsed YAML data.\n * Handles exactOptionalPropertyTypes correctly.\n * Tracks unknown fields for validation.\n */\nfunction buildSchemaDefinition(\n data: Record<string, unknown>\n): SchemaWithRawFields {\n const schema: SchemaWithRawFields = {};\n\n // Track unknown fields for validation\n const unknownFields: string[] = [];\n for (const key of Object.keys(data)) {\n if (!VALID_SCHEMA_FIELDS.has(key)) {\n unknownFields.push(key);\n }\n }\n if (unknownFields.length > 0) {\n (schema as { _unknownFields: readonly string[] })._unknownFields = unknownFields;\n }\n\n // Handle optional properties with conditional assignment\n if (data.kind !== undefined) {\n (schema as { kind: 'object' | 'enum' | 'partial' }).kind = data.kind as 'object' | 'enum' | 'partial';\n }\n\n // Target schema for partial schemas\n if (data.target !== undefined && typeof data.target === 'string') {\n (schema as { target: string }).target = data.target;\n }\n\n if (data.displayName !== undefined && isLocalizedString(data.displayName)) {\n (schema as { displayName: LocalizedString }).displayName = data.displayName;\n }\n\n if (data.titleIndex !== undefined && typeof data.titleIndex === 'string') {\n (schema as { titleIndex: string }).titleIndex = data.titleIndex;\n }\n\n if (data.group !== undefined && typeof data.group === 'string') {\n (schema as { group: string }).group = data.group;\n }\n\n // Parse options and track unknown options fields\n if (data.options !== undefined && typeof data.options === 'object') {\n const optionsData = data.options as Record<string, unknown>;\n const unknownOptionsFields: string[] = [];\n for (const key of Object.keys(optionsData)) {\n if (!VALID_SCHEMA_OPTIONS_FIELDS.has(key)) {\n unknownOptionsFields.push(key);\n }\n }\n if (unknownOptionsFields.length > 0) {\n (schema as { _unknownOptionsFields: readonly string[] })._unknownOptionsFields = unknownOptionsFields;\n }\n\n const options = buildSchemaOptions(optionsData);\n if (Object.keys(options).length > 0) {\n (schema as { options: SchemaOptions }).options = options;\n }\n }\n\n // Parse properties\n if (data.properties !== undefined && typeof data.properties === 'object') {\n const { properties, invalidProperties } = buildProperties(data.properties as Record<string, unknown>);\n if (Object.keys(properties).length > 0) {\n (schema as { properties: Record<string, PropertyDefinition> }).properties = properties;\n }\n if (invalidProperties.length > 0) {\n (schema as { _invalidProperties: readonly InvalidPropertyFormat[] })._invalidProperties = invalidProperties;\n }\n }\n\n // Parse enum values\n if (data.values !== undefined && Array.isArray(data.values)) {\n (schema as { values: readonly string[] }).values = data.values as string[];\n }\n\n return schema;\n}\n\n/**\n * Builds SchemaOptions from parsed data.\n */\nfunction buildSchemaOptions(data: Record<string, unknown>): SchemaOptions {\n const options: SchemaOptions = {};\n\n if (data.timestamps !== undefined && typeof data.timestamps === 'boolean') {\n (options as { timestamps: boolean }).timestamps = data.timestamps;\n }\n\n if (data.softDelete !== undefined && typeof data.softDelete === 'boolean') {\n (options as { softDelete: boolean }).softDelete = data.softDelete;\n }\n\n if (data.unique !== undefined) {\n (options as { unique: readonly string[] | readonly (readonly string[])[] }).unique =\n data.unique as readonly string[] | readonly (readonly string[])[];\n }\n\n if (data.indexes !== undefined && Array.isArray(data.indexes)) {\n (options as { indexes: SchemaOptions['indexes'] }).indexes =\n data.indexes as SchemaOptions['indexes'];\n }\n\n if (data.translations !== undefined && typeof data.translations === 'boolean') {\n (options as { translations: boolean }).translations = data.translations;\n }\n\n if (data.tableName !== undefined && typeof data.tableName === 'string') {\n (options as { tableName: string }).tableName = data.tableName;\n }\n\n // New id options\n if (data.id !== undefined && typeof data.id === 'boolean') {\n (options as { id: boolean }).id = data.id;\n }\n\n if (data.idType !== undefined) {\n (options as { idType: 'Int' | 'BigInt' | 'Uuid' | 'String' }).idType =\n data.idType as 'Int' | 'BigInt' | 'Uuid' | 'String';\n }\n\n if (data.authenticatable !== undefined && typeof data.authenticatable === 'boolean') {\n (options as { authenticatable: boolean }).authenticatable = data.authenticatable;\n }\n\n if (data.authenticatableLoginIdField !== undefined && typeof data.authenticatableLoginIdField === 'string') {\n (options as { authenticatableLoginIdField: string }).authenticatableLoginIdField =\n data.authenticatableLoginIdField;\n }\n\n if (data.authenticatablePasswordField !== undefined && typeof data.authenticatablePasswordField === 'string') {\n (options as { authenticatablePasswordField: string }).authenticatablePasswordField =\n data.authenticatablePasswordField;\n }\n\n if (data.authenticatableGuardName !== undefined && typeof data.authenticatableGuardName === 'string') {\n (options as { authenticatableGuardName: string }).authenticatableGuardName =\n data.authenticatableGuardName;\n }\n\n // Hidden option - skip model generation when true\n if (data.hidden !== undefined && typeof data.hidden === 'boolean') {\n (options as { hidden: boolean }).hidden = data.hidden;\n }\n\n return options;\n}\n\n/**\n * Builds property definitions from parsed data.\n * Validates that all properties are in object format.\n * Tracks invalid properties for validation error reporting.\n */\nfunction buildProperties(\n data: Record<string, unknown>\n): { properties: Record<string, PropertyDefinition>; invalidProperties: InvalidPropertyFormat[] } {\n const properties: Record<string, PropertyDefinition> = {};\n const invalidProperties: InvalidPropertyFormat[] = [];\n\n for (const [name, value] of Object.entries(data)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (typeof value === 'object') {\n // Valid object format: { type: \"String\", nullable: true, ... }\n properties[name] = buildPropertyDefinition(value as Record<string, unknown>);\n } else {\n // Invalid format - track for error reporting\n invalidProperties.push({\n propertyName: name,\n value,\n expectedFormat: `Property '${name}' must be an object with 'type' field. Example:\\n ${name}:\\n type: String\\n nullable: true`,\n });\n }\n }\n\n return { properties, invalidProperties };\n}\n\n/**\n * All valid property fields (for unknown field tracking).\n */\nconst VALID_PROPERTY_FIELDS = new Set([\n 'type',\n 'displayName',\n 'nullable',\n 'default',\n 'unique',\n 'primary',\n 'description',\n 'renamedFrom',\n // Placeholder for form inputs (multi-language)\n 'placeholder',\n // String properties\n 'length',\n // Numeric properties\n 'unsigned',\n 'precision',\n 'scale',\n // Enum properties\n 'enum',\n // Association properties\n 'relation',\n 'target',\n 'targets',\n 'morphName',\n 'inversedBy',\n 'mappedBy',\n 'onDelete',\n 'onUpdate',\n 'owning',\n 'joinTable',\n 'pivotFields',\n // File properties\n 'multiple',\n 'maxFiles',\n 'accept',\n 'maxSize',\n // Validation rules (application-level only)\n 'rules',\n // Laravel-specific properties\n 'hidden',\n 'fillable',\n // Per-field settings for compound types\n 'fields',\n // Timestamp-specific properties\n 'useCurrent',\n 'useCurrentOnUpdate',\n]);\n\n/**\n * Builds a single PropertyDefinition from parsed data.\n * Uses a generic record to avoid exactOptionalPropertyTypes issues.\n * Tracks unknown fields for validation.\n */\nfunction buildPropertyDefinition(\n data: Record<string, unknown>\n): PropertyDefinition {\n // Build as a generic record first, then cast at the end\n const prop: Record<string, unknown> = {\n type: (data.type as string) || 'String',\n };\n\n // Track unknown fields for validation\n const unknownFields: string[] = [];\n for (const key of Object.keys(data)) {\n if (!VALID_PROPERTY_FIELDS.has(key)) {\n unknownFields.push(key);\n }\n }\n if (unknownFields.length > 0) {\n prop._unknownFields = unknownFields;\n }\n\n // Common properties (supports LocalizedString - string or locale map)\n if (data.displayName !== undefined && isLocalizedString(data.displayName)) {\n prop.displayName = data.displayName;\n }\n\n if (data.nullable !== undefined && typeof data.nullable === 'boolean') {\n prop.nullable = data.nullable;\n }\n\n if (data.default !== undefined) {\n prop.default = data.default;\n }\n\n if (data.unique !== undefined && typeof data.unique === 'boolean') {\n prop.unique = data.unique;\n }\n\n // Primary key (for custom primary keys with id: false)\n if (data.primary !== undefined && typeof data.primary === 'boolean') {\n prop.primary = data.primary;\n }\n\n // Description also supports LocalizedString\n if (data.description !== undefined && isLocalizedString(data.description)) {\n prop.description = data.description;\n }\n\n // Placeholder also supports LocalizedString\n if (data.placeholder !== undefined && isLocalizedString(data.placeholder)) {\n prop.placeholder = data.placeholder;\n }\n\n // Rename tracking for migrations\n if (data.renamedFrom !== undefined && typeof data.renamedFrom === 'string') {\n prop.renamedFrom = data.renamedFrom;\n }\n\n // String properties\n if (data.length !== undefined && typeof data.length === 'number') {\n prop.length = data.length;\n }\n\n // Numeric properties\n if (data.unsigned !== undefined && typeof data.unsigned === 'boolean') {\n prop.unsigned = data.unsigned;\n }\n\n if (data.precision !== undefined && typeof data.precision === 'number') {\n prop.precision = data.precision;\n }\n\n if (data.scale !== undefined && typeof data.scale === 'number') {\n prop.scale = data.scale;\n }\n\n // Enum properties\n if (data.enum !== undefined) {\n prop.enum = data.enum;\n }\n\n // Association properties\n if (data.relation !== undefined && typeof data.relation === 'string') {\n prop.relation = data.relation;\n }\n\n if (data.target !== undefined && typeof data.target === 'string') {\n prop.target = data.target;\n }\n\n if (data.inversedBy !== undefined && typeof data.inversedBy === 'string') {\n prop.inversedBy = data.inversedBy;\n }\n\n if (data.mappedBy !== undefined && typeof data.mappedBy === 'string') {\n prop.mappedBy = data.mappedBy;\n }\n\n if (data.onDelete !== undefined && typeof data.onDelete === 'string') {\n prop.onDelete = data.onDelete;\n }\n\n if (data.onUpdate !== undefined && typeof data.onUpdate === 'string') {\n prop.onUpdate = data.onUpdate;\n }\n\n if (data.owning !== undefined && typeof data.owning === 'boolean') {\n prop.owning = data.owning;\n }\n\n if (data.joinTable !== undefined && typeof data.joinTable === 'string') {\n prop.joinTable = data.joinTable;\n }\n\n // Polymorphic association properties\n if (data.targets !== undefined && Array.isArray(data.targets)) {\n prop.targets = data.targets;\n }\n\n if (data.morphName !== undefined && typeof data.morphName === 'string') {\n prop.morphName = data.morphName;\n }\n\n // Pivot fields for ManyToMany\n if (data.pivotFields !== undefined && typeof data.pivotFields === 'object') {\n prop.pivotFields = data.pivotFields;\n }\n\n // File type properties\n if (data.multiple !== undefined && typeof data.multiple === 'boolean') {\n prop.multiple = data.multiple;\n }\n\n if (data.maxFiles !== undefined && typeof data.maxFiles === 'number') {\n prop.maxFiles = data.maxFiles;\n }\n\n if (data.accept !== undefined && Array.isArray(data.accept)) {\n prop.accept = data.accept;\n }\n\n if (data.maxSize !== undefined && typeof data.maxSize === 'number') {\n prop.maxSize = data.maxSize;\n }\n\n // Validation rules (application-level only)\n if (data.rules !== undefined && typeof data.rules === 'object') {\n prop.rules = data.rules;\n }\n\n // Laravel-specific: hidden field for $hidden array\n if (data.hidden !== undefined && typeof data.hidden === 'boolean') {\n prop.hidden = data.hidden;\n }\n\n // Laravel-specific: fillable field for $fillable array\n if (data.fillable !== undefined && typeof data.fillable === 'boolean') {\n prop.fillable = data.fillable;\n }\n\n // Timestamp-specific: useCurrent for default CURRENT_TIMESTAMP\n if (data.useCurrent !== undefined && typeof data.useCurrent === 'boolean') {\n prop.useCurrent = data.useCurrent;\n }\n\n // Timestamp-specific: useCurrentOnUpdate for ON UPDATE CURRENT_TIMESTAMP\n if (data.useCurrentOnUpdate !== undefined && typeof data.useCurrentOnUpdate === 'boolean') {\n prop.useCurrentOnUpdate = data.useCurrentOnUpdate;\n }\n\n // Per-field settings for compound types\n if (data.fields !== undefined && typeof data.fields === 'object' && data.fields !== null) {\n prop.fields = data.fields;\n }\n\n return prop as unknown as PropertyDefinition;\n}\n\n/**\n * Loads a single schema file.\n * Supports both YAML (.yaml, .yml) and JSON (.json) formats.\n *\n * @param filePath - Path to the schema file\n * @param options - Loading options\n * @returns Loaded schema with metadata\n * @throws OmnifyError if file not found or invalid syntax\n */\nexport async function loadSchema(\n filePath: string,\n options: LoadSchemaOptions = {}\n): Promise<LoadedSchema> {\n const absolutePath = path.resolve(filePath);\n const baseDir = options.baseDir ? path.resolve(options.baseDir) : path.dirname(absolutePath);\n\n // Check if file exists\n try {\n await fs.access(absolutePath);\n } catch {\n throw schemaNotFoundError(filePath);\n }\n\n // Read file content\n const content = await fs.readFile(absolutePath, 'utf-8');\n\n // Parse based on file extension\n const ext = path.extname(absolutePath).toLowerCase();\n const schemaDefinition = ext === '.json'\n ? parseJsonSchema(content, filePath)\n : parseYamlSchema(content, filePath);\n\n // Build LoadedSchema\n const name = fileNameToSchemaName(absolutePath);\n const relativePath = path.relative(baseDir, absolutePath);\n\n const loadedSchema: LoadedSchema = {\n ...schemaDefinition,\n name,\n filePath: absolutePath,\n relativePath,\n };\n\n return loadedSchema;\n}\n\n/**\n * Recursively finds all schema files in a directory.\n */\nasync function findSchemaFiles(\n dirPath: string,\n extensions: readonly string[],\n recursive: boolean\n): Promise<string[]> {\n const files: string[] = [];\n\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory() && recursive) {\n const subFiles = await findSchemaFiles(fullPath, extensions, recursive);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (extensions.includes(ext)) {\n files.push(fullPath);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Loads all schemas from a directory.\n *\n * @param directoryPath - Path to the schemas directory\n * @param options - Loading options\n * @returns Collection of loaded schemas indexed by name\n * @throws OmnifyError if duplicate schema names or invalid files\n */\nexport async function loadSchemas(\n directoryPath: string,\n options: LoadSchemasOptions = {}\n): Promise<SchemaCollection> {\n const {\n extensions = ['.yaml', '.yml', '.json'],\n recursive = true,\n } = options;\n\n const absoluteDir = path.resolve(directoryPath);\n\n // Check if directory exists\n try {\n const stat = await fs.stat(absoluteDir);\n if (!stat.isDirectory()) {\n throw schemaNotFoundError(directoryPath);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw schemaNotFoundError(directoryPath);\n }\n throw error;\n }\n\n // Find all schema files\n const schemaFiles = await findSchemaFiles(absoluteDir, extensions, recursive);\n\n // Load each schema - separate regular and partial schemas\n const schemas: Record<string, LoadedSchema> = {};\n const partialSchemas: LoadedSchema[] = [];\n const schemaLocations: Record<string, string> = {};\n\n for (const filePath of schemaFiles) {\n const schema = await loadSchema(filePath, { baseDir: absoluteDir });\n\n // Partial schemas are collected separately for later merging\n if (schema.kind === 'partial') {\n partialSchemas.push(schema);\n continue;\n }\n\n // Check for duplicate names (only for non-partial schemas)\n const existingLocation = schemaLocations[schema.name];\n if (existingLocation !== undefined) {\n throw duplicateSchemaError(\n schema.name,\n { file: filePath },\n { file: existingLocation }\n );\n }\n\n schemas[schema.name] = schema;\n schemaLocations[schema.name] = filePath;\n }\n\n // Merge partial schemas into their targets\n for (const partial of partialSchemas) {\n const targetName = partial.target;\n if (!targetName) {\n console.warn(`Partial schema '${partial.name}' has no target, skipping`);\n continue;\n }\n\n const target = schemas[targetName];\n if (!target) {\n console.warn(`Partial schema '${partial.name}' targets unknown schema '${targetName}', skipping`);\n continue;\n }\n\n // Merge properties: target properties take priority\n const mergedProperties = {\n ...(partial.properties ?? {}),\n ...(target.properties ?? {}),\n };\n\n // Update the target schema with merged properties\n schemas[targetName] = {\n ...target,\n properties: mergedProperties,\n };\n }\n\n return schemas;\n}\n\n/**\n * The reserved name for the File schema (polymorphic file storage).\n */\nexport const FILE_SCHEMA_NAME = 'File';\n\n/**\n * Checks if any schema in the collection has File type properties.\n */\nexport function schemasHaveFileProperties(schemas: SchemaCollection): boolean {\n for (const schema of Object.values(schemas)) {\n if (!schema.properties) continue;\n for (const prop of Object.values(schema.properties)) {\n if (prop.type === 'File') {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Creates the File schema definition for polymorphic file storage.\n * This schema represents files stored with morphOne/morphMany relationships.\n */\nexport function createFileSchemaDefinition(): SchemaDefinition {\n return {\n displayName: 'File',\n options: {\n timestamps: true,\n tableName: 'files',\n indexes: [\n {\n columns: ['fileableType', 'fileableId', 'fileableField'],\n name: 'files_fileable_index',\n },\n ],\n },\n properties: {\n path: {\n type: 'String',\n displayName: 'Storage Path',\n },\n disk: {\n type: 'String',\n displayName: 'Storage Disk',\n default: 'local',\n },\n size: {\n type: 'BigInt',\n displayName: 'File Size (bytes)',\n unsigned: true,\n },\n mimeType: {\n type: 'String',\n displayName: 'MIME Type',\n },\n fileableType: {\n type: 'String',\n displayName: 'Fileable Type',\n },\n fileableId: {\n type: 'BigInt',\n displayName: 'Fileable ID',\n unsigned: true,\n },\n fileableField: {\n type: 'String',\n displayName: 'Fileable Field',\n },\n },\n };\n}\n\n/**\n * Creates a LoadedSchema for the File schema.\n * Used when auto-generating File schema in memory.\n */\nexport function createFileLoadedSchema(schemasDir: string): LoadedSchema {\n const definition = createFileSchemaDefinition();\n const filePath = path.join(schemasDir, 'File.yaml');\n\n return {\n ...definition,\n name: FILE_SCHEMA_NAME,\n filePath,\n relativePath: 'File.yaml',\n };\n}\n\n/**\n * Generates YAML content for File.yaml schema.\n * Can be written to disk for user customization.\n */\nexport function generateFileSchemaYaml(): string {\n return `# File Schema - Polymorphic file storage\n# Auto-generated by Omnify when File type is detected\n# You can customize this schema as needed\n\ndisplayName: File\n\noptions:\n timestamps: true\n tableName: files\n indexes:\n - columns: [fileableType, fileableId, fileableField]\n name: files_fileable_index\n\nproperties:\n path:\n type: String\n displayName: Storage Path\n\n disk:\n type: String\n displayName: Storage Disk\n default: local\n\n size:\n type: BigInt\n displayName: File Size (bytes)\n unsigned: true\n\n mimeType:\n type: String\n displayName: MIME Type\n\n fileableType:\n type: String\n displayName: Fileable Type\n\n fileableId:\n type: BigInt\n displayName: Fileable ID\n unsigned: true\n\n fileableField:\n type: String\n displayName: Fileable Field\n`;\n}\n\n/**\n * Ensures File schema exists when File type is used.\n * Returns the schema collection with File schema added if needed.\n *\n * @param schemas - Existing schema collection\n * @param schemasDir - Directory where schemas are stored\n * @param autoCreate - If true, creates File.yaml on disk; if false, adds in-memory only\n * @returns Updated schema collection\n */\nexport async function ensureFileSchema(\n schemas: SchemaCollection,\n schemasDir: string,\n autoCreate: boolean = false\n): Promise<SchemaCollection> {\n // Check if File type is used\n if (!schemasHaveFileProperties(schemas)) {\n return schemas;\n }\n\n // Check if File schema already exists\n if (schemas[FILE_SCHEMA_NAME]) {\n return schemas;\n }\n\n // Create File schema\n const fileSchema = createFileLoadedSchema(schemasDir);\n\n // Optionally write to disk\n if (autoCreate) {\n const filePath = path.join(schemasDir, 'File.yaml');\n const yamlContent = generateFileSchemaYaml();\n await fs.writeFile(filePath, yamlContent, 'utf-8');\n }\n\n // Return updated collection\n return {\n [FILE_SCHEMA_NAME]: fileSchema,\n ...schemas,\n };\n}\n","/**\n * @famgia/omnify-core - Schema Validator\n *\n * Validates schema definitions for correctness and consistency.\n * Uses class-based type system for extensible validation.\n */\n\nimport type {\n SchemaDefinition,\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n BuiltInPropertyType,\n LocalizedString,\n LocaleConfig,\n} from '@famgia/omnify-types';\nimport { isLocaleMap } from '@famgia/omnify-types';\nimport {\n OmnifyError,\n validationError,\n invalidPropertyTypeError,\n missingFieldError,\n invalidAssociationTargetError,\n} from '../errors/index.js';\nimport type {\n SchemaValidationResult,\n ValidationResult,\n ValidationOptions,\n DatabaseDriver,\n} from './types.js';\nimport {\n typeRegistry,\n VALID_RELATIONS,\n VALID_REFERENTIAL_ACTIONS,\n BASE_PROPERTY_FIELDS,\n VALID_RULES_FIELDS,\n} from './types/index.js';\n\n/**\n * Valid ID types for auto-generated primary key.\n */\nconst VALID_ID_TYPES = ['Int', 'BigInt', 'Uuid', 'String'] as const;\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string, line?: number, column?: number) {\n const loc: { file: string; line?: number; column?: number } = { file };\n if (line !== undefined) {\n loc.line = line;\n }\n if (column !== undefined) {\n loc.column = column;\n }\n return loc;\n}\n\n/**\n * Validates unknown fields at the schema root level.\n * Returns errors for fields that are not part of the schema spec.\n * Uses _unknownFields populated by the loader.\n */\nexport function validateUnknownSchemaFields(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for unknown fields tracked by the loader\n const unknownFields = (schema as { _unknownFields?: readonly string[] })._unknownFields;\n if (!unknownFields || unknownFields.length === 0) {\n return errors;\n }\n\n for (const field of unknownFields) {\n // Provide specific suggestions based on common mistakes\n let suggestion = `Valid schema fields: kind, displayName, titleIndex, group, options, properties, values`;\n\n if (field === 'associations') {\n suggestion = `Associations should be defined inside 'properties' with type: Association.\nExample:\n properties:\n author:\n type: Association\n relation: ManyToOne\n target: User\n onDelete: CASCADE`;\n } else if (field === 'indexes') {\n suggestion = `Indexes should be inside 'options.indexes'.\nExample:\n options:\n indexes:\n - columns: [email]\n unique: true`;\n } else if (field === 'required') {\n suggestion = `'required' is not a valid field. Use 'nullable: false' on properties (default is not nullable).\nExample:\n properties:\n email:\n type: String\n # not nullable by default, explicitly use nullable: true to make optional`;\n } else if (field === 'hidden') {\n suggestion = `'hidden' is not a schema-level field. Hidden fields should be handled by your framework.\nFor Laravel, the model generator can handle this, but you need to use a custom property.`;\n }\n\n errors.push(\n validationError(\n `Unknown schema field '${field}'`,\n buildLocation(filePath),\n suggestion\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates unknown fields in schema options.\n * Returns errors for option fields that are not recognized.\n * Uses _unknownOptionsFields populated by the loader.\n */\nexport function validateUnknownOptionsFields(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for unknown options fields tracked by the loader\n const unknownOptionsFields = (schema as { _unknownOptionsFields?: readonly string[] })._unknownOptionsFields;\n if (!unknownOptionsFields || unknownOptionsFields.length === 0) {\n return errors;\n }\n\n for (const field of unknownOptionsFields) {\n errors.push(\n validationError(\n `Unknown option field '${field}'`,\n buildLocation(filePath),\n `Valid option fields: id, idType, timestamps, softDelete, unique, indexes, translations, tableName, authenticatable, authenticatableLoginIdField, authenticatablePasswordField, authenticatableGuardName`\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Invalid property format info from loader.\n */\ninterface InvalidPropertyFormat {\n propertyName: string;\n value: unknown;\n expectedFormat: string;\n}\n\n/**\n * Validates that all properties are in correct object format.\n * Returns errors for properties that are not objects (e.g., shorthand strings).\n * Uses _invalidProperties populated by the loader.\n */\nexport function validatePropertyFormat(\n schema: LoadedSchema,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n // Check for invalid properties tracked by the loader\n const invalidProperties = (schema as { _invalidProperties?: readonly InvalidPropertyFormat[] })._invalidProperties;\n if (!invalidProperties || invalidProperties.length === 0) {\n return errors;\n }\n\n for (const invalid of invalidProperties) {\n const valueType = typeof invalid.value;\n const valuePreview = valueType === 'string'\n ? `\"${invalid.value}\"`\n : String(invalid.value);\n\n errors.push(\n validationError(\n `Property '${invalid.propertyName}' has invalid format: got ${valueType} (${valuePreview})`,\n buildLocation(filePath),\n invalid.expectedFormat\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates database compatibility for a property type.\n * Returns warnings for types with limited support, errors for unsupported types.\n */\nexport function validateDbCompatibility(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n databaseDriver?: DatabaseDriver\n): { errors: OmnifyError[]; warnings: OmnifyError[] } {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n\n if (!databaseDriver || !property.type) {\n return { errors, warnings };\n }\n\n const compatibility = typeRegistry.getDbCompatibility(property.type, databaseDriver);\n\n if (compatibility === 'unsupported') {\n errors.push(\n validationError(\n `Property '${propertyName}' uses type '${property.type}' which is not supported in ${databaseDriver}`,\n buildLocation(filePath),\n `Consider using a different type or database driver`\n )\n );\n } else if (compatibility === 'limited') {\n warnings.push(\n validationError(\n `Property '${propertyName}' uses type '${property.type}' which has limited support in ${databaseDriver}`,\n buildLocation(filePath),\n `The type will work but may have precision or feature limitations`\n )\n );\n }\n\n return { errors, warnings };\n}\n\n/**\n * Result of unknown field validation.\n */\nexport interface UnknownFieldsResult {\n /** Errors: fields valid for other types but not this type */\n readonly errors: OmnifyError[];\n /** Warnings: completely unknown fields */\n readonly warnings: OmnifyError[];\n}\n\n/**\n * Validates unknown fields in a property definition.\n * Checks:\n * 1. Fields tracked by loader as unknown (_unknownFields) → warnings\n * 2. Fields that are valid for other types but not this type → errors\n */\nexport function validateUnknownFields(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n): OmnifyError[] {\n const result = validateUnknownFieldsDetailed(propertyName, property, filePath);\n // For backwards compatibility, return combined errors (warnings become errors)\n // But the detailed version separates them properly\n return [...result.errors, ...result.warnings];\n}\n\n/**\n * Validates unknown fields with detailed separation of errors and warnings.\n */\nexport function validateUnknownFieldsDetailed(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n customTypeDefinitions?: ReadonlyMap<string, import('@famgia/omnify-types').CustomTypeDefinition>\n): UnknownFieldsResult {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n\n // Skip if no type\n if (!property.type) {\n return { errors, warnings };\n }\n\n // Get valid fields for this type\n let validFields: readonly string[];\n const isBuiltIn = typeRegistry.has(property.type);\n\n if (isBuiltIn) {\n // Built-in type - use registry\n validFields = typeRegistry.getValidFields(property.type);\n } else {\n // Custom type - check if we have full definition\n const customTypeDef = customTypeDefinitions?.get(property.type);\n if (customTypeDef?.validFields) {\n // Custom type with validFields - use base fields + custom validFields\n validFields = [...BASE_PROPERTY_FIELDS, ...customTypeDef.validFields];\n } else {\n // Custom type without validFields - only allow base fields\n validFields = [...BASE_PROPERTY_FIELDS];\n }\n }\n\n const validFieldsSet = new Set(validFields);\n\n // Check each field in the property (except internal fields)\n for (const field of Object.keys(property)) {\n if (field.startsWith('_')) continue; // Skip internal fields\n if (validFieldsSet.has(field)) continue; // Field is valid for this type\n\n // Field is not valid for this type - determine if it's an error or warning\n // Error: field is valid for SOME other type (user likely made a mistake)\n // Warning: field is completely unknown (might be intentional extension)\n const isValidForOtherType = typeRegistry.isFieldValidForAnyType(field);\n\n if (isValidForOtherType) {\n // Field is valid for another type - this is an error\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${property.type}' has invalid field '${field}'`,\n buildLocation(filePath),\n `'${field}' is not valid for type '${property.type}'. Valid fields: ${validFields.join(', ')}`\n )\n );\n } else {\n // Field is completely unknown - this is an ERROR (not warning)\n // Unknown fields should not be silently ignored\n errors.push(\n validationError(\n `Property '${propertyName}' has unknown field '${field}'`,\n buildLocation(filePath),\n getSuggestionForUnknownField(field)\n )\n );\n }\n }\n\n return { errors, warnings };\n}\n\n/**\n * Get suggestion message for unknown field.\n */\nfunction getSuggestionForUnknownField(field: string): string {\n if (field === 'required') {\n return `'required' should be inside 'rules' field.\nExample:\n name:\n type: String\n rules:\n required: true\nNote: rules.required is for validation only, does NOT affect database nullable.\nRecommended: set 'nullable: false' if required: true.`;\n }\n\n if (field === 'maxLength' || field === 'minLength') {\n return `'${field}' should be inside 'rules' field.\nExample:\n name:\n type: String\n length: 255 # Database column size\n rules:\n minLength: 5\n maxLength: 100\nNote: 'length' is for database column size, 'rules.maxLength' is for validation only.`;\n }\n\n // 'hidden' is now a valid base field - no suggestion needed\n\n if (field === 'foreignKey') {\n return `'foreignKey' is not needed. Omnify auto-generates foreign keys from Association properties.\nThe foreign key name is derived from the property name + '_id'.\nExample:\n author:\n type: Association\n relation: ManyToOne\n target: User\n # Creates author_id column automatically`;\n }\n\n return `Unknown field '${field}'. Valid property fields: type, displayName, placeholder, nullable, default, unique, primary, description, length, unsigned, precision, scale, enum, relation, target, onDelete, onUpdate, joinTable, rules, hidden, fillable, fields`;\n}\n\n/**\n * Types that allow minLength/maxLength in rules.\n */\nconst STRING_TYPES_WITH_LENGTH_RULES = ['String', 'Email', 'Password'] as const;\n\n/**\n * Validates the rules field in a property definition.\n * Checks:\n * 1. Unknown fields in rules object\n * 2. minLength/maxLength only allowed for String, Email, Password types\n * 3. maxLength <= length (database column size)\n * 4. minLength <= maxLength\n */\nexport function validateRules(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n const rules = (property as { rules?: Record<string, unknown> }).rules;\n\n if (!rules || typeof rules !== 'object') {\n return errors;\n }\n\n // Check for unknown fields in rules\n const validRulesSet = new Set(VALID_RULES_FIELDS as readonly string[]);\n for (const field of Object.keys(rules)) {\n if (!validRulesSet.has(field)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has unknown field in rules: '${field}'`,\n buildLocation(filePath),\n `Valid rules fields: ${VALID_RULES_FIELDS.join(', ')}`\n )\n );\n }\n }\n\n const { required, minLength, maxLength } = rules as {\n required?: unknown;\n minLength?: unknown;\n maxLength?: unknown;\n };\n\n // Validate required is boolean\n if (required !== undefined && typeof required !== 'boolean') {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.required value`,\n buildLocation(filePath),\n 'rules.required must be a boolean (true or false)'\n )\n );\n }\n\n // Validate minLength/maxLength only for String, Email, Password types\n const propertyType = property.type;\n const allowsLengthRules = STRING_TYPES_WITH_LENGTH_RULES.includes(\n propertyType as typeof STRING_TYPES_WITH_LENGTH_RULES[number]\n );\n\n if (minLength !== undefined && !allowsLengthRules) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${propertyType}' cannot use rules.minLength`,\n buildLocation(filePath),\n `rules.minLength is only valid for types: ${STRING_TYPES_WITH_LENGTH_RULES.join(', ')}`\n )\n );\n }\n\n if (maxLength !== undefined && !allowsLengthRules) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type '${propertyType}' cannot use rules.maxLength`,\n buildLocation(filePath),\n `rules.maxLength is only valid for types: ${STRING_TYPES_WITH_LENGTH_RULES.join(', ')}`\n )\n );\n }\n\n // Validate minLength value\n if (minLength !== undefined && allowsLengthRules) {\n if (typeof minLength !== 'number' || minLength < 0 || minLength > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.minLength '${minLength}'`,\n buildLocation(filePath),\n 'rules.minLength must be a non-negative number between 0 and 65535'\n )\n );\n }\n }\n\n // Validate maxLength value and compare with length\n if (maxLength !== undefined && allowsLengthRules) {\n if (typeof maxLength !== 'number' || maxLength < 1 || maxLength > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid rules.maxLength '${maxLength}'`,\n buildLocation(filePath),\n 'rules.maxLength must be a positive number between 1 and 65535'\n )\n );\n } else {\n // Check maxLength <= length (database column size)\n const dbLength = (property as { length?: number }).length;\n if (dbLength !== undefined && typeof dbLength === 'number' && maxLength > dbLength) {\n errors.push(\n validationError(\n `Property '${propertyName}' has rules.maxLength (${maxLength}) greater than length (${dbLength})`,\n buildLocation(filePath),\n 'rules.maxLength must be less than or equal to length (database column size)'\n )\n );\n }\n }\n }\n\n // Validate minLength <= maxLength\n if (minLength !== undefined && maxLength !== undefined &&\n typeof minLength === 'number' && typeof maxLength === 'number' &&\n minLength > maxLength) {\n errors.push(\n validationError(\n `Property '${propertyName}' has rules.minLength (${minLength}) greater than rules.maxLength (${maxLength})`,\n buildLocation(filePath),\n 'rules.minLength must be less than or equal to rules.maxLength'\n )\n );\n }\n\n return errors;\n}\n\n/**\n * Validates a property type.\n */\nexport function validatePropertyType(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string,\n customTypes: readonly string[] = []\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!property.type) {\n errors.push(\n missingFieldError('type', buildLocation(filePath))\n );\n return errors;\n }\n\n // Check if type exists (built-in or custom)\n const isBuiltIn = typeRegistry.has(property.type);\n const isCustom = customTypes.includes(property.type);\n\n if (!isBuiltIn && !isCustom) {\n errors.push(\n invalidPropertyTypeError(\n property.type,\n buildLocation(filePath),\n typeRegistry.getAllTypeNames() as readonly BuiltInPropertyType[]\n )\n );\n return errors;\n }\n\n // Run type-specific validation for built-in types\n if (isBuiltIn) {\n const typeErrors = typeRegistry.validateProperty(propertyName, property, filePath);\n errors.push(...typeErrors);\n }\n\n return errors;\n}\n\n/**\n * Validates all properties in a schema.\n */\nexport function validateProperties(\n schema: SchemaDefinition,\n filePath: string,\n customTypes: readonly string[] = []\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!schema.properties) {\n // No properties is valid for enum schemas\n if (schema.kind !== 'enum') {\n // Warning: object schema without properties\n }\n return errors;\n }\n\n for (const [name, property] of Object.entries(schema.properties)) {\n const propErrors = validatePropertyType(name, property, filePath, customTypes);\n errors.push(...propErrors);\n }\n\n return errors;\n}\n\n/**\n * Polymorphic relation types that use 'targets' instead of 'target'.\n */\nconst MORPH_TO_RELATIONS = ['MorphTo'] as const;\n\n/**\n * Polymorphic relation types that require 'morphName' pointing to MorphTo on target.\n * Note: MorphedByMany also uses morphName but for pivot table name, not property reference.\n */\nconst MORPH_INVERSE_RELATIONS = ['MorphOne', 'MorphMany'] as const;\n\n/**\n * Validates associations in a schema against available schemas.\n */\nexport function validateAssociations(\n schema: LoadedSchema,\n allSchemas: SchemaCollection\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (!schema.properties) {\n return errors;\n }\n\n const availableSchemas = Object.keys(allSchemas);\n\n for (const [name, property] of Object.entries(schema.properties)) {\n if (property.type !== 'Association') {\n continue;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n targets?: readonly string[];\n morphName?: string;\n inversedBy?: string;\n mappedBy?: string;\n onDelete?: string;\n onUpdate?: string;\n };\n\n // Validate relation type\n if (assocProp.relation && !VALID_RELATIONS.includes(assocProp.relation as typeof VALID_RELATIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid relation '${assocProp.relation}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_RELATIONS.join(', ')}`\n )\n );\n }\n\n const relation = assocProp.relation as typeof VALID_RELATIONS[number] | undefined;\n\n // Validate targets for MorphTo\n if (relation && MORPH_TO_RELATIONS.includes(relation as typeof MORPH_TO_RELATIONS[number])) {\n if (assocProp.targets) {\n for (const target of assocProp.targets) {\n if (!availableSchemas.includes(target)) {\n errors.push(\n invalidAssociationTargetError(\n target,\n buildLocation(schema.filePath),\n availableSchemas\n )\n );\n }\n }\n }\n }\n // Validate target for standard relations and inverse polymorphic\n else if (assocProp.target && !availableSchemas.includes(assocProp.target)) {\n errors.push(\n invalidAssociationTargetError(\n assocProp.target,\n buildLocation(schema.filePath),\n availableSchemas\n )\n );\n }\n\n // Validate morphName matches a MorphTo property on target schema\n if (relation && MORPH_INVERSE_RELATIONS.includes(relation as typeof MORPH_INVERSE_RELATIONS[number])) {\n if (assocProp.morphName && assocProp.target) {\n const targetSchema = allSchemas[assocProp.target];\n if (targetSchema?.properties) {\n const morphProperty = targetSchema.properties[assocProp.morphName];\n if (!morphProperty) {\n errors.push(\n validationError(\n `Property '${name}' references non-existent morphName '${assocProp.morphName}' on '${assocProp.target}'`,\n buildLocation(schema.filePath),\n `Add a MorphTo property '${assocProp.morphName}' to ${assocProp.target} schema`\n )\n );\n } else if (morphProperty.type === 'Association') {\n const morphAssoc = morphProperty as { relation?: string };\n if (morphAssoc.relation !== 'MorphTo') {\n errors.push(\n validationError(\n `Property '${name}' morphName '${assocProp.morphName}' on '${assocProp.target}' must be a MorphTo relation`,\n buildLocation(schema.filePath),\n `Change ${assocProp.target}.${assocProp.morphName} relation to MorphTo`\n )\n );\n }\n }\n }\n }\n }\n\n // Validate inversedBy/mappedBy references exist (for standard relations)\n if (assocProp.inversedBy && assocProp.target) {\n const targetSchema = allSchemas[assocProp.target];\n if (targetSchema?.properties) {\n const inverseProperty = targetSchema.properties[assocProp.inversedBy];\n if (!inverseProperty) {\n errors.push(\n validationError(\n `Property '${name}' references non-existent inverse property '${assocProp.inversedBy}' on '${assocProp.target}'`,\n buildLocation(schema.filePath),\n `Add property '${assocProp.inversedBy}' to ${assocProp.target} schema`\n )\n );\n }\n }\n }\n\n // Validate referential actions\n if (assocProp.onDelete && !VALID_REFERENTIAL_ACTIONS.includes(assocProp.onDelete as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid onDelete action '${assocProp.onDelete}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n\n if (assocProp.onUpdate && !VALID_REFERENTIAL_ACTIONS.includes(assocProp.onUpdate as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${name}' has invalid onUpdate action '${assocProp.onUpdate}'`,\n buildLocation(schema.filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n return errors;\n}\n\n/**\n * Validates schema options.\n */\nexport function validateOptions(\n schema: SchemaDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n const options = schema.options;\n\n if (!options) {\n return errors;\n }\n\n // Validate idType\n if (options.idType !== undefined) {\n if (!VALID_ID_TYPES.includes(options.idType as typeof VALID_ID_TYPES[number])) {\n errors.push(\n validationError(\n `Invalid idType '${options.idType}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_ID_TYPES.join(', ')}`\n )\n );\n }\n }\n\n // Validate unique constraints reference existing properties\n if (options.unique && schema.properties) {\n const propertyNames = Object.keys(schema.properties);\n const uniqueConstraints = Array.isArray(options.unique[0])\n ? (options.unique as readonly (readonly string[])[])\n : [options.unique as readonly string[]];\n\n for (const constraint of uniqueConstraints) {\n for (const column of constraint) {\n if (!propertyNames.includes(column)) {\n errors.push(\n validationError(\n `Unique constraint references non-existent property '${column}'`,\n buildLocation(filePath),\n `Available properties: ${propertyNames.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n // Validate indexes reference existing properties\n if (options.indexes && schema.properties) {\n const propertyNames = Object.keys(schema.properties);\n\n for (const index of options.indexes) {\n // Handle both shorthand (string) and full object format\n const columns = typeof index === 'string' ? [index] : index.columns;\n for (const column of columns) {\n if (!propertyNames.includes(column)) {\n errors.push(\n validationError(\n `Index references non-existent property '${column}'`,\n buildLocation(filePath),\n `Available properties: ${propertyNames.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n // Validate authenticatable options\n if (options.authenticatable) {\n if (options.authenticatableLoginIdField && schema.properties) {\n if (!schema.properties[options.authenticatableLoginIdField]) {\n errors.push(\n validationError(\n `authenticatableLoginIdField references non-existent property '${options.authenticatableLoginIdField}'`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n if (options.authenticatablePasswordField && schema.properties) {\n if (!schema.properties[options.authenticatablePasswordField]) {\n errors.push(\n validationError(\n `authenticatablePasswordField references non-existent property '${options.authenticatablePasswordField}'`,\n buildLocation(filePath)\n )\n );\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Validates an enum schema.\n */\nexport function validateEnumSchema(\n schema: SchemaDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (schema.kind !== 'enum') {\n return errors;\n }\n\n if (!schema.values || schema.values.length === 0) {\n errors.push(\n validationError(\n 'Enum schema requires at least one value',\n buildLocation(filePath),\n 'Add values: [value1, value2, ...]'\n )\n );\n }\n\n // Check for duplicate values\n if (schema.values) {\n const seen = new Set<string>();\n for (const value of schema.values) {\n if (seen.has(value)) {\n errors.push(\n validationError(\n `Duplicate enum value '${value}'`,\n buildLocation(filePath)\n )\n );\n }\n seen.add(value);\n }\n }\n\n return errors;\n}\n\n/**\n * Validates a partial schema.\n * Partial schemas extend existing schemas with additional properties.\n */\nexport function validatePartialSchema(\n schema: SchemaDefinition,\n filePath: string\n): OmnifyError[] {\n const errors: OmnifyError[] = [];\n\n if (schema.kind !== 'partial') {\n return errors;\n }\n\n // Partial schema must have a target\n if (!schema.target) {\n errors.push(\n validationError(\n 'Partial schema requires a target schema name',\n buildLocation(filePath),\n 'Add target: SchemaName to specify which schema to extend'\n )\n );\n } else if (typeof schema.target !== 'string') {\n errors.push(\n validationError(\n 'Partial schema target must be a string',\n buildLocation(filePath),\n 'Example: target: User'\n )\n );\n }\n\n // Partial schema must have properties\n if (!schema.properties || Object.keys(schema.properties).length === 0) {\n errors.push(\n validationError(\n 'Partial schema requires at least one property to extend the target',\n buildLocation(filePath),\n 'Add properties to extend the target schema'\n )\n );\n }\n\n // Partial schema should not have values (that's for enums)\n if (schema.values && schema.values.length > 0) {\n errors.push(\n validationError(\n 'Partial schema cannot have values (values are for enum schemas)',\n buildLocation(filePath),\n 'Remove values or change kind to enum'\n )\n );\n }\n\n // Partial schema should not have certain options\n if (schema.options) {\n const invalidOptions = ['id', 'timestamps', 'softDelete', 'tableName'];\n for (const opt of invalidOptions) {\n if ((schema.options as Record<string, unknown>)[opt] !== undefined) {\n errors.push(\n validationError(\n `Partial schema cannot have option '${opt}' (table options belong to the target schema)`,\n buildLocation(filePath),\n `Remove options.${opt} - table-level options should be in the target schema`\n )\n );\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Result of localized string validation.\n */\nexport interface LocalizedStringValidationResult {\n /** Warnings for locales not in config */\n readonly warnings: OmnifyError[];\n}\n\n/**\n * Validates a localized string against locale configuration.\n * Returns warnings for locales used but not in the configured list.\n *\n * @param fieldName - Name of the field being validated (e.g., 'displayName', 'description')\n * @param value - The localized string value\n * @param filePath - File path for error location\n * @param localeConfig - Optional locale configuration\n * @param context - Optional context (e.g., property name)\n * @returns Validation warnings\n */\nexport function validateLocalizedString(\n fieldName: string,\n value: LocalizedString | undefined,\n filePath: string,\n localeConfig?: LocaleConfig,\n context?: string\n): LocalizedStringValidationResult {\n const warnings: OmnifyError[] = [];\n\n // Skip if no value or not a locale map\n if (value === undefined || !isLocaleMap(value)) {\n return { warnings };\n }\n\n // Skip if no locale config provided\n if (!localeConfig) {\n return { warnings };\n }\n\n // Check each locale in the value\n const configuredLocales = new Set(localeConfig.locales);\n const usedLocales = Object.keys(value);\n\n for (const locale of usedLocales) {\n if (!configuredLocales.has(locale)) {\n const contextStr = context ? ` (property '${context}')` : '';\n warnings.push(\n validationError(\n `${fieldName}${contextStr} uses locale '${locale}' which is not in configured locales`,\n buildLocation(filePath),\n `Configured locales: ${localeConfig.locales.join(', ')}. Add '${locale}' to your locale configuration or remove it from the schema.`\n )\n );\n }\n }\n\n return { warnings };\n}\n\n/**\n * Validates all localized strings in a schema.\n * Checks displayName and description fields at schema and property levels.\n */\nexport function validateLocalizedStrings(\n schema: LoadedSchema,\n localeConfig?: LocaleConfig\n): OmnifyError[] {\n const warnings: OmnifyError[] = [];\n\n // Validate schema-level displayName\n const schemaDisplayNameResult = validateLocalizedString(\n 'displayName',\n schema.displayName,\n schema.filePath,\n localeConfig\n );\n warnings.push(...schemaDisplayNameResult.warnings);\n\n // Validate property-level displayName and description\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Validate property displayName\n const propDisplayNameResult = validateLocalizedString(\n 'displayName',\n property.displayName,\n schema.filePath,\n localeConfig,\n propName\n );\n warnings.push(...propDisplayNameResult.warnings);\n\n // Validate property description (cast to access optional field)\n const propDescription = (property as { description?: LocalizedString }).description;\n const propDescriptionResult = validateLocalizedString(\n 'description',\n propDescription,\n schema.filePath,\n localeConfig,\n propName\n );\n warnings.push(...propDescriptionResult.warnings);\n }\n }\n\n return warnings;\n}\n\n/**\n * Validates a single schema.\n */\nexport function validateSchema(\n schema: LoadedSchema,\n options: ValidationOptions = {}\n): SchemaValidationResult {\n const errors: OmnifyError[] = [];\n const warnings: OmnifyError[] = [];\n const customTypes = options.customTypes ?? [];\n\n // Validate unknown fields at schema root level\n const unknownSchemaFieldErrors = validateUnknownSchemaFields(schema, schema.filePath);\n errors.push(...unknownSchemaFieldErrors);\n\n // Validate unknown fields in options\n const unknownOptionsErrors = validateUnknownOptionsFields(schema, schema.filePath);\n errors.push(...unknownOptionsErrors);\n\n // Validate property format (must be objects, not strings)\n const propertyFormatErrors = validatePropertyFormat(schema, schema.filePath);\n errors.push(...propertyFormatErrors);\n\n // Validate properties\n const propErrors = validateProperties(schema, schema.filePath, customTypes);\n errors.push(...propErrors);\n\n // Validate options\n const optErrors = validateOptions(schema, schema.filePath);\n errors.push(...optErrors);\n\n // Validate enum schema\n if (schema.kind === 'enum') {\n const enumErrors = validateEnumSchema(schema, schema.filePath);\n errors.push(...enumErrors);\n }\n\n // Validate partial schema\n if (schema.kind === 'partial') {\n const partialErrors = validatePartialSchema(schema, schema.filePath);\n errors.push(...partialErrors);\n }\n\n // Validate titleIndex references existing property\n if (schema.titleIndex && schema.properties) {\n if (!schema.properties[schema.titleIndex]) {\n errors.push(\n validationError(\n `titleIndex references non-existent property '${schema.titleIndex}'`,\n buildLocation(schema.filePath),\n `Available properties: ${Object.keys(schema.properties).join(', ')}`\n )\n );\n }\n }\n\n // Validate properties for unknown fields and DB compatibility\n if (schema.properties) {\n for (const [name, property] of Object.entries(schema.properties)) {\n // Check for unknown fields tracked by loader (stripped from property but saved in _unknownFields)\n const propertyUnknownFields = (property as { _unknownFields?: readonly string[] })._unknownFields;\n if (propertyUnknownFields && propertyUnknownFields.length > 0) {\n for (const field of propertyUnknownFields) {\n errors.push(\n validationError(\n `Property '${name}' has unknown field '${field}'`,\n buildLocation(schema.filePath),\n getSuggestionForUnknownField(field)\n )\n );\n }\n }\n\n // Check for unknown fields (errors for wrong type, warnings for completely unknown)\n const unknownFieldResult = validateUnknownFieldsDetailed(\n name,\n property,\n schema.filePath,\n options.customTypeDefinitions\n );\n errors.push(...unknownFieldResult.errors);\n warnings.push(...unknownFieldResult.warnings);\n\n // Check DB compatibility (errors and warnings)\n const dbCompat = validateDbCompatibility(name, property, schema.filePath, options.databaseDriver);\n errors.push(...dbCompat.errors);\n warnings.push(...dbCompat.warnings);\n\n // Validate rules field (if present)\n const rulesErrors = validateRules(name, property, schema.filePath);\n errors.push(...rulesErrors);\n }\n }\n\n // Validate localized strings (displayName, description)\n const localizedStringWarnings = validateLocalizedStrings(schema, options.localeConfig);\n warnings.push(...localizedStringWarnings);\n\n return {\n schemaName: schema.name,\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validates a collection of schemas.\n */\nexport function validateSchemas(\n schemas: SchemaCollection,\n options: ValidationOptions = {}\n): ValidationResult {\n const schemaResults: SchemaValidationResult[] = [];\n const allErrors: OmnifyError[] = [];\n const allWarnings: OmnifyError[] = [];\n const validateAssocs = options.validateAssociations ?? true;\n\n // First pass: validate each schema individually\n for (const schema of Object.values(schemas)) {\n const result = validateSchema(schema, options);\n schemaResults.push(result);\n allErrors.push(...result.errors);\n allWarnings.push(...result.warnings);\n }\n\n // Second pass: validate associations across schemas\n if (validateAssocs) {\n for (const schema of Object.values(schemas)) {\n const assocErrors = validateAssociations(schema, schemas);\n allErrors.push(...assocErrors);\n\n // Update the schema result\n const existingResult = schemaResults.find(r => r.schemaName === schema.name);\n if (existingResult && assocErrors.length > 0) {\n const updatedResult: SchemaValidationResult = {\n ...existingResult,\n valid: false,\n errors: [...existingResult.errors, ...assocErrors],\n };\n const index = schemaResults.indexOf(existingResult);\n schemaResults[index] = updatedResult;\n }\n }\n }\n\n // Third pass: validate partial schema targets\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'partial' && schema.target) {\n const targetExists = schemas[schema.target] !== undefined;\n if (!targetExists) {\n const error = validationError(\n `Partial schema '${schema.name}' targets non-existent schema '${schema.target}'`,\n buildLocation(schema.filePath),\n `Available schemas: ${Object.keys(schemas).filter(n => n !== schema.name).join(', ')}`\n );\n allErrors.push(error);\n\n // Update the schema result\n const existingResult = schemaResults.find(r => r.schemaName === schema.name);\n if (existingResult) {\n const updatedResult: SchemaValidationResult = {\n ...existingResult,\n valid: false,\n errors: [...existingResult.errors, error],\n };\n const index = schemaResults.indexOf(existingResult);\n schemaResults[index] = updatedResult;\n }\n }\n }\n }\n\n return {\n valid: allErrors.length === 0,\n errorCount: allErrors.length,\n warningCount: allWarnings.length,\n schemas: schemaResults,\n errors: allErrors,\n warnings: allWarnings,\n };\n}\n","/**\n * @famgia/omnify-core - Property Type Definition Base\n *\n * Base interface for all property type definitions.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport type { OmnifyError } from '../../errors/index.js';\nimport type { DatabaseDriver } from '../types.js';\n\n/**\n * Database compatibility level for a type.\n */\nexport type DbCompatibilityLevel = 'full' | 'limited' | 'unsupported';\n\n/**\n * Property type category for grouping.\n */\nexport type PropertyTypeCategory =\n | 'primitive'\n | 'text'\n | 'numeric'\n | 'temporal'\n | 'special'\n | 'enum'\n | 'relation';\n\n/**\n * Base fields valid for all property types.\n */\nexport const BASE_PROPERTY_FIELDS = [\n 'type',\n 'displayName',\n 'placeholder', // Placeholder for form inputs (supports multi-language)\n 'nullable',\n 'default',\n 'unique',\n 'primary', // Custom primary key (use with options.id: false)\n 'description',\n 'renamedFrom',\n 'rules', // Validation rules (application-level only)\n 'hidden', // Laravel: $hidden array\n 'fillable', // Laravel: $fillable array (default true)\n 'fields', // Per-field settings for compound types\n] as const;\n\n/**\n * Valid fields inside the 'rules' object.\n */\nexport const VALID_RULES_FIELDS = [\n 'required',\n 'minLength',\n 'maxLength',\n] as const;\n\n/**\n * Result of default value validation.\n */\nexport interface DefaultValueValidationResult {\n /** Whether the value is valid */\n readonly valid: boolean;\n /** Error message if invalid */\n readonly error?: string;\n}\n\n/**\n * Definition interface for a property type.\n * Each type implements this to self-describe its validation rules.\n */\nexport interface PropertyTypeDefinition {\n /** Type name (e.g., 'String', 'Decimal') */\n readonly name: string;\n\n /** Category for grouping */\n readonly category: PropertyTypeCategory;\n\n /** Fields valid for this type (includes BASE_PROPERTY_FIELDS) */\n readonly validFields: readonly string[];\n\n /** Fields required for this type */\n readonly requiredFields?: readonly string[];\n\n /** Database compatibility per driver */\n readonly dbCompatibility: Readonly<Record<DatabaseDriver, DbCompatibilityLevel>>;\n\n /** Default values for optional fields */\n readonly defaults?: Partial<PropertyDefinition>;\n\n /**\n * Validate type-specific rules.\n * Should not check type name or base fields - registry handles that.\n */\n validate(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n ): OmnifyError[];\n\n /**\n * Validate that a default value is appropriate for this type.\n * Returns validation result with error message if invalid.\n */\n validateDefaultValue?(\n value: unknown,\n property?: PropertyDefinition\n ): DefaultValueValidationResult;\n}\n\n/**\n * Helper to create valid fields array with base fields included.\n */\nexport function createValidFields(\n additionalFields: readonly string[]\n): readonly string[] {\n return [...BASE_PROPERTY_FIELDS, ...additionalFields];\n}\n\n/**\n * Helper to create full DB compatibility (supported on all drivers).\n */\nexport function fullDbCompatibility(): Readonly<Record<DatabaseDriver, DbCompatibilityLevel>> {\n return {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'full',\n sqlserver: 'full',\n };\n}\n","/**\n * @famgia/omnify-core - Type Registry\n *\n * Registry for property type definitions.\n * Provides centralized type lookup and validation.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport type { OmnifyError } from '../../errors/index.js';\nimport type { DatabaseDriver } from '../types.js';\nimport type {\n PropertyTypeDefinition,\n DbCompatibilityLevel,\n} from './base.js';\nimport { BASE_PROPERTY_FIELDS } from './base.js';\n\n/**\n * Registry for property type definitions.\n * Allows built-in and custom types to be registered and looked up.\n */\nexport class TypeRegistry {\n private readonly types = new Map<string, PropertyTypeDefinition>();\n\n /**\n * Register a type definition.\n */\n register(type: PropertyTypeDefinition): void {\n if (this.types.has(type.name)) {\n throw new Error(`Type '${type.name}' is already registered`);\n }\n this.types.set(type.name, type);\n }\n\n /**\n * Register multiple type definitions.\n */\n registerAll(types: readonly PropertyTypeDefinition[]): void {\n for (const type of types) {\n this.register(type);\n }\n }\n\n /**\n * Get a type definition by name.\n */\n get(name: string): PropertyTypeDefinition | undefined {\n return this.types.get(name);\n }\n\n /**\n * Check if a type is registered.\n */\n has(name: string): boolean {\n return this.types.has(name);\n }\n\n /**\n * Get valid fields for a type.\n * Returns base fields if type not found.\n */\n getValidFields(name: string): readonly string[] {\n const type = this.types.get(name);\n return type?.validFields ?? BASE_PROPERTY_FIELDS;\n }\n\n /**\n * Get database compatibility for a type.\n * Returns 'full' if type not found (custom types assumed compatible).\n */\n getDbCompatibility(\n name: string,\n driver: DatabaseDriver\n ): DbCompatibilityLevel {\n const type = this.types.get(name);\n return type?.dbCompatibility[driver] ?? 'full';\n }\n\n /**\n * Get default values for a type.\n */\n getDefaults(name: string): Partial<PropertyDefinition> | undefined {\n return this.types.get(name)?.defaults;\n }\n\n /**\n * Validate a property using its type's validator.\n * Returns empty array if type not found (validation handled elsewhere).\n */\n validateProperty(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n ): OmnifyError[] {\n const type = this.types.get(property.type);\n if (!type) {\n return [];\n }\n return type.validate(propertyName, property, filePath);\n }\n\n /**\n * Get all registered type names.\n */\n getAllTypeNames(): readonly string[] {\n return [...this.types.keys()];\n }\n\n /**\n * Get all valid fields across ALL types.\n * Used to determine if a field is valid for any type.\n */\n getAllValidFields(): ReadonlySet<string> {\n const allFields = new Set<string>();\n for (const type of this.types.values()) {\n for (const field of type.validFields) {\n allFields.add(field);\n }\n }\n return allFields;\n }\n\n /**\n * Check if a field is valid for any registered type.\n */\n isFieldValidForAnyType(field: string): boolean {\n for (const type of this.types.values()) {\n if (type.validFields.includes(field)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get count of registered types.\n */\n get size(): number {\n return this.types.size;\n }\n\n /**\n * Clear all registered types.\n * Useful for testing.\n */\n clear(): void {\n this.types.clear();\n }\n}\n\n/**\n * Global type registry instance.\n * Pre-populated with built-in types.\n */\nexport const typeRegistry = new TypeRegistry();\n","/**\n * @famgia/omnify-core - Primitive Types\n *\n * Boolean type definition.\n */\n\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate boolean default value.\n */\nfunction validateBooleanDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value).toLowerCase();\n if (!['true', 'false', '1', '0'].includes(strValue)) {\n return { valid: false, error: 'Must be true or false' };\n }\n return { valid: true };\n}\n\n/**\n * Boolean type - true/false values.\n */\nexport const BooleanType: PropertyTypeDefinition = {\n name: 'Boolean',\n category: 'primitive',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n // Boolean has no type-specific validation\n return [];\n },\n\n validateDefaultValue: validateBooleanDefault,\n};\n\n/**\n * All primitive types.\n */\nexport const primitiveTypes: readonly PropertyTypeDefinition[] = [\n BooleanType,\n];\n","/**\n * @famgia/omnify-core - Text Types\n *\n * String, Text, LongText, Email, Password type definitions.\n */\n\nimport type { PropertyDefinition } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * No validation needed for text default values (any string is valid).\n */\nfunction validateTextDefault(): DefaultValueValidationResult {\n return { valid: true };\n}\n\n/**\n * Validate email default value.\n */\nfunction validateEmailDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return { valid: false, error: 'Must be a valid email address' };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Validate length field (database column size only).\n * minLength/maxLength are now in rules field, validated separately.\n */\nfunction validateLength(\n propertyName: string,\n property: PropertyDefinition,\n filePath: string\n) {\n const errors = [];\n const { length } = property as { length?: unknown };\n\n // Validate length (database column size)\n if (length !== undefined) {\n if (typeof length !== 'number' || length < 1 || length > 65535) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid length '${length}'`,\n buildLocation(filePath),\n 'length must be a positive number between 1 and 65535'\n )\n );\n }\n }\n\n return errors;\n}\n\n/**\n * String type - variable length text with optional length constraint.\n */\nexport const StringType: PropertyTypeDefinition = {\n name: 'String',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n defaults: {\n // Default length depends on database, handled by generator\n },\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * Text type - longer text without length constraint.\n */\nexport const TextType: PropertyTypeDefinition = {\n name: 'Text',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * MediumText type - medium length text (MEDIUMTEXT in MySQL, TEXT in PostgreSQL).\n */\nexport const MediumTextType: PropertyTypeDefinition = {\n name: 'MediumText',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * LongText type - very long text (LONGTEXT in MySQL, TEXT in PostgreSQL).\n */\nexport const LongTextType: PropertyTypeDefinition = {\n name: 'LongText',\n category: 'text',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'full',\n sqlserver: 'limited', // Uses NVARCHAR(MAX)\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * Email type - string with email format validation.\n */\nexport const EmailType: PropertyTypeDefinition = {\n name: 'Email',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateEmailDefault,\n};\n\n/**\n * Password type - string for password storage (hashed).\n */\nexport const PasswordType: PropertyTypeDefinition = {\n name: 'Password',\n category: 'text',\n validFields: createValidFields(['length']),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n return validateLength(propertyName, property, filePath);\n },\n\n validateDefaultValue: validateTextDefault,\n};\n\n/**\n * All text types.\n */\nexport const textTypes: readonly PropertyTypeDefinition[] = [\n StringType,\n TextType,\n MediumTextType,\n LongTextType,\n EmailType,\n PasswordType,\n];\n","/**\n * @famgia/omnify-core - Numeric Types\n *\n * Int, BigInt, Float, Decimal type definitions.\n */\n\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate integer default value.\n */\nfunction validateIntegerDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^-?\\d+$/.test(strValue)) {\n return { valid: false, error: 'Must be an integer' };\n }\n return { valid: true };\n}\n\n/**\n * Validate float/decimal default value.\n */\nfunction validateNumberDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^-?\\d+(\\.\\d+)?$/.test(strValue)) {\n return { valid: false, error: 'Must be a number' };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * TinyInt type - 8-bit integer (-128 to 127, or 0 to 255 if unsigned).\n */\nexport const TinyIntType: PropertyTypeDefinition = {\n name: 'TinyInt',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * Int type - 32-bit integer.\n */\nexport const IntType: PropertyTypeDefinition = {\n name: 'Int',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * BigInt type - 64-bit integer.\n */\nexport const BigIntType: PropertyTypeDefinition = {\n name: 'BigInt',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateIntegerDefault,\n};\n\n/**\n * Float type - floating point number.\n */\nexport const FloatType: PropertyTypeDefinition = {\n name: 'Float',\n category: 'numeric',\n validFields: createValidFields(['unsigned']),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateNumberDefault,\n};\n\n/**\n * Decimal type - precise decimal number with precision and scale.\n */\nexport const DecimalType: PropertyTypeDefinition = {\n name: 'Decimal',\n category: 'numeric',\n validFields: createValidFields(['precision', 'scale', 'unsigned']),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as REAL, loses precision\n sqlserver: 'full',\n },\n defaults: {\n // precision: 8, scale: 2 - handled by generator\n },\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { precision, scale } = property as { precision?: unknown; scale?: unknown };\n\n // Validate precision\n if (precision !== undefined) {\n if (typeof precision !== 'number' || precision < 1 || precision > 65) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid precision '${precision}'`,\n buildLocation(filePath),\n 'precision must be a number between 1 and 65'\n )\n );\n }\n }\n\n // Validate scale\n if (scale !== undefined) {\n if (typeof scale !== 'number' || scale < 0 || scale > 30) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid scale '${scale}'`,\n buildLocation(filePath),\n 'scale must be a number between 0 and 30'\n )\n );\n }\n\n // Scale cannot be greater than precision\n const effectivePrecision = typeof precision === 'number' ? precision : 8;\n if (typeof scale === 'number' && scale > effectivePrecision) {\n errors.push(\n validationError(\n `Property '${propertyName}' has scale (${scale}) greater than precision (${effectivePrecision})`,\n buildLocation(filePath),\n 'scale cannot be greater than precision'\n )\n );\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateNumberDefault,\n};\n\n/**\n * All numeric types.\n */\nexport const numericTypes: readonly PropertyTypeDefinition[] = [\n TinyIntType,\n IntType,\n BigIntType,\n FloatType,\n DecimalType,\n];\n","/**\n * @famgia/omnify-core - Temporal Types\n *\n * Date, Time, DateTime, Timestamp type definitions.\n */\n\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Validate date default value (YYYY-MM-DD format).\n */\nfunction validateDateDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(strValue)) {\n return { valid: false, error: 'Must be in YYYY-MM-DD format' };\n }\n return { valid: true };\n}\n\n/**\n * Validate time default value (HH:MM or HH:MM:SS format).\n */\nfunction validateTimeDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n if (!/^\\d{2}:\\d{2}(:\\d{2})?$/.test(strValue)) {\n return { valid: false, error: 'Must be in HH:MM or HH:MM:SS format' };\n }\n return { valid: true };\n}\n\n/**\n * Validate datetime/timestamp default value (YYYY-MM-DD HH:MM:SS format).\n */\nfunction validateTimestampDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n // Accept ISO format (T separator) or space separator\n if (!/^\\d{4}-\\d{2}-\\d{2}(T|\\s)\\d{2}:\\d{2}(:\\d{2})?/.test(strValue)) {\n return { valid: false, error: 'Must be in YYYY-MM-DD HH:MM:SS format' };\n }\n return { valid: true };\n}\n\n/**\n * Date type - date without time.\n */\nexport const DateType: PropertyTypeDefinition = {\n name: 'Date',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateDateDefault,\n};\n\n/**\n * Time type - time without date.\n */\nexport const TimeType: PropertyTypeDefinition = {\n name: 'Time',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as TEXT\n sqlserver: 'full',\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimeDefault,\n};\n\n/**\n * DateTime type - date with time.\n */\nexport const DateTimeType: PropertyTypeDefinition = {\n name: 'DateTime',\n category: 'temporal',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimestampDefault,\n};\n\n/**\n * Timestamp type - Unix timestamp or database timestamp.\n */\nexport const TimestampType: PropertyTypeDefinition = {\n name: 'Timestamp',\n category: 'temporal',\n validFields: createValidFields(['useCurrent', 'useCurrentOnUpdate']),\n dbCompatibility: {\n mysql: 'full',\n postgres: 'full',\n sqlite: 'limited', // Stored as INTEGER or TEXT\n sqlserver: 'full',\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateTimestampDefault,\n};\n\n/**\n * All temporal types.\n */\nexport const temporalTypes: readonly PropertyTypeDefinition[] = [\n DateType,\n TimeType,\n DateTimeType,\n TimestampType,\n];\n","/**\n * @famgia/omnify-core - Special Types\n *\n * Json, Uuid, File type definitions.\n */\n\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Valid fields for File type.\n */\nconst FILE_VALID_FIELDS = ['multiple', 'maxFiles', 'accept', 'maxSize'] as const;\n\n/**\n * Validate JSON default value.\n */\nfunction validateJsonDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n try {\n JSON.parse(strValue);\n return { valid: true };\n } catch {\n return { valid: false, error: 'Must be valid JSON' };\n }\n}\n\n/**\n * Validate UUID default value.\n */\nfunction validateUuidDefault(value: unknown): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const strValue = String(value);\n // UUID v4 format\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(strValue)) {\n return { valid: false, error: 'Must be a valid UUID' };\n }\n return { valid: true };\n}\n\n/**\n * No validation needed for file default values.\n */\nfunction validateFileDefault(): DefaultValueValidationResult {\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Json type - JSON data stored as text.\n */\nexport const JsonType: PropertyTypeDefinition = {\n name: 'Json',\n category: 'special',\n validFields: createValidFields([]),\n dbCompatibility: {\n mysql: 'full', // Native JSON type\n postgres: 'full', // Native JSONB type\n sqlite: 'limited', // Stored as TEXT\n sqlserver: 'limited', // Stored as NVARCHAR(MAX)\n },\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateJsonDefault,\n};\n\n/**\n * Uuid type - UUID/GUID string.\n */\nexport const UuidType: PropertyTypeDefinition = {\n name: 'Uuid',\n category: 'special',\n validFields: createValidFields([]),\n dbCompatibility: fullDbCompatibility(),\n\n validate() {\n return [];\n },\n\n validateDefaultValue: validateUuidDefault,\n};\n\n/**\n * File type - polymorphic file attachment.\n * Creates morphOne (single) or morphMany (multiple) relationship to files table.\n */\nexport const FileType: PropertyTypeDefinition = {\n name: 'File',\n category: 'special',\n validFields: createValidFields(FILE_VALID_FIELDS),\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const {\n multiple,\n maxFiles,\n accept,\n maxSize,\n } = property as {\n multiple?: unknown;\n maxFiles?: unknown;\n accept?: unknown;\n maxSize?: unknown;\n };\n\n // Validate multiple\n if (multiple !== undefined && typeof multiple !== 'boolean') {\n errors.push(\n validationError(\n `Property '${propertyName}' multiple must be a boolean`,\n buildLocation(filePath)\n )\n );\n }\n\n // Validate maxFiles\n if (maxFiles !== undefined) {\n if (!multiple) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxFiles is only valid when multiple=true`,\n buildLocation(filePath),\n 'Add multiple: true or remove maxFiles'\n )\n );\n } else if (typeof maxFiles !== 'number' || maxFiles < 1 || !Number.isInteger(maxFiles)) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxFiles must be a positive integer`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n // Validate accept\n if (accept !== undefined) {\n if (!Array.isArray(accept)) {\n errors.push(\n validationError(\n `Property '${propertyName}' accept must be an array of file extensions`,\n buildLocation(filePath),\n 'Example: accept: [jpg, png, pdf]'\n )\n );\n } else {\n for (const ext of accept) {\n if (typeof ext !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' accept array contains non-string value`,\n buildLocation(filePath)\n )\n );\n break;\n }\n }\n }\n }\n\n // Validate maxSize\n if (maxSize !== undefined) {\n if (typeof maxSize !== 'number' || maxSize < 1 || !Number.isInteger(maxSize)) {\n errors.push(\n validationError(\n `Property '${propertyName}' maxSize must be a positive integer (KB)`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateFileDefault,\n};\n\n/**\n * All special types.\n */\nexport const specialTypes: readonly PropertyTypeDefinition[] = [\n JsonType,\n UuidType,\n FileType,\n];\n","/**\n * @famgia/omnify-core - Enum Types\n *\n * Enum, EnumRef type definitions.\n */\n\nimport type { PropertyDefinition, InlineEnumValue } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { DefaultValueValidationResult, PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Type guard for InlineEnumValue object.\n */\nfunction isInlineEnumValue(value: unknown): value is InlineEnumValue {\n return typeof value === 'object' && value !== null && 'value' in value;\n}\n\n/**\n * Extracts the string value from an enum value (string or object).\n */\nfunction getEnumStringValue(value: string | InlineEnumValue): string {\n return typeof value === 'string' ? value : value.value;\n}\n\n/**\n * Validate enum default value.\n */\nfunction validateEnumDefault(\n value: unknown,\n property?: PropertyDefinition\n): DefaultValueValidationResult {\n if (value === undefined || value === null || value === '') {\n return { valid: true };\n }\n const enumValues = (property as { enum?: readonly (string | InlineEnumValue)[] })?.enum;\n if (!enumValues || !Array.isArray(enumValues)) {\n return { valid: true }; // No enum values to validate against\n }\n const strValue = String(value);\n const validValues = enumValues.map(getEnumStringValue);\n if (!validValues.includes(strValue)) {\n return {\n valid: false,\n error: `Must be one of: ${validValues.join(', ')}`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Enum type - fixed set of string values.\n */\nexport const EnumType: PropertyTypeDefinition = {\n name: 'Enum',\n category: 'enum',\n validFields: createValidFields(['enum']),\n requiredFields: ['enum'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { enum: enumValues } = property as { enum?: unknown };\n\n if (enumValues === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Enum' requires 'enum' field`,\n buildLocation(filePath),\n 'Add enum values: enum: [value1, value2]'\n )\n );\n } else if (!Array.isArray(enumValues)) {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field must be an array`,\n buildLocation(filePath),\n 'enum: [value1, value2]'\n )\n );\n } else if (enumValues.length === 0) {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field cannot be empty`,\n buildLocation(filePath),\n 'Add at least one enum value'\n )\n );\n } else {\n // Check for duplicate values - supports both string and object format\n const seen = new Set<string>();\n for (const value of enumValues) {\n // Accept both string and object with value field\n if (typeof value === 'string') {\n if (seen.has(value)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has duplicate enum value '${value}'`,\n buildLocation(filePath)\n )\n );\n } else {\n seen.add(value);\n }\n } else if (isInlineEnumValue(value)) {\n // Object format: { value, label?, extra? }\n if (typeof value.value !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum value.value must be a string`,\n buildLocation(filePath),\n 'Use format: { value: \"string\", label: \"Display Label\" }'\n )\n );\n } else if (seen.has(value.value)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has duplicate enum value '${value.value}'`,\n buildLocation(filePath)\n )\n );\n } else {\n seen.add(value.value);\n }\n } else {\n errors.push(\n validationError(\n `Property '${propertyName}' enum values must be strings or objects with 'value' field`,\n buildLocation(filePath),\n 'Use: \"value\" or { value: \"value\", label: \"Label\" }'\n )\n );\n }\n }\n }\n\n return errors;\n },\n\n validateDefaultValue: validateEnumDefault,\n};\n\n/**\n * EnumRef type - reference to shared enum schema.\n */\nexport const EnumRefType: PropertyTypeDefinition = {\n name: 'EnumRef',\n category: 'enum',\n validFields: createValidFields(['enum']),\n requiredFields: ['enum'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const { enum: enumRef } = property as { enum?: unknown };\n\n if (enumRef === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'EnumRef' requires 'enum' field`,\n buildLocation(filePath),\n 'Add enum schema reference: enum: EnumSchemaName'\n )\n );\n } else if (typeof enumRef !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field must be a string (enum schema name)`,\n buildLocation(filePath),\n 'enum: EnumSchemaName'\n )\n );\n } else if (enumRef.trim() === '') {\n errors.push(\n validationError(\n `Property '${propertyName}' enum field cannot be empty`,\n buildLocation(filePath),\n 'Add enum schema name'\n )\n );\n }\n\n return errors;\n },\n\n // EnumRef default value validation requires schema context\n // This is handled at a higher level (validator.ts) where schemas are available\n validateDefaultValue: () => ({ valid: true }),\n};\n\n/**\n * All enum types.\n */\nexport const enumTypes: readonly PropertyTypeDefinition[] = [\n EnumType,\n EnumRefType,\n];\n","/**\n * @famgia/omnify-core - Relation Types\n *\n * Association, Polymorphic type definitions.\n */\n\nimport type { AssociationRelation } from '@famgia/omnify-types';\nimport { validationError } from '../../errors/index.js';\nimport type { PropertyTypeDefinition } from './base.js';\nimport { createValidFields, fullDbCompatibility } from './base.js';\n\n/**\n * Helper to build ErrorLocation safely.\n */\nfunction buildLocation(file: string) {\n return { file };\n}\n\n/**\n * Valid association relation types.\n */\nconst VALID_RELATIONS: readonly AssociationRelation[] = [\n 'OneToOne',\n 'OneToMany',\n 'ManyToOne',\n 'ManyToMany',\n // Polymorphic relations\n 'MorphTo',\n 'MorphOne',\n 'MorphMany',\n 'MorphToMany',\n 'MorphedByMany',\n];\n\n/**\n * Polymorphic relation types that use 'targets' instead of 'target'.\n */\nconst MORPH_TO_RELATIONS: readonly AssociationRelation[] = ['MorphTo'];\n\n/**\n * Polymorphic relation types that require 'morphName' pointing to MorphTo on target.\n * Note: MorphedByMany uses optional morphName for pivot table naming only.\n */\nconst MORPH_INVERSE_RELATIONS: readonly AssociationRelation[] = [\n 'MorphOne',\n 'MorphMany',\n];\n\n/**\n * Valid referential actions for foreign keys.\n */\nconst VALID_REFERENTIAL_ACTIONS = [\n 'CASCADE',\n 'SET NULL',\n 'SET DEFAULT',\n 'RESTRICT',\n 'NO ACTION',\n] as const;\n\n/**\n * Relation types that support pivot tables (and thus pivot fields).\n */\nconst PIVOT_TABLE_RELATIONS: readonly AssociationRelation[] = [\n 'ManyToMany',\n 'MorphToMany',\n];\n\n/**\n * Valid types for pivot fields (basic types only, no Association).\n */\nconst VALID_PIVOT_FIELD_TYPES = [\n 'String',\n 'Int',\n 'BigInt',\n 'Float',\n 'Decimal',\n 'Boolean',\n 'Text',\n 'Date',\n 'Time',\n 'Timestamp',\n 'Json',\n] as const;\n\n/**\n * Association fields.\n */\nconst ASSOCIATION_FIELDS = [\n 'relation',\n 'target',\n 'targets', // For MorphTo: array of target schema names\n 'morphName', // For MorphOne/MorphMany/MorphedByMany: polymorphic name\n 'inversedBy',\n 'mappedBy',\n 'onDelete',\n 'onUpdate',\n 'owning',\n 'joinTable',\n 'pivotFields', // For ManyToMany/MorphToMany: additional fields on pivot table\n] as const;\n\n/**\n * Association type - relationship to another schema.\n */\nexport const AssociationType: PropertyTypeDefinition = {\n name: 'Association',\n category: 'relation',\n validFields: createValidFields(ASSOCIATION_FIELDS),\n requiredFields: ['relation'],\n dbCompatibility: fullDbCompatibility(),\n\n validate(propertyName, property, filePath) {\n const errors = [];\n const {\n relation,\n target,\n targets,\n morphName,\n onDelete,\n onUpdate,\n } = property as {\n relation?: unknown;\n target?: unknown;\n targets?: unknown;\n morphName?: unknown;\n onDelete?: unknown;\n onUpdate?: unknown;\n };\n\n // Validate required field: relation\n if (relation === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Association' requires 'relation' field`,\n buildLocation(filePath),\n 'Add relation: OneToOne, OneToMany, ManyToOne, ManyToMany, MorphTo, MorphOne, MorphMany, MorphToMany, or MorphedByMany'\n )\n );\n return errors;\n }\n\n if (typeof relation !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' relation field must be a string`,\n buildLocation(filePath)\n )\n );\n return errors;\n }\n\n if (!VALID_RELATIONS.includes(relation as AssociationRelation)) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid relation '${relation}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_RELATIONS.join(', ')}`\n )\n );\n return errors;\n }\n\n const relationTyped = relation as AssociationRelation;\n\n // Validate based on relation type\n if (MORPH_TO_RELATIONS.includes(relationTyped)) {\n // MorphTo: requires 'targets' array, not 'target'\n if (targets === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphTo' requires 'targets' field`,\n buildLocation(filePath),\n 'Add targets: [Post, Video, Image]'\n )\n );\n } else if (!Array.isArray(targets)) {\n errors.push(\n validationError(\n `Property '${propertyName}' targets field must be an array of schema names`,\n buildLocation(filePath),\n 'Example: targets: [Post, Video, Image]'\n )\n );\n } else if (targets.length === 0) {\n errors.push(\n validationError(\n `Property '${propertyName}' targets array cannot be empty`,\n buildLocation(filePath),\n 'Add at least one target schema'\n )\n );\n } else {\n // Validate each target is a string\n for (const t of targets) {\n if (typeof t !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' targets array contains non-string value`,\n buildLocation(filePath)\n )\n );\n }\n }\n }\n\n // MorphTo should not have 'target'\n if (target !== undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphTo' should use 'targets' (plural) not 'target'`,\n buildLocation(filePath),\n 'Change target to targets array'\n )\n );\n }\n } else if (MORPH_INVERSE_RELATIONS.includes(relationTyped)) {\n // MorphOne/MorphMany: requires 'target' and 'morphName' pointing to MorphTo property\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Comment'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n\n if (morphName === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' requires 'morphName' field`,\n buildLocation(filePath),\n 'Add morphName to match the MorphTo property name (e.g., morphName: commentable)'\n )\n );\n } else if (typeof morphName !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' morphName field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else if (relationTyped === 'MorphToMany') {\n // MorphToMany: requires 'target', optional 'joinTable'\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphToMany' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Tag'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else if (relationTyped === 'MorphedByMany') {\n // MorphedByMany: requires 'target', optional 'morphName' for pivot table naming\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation 'MorphedByMany' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: Post'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n // morphName is optional for MorphedByMany (used for pivot table naming)\n if (morphName !== undefined && typeof morphName !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' morphName field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n } else {\n // Standard relations: OneToOne, OneToMany, ManyToOne, ManyToMany\n if (target === undefined) {\n errors.push(\n validationError(\n `Property '${propertyName}' of type 'Association' requires 'target' field`,\n buildLocation(filePath),\n 'Add target schema name: target: User'\n )\n );\n } else if (typeof target !== 'string') {\n errors.push(\n validationError(\n `Property '${propertyName}' target field must be a string`,\n buildLocation(filePath)\n )\n );\n }\n }\n\n // Validate referential actions (only for owning side relations)\n if (onDelete !== undefined && typeof onDelete === 'string') {\n if (!VALID_REFERENTIAL_ACTIONS.includes(onDelete as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid onDelete action '${onDelete}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n if (onUpdate !== undefined && typeof onUpdate === 'string') {\n if (!VALID_REFERENTIAL_ACTIONS.includes(onUpdate as typeof VALID_REFERENTIAL_ACTIONS[number])) {\n errors.push(\n validationError(\n `Property '${propertyName}' has invalid onUpdate action '${onUpdate}'`,\n buildLocation(filePath),\n `Use one of: ${VALID_REFERENTIAL_ACTIONS.join(', ')}`\n )\n );\n }\n }\n\n // Validate pivotFields (only for ManyToMany and MorphToMany)\n const pivotFields = (property as { pivotFields?: unknown }).pivotFields;\n if (pivotFields !== undefined) {\n if (!PIVOT_TABLE_RELATIONS.includes(relationTyped)) {\n errors.push(\n validationError(\n `Property '${propertyName}' with relation '${relation}' cannot have pivotFields`,\n buildLocation(filePath),\n 'pivotFields is only allowed for ManyToMany and MorphToMany relations'\n )\n );\n } else if (typeof pivotFields !== 'object' || pivotFields === null || Array.isArray(pivotFields)) {\n errors.push(\n validationError(\n `Property '${propertyName}' pivotFields must be an object`,\n buildLocation(filePath),\n 'Example: pivotFields: { assigned_at: { type: \"Timestamp\" } }'\n )\n );\n } else {\n // Validate each pivot field\n for (const [fieldName, fieldDef] of Object.entries(pivotFields)) {\n if (typeof fieldDef !== 'object' || fieldDef === null) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' must be an object`,\n buildLocation(filePath)\n )\n );\n continue;\n }\n\n const { type: fieldType } = fieldDef as { type?: unknown };\n if (fieldType === undefined) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' requires 'type' field`,\n buildLocation(filePath),\n `Example: ${fieldName}: { type: \"String\" }`\n )\n );\n } else if (typeof fieldType !== 'string') {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' type must be a string`,\n buildLocation(filePath)\n )\n );\n } else if (fieldType === 'Association') {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' cannot be of type 'Association'`,\n buildLocation(filePath),\n 'Pivot fields only support basic types like String, Int, Boolean, Timestamp, etc.'\n )\n );\n } else if (!VALID_PIVOT_FIELD_TYPES.includes(fieldType as typeof VALID_PIVOT_FIELD_TYPES[number])) {\n errors.push(\n validationError(\n `Pivot field '${fieldName}' in '${propertyName}' has unsupported type '${fieldType}'`,\n buildLocation(filePath),\n `Supported types: ${VALID_PIVOT_FIELD_TYPES.join(', ')}`\n )\n );\n }\n }\n }\n }\n\n return errors;\n },\n};\n\n/**\n * All relation types.\n */\nexport const relationTypes: readonly PropertyTypeDefinition[] = [\n AssociationType,\n];\n\n/**\n * Export constants for use in cross-schema validation.\n */\nexport { VALID_RELATIONS, VALID_REFERENTIAL_ACTIONS };\n","/**\n * @famgia/omnify-core - Property Type Definitions\n *\n * Exports all property type definitions and the type registry.\n */\n\n// Base interface and helpers\nexport type {\n PropertyTypeDefinition,\n PropertyTypeCategory,\n DbCompatibilityLevel,\n DefaultValueValidationResult,\n} from './base.js';\nexport { BASE_PROPERTY_FIELDS, VALID_RULES_FIELDS, createValidFields, fullDbCompatibility } from './base.js';\n\n// Registry\nexport { TypeRegistry, typeRegistry } from './registry.js';\n\n// Type definitions by category\nexport { BooleanType, primitiveTypes } from './primitives.js';\nexport {\n StringType,\n TextType,\n MediumTextType,\n LongTextType,\n EmailType,\n PasswordType,\n textTypes,\n} from './text.js';\nexport {\n TinyIntType,\n IntType,\n BigIntType,\n FloatType,\n DecimalType,\n numericTypes,\n} from './numeric.js';\nexport {\n DateType,\n TimeType,\n DateTimeType,\n TimestampType,\n temporalTypes,\n} from './temporal.js';\nexport {\n JsonType,\n UuidType,\n FileType,\n specialTypes,\n} from './special.js';\nexport {\n EnumType,\n EnumRefType,\n enumTypes,\n} from './enum.js';\nexport {\n AssociationType,\n relationTypes,\n VALID_RELATIONS,\n VALID_REFERENTIAL_ACTIONS,\n} from './relations.js';\n\n// Import for registration\nimport { typeRegistry } from './registry.js';\nimport { primitiveTypes } from './primitives.js';\nimport { textTypes } from './text.js';\nimport { numericTypes } from './numeric.js';\nimport { temporalTypes } from './temporal.js';\nimport { specialTypes } from './special.js';\nimport { enumTypes } from './enum.js';\nimport { relationTypes } from './relations.js';\n\n/**\n * All built-in types grouped by category.\n */\nexport const allBuiltInTypes = [\n ...primitiveTypes,\n ...textTypes,\n ...numericTypes,\n ...temporalTypes,\n ...specialTypes,\n ...enumTypes,\n ...relationTypes,\n] as const;\n\n/**\n * Register all built-in types with the global registry.\n */\nfunction registerBuiltInTypes(): void {\n for (const type of allBuiltInTypes) {\n if (!typeRegistry.has(type.name)) {\n typeRegistry.register(type);\n }\n }\n}\n\n// Auto-register on import\nregisterBuiltInTypes();\n\n/**\n * Validate a default value for a given type.\n *\n * @param typeName - The type name (e.g., 'Int', 'String', 'Enum')\n * @param value - The default value to validate\n * @param property - Optional property definition for context (needed for Enum/Select)\n * @returns Validation result with valid flag and optional error message\n */\nexport function validateDefaultValue(\n typeName: string,\n value: unknown,\n property?: { enum?: readonly string[]; options?: unknown[] }\n): { valid: boolean; error?: string } {\n const typeDef = typeRegistry.get(typeName);\n if (!typeDef) {\n return { valid: true }; // Unknown type, skip validation\n }\n\n if (typeDef.validateDefaultValue) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeDef.validateDefaultValue(value, property as any);\n }\n\n return { valid: true }; // No validator for this type\n}\n","/**\n * @famgia/omnify-core - Generator Runner\n *\n * Executes generators in topological order based on dependencies (DAG).\n */\n\nimport type { SchemaCollection, PluginLogger, GeneratorOutput, CustomTypeDefinition, PluginEnumDefinition, SchemaChange, LocaleConfig } from '@famgia/omnify-types';\nimport type { RegisteredGenerator, GeneratorContext } from './types.js';\n\n/**\n * Result of running all generators.\n */\nexport interface GeneratorRunResult {\n /** Whether all generators succeeded */\n success: boolean;\n /** All generated outputs */\n outputs: GeneratorOutput[];\n /** Outputs grouped by generator name */\n outputsByGenerator: ReadonlyMap<string, GeneratorOutput[]>;\n /** Execution order (topological) */\n executionOrder: string[];\n /** Errors if any */\n errors: GeneratorError[];\n}\n\n/**\n * Error from generator execution.\n */\nexport interface GeneratorError {\n /** Generator name */\n generatorName: string;\n /** Error message */\n message: string;\n /** Original error */\n cause?: unknown;\n}\n\n/**\n * Options for generator runner.\n */\nexport interface GeneratorRunnerOptions {\n /** Current working directory */\n cwd: string;\n /** Logger for output */\n logger: PluginLogger;\n /** Custom types registered by all plugins */\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>;\n /** Enums registered by all plugins */\n pluginEnums?: ReadonlyMap<string, PluginEnumDefinition>;\n /** Locale configuration for multi-language support */\n localeConfig?: LocaleConfig;\n}\n\n/**\n * Generator Runner - executes generators in DAG order.\n */\nexport class GeneratorRunner {\n private generators = new Map<string, RegisteredGenerator>();\n private readonly options: GeneratorRunnerOptions;\n\n constructor(options: GeneratorRunnerOptions) {\n this.options = options;\n }\n\n /**\n * Register a generator.\n */\n register(generator: RegisteredGenerator): void {\n const name = generator.definition.name;\n if (this.generators.has(name)) {\n throw new Error(`Generator \"${name}\" is already registered`);\n }\n this.generators.set(name, generator);\n }\n\n /**\n * Register multiple generators.\n */\n registerAll(generators: RegisteredGenerator[]): void {\n for (const gen of generators) {\n this.register(gen);\n }\n }\n\n /**\n * Clear all registered generators.\n */\n clear(): void {\n this.generators.clear();\n }\n\n /**\n * Get all registered generator names.\n */\n getGeneratorNames(): string[] {\n return Array.from(this.generators.keys());\n }\n\n /**\n * Check if a generator is registered.\n */\n hasGenerator(name: string): boolean {\n return this.generators.has(name);\n }\n\n /**\n * Run all generators in topological order.\n * @param schemas - The schemas to generate from\n * @param changes - Schema changes detected from lock file comparison\n */\n async runAll(\n schemas: SchemaCollection,\n changes?: readonly SchemaChange[]\n ): Promise<GeneratorRunResult> {\n const errors: GeneratorError[] = [];\n const outputs: GeneratorOutput[] = [];\n const outputsByGenerator = new Map<string, GeneratorOutput[]>();\n\n // Get topological order\n let executionOrder: string[];\n try {\n executionOrder = this.topologicalSort();\n } catch (error) {\n return {\n success: false,\n outputs: [],\n outputsByGenerator: new Map(),\n executionOrder: [],\n errors: [{\n generatorName: '',\n message: error instanceof Error ? error.message : String(error),\n cause: error,\n }],\n };\n }\n\n // Track outputs from each generator for dependencies\n const previousOutputs = new Map<string, readonly GeneratorOutput[]>();\n\n // Run generators in order\n for (const name of executionOrder) {\n const generator = this.generators.get(name)!;\n const { definition, pluginConfig } = generator;\n\n try {\n this.options.logger.debug(`Running generator: ${name}`);\n\n // Build context\n const ctx: GeneratorContext = {\n schemas,\n changes,\n pluginConfig,\n cwd: this.options.cwd,\n logger: this.options.logger,\n previousOutputs,\n customTypes: this.options.customTypes ?? new Map(),\n pluginEnums: this.options.pluginEnums ?? new Map(),\n localeConfig: this.options.localeConfig,\n };\n\n // Execute generator\n const result = await definition.generate(ctx);\n const generatorOutputs = Array.isArray(result) ? result : [result];\n\n // Store outputs\n outputsByGenerator.set(name, generatorOutputs);\n previousOutputs.set(name, generatorOutputs);\n outputs.push(...generatorOutputs);\n\n this.options.logger.debug(`Generator ${name} produced ${generatorOutputs.length} outputs`);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.options.logger.error(`Generator ${name} failed: ${message}`);\n errors.push({\n generatorName: name,\n message,\n cause: error,\n });\n }\n }\n\n return {\n success: errors.length === 0,\n outputs,\n outputsByGenerator,\n executionOrder,\n errors,\n };\n }\n\n /**\n * Topological sort using Kahn's algorithm.\n * Returns generators in execution order (dependencies first).\n * Throws if circular dependencies detected.\n */\n private topologicalSort(): string[] {\n const names = Array.from(this.generators.keys());\n\n // Build adjacency list and in-degree count\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n // Initialize\n for (const name of names) {\n inDegree.set(name, 0);\n adjacency.set(name, []);\n }\n\n // Build graph\n for (const name of names) {\n const generator = this.generators.get(name)!;\n const deps = generator.definition.dependsOn ?? [];\n\n for (const dep of deps) {\n if (!this.generators.has(dep)) {\n throw new Error(\n `Generator \"${name}\" depends on \"${dep}\" which is not registered`\n );\n }\n // dep -> name (dep must run before name)\n adjacency.get(dep)!.push(name);\n inDegree.set(name, inDegree.get(name)! + 1);\n }\n }\n\n // Kahn's algorithm\n const queue: string[] = [];\n const result: string[] = [];\n\n // Start with generators that have no dependencies\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n result.push(current);\n\n for (const neighbor of adjacency.get(current)!) {\n const newDegree = inDegree.get(neighbor)! - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Check for cycles\n if (result.length !== names.length) {\n const remaining = names.filter(n => !result.includes(n));\n throw new Error(\n `Circular dependency detected among generators: ${remaining.join(', ')}`\n );\n }\n\n return result;\n }\n}\n","/**\n * @famgia/omnify-core - Plugin Manager\n *\n * Manages plugin registration and type resolution.\n */\n\nimport type {\n OmnifyPlugin,\n CustomTypeDefinition,\n PluginEnumDefinition,\n PluginContext,\n PluginLogger,\n SchemaCollection,\n SchemaChange,\n} from '@famgia/omnify-types';\nimport type {\n RegisteredType,\n RegisteredGenerator,\n PluginRegistry,\n PluginManagerOptions,\n PluginRegistrationResult,\n} from './types.js';\nimport { pluginError, pluginTypeConflictError, pluginNotFoundError } from '../errors/index.js';\nimport { GeneratorRunner, type GeneratorRunResult } from './generator-runner.js';\n\n/**\n * Default logger that does nothing.\n */\nconst nullLogger: PluginLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\n/**\n * Console logger for verbose mode.\n */\nconst consoleLogger: PluginLogger = {\n debug: (msg) => console.log(`[plugin:debug] ${msg}`),\n info: (msg) => console.log(`[plugin:info] ${msg}`),\n warn: (msg) => console.warn(`[plugin:warn] ${msg}`),\n error: (msg) => console.error(`[plugin:error] ${msg}`),\n};\n\n/**\n * Plugin Manager class for managing plugin lifecycle.\n */\nexport class PluginManager {\n private readonly _plugins: Map<string, OmnifyPlugin> = new Map();\n private readonly _types: Map<string, RegisteredType> = new Map();\n private readonly _enums: Map<string, PluginEnumDefinition> = new Map();\n private readonly _generators: Map<string, RegisteredGenerator> = new Map();\n private readonly _pluginConfigs: Map<string, Record<string, unknown>> = new Map();\n private readonly _cwd: string;\n private readonly _verbose: boolean;\n private readonly _logger: PluginLogger;\n\n constructor(options: PluginManagerOptions = {}) {\n this._cwd = options.cwd ?? process.cwd();\n this._verbose = options.verbose ?? false;\n this._logger = options.logger ?? (this._verbose ? consoleLogger : nullLogger);\n }\n\n /**\n * Creates a plugin context for plugin setup.\n */\n private createContext(): PluginContext {\n return {\n cwd: this._cwd,\n verbose: this._verbose,\n logger: this._logger,\n };\n }\n\n /**\n * Registers a single plugin.\n * @param plugin - The plugin to register\n * @param pluginConfig - Optional configuration passed to plugin generators\n */\n async register(\n plugin: OmnifyPlugin,\n pluginConfig: Record<string, unknown> = {}\n ): Promise<PluginRegistrationResult> {\n const warnings: string[] = [];\n const registeredTypes: RegisteredType[] = [];\n\n // Check for duplicate plugin\n if (this._plugins.has(plugin.name)) {\n return {\n success: false,\n types: [],\n warnings: [],\n error: `Plugin '${plugin.name}' is already registered`,\n };\n }\n\n this._logger.debug(`Registering plugin: ${plugin.name}@${plugin.version}`);\n\n // Store plugin config\n this._pluginConfigs.set(plugin.name, pluginConfig);\n\n // Run setup if provided\n if (plugin.setup) {\n try {\n await plugin.setup(this.createContext());\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n types: [],\n warnings: [],\n error: `Plugin setup failed: ${message}`,\n };\n }\n }\n\n // Register types\n if (plugin.types) {\n for (const typeDef of plugin.types) {\n // Check for type conflicts\n const existing = this._types.get(typeDef.name);\n if (existing) {\n throw pluginTypeConflictError(\n typeDef.name,\n existing.pluginName,\n plugin.name\n );\n }\n\n // Validate type definition\n const validationError = this.validateTypeDefinition(typeDef);\n if (validationError) {\n warnings.push(`Type '${typeDef.name}': ${validationError}`);\n continue;\n }\n\n const registeredType: RegisteredType = {\n ...typeDef,\n pluginName: plugin.name,\n pluginVersion: plugin.version,\n };\n\n this._types.set(typeDef.name, registeredType);\n registeredTypes.push(registeredType);\n\n this._logger.debug(` Registered type: ${typeDef.name}`);\n }\n }\n\n // Register enums\n if (plugin.enums) {\n for (const enumDef of plugin.enums) {\n // Check for enum conflicts\n const existing = this._enums.get(enumDef.name);\n if (existing) {\n warnings.push(\n `Enum '${enumDef.name}' already registered by another plugin`\n );\n continue;\n }\n\n this._enums.set(enumDef.name, enumDef);\n this._logger.debug(` Registered enum: ${enumDef.name}`);\n }\n }\n\n // Register generators\n if (plugin.generators) {\n for (const genDef of plugin.generators) {\n // Check for generator conflicts\n const existing = this._generators.get(genDef.name);\n if (existing) {\n warnings.push(\n `Generator '${genDef.name}' already registered by plugin '${existing.pluginName}'`\n );\n continue;\n }\n\n const registeredGenerator: RegisteredGenerator = {\n definition: genDef,\n pluginName: plugin.name,\n pluginVersion: plugin.version,\n pluginConfig,\n };\n\n this._generators.set(genDef.name, registeredGenerator);\n this._logger.debug(` Registered generator: ${genDef.name}`);\n }\n }\n\n // Store plugin\n this._plugins.set(plugin.name, plugin);\n\n const genCount = plugin.generators?.length ?? 0;\n const enumCount = plugin.enums?.length ?? 0;\n this._logger.info(\n `Plugin registered: ${plugin.name} (${registeredTypes.length} types, ${enumCount} enums, ${genCount} generators)`\n );\n\n return {\n success: true,\n types: registeredTypes,\n warnings,\n };\n }\n\n /**\n * Registers multiple plugins.\n */\n async registerAll(plugins: readonly OmnifyPlugin[]): Promise<void> {\n for (const plugin of plugins) {\n const result = await this.register(plugin);\n if (!result.success) {\n throw pluginError(result.error ?? 'Unknown error', plugin.name);\n }\n }\n }\n\n /**\n * Validates a type definition.\n */\n private validateTypeDefinition(typeDef: CustomTypeDefinition): string | undefined {\n if (!typeDef.name || typeDef.name.length === 0) {\n return 'Type name is required';\n }\n\n if (typeDef.compound) {\n if (!typeDef.expand || typeDef.expand.length === 0) {\n return 'Compound type must have expand definitions';\n }\n\n for (const field of typeDef.expand) {\n if (!field.suffix) {\n return 'Expanded field must have a suffix';\n }\n // Field must have either sql definition OR enumRef\n const hasSql = field.sql && field.sql.sqlType;\n const hasEnumRef = 'enumRef' in field && typeof field.enumRef === 'string';\n if (!hasSql && !hasEnumRef) {\n return `Expanded field '${field.suffix}' must have SQL type or enumRef`;\n }\n // TypeScript type is optional when using enumRef (will be derived from enum)\n if (!hasEnumRef && (!field.typescript || !field.typescript.type)) {\n return `Expanded field '${field.suffix}' must have TypeScript type`;\n }\n }\n } else {\n if (!typeDef.sql || !typeDef.sql.sqlType) {\n return 'Non-compound type must have SQL definition';\n }\n if (!typeDef.typescript || !typeDef.typescript.type) {\n return 'Non-compound type must have TypeScript type';\n }\n }\n\n return undefined;\n }\n\n /**\n * Unregisters a plugin and its types/generators.\n */\n async unregister(pluginName: string): Promise<void> {\n const plugin = this._plugins.get(pluginName);\n if (!plugin) {\n throw pluginNotFoundError(pluginName);\n }\n\n // Run teardown if provided\n if (plugin.teardown) {\n try {\n await plugin.teardown();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this._logger.warn(`Plugin teardown failed: ${message}`);\n }\n }\n\n // Remove types from this plugin\n for (const [typeName, type] of this._types) {\n if (type.pluginName === pluginName) {\n this._types.delete(typeName);\n }\n }\n\n // Remove generators from this plugin\n for (const [genName, gen] of this._generators) {\n if (gen.pluginName === pluginName) {\n this._generators.delete(genName);\n }\n }\n\n // Remove plugin config\n this._pluginConfigs.delete(pluginName);\n\n // Remove plugin\n this._plugins.delete(pluginName);\n\n this._logger.info(`Plugin unregistered: ${pluginName}`);\n }\n\n /**\n * Gets a registered type by name.\n */\n getType(typeName: string): RegisteredType | undefined {\n return this._types.get(typeName);\n }\n\n /**\n * Checks if a type is registered.\n */\n hasType(typeName: string): boolean {\n return this._types.has(typeName);\n }\n\n /**\n * Gets all registered types.\n */\n getAllTypes(): ReadonlyMap<string, RegisteredType> {\n return this._types;\n }\n\n /**\n * Gets all registered type names.\n */\n getTypeNames(): readonly string[] {\n return Array.from(this._types.keys());\n }\n\n /**\n * Gets a registered plugin by name.\n */\n getPlugin(pluginName: string): OmnifyPlugin | undefined {\n return this._plugins.get(pluginName);\n }\n\n /**\n * Gets all registered plugins.\n */\n getAllPlugins(): ReadonlyMap<string, OmnifyPlugin> {\n return this._plugins;\n }\n\n /**\n * Gets a registered generator by name.\n */\n getGenerator(generatorName: string): RegisteredGenerator | undefined {\n return this._generators.get(generatorName);\n }\n\n /**\n * Checks if a generator is registered.\n */\n hasGenerator(generatorName: string): boolean {\n return this._generators.has(generatorName);\n }\n\n /**\n * Gets all registered generators.\n */\n getAllGenerators(): ReadonlyMap<string, RegisteredGenerator> {\n return this._generators;\n }\n\n /**\n * Gets all registered generator names.\n */\n getGeneratorNames(): readonly string[] {\n return Array.from(this._generators.keys());\n }\n\n /**\n * Gets the current registry state.\n */\n getRegistry(): PluginRegistry {\n return {\n plugins: this._plugins,\n types: this._types,\n generators: this._generators,\n };\n }\n\n /**\n * Runs all registered generators in topological order.\n * @param schemas - The schemas to generate from\n * @param changes - Schema changes detected from lock file comparison\n * @returns Result with all generated outputs\n */\n async runGenerators(\n schemas: SchemaCollection,\n changes?: readonly SchemaChange[]\n ): Promise<GeneratorRunResult> {\n // Build customTypes map from registered types (convert RegisteredType to CustomTypeDefinition)\n const customTypes = new Map<string, CustomTypeDefinition>();\n for (const [name, registeredType] of this._types) {\n // Extract CustomTypeDefinition fields (exclude pluginName, pluginVersion)\n const { pluginName, pluginVersion, ...typeDefinition } = registeredType;\n customTypes.set(name, typeDefinition as CustomTypeDefinition);\n }\n\n const runner = new GeneratorRunner({\n cwd: this._cwd,\n logger: this._logger,\n customTypes,\n pluginEnums: this._enums,\n });\n\n // Register all generators\n for (const gen of this._generators.values()) {\n runner.register(gen);\n }\n\n // Run all generators with changes\n return runner.runAll(schemas, changes);\n }\n\n /**\n * Clears all registered plugins, types, and generators.\n */\n async clear(): Promise<void> {\n // Teardown all plugins\n for (const plugin of this._plugins.values()) {\n if (plugin.teardown) {\n try {\n await plugin.teardown();\n } catch {\n // Ignore teardown errors during clear\n }\n }\n }\n\n this._plugins.clear();\n this._types.clear();\n this._enums.clear();\n this._generators.clear();\n this._pluginConfigs.clear();\n\n this._logger.debug('Plugin registry cleared');\n }\n}\n\n/**\n * Creates a new plugin manager instance.\n */\nexport function createPluginManager(options?: PluginManagerOptions): PluginManager {\n return new PluginManager(options);\n}\n","/**\n * @famgia/omnify-core - Compound Type Expander\n *\n * Expands compound types into multiple fields.\n */\n\nimport type {\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n} from '@famgia/omnify-types';\nimport type { RegisteredType, PluginRegistry } from './types.js';\n\n/**\n * Expanded property with original property name.\n */\nexport interface ExpandedProperty {\n /** Original property name */\n originalName: string;\n /** Expanded column name (originalName + suffix) */\n expandedName: string;\n /** The expanded field definition */\n property: PropertyDefinition;\n /** Whether this is from a compound type */\n isCompound: boolean;\n /** Source type name if from plugin */\n sourceType?: string;\n}\n\n/**\n * Expands a single property if it's a compound type.\n */\nexport function expandProperty(\n propertyName: string,\n property: PropertyDefinition,\n registry: PluginRegistry\n): ExpandedProperty[] {\n const typeName = property.type;\n const registeredType = registry.types.get(typeName);\n\n // If not a registered type or not compound, return as-is\n if (!registeredType || !registeredType.compound || !registeredType.expand) {\n return [{\n originalName: propertyName,\n expandedName: propertyName,\n property,\n isCompound: false,\n }];\n }\n\n // Expand compound type\n const expanded: ExpandedProperty[] = [];\n\n for (const field of registeredType.expand) {\n const expandedName = `${propertyName}${field.suffix}`;\n\n // Create property definition for expanded field\n const expandedProperty: PropertyDefinition = {\n type: 'String', // Use String as placeholder, actual SQL type is in field.sql\n // Copy nullable from original property\n ...((property as { nullable?: boolean }).nullable !== undefined\n ? { nullable: (property as { nullable?: boolean }).nullable }\n : {}),\n };\n\n expanded.push({\n originalName: propertyName,\n expandedName,\n property: expandedProperty,\n isCompound: true,\n sourceType: typeName,\n });\n }\n\n return expanded;\n}\n\n/**\n * Expands all compound types in a schema's properties.\n */\nexport function expandSchemaProperties(\n schema: LoadedSchema,\n registry: PluginRegistry\n): Map<string, ExpandedProperty[]> {\n const expandedMap = new Map<string, ExpandedProperty[]>();\n\n if (!schema.properties) {\n return expandedMap;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n const expanded = expandProperty(propName, property, registry);\n expandedMap.set(propName, expanded);\n }\n\n return expandedMap;\n}\n\n/**\n * Creates a new schema with compound types expanded.\n */\nexport function expandSchema(\n schema: LoadedSchema,\n registry: PluginRegistry\n): LoadedSchema {\n if (!schema.properties || schema.kind === 'enum') {\n return schema;\n }\n\n const expandedProperties: Record<string, PropertyDefinition> = {};\n let hasExpansion = false;\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n const expanded = expandProperty(propName, property, registry);\n\n const firstExpanded = expanded[0];\n if (expanded.length === 1 && firstExpanded && !firstExpanded.isCompound) {\n // Not a compound type, keep original\n expandedProperties[propName] = property;\n } else {\n // Compound type expanded\n hasExpansion = true;\n for (const exp of expanded) {\n expandedProperties[exp.expandedName] = exp.property;\n }\n }\n }\n\n if (!hasExpansion) {\n return schema;\n }\n\n return {\n ...schema,\n properties: expandedProperties,\n };\n}\n\n/**\n * Expands compound types in all schemas.\n */\nexport function expandSchemas(\n schemas: SchemaCollection,\n registry: PluginRegistry\n): SchemaCollection {\n const expanded: Record<string, LoadedSchema> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n expanded[name] = expandSchema(schema, registry);\n }\n\n return expanded;\n}\n\n/**\n * Gets the registered type info for a property type.\n */\nexport function getTypeInfo(\n typeName: string,\n registry: PluginRegistry\n): RegisteredType | undefined {\n return registry.types.get(typeName);\n}\n\n/**\n * Checks if a type is a compound type.\n */\nexport function isCompoundType(\n typeName: string,\n registry: PluginRegistry\n): boolean {\n const type = registry.types.get(typeName);\n return type?.compound === true;\n}\n\n/**\n * Gets all custom type names from the registry.\n */\nexport function getCustomTypeNames(registry: PluginRegistry): string[] {\n return Array.from(registry.types.keys());\n}\n","/**\n * @famgia/omnify-core - Omnify Programmatic API\n *\n * Main entry point for using omnify-schema programmatically.\n */\n\nimport { resolve } from 'node:path';\nimport type { SchemaCollection, OmnifyPlugin } from '@famgia/omnify-types';\nimport type {\n OmnifyOptions,\n OmnifyLogger,\n LoadResult,\n SchemaError,\n SchemaIntrospection,\n} from './types.js';\nimport { loadSchemas } from '../schema/index.js';\nimport { validateSchemas } from '../validation/index.js';\nimport { PluginManager, createPluginManager } from '../plugins/index.js';\nimport type { PluginRegistry } from '../plugins/types.js';\nimport { OmnifyError } from '../errors/index.js';\nimport {\n introspectSchema,\n introspectSchemas,\n getSchemaNames,\n getEntitySchemas,\n getEnumSchemas,\n getSchemasByGroup,\n getGroups,\n findReferencingSchemas,\n findReferencedSchemas,\n hasCircularReferences,\n getTopologicalOrder,\n} from './metadata.js';\n\n/**\n * Default logger that does nothing.\n */\nconst nullLogger: OmnifyLogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Console logger for verbose mode.\n */\nconst consoleLogger: OmnifyLogger = {\n debug: (msg, ...args) => console.debug(`[omnify] ${msg}`, ...args),\n info: (msg, ...args) => console.info(`[omnify] ${msg}`, ...args),\n warn: (msg, ...args) => console.warn(`[omnify] ${msg}`, ...args),\n error: (msg, ...args) => console.error(`[omnify] ${msg}`, ...args),\n};\n\n/**\n * Main Omnify API class for programmatic usage.\n *\n * @example\n * ```typescript\n * import { Omnify } from '@famgia/omnify-core';\n *\n * const omnify = new Omnify({\n * schemaDir: './schemas',\n * plugins: [japanTypesPlugin],\n * });\n *\n * // Load and validate schemas\n * const { schemas, errors } = await omnify.load();\n *\n * // Get schema metadata\n * const users = omnify.getSchema('User');\n *\n * // Introspect schema\n * const introspection = omnify.introspect('User');\n * ```\n */\nexport class Omnify {\n private readonly options: OmnifyOptions;\n private readonly logger: OmnifyLogger;\n private readonly pluginManager: PluginManager;\n private schemas: SchemaCollection | null = null;\n private loaded = false;\n\n constructor(options: OmnifyOptions) {\n this.options = {\n ...options,\n schemaDir: resolve(options.schemaDir),\n };\n this.logger = options.logger ?? (options.verbose ? consoleLogger : nullLogger);\n this.pluginManager = createPluginManager({ logger: this.logger });\n }\n\n /**\n * Registers plugins with the plugin manager.\n */\n async registerPlugins(plugins: OmnifyPlugin[]): Promise<void> {\n for (const plugin of plugins) {\n this.logger.debug(`Registering plugin: ${plugin.name}`);\n const result = await this.pluginManager.register(plugin);\n if (!result.success) {\n throw new Error(`Failed to register plugin ${plugin.name}: ${result.error}`);\n }\n if (result.warnings.length > 0) {\n for (const warning of result.warnings) {\n this.logger.warn(warning);\n }\n }\n }\n }\n\n /**\n * Loads and validates schemas from the configured directory.\n */\n async load(): Promise<LoadResult> {\n this.logger.info(`Loading schemas from: ${this.options.schemaDir}`);\n\n // Register plugins if provided\n if (this.options.plugins?.length) {\n await this.registerPlugins(this.options.plugins);\n }\n\n const errors: SchemaError[] = [];\n const warnings: { file: string; message: string }[] = [];\n\n try {\n // Load schemas\n const schemas = await loadSchemas(this.options.schemaDir, {\n recursive: true,\n });\n this.logger.debug(`Loaded ${Object.keys(schemas).length} schemas`);\n\n // Get custom type names from plugin registry\n const customTypeNames = Array.from(this.pluginManager.getRegistry().types.keys());\n\n // Validate schemas\n const validationResult = validateSchemas(schemas, {\n customTypes: customTypeNames,\n });\n\n // Collect errors and warnings\n for (const error of validationResult.errors) {\n const schemaError: SchemaError = {\n file: error.file ?? 'unknown',\n message: error.message,\n };\n if (error.line !== undefined) {\n schemaError.line = error.line;\n }\n if (error.suggestion !== undefined) {\n schemaError.suggestion = error.suggestion;\n }\n errors.push(schemaError);\n }\n\n for (const warning of validationResult.warnings) {\n warnings.push({\n file: warning.file ?? 'unknown',\n message: warning.message,\n });\n }\n\n if (validationResult.valid) {\n this.schemas = schemas;\n this.loaded = true;\n }\n\n return {\n success: validationResult.valid,\n schemas: schemas,\n errors,\n warnings,\n };\n } catch (error) {\n if (error instanceof OmnifyError) {\n const schemaError: SchemaError = {\n file: error.file ?? 'unknown',\n message: error.message,\n };\n if (error.line !== undefined) {\n schemaError.line = error.line;\n }\n if (error.suggestion !== undefined) {\n schemaError.suggestion = error.suggestion;\n }\n errors.push(schemaError);\n } else {\n errors.push({\n file: 'unknown',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n\n return {\n success: false,\n schemas: {},\n errors,\n warnings,\n };\n }\n }\n\n /**\n * Gets loaded schemas. Throws if not loaded.\n */\n getSchemas(): SchemaCollection {\n if (!this.loaded || !this.schemas) {\n throw new Error('Schemas not loaded. Call load() first.');\n }\n return this.schemas;\n }\n\n /**\n * Gets a single schema by name.\n */\n getSchema(name: string): SchemaIntrospection | undefined {\n const schemas = this.getSchemas();\n const schema = schemas[name];\n if (!schema) return undefined;\n return introspectSchema(schema, this.pluginManager.getRegistry());\n }\n\n /**\n * Gets all schema names.\n */\n getSchemaNames(): string[] {\n return getSchemaNames(this.getSchemas());\n }\n\n /**\n * Gets entity schemas (non-enum).\n */\n getEntitySchemas(): SchemaIntrospection[] {\n const schemas = getEntitySchemas(this.getSchemas());\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets enum schemas.\n */\n getEnumSchemas(): SchemaIntrospection[] {\n const schemas = getEnumSchemas(this.getSchemas());\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets schemas by group.\n */\n getSchemasByGroup(group: string): SchemaIntrospection[] {\n const schemas = getSchemasByGroup(this.getSchemas(), group);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Gets all unique group names.\n */\n getGroups(): string[] {\n return getGroups(this.getSchemas());\n }\n\n /**\n * Introspects a specific schema.\n */\n introspect(name: string): SchemaIntrospection | undefined {\n return this.getSchema(name);\n }\n\n /**\n * Introspects all schemas.\n */\n introspectAll(): Map<string, SchemaIntrospection> {\n return introspectSchemas(this.getSchemas(), this.pluginManager.getRegistry());\n }\n\n /**\n * Finds schemas that reference a target schema.\n */\n findReferencingSchemas(targetName: string): SchemaIntrospection[] {\n const schemas = findReferencingSchemas(this.getSchemas(), targetName);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Finds schemas referenced by a source schema.\n */\n findReferencedSchemas(sourceName: string): SchemaIntrospection[] {\n const schemas = findReferencedSchemas(this.getSchemas(), sourceName);\n return schemas.map((s) =>\n introspectSchema(s, this.pluginManager.getRegistry())\n );\n }\n\n /**\n * Checks if schemas have circular references.\n */\n hasCircularReferences(): boolean {\n return hasCircularReferences(this.getSchemas());\n }\n\n /**\n * Gets topological order of schemas (dependencies first).\n */\n getTopologicalOrder(): string[] {\n return getTopologicalOrder(this.getSchemas());\n }\n\n /**\n * Gets the plugin registry.\n */\n getPluginRegistry(): PluginRegistry {\n return this.pluginManager.getRegistry();\n }\n\n /**\n * Checks if a type is registered (from plugin).\n */\n hasType(typeName: string): boolean {\n return this.pluginManager.hasType(typeName);\n }\n\n /**\n * Gets custom type names from all registered plugins.\n */\n getCustomTypeNames(): string[] {\n return Array.from(this.pluginManager.getRegistry().types.keys());\n }\n}\n\n/**\n * Creates an Omnify instance.\n *\n * @example\n * ```typescript\n * const omnify = createOmnify({\n * schemaDir: './schemas',\n * });\n *\n * const { schemas } = await omnify.load();\n * ```\n */\nexport function createOmnify(options: OmnifyOptions): Omnify {\n return new Omnify(options);\n}\n","/**\n * @famgia/omnify-core - Schema Metadata Access\n *\n * Utilities for accessing schema metadata programmatically.\n */\n\nimport type {\n LoadedSchema,\n SchemaCollection,\n PropertyDefinition,\n AssociationDefinition,\n} from '@famgia/omnify-types';\nimport type {\n SchemaMetadata,\n PropertyMetadata,\n AssociationMetadata,\n SchemaIntrospection,\n} from './types.js';\nimport type { PluginRegistry } from '../plugins/types.js';\n\n/**\n * Type guard to check if a property is an association.\n */\nfunction isAssociation(prop: PropertyDefinition): prop is AssociationDefinition {\n return prop.type === 'Association';\n}\n\n/**\n * Extracts metadata from a loaded schema.\n */\nexport function getSchemaMetadata(schema: LoadedSchema): SchemaMetadata {\n const propertyNames: string[] = [];\n const associationNames: string[] = [];\n\n if (schema.properties) {\n for (const [name, prop] of Object.entries(schema.properties)) {\n if (isAssociation(prop)) {\n associationNames.push(name);\n } else {\n propertyNames.push(name);\n }\n }\n }\n\n // Map 'object' to 'entity' for our API\n const kind = schema.kind === 'enum' ? 'enum' : 'entity';\n\n const result: SchemaMetadata = {\n name: schema.name,\n kind,\n filePath: schema.filePath,\n propertyNames,\n associationNames,\n hasTimestamps: schema.options?.timestamps ?? false,\n hasSoftDelete: schema.options?.softDelete ?? false,\n idType: schema.options?.idType ?? 'BigInt',\n };\n\n if (schema.displayName !== undefined) {\n result.displayName = schema.displayName;\n }\n if (schema.group !== undefined) {\n result.group = schema.group;\n }\n\n return result;\n}\n\n/**\n * Extracts property metadata.\n */\nexport function getPropertyMetadata(\n name: string,\n property: PropertyDefinition,\n registry?: PluginRegistry\n): PropertyMetadata {\n // Associations are handled separately\n if (isAssociation(property)) {\n return {\n name,\n type: 'Association',\n nullable: false,\n unique: false,\n hasDefault: false,\n isPluginType: false,\n };\n }\n\n const isPluginType = registry?.types.has(property.type) ?? false;\n const pluginType = registry?.types.get(property.type);\n\n const result: PropertyMetadata = {\n name,\n type: property.type,\n nullable: (property as { nullable?: boolean }).nullable ?? false,\n unique: (property as { unique?: boolean }).unique ?? false,\n hasDefault: 'default' in property && (property as { default?: unknown }).default !== undefined,\n isPluginType,\n };\n\n if ('default' in property && (property as { default?: unknown }).default !== undefined) {\n result.defaultValue = (property as { default?: unknown }).default;\n }\n\n if (pluginType?.pluginName !== undefined) {\n result.pluginName = pluginType.pluginName;\n }\n\n return result;\n}\n\n/**\n * Extracts association metadata.\n */\nexport function getAssociationMetadata(\n name: string,\n association: AssociationDefinition\n): AssociationMetadata {\n const result: AssociationMetadata = {\n name,\n relation: association.relation,\n };\n\n // Handle target (for standard and inverse polymorphic relations)\n if (association.target !== undefined) {\n result.target = association.target;\n }\n\n // Handle targets (for MorphTo)\n if (association.targets !== undefined) {\n result.targets = association.targets;\n }\n\n // Handle morphName (for MorphOne/MorphMany/MorphedByMany)\n if (association.morphName !== undefined) {\n result.morphName = association.morphName;\n }\n\n if (association.inversedBy !== undefined) {\n result.inversedBy = association.inversedBy;\n }\n if (association.mappedBy !== undefined) {\n result.mappedBy = association.mappedBy;\n }\n if (association.onDelete !== undefined) {\n result.onDelete = association.onDelete;\n }\n if (association.onUpdate !== undefined) {\n result.onUpdate = association.onUpdate;\n }\n\n return result;\n}\n\n/**\n * Full schema introspection.\n */\nexport function introspectSchema(\n schema: LoadedSchema,\n registry?: PluginRegistry\n): SchemaIntrospection {\n const metadata = getSchemaMetadata(schema);\n\n const properties: PropertyMetadata[] = [];\n const associations: AssociationMetadata[] = [];\n\n if (schema.properties) {\n for (const [name, prop] of Object.entries(schema.properties)) {\n if (isAssociation(prop)) {\n associations.push(getAssociationMetadata(name, prop));\n } else {\n properties.push(getPropertyMetadata(name, prop, registry));\n }\n }\n }\n\n return {\n metadata,\n properties,\n associations,\n schema,\n };\n}\n\n/**\n * Introspects all schemas in a collection.\n */\nexport function introspectSchemas(\n schemas: SchemaCollection,\n registry?: PluginRegistry\n): Map<string, SchemaIntrospection> {\n const result = new Map<string, SchemaIntrospection>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n result.set(name, introspectSchema(schema, registry));\n }\n\n return result;\n}\n\n/**\n * Gets all schema names from a collection.\n */\nexport function getSchemaNames(schemas: SchemaCollection): string[] {\n return Object.keys(schemas);\n}\n\n/**\n * Gets schemas by kind.\n */\nexport function getSchemasByKind(\n schemas: SchemaCollection,\n kind: 'entity' | 'enum'\n): LoadedSchema[] {\n return Object.values(schemas).filter((schema) => {\n const schemaKind = schema.kind === 'enum' ? 'enum' : 'entity';\n return schemaKind === kind;\n });\n}\n\n/**\n * Gets entity schemas (non-enum).\n */\nexport function getEntitySchemas(schemas: SchemaCollection): LoadedSchema[] {\n return getSchemasByKind(schemas, 'entity');\n}\n\n/**\n * Gets enum schemas.\n */\nexport function getEnumSchemas(schemas: SchemaCollection): LoadedSchema[] {\n return getSchemasByKind(schemas, 'enum');\n}\n\n/**\n * Gets schemas by group.\n */\nexport function getSchemasByGroup(\n schemas: SchemaCollection,\n group: string\n): LoadedSchema[] {\n return Object.values(schemas).filter((schema) => schema.group === group);\n}\n\n/**\n * Gets all unique group names.\n */\nexport function getGroups(schemas: SchemaCollection): string[] {\n const groups = new Set<string>();\n\n for (const schema of Object.values(schemas)) {\n if (schema.group) {\n groups.add(schema.group);\n }\n }\n\n return Array.from(groups).sort();\n}\n\n/**\n * Gets associations from a schema.\n */\nfunction getSchemaAssociations(schema: LoadedSchema): AssociationDefinition[] {\n if (!schema.properties) return [];\n\n const associations: AssociationDefinition[] = [];\n for (const prop of Object.values(schema.properties)) {\n if (isAssociation(prop)) {\n associations.push(prop);\n }\n }\n return associations;\n}\n\n/**\n * Finds schemas that reference a target schema.\n */\nexport function findReferencingSchemas(\n schemas: SchemaCollection,\n targetName: string\n): LoadedSchema[] {\n const result: LoadedSchema[] = [];\n\n for (const schema of Object.values(schemas)) {\n const associations = getSchemaAssociations(schema);\n for (const association of associations) {\n if (association.target === targetName) {\n result.push(schema);\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Finds schemas referenced by a source schema.\n */\nexport function findReferencedSchemas(\n schemas: SchemaCollection,\n sourceName: string\n): LoadedSchema[] {\n const source = schemas[sourceName];\n if (!source) return [];\n\n const associations = getSchemaAssociations(source);\n const targetNames = new Set(associations.map((a) => a.target));\n\n return Object.values(schemas).filter((s) => targetNames.has(s.name));\n}\n\n/**\n * Gets the relationship graph as adjacency list.\n */\nexport function getRelationshipGraph(\n schemas: SchemaCollection\n): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const schema of Object.values(schemas)) {\n const targets: string[] = [];\n const associations = getSchemaAssociations(schema);\n\n for (const association of associations) {\n // Handle MorphTo with multiple targets\n if (association.targets) {\n for (const target of association.targets) {\n if (!targets.includes(target)) {\n targets.push(target);\n }\n }\n }\n // Handle standard and inverse polymorphic with single target\n else if (association.target && !targets.includes(association.target)) {\n targets.push(association.target);\n }\n }\n\n graph.set(schema.name, targets);\n }\n\n return graph;\n}\n\n/**\n * Checks if schemas form a valid DAG (no circular references).\n */\nexport function hasCircularReferences(schemas: SchemaCollection): boolean {\n const graph = getRelationshipGraph(schemas);\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n function hasCycle(node: string): boolean {\n if (recursionStack.has(node)) return true;\n if (visited.has(node)) return false;\n\n visited.add(node);\n recursionStack.add(node);\n\n const neighbors = graph.get(node) ?? [];\n for (const neighbor of neighbors) {\n if (hasCycle(neighbor)) return true;\n }\n\n recursionStack.delete(node);\n return false;\n }\n\n for (const schemaName of graph.keys()) {\n if (hasCycle(schemaName)) return true;\n }\n\n return false;\n}\n\n/**\n * Gets topological sort order for schemas (dependencies first).\n */\nexport function getTopologicalOrder(schemas: SchemaCollection): string[] {\n const graph = getRelationshipGraph(schemas);\n const result: string[] = [];\n const visited = new Set<string>();\n\n function visit(node: string): void {\n if (visited.has(node)) return;\n visited.add(node);\n\n const neighbors = graph.get(node) ?? [];\n for (const neighbor of neighbors) {\n visit(neighbor);\n }\n\n result.push(node);\n }\n\n for (const schemaName of graph.keys()) {\n visit(schemaName);\n }\n\n // Post-order DFS already gives correct dependency order\n // (dependencies/referenced schemas come first)\n return result;\n}\n","/**\n * @famgia/omnify-core - Version Store\n *\n * Manages version history files for schema tracking.\n */\n\nimport { readdir, readFile, writeFile, mkdir, rm, access } from 'fs/promises';\nimport { join } from 'path';\nimport yaml from 'js-yaml';\nimport type {\n VersionFile,\n VersionSummary,\n VersionSchemaSnapshot,\n VersionChange,\n VersionDiff,\n CreateVersionOptions,\n VersionStoreConfig,\n} from './types.js';\n\n/**\n * Directory name for omnify data.\n */\nconst OMNIFY_DIR = '.omnify';\n\n/**\n * Subdirectory for version files.\n */\nconst VERSIONS_DIR = 'versions';\n\n/**\n * Deep equality comparison that ignores property order.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return a === b;\n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n if (typeof a === 'object' && typeof b === 'object') {\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;\n if (!deepEqual(aObj[key], bObj[key])) return false;\n }\n return true;\n }\n\n return false;\n}\n\n/**\n * Current version symlink/file name.\n */\nconst CURRENT_FILE = 'current.lock';\n\n/**\n * Version file name pattern.\n */\nconst VERSION_FILE_PATTERN = /^(\\d{4})(?:_(.+))?\\.lock$/;\n\n/**\n * Format version number to 4-digit string.\n */\nfunction formatVersionNumber(version: number): string {\n return version.toString().padStart(4, '0');\n}\n\n/**\n * Parse version number from filename.\n */\nfunction parseVersionFilename(filename: string): { version: number; name?: string | undefined } | null {\n const match = filename.match(VERSION_FILE_PATTERN);\n if (!match || !match[1]) return null;\n const result: { version: number; name?: string | undefined } = {\n version: parseInt(match[1], 10),\n };\n if (match[2] !== undefined) {\n result.name = match[2];\n }\n return result;\n}\n\n/**\n * Generate version filename.\n */\nfunction generateVersionFilename(version: number, migration?: string): string {\n const versionStr = formatVersionNumber(version);\n if (migration) {\n // Extract name from migration file (e.g., \"0001_create_users.sql\" -> \"create_users\")\n const name = migration.replace(/^\\d+_/, '').replace(/\\.sql$/, '');\n return `${versionStr}_${name}.lock`;\n }\n return `${versionStr}.lock`;\n}\n\n/**\n * Check if directory exists.\n */\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Version Store class for managing schema version history.\n */\nexport class VersionStore {\n private readonly omnifyDir: string;\n private readonly versionsDir: string;\n private readonly maxVersions: number;\n\n constructor(config: VersionStoreConfig) {\n this.omnifyDir = join(config.baseDir, OMNIFY_DIR);\n this.versionsDir = join(this.omnifyDir, VERSIONS_DIR);\n this.maxVersions = config.maxVersions ?? 0;\n }\n\n /**\n * Initialize the version store directory structure.\n */\n async initialize(): Promise<void> {\n await mkdir(this.versionsDir, { recursive: true });\n }\n\n /**\n * Get the path to the versions directory.\n */\n getVersionsDir(): string {\n return this.versionsDir;\n }\n\n /**\n * Get the path to a specific version file.\n */\n getVersionPath(version: number, migration?: string): string {\n const filename = generateVersionFilename(version, migration);\n return join(this.versionsDir, filename);\n }\n\n /**\n * List all available versions.\n */\n async listVersions(): Promise<VersionSummary[]> {\n if (!(await dirExists(this.versionsDir))) {\n return [];\n }\n\n const files = await readdir(this.versionsDir);\n const versions: VersionSummary[] = [];\n\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (!parsed) continue;\n\n try {\n const filePath = join(this.versionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const versionFile = yaml.load(content) as VersionFile;\n\n const summary: VersionSummary = {\n version: versionFile.version,\n timestamp: versionFile.timestamp,\n ...(versionFile.migration !== undefined && { migration: versionFile.migration }),\n ...(versionFile.description !== undefined && { description: versionFile.description }),\n schemaCount: Object.keys(versionFile.snapshot).length,\n changeCount: versionFile.changes.length,\n };\n versions.push(summary);\n } catch {\n // Skip invalid files\n }\n }\n\n return versions.sort((a, b) => a.version - b.version);\n }\n\n /**\n * Get the latest version number.\n */\n async getLatestVersion(): Promise<number> {\n const versions = await this.listVersions();\n if (versions.length === 0) return 0;\n const lastVersion = versions[versions.length - 1];\n return lastVersion?.version ?? 0;\n }\n\n /**\n * Read a specific version file.\n */\n async readVersion(version: number): Promise<VersionFile | null> {\n if (!(await dirExists(this.versionsDir))) {\n return null;\n }\n\n const files = await readdir(this.versionsDir);\n\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (parsed?.version === version) {\n const filePath = join(this.versionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n return yaml.load(content) as VersionFile;\n }\n }\n\n return null;\n }\n\n /**\n * Read the latest version file.\n */\n async readLatestVersion(): Promise<VersionFile | null> {\n const latestVersion = await this.getLatestVersion();\n if (latestVersion === 0) return null;\n return this.readVersion(latestVersion);\n }\n\n /**\n * Create a new version.\n */\n async createVersion(\n snapshot: Record<string, VersionSchemaSnapshot>,\n changes: readonly VersionChange[],\n options: CreateVersionOptions\n ): Promise<VersionFile> {\n await this.initialize();\n\n const latestVersion = await this.getLatestVersion();\n const newVersion = latestVersion + 1;\n\n const versionFile: VersionFile = {\n version: newVersion,\n timestamp: new Date().toISOString(),\n driver: options.driver,\n ...(options.migration !== undefined && { migration: options.migration }),\n ...(options.description !== undefined && { description: options.description }),\n changes,\n snapshot,\n };\n\n const filePath = this.getVersionPath(newVersion, options.migration);\n const content = yaml.dump(versionFile, {\n lineWidth: -1, // Disable line wrapping\n noRefs: true,\n quotingType: '\"',\n });\n\n await writeFile(filePath, content, 'utf-8');\n\n // Update current.lock symlink/copy\n await this.updateCurrentLink(versionFile);\n\n // Cleanup old versions if maxVersions is set\n if (this.maxVersions > 0) {\n await this.cleanupOldVersions();\n }\n\n return versionFile;\n }\n\n /**\n * Update the current.lock file to point to latest version.\n */\n private async updateCurrentLink(versionFile: VersionFile): Promise<void> {\n const currentPath = join(this.omnifyDir, CURRENT_FILE);\n const content = yaml.dump(versionFile, {\n lineWidth: -1,\n noRefs: true,\n quotingType: '\"',\n });\n await writeFile(currentPath, content, 'utf-8');\n }\n\n /**\n * Cleanup old versions beyond maxVersions limit.\n */\n private async cleanupOldVersions(): Promise<void> {\n const versions = await this.listVersions();\n if (versions.length <= this.maxVersions) return;\n\n const toDelete = versions.slice(0, versions.length - this.maxVersions);\n for (const v of toDelete) {\n const files = await readdir(this.versionsDir);\n for (const file of files) {\n const parsed = parseVersionFilename(file);\n if (parsed?.version === v.version) {\n await rm(join(this.versionsDir, file));\n break;\n }\n }\n }\n }\n\n /**\n * Get diff between two versions.\n */\n async diffVersions(fromVersion: number, toVersion: number): Promise<VersionDiff | null> {\n const fromFile = await this.readVersion(fromVersion);\n const toFile = await this.readVersion(toVersion);\n\n if (!fromFile || !toFile) return null;\n\n // Collect all changes between versions\n const allChanges: VersionChange[] = [];\n\n if (fromVersion < toVersion) {\n // Forward diff: collect changes from fromVersion+1 to toVersion\n for (let v = fromVersion + 1; v <= toVersion; v++) {\n const vFile = await this.readVersion(v);\n if (vFile) {\n allChanges.push(...vFile.changes);\n }\n }\n } else {\n // Backward diff: compute changes needed to go FROM current TO target\n // e.g., v5 -> v2 means what's in v5 but not in v2 needs to be removed\n const changes = this.computeSnapshotDiff(fromFile.snapshot, toFile.snapshot);\n allChanges.push(...changes);\n }\n\n return {\n fromVersion,\n toVersion,\n changes: allChanges,\n };\n }\n\n /**\n * Compute changes between two snapshots.\n */\n computeSnapshotDiff(\n from: Record<string, VersionSchemaSnapshot>,\n to: Record<string, VersionSchemaSnapshot>\n ): VersionChange[] {\n const changes: VersionChange[] = [];\n const fromNames = new Set(Object.keys(from));\n const toNames = new Set(Object.keys(to));\n\n // Added schemas\n for (const name of toNames) {\n if (!fromNames.has(name)) {\n changes.push({ action: 'schema_added', schema: name });\n }\n }\n\n // Removed schemas\n for (const name of fromNames) {\n if (!toNames.has(name)) {\n changes.push({ action: 'schema_removed', schema: name });\n }\n }\n\n // Modified schemas\n for (const name of fromNames) {\n if (!toNames.has(name)) continue;\n\n const fromSchema = from[name];\n const toSchema = to[name];\n if (!fromSchema || !toSchema) continue;\n\n // Compare properties\n const fromProps = fromSchema.properties ?? {};\n const toProps = toSchema.properties ?? {};\n const fromPropNames = new Set(Object.keys(fromProps));\n const toPropNames = new Set(Object.keys(toProps));\n\n for (const prop of toPropNames) {\n if (!fromPropNames.has(prop)) {\n changes.push({\n action: 'property_added',\n schema: name,\n property: prop,\n to: toProps[prop],\n });\n }\n }\n\n for (const prop of fromPropNames) {\n if (!toPropNames.has(prop)) {\n changes.push({\n action: 'property_removed',\n schema: name,\n property: prop,\n from: fromProps[prop],\n });\n }\n }\n\n for (const prop of fromPropNames) {\n if (!toPropNames.has(prop)) continue;\n if (!deepEqual(fromProps[prop], toProps[prop])) {\n changes.push({\n action: 'property_modified',\n schema: name,\n property: prop,\n from: fromProps[prop],\n to: toProps[prop],\n });\n }\n }\n\n // Compare options granularly\n const fromOpts = fromSchema.options ?? {};\n const toOpts = toSchema.options ?? {};\n\n // Default values for options - used to normalize undefined values\n const optionDefaults: Record<string, unknown> = {\n id: true,\n idType: 'BigInt',\n timestamps: true,\n softDelete: false,\n tableName: undefined, // no default\n translations: false,\n authenticatable: false,\n };\n\n // Helper to get normalized option value (undefined → default)\n const getNormalizedOption = (opts: Record<string, unknown>, key: string): unknown => {\n const value = opts[key];\n if (value === undefined) {\n return optionDefaults[key];\n }\n return value;\n };\n\n // Compare simple options with normalization\n const simpleOptions = ['timestamps', 'softDelete', 'id', 'idType', 'tableName', 'translations', 'authenticatable'] as const;\n for (const opt of simpleOptions) {\n const fromVal = getNormalizedOption(fromOpts, opt);\n const toVal = getNormalizedOption(toOpts, opt);\n if (!deepEqual(fromVal, toVal)) {\n changes.push({\n action: 'option_changed',\n schema: name,\n property: opt,\n from: fromOpts[opt], // Keep original value for display\n to: toOpts[opt],\n });\n }\n }\n\n // Compare indexes specifically - match by columns (unique identifier)\n const fromIndexes = (fromOpts.indexes ?? []) as Array<{ columns: string[]; unique?: boolean; name?: string; type?: string }>;\n const toIndexes = (toOpts.indexes ?? []) as Array<{ columns: string[]; unique?: boolean; name?: string; type?: string }>;\n\n // Helper to check if columns match\n const columnsMatch = (a: string[], b: string[]): boolean => {\n if (a.length !== b.length) return false;\n return a.every((col, i) => col === b[i]);\n };\n\n const matchedFromIndexes = new Set<number>();\n\n // Check each \"to\" index\n for (const toIdx of toIndexes) {\n // Find matching \"from\" index by columns\n const fromIndex = fromIndexes.findIndex((fromIdx, i) =>\n !matchedFromIndexes.has(i) && columnsMatch(fromIdx.columns, toIdx.columns)\n );\n\n if (fromIndex === -1) {\n // No match by columns → new index\n changes.push({\n action: 'index_added',\n schema: name,\n to: toIdx,\n });\n } else {\n matchedFromIndexes.add(fromIndex);\n const fromIdx = fromIndexes[fromIndex];\n // Check if other properties changed\n if (!deepEqual(fromIdx, toIdx)) {\n changes.push({\n action: 'index_modified',\n schema: name,\n from: fromIdx,\n to: toIdx,\n });\n }\n }\n }\n\n // Any unmatched \"from\" indexes are removed\n for (let i = 0; i < fromIndexes.length; i++) {\n if (!matchedFromIndexes.has(i)) {\n changes.push({\n action: 'index_removed',\n schema: name,\n from: fromIndexes[i],\n });\n }\n }\n }\n\n return changes;\n }\n\n /**\n * Get snapshot at a specific version (for rollback).\n */\n async getSnapshotAt(version: number): Promise<Record<string, VersionSchemaSnapshot> | null> {\n const versionFile = await this.readVersion(version);\n return versionFile?.snapshot ?? null;\n }\n}\n\n/**\n * Create a new VersionStore instance.\n */\nexport function createVersionStore(config: VersionStoreConfig): VersionStore {\n return new VersionStore(config);\n}\n"],"mappings":"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","names":["import_omnify_types","path","yaml","stat","import_omnify_types","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","buildLocation","MORPH_TO_RELATIONS","MORPH_INVERSE_RELATIONS","validationError","nullLogger","consoleLogger","import_js_yaml","path","yaml"]}