@happyvertical/smrt-core 0.36.5 → 0.36.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/collection.d.ts +1 -1
  2. package/dist/config.d.ts +1 -1
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/consumer-plugin/index.d.ts.map +1 -1
  6. package/dist/consumer-plugin/index.js +7 -3
  7. package/dist/consumer-plugin/index.js.map +1 -1
  8. package/dist/database.d.ts +3 -3
  9. package/dist/database.d.ts.map +1 -1
  10. package/dist/database.js.map +1 -1
  11. package/dist/embeddings/provider.d.ts +14 -2
  12. package/dist/embeddings/provider.d.ts.map +1 -1
  13. package/dist/embeddings/provider.js +3 -3
  14. package/dist/embeddings/provider.js.map +1 -1
  15. package/dist/embeddings/storage.js.map +1 -1
  16. package/dist/errors.d.ts +22 -22
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +5 -4
  19. package/dist/errors.js.map +1 -1
  20. package/dist/generators/cli.d.ts +4 -22
  21. package/dist/generators/cli.d.ts.map +1 -1
  22. package/dist/generators/cli.js +9 -5
  23. package/dist/generators/cli.js.map +1 -1
  24. package/dist/generators/mcp-runtime-template.d.ts +1 -1
  25. package/dist/generators/mcp-runtime-template.d.ts.map +1 -1
  26. package/dist/generators/mcp-runtime-template.js.map +1 -1
  27. package/dist/generators/mcp.d.ts +16 -4
  28. package/dist/generators/mcp.d.ts.map +1 -1
  29. package/dist/generators/mcp.js +25 -9
  30. package/dist/generators/mcp.js.map +1 -1
  31. package/dist/generators/rest.d.ts +6 -5
  32. package/dist/generators/rest.d.ts.map +1 -1
  33. package/dist/generators/rest.js +8 -5
  34. package/dist/generators/rest.js.map +1 -1
  35. package/dist/generators/swagger.d.ts +12 -2
  36. package/dist/generators/swagger.d.ts.map +1 -1
  37. package/dist/generators/swagger.js +6 -3
  38. package/dist/generators/swagger.js.map +1 -1
  39. package/dist/knowledge.d.ts +12 -1
  40. package/dist/knowledge.d.ts.map +1 -1
  41. package/dist/knowledge.js.map +1 -1
  42. package/dist/lazy-config.d.ts.map +1 -1
  43. package/dist/lazy-config.js.map +1 -1
  44. package/dist/manifest/generator.d.ts.map +1 -1
  45. package/dist/manifest/generator.js +14 -12
  46. package/dist/manifest/generator.js.map +1 -1
  47. package/dist/manifest/manager.d.ts +3 -3
  48. package/dist/manifest/manager.d.ts.map +1 -1
  49. package/dist/manifest/manager.js.map +1 -1
  50. package/dist/manifest/manifest-loader.d.ts +3 -2
  51. package/dist/manifest/manifest-loader.d.ts.map +1 -1
  52. package/dist/manifest/manifest-loader.js +3 -2
  53. package/dist/manifest/manifest-loader.js.map +1 -1
  54. package/dist/manifest/static-manifest.js +2 -2
  55. package/dist/manifest/static-manifest.js.map +1 -1
  56. package/dist/manifest/store.js +2 -2
  57. package/dist/manifest/test-manifest-stub.js +2 -2
  58. package/dist/manifest/test-manifest-stub.js.map +1 -1
  59. package/dist/manifest.json +2 -2
  60. package/dist/mcp-advisor/index.d.ts +1 -1
  61. package/dist/mcp-advisor/index.d.ts.map +1 -1
  62. package/dist/mcp-advisor/tools/get-object-config.d.ts.map +1 -1
  63. package/dist/mcp-advisor/types.d.ts +5 -5
  64. package/dist/mcp-advisor/types.d.ts.map +1 -1
  65. package/dist/migrations/differ.js.map +1 -1
  66. package/dist/scanner/manifest-generator.d.ts +11 -3
  67. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  68. package/dist/scanner/manifest-generator.js +19 -15
  69. package/dist/scanner/manifest-generator.js.map +1 -1
  70. package/dist/scanner/types.d.ts +60 -6
  71. package/dist/scanner/types.d.ts.map +1 -1
  72. package/dist/schema/code-generator.d.ts.map +1 -1
  73. package/dist/schema/ddl/base-strategy.d.ts +2 -2
  74. package/dist/schema/ddl/base-strategy.d.ts.map +1 -1
  75. package/dist/schema/ddl/base-strategy.js.map +1 -1
  76. package/dist/schema/ddl/sqlite-strategy.d.ts +1 -1
  77. package/dist/schema/ddl/sqlite-strategy.d.ts.map +1 -1
  78. package/dist/schema/ddl/sqlite-strategy.js.map +1 -1
  79. package/dist/schema/ddl/types.d.ts +1 -1
  80. package/dist/schema/ddl/types.d.ts.map +1 -1
  81. package/dist/schema/generator.d.ts +27 -4
  82. package/dist/schema/generator.d.ts.map +1 -1
  83. package/dist/schema/generator.js +3 -2
  84. package/dist/schema/generator.js.map +1 -1
  85. package/dist/schema/override-system.d.ts +3 -3
  86. package/dist/schema/override-system.d.ts.map +1 -1
  87. package/dist/schema/schema-aggregator.d.ts.map +1 -1
  88. package/dist/schema/schema-manager.d.ts.map +1 -1
  89. package/dist/schema/schema-manager.js +12 -4
  90. package/dist/schema/schema-manager.js.map +1 -1
  91. package/dist/schema/types.d.ts +1 -1
  92. package/dist/schema/types.d.ts.map +1 -1
  93. package/dist/schema/utils.d.ts +6 -1
  94. package/dist/schema/utils.d.ts.map +1 -1
  95. package/dist/schema/utils.js +2 -1
  96. package/dist/schema/utils.js.map +1 -1
  97. package/dist/signals/sanitizer.d.ts +1 -1
  98. package/dist/signals/sanitizer.d.ts.map +1 -1
  99. package/dist/signals/sanitizer.js +12 -2
  100. package/dist/signals/sanitizer.js.map +1 -1
  101. package/dist/smrt-knowledge.json +4 -4
  102. package/dist/system/types.d.ts +2 -2
  103. package/dist/system/types.d.ts.map +1 -1
  104. package/dist/system-fields.d.ts +5 -43
  105. package/dist/system-fields.d.ts.map +1 -1
  106. package/dist/system-fields.js +2 -1
  107. package/dist/system-fields.js.map +1 -1
  108. package/dist/test-utils.d.ts +39 -13
  109. package/dist/test-utils.d.ts.map +1 -1
  110. package/dist/testing/database.d.ts.map +1 -1
  111. package/dist/testing/database.js.map +1 -1
  112. package/dist/tools/tool-executor.d.ts +19 -5
  113. package/dist/tools/tool-executor.d.ts.map +1 -1
  114. package/dist/tools/tool-executor.js +4 -2
  115. package/dist/tools/tool-executor.js.map +1 -1
  116. package/dist/tools/tool-generator.d.ts +8 -1
  117. package/dist/tools/tool-generator.d.ts.map +1 -1
  118. package/dist/tools/tool-generator.js +10 -11
  119. package/dist/tools/tool-generator.js.map +1 -1
  120. package/dist/utils/json.js.map +1 -1
  121. package/dist/utils.d.ts +16 -8
  122. package/dist/utils.d.ts.map +1 -1
  123. package/dist/utils.js.map +1 -1
  124. package/dist/vite-plugin/index.d.ts.map +1 -1
  125. package/dist/vite-plugin/index.js +9 -7
  126. package/dist/vite-plugin/index.js.map +1 -1
  127. package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
  128. package/dist/vite-plugin/sveltekit-generator.js +4 -3
  129. package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
  130. package/dist/vite-plugin/templates/default-ui.ts +20 -6
  131. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sources":["../../src/schema/generator.ts"],"sourcesContent":["/**\n * Schema generator for SMRT objects\n * Converts AST field definitions to database schema definitions\n */\n\nimport { createHash } from 'node:crypto';\nimport type {\n FieldDefinition,\n ManifestColumnDefinition,\n ManifestIndexDefinition,\n ManifestSchema,\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types.js';\nimport { classnameToTablename } from '../utils/naming.js';\nimport { getDDLStrategy } from './ddl/index.js';\nimport type { DatabaseEngine } from './ddl/types.js';\nimport {\n formatDefaultValue as formatDefaultValueShared,\n quoteIdentifier,\n quoteStringLiteral,\n} from './sql-identifiers.js';\nimport type {\n ColumnDefinition,\n ForeignKeyDefinition,\n IndexDefinition,\n SchemaDefinition,\n SQLDataType,\n TriggerDefinition,\n} from './types.js';\n\ntype SchemaGeneratorConfig = {\n conflictColumns?: string[];\n idType?: 'uuid' | 'text';\n registry?: {\n getConfig?(className: string): { idType?: 'uuid' | 'text' };\n getDescendants(baseClassName: string): string[];\n getAllFields(className: string): Promise<Map<string, any>>;\n getSTIBase?(className: string): string | null;\n };\n};\n\nexport class SchemaGenerator {\n /**\n * Generate schema definition from SMRT object definition\n */\n generateSchema(objectDef: SmartObjectDefinition): SchemaDefinition {\n const tableName = this.getTableName(objectDef);\n const columns = this.generateColumns(\n objectDef.fields,\n objectDef.decoratorConfig,\n );\n const indexes = this.generateIndexes(objectDef, columns);\n const triggers = this.generateTriggers(objectDef, tableName);\n const foreignKeys = this.extractForeignKeys(columns);\n const dependencies = this.extractDependencies(objectDef, foreignKeys);\n const version = this.generateVersion(objectDef);\n\n return {\n tableName,\n columns,\n indexes,\n triggers,\n foreignKeys,\n dependencies,\n version,\n packageName: this.extractPackageName(objectDef.filePath),\n baseClass: objectDef.extends,\n };\n }\n\n /**\n * Convert field type to SQL data type\n */\n private mapFieldTypeToSQL(fieldType: FieldDefinition['type']): SQLDataType {\n switch (fieldType) {\n case 'text':\n return 'TEXT';\n case 'integer':\n return 'INTEGER';\n case 'decimal':\n return 'REAL';\n case 'boolean':\n return 'BOOLEAN';\n case 'datetime':\n return 'TIMESTAMP';\n case 'json':\n return 'JSON';\n case 'foreignKey':\n return 'UUID'; // Foreign keys default to UUID, then same-package refs can be reconciled to target idType\n case 'crossPackageRef':\n return 'UUID'; // Cross-package refs are UUID ids with no DDL FK constraint\n default:\n return 'TEXT'; // Default fallback\n }\n }\n\n private getIdColumnType(config?: { idType?: 'uuid' | 'text' }): SQLDataType {\n return config?.idType === 'text' ? 'TEXT' : 'UUID';\n }\n\n private getRelationshipColumnType(field: any): SQLDataType {\n if (field?._meta?.sqlType) {\n return String(field._meta.sqlType).toUpperCase() as SQLDataType;\n }\n\n if (\n field?.type === 'crossPackageRef' &&\n (field._meta?.idType === 'text' || field.idType === 'text')\n ) {\n return 'TEXT';\n }\n\n return this.mapFieldTypeToSQL(field?.type || 'text');\n }\n\n private getReferenceKind(\n field: any,\n ): ColumnDefinition['referenceKind'] | undefined {\n if (\n field?.__tenancy?.isTenantIdField ||\n field?._meta?.__tenancy?.isTenantIdField\n ) {\n return 'tenantId';\n }\n\n if (field?.type === 'foreignKey') {\n return 'foreignKey';\n }\n\n if (field?.type === 'crossPackageRef') {\n return 'crossPackageRef';\n }\n\n return undefined;\n }\n\n private shouldEmitDefault(field: any, defaultValue: unknown): boolean {\n return !(\n this.getReferenceKind(field) === 'tenantId' &&\n this.getRelationshipColumnType(field) === 'UUID' &&\n defaultValue === ''\n );\n }\n\n private getRegistryTargetIdColumnType(\n relatedName: string | undefined,\n registry: SchemaGeneratorConfig['registry'] | undefined,\n ): SQLDataType | undefined {\n if (!relatedName || !registry?.getConfig) {\n return undefined;\n }\n\n const targetName = relatedName.split('.')[0];\n const targetNames = [targetName];\n const stiBase = registry.getSTIBase?.(targetName);\n if (stiBase && !targetNames.includes(stiBase)) {\n targetNames.push(stiBase);\n }\n\n for (const name of targetNames) {\n const idType = registry.getConfig(name)?.idType;\n if (idType === 'text') {\n return 'TEXT';\n }\n if (idType === 'uuid') {\n return 'UUID';\n }\n }\n\n return undefined;\n }\n\n private reconcileRegistryForeignKeyColumnTypes(\n columns: Record<string, ColumnDefinition>,\n fields: Map<string, any>,\n registry: SchemaGeneratorConfig['registry'] | undefined,\n ): void {\n if (!registry?.getConfig) {\n return;\n }\n\n for (const [fieldName, field] of fields.entries()) {\n if (field.type !== 'foreignKey' || field._meta?.sqlType) {\n continue;\n }\n\n const targetIdType = this.getRegistryTargetIdColumnType(\n field.related,\n registry,\n );\n if (!targetIdType) {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n if (columns[columnName]) {\n columns[columnName] = {\n ...columns[columnName],\n type: targetIdType,\n };\n }\n }\n }\n\n /**\n * Generate column definitions\n */\n private generateColumns(\n fields: Record<string, FieldDefinition>,\n config?: { idType?: 'uuid' | 'text' },\n ): Record<string, ColumnDefinition> {\n const columns: Record<string, ColumnDefinition> = {};\n\n // Always include base SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n\n // Add fields from object definition\n for (const [fieldName, fieldDef] of Object.entries(fields)) {\n // Skip id fields as we handle them above\n if (\n fieldName === 'id' ||\n fieldName === 'created_at' ||\n fieldName === 'updated_at'\n ) {\n continue;\n }\n\n // Skip transient fields (non-persisted)\n // NOTE: This filtering logic must match SmrtObject.toJSON()\n // Changes to field filtering should be applied in BOTH places\n if (fieldDef.transient || fieldDef._meta?.transient) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n // oneToMany and manyToMany are relationship metadata, not actual database columns\n // foreignKey DOES create a column (it stores the foreign key ID)\n // NOTE: This must match the filtering in SmrtObject.toJSON()\n if (fieldDef.type === 'oneToMany' || fieldDef.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column (STI only)\n // In CTI mode, meta fields shouldn't be used, but skip them anyway for safety\n if (fieldDef.type === 'meta') {\n continue;\n }\n\n const column: ColumnDefinition = {\n type: this.getRelationshipColumnType(fieldDef),\n referenceKind: this.getReferenceKind(fieldDef),\n // If _meta.nullable is true, the field can be null regardless of required\n // This handles field helpers like text({ required: true, nullable: true })\n notNull: fieldDef._meta?.nullable ? false : fieldDef.required || false,\n unique: fieldDef._meta?.unique || false,\n description: fieldDef.description,\n };\n\n // Handle default values\n if (\n fieldDef.default !== undefined &&\n this.shouldEmitDefault(fieldDef, fieldDef.default)\n ) {\n column.defaultValue = fieldDef.default;\n }\n // Note: Removed automatic NOT NULL DEFAULT '' for TEXT columns\n // This was forcing all TEXT fields to be NOT NULL regardless of required option\n // If DuckDB ANY type inference is an issue, it should be handled at the adapter level\n // or with an explicit field option, not by silently changing schema semantics\n\n // Handle foreign keys\n if (fieldDef.type === 'foreignKey' && fieldDef.related) {\n const [table, columnName = 'id'] = fieldDef.related.split('.');\n column.foreignKey = {\n table,\n column: columnName,\n onDelete: 'CASCADE', // Default behavior\n onUpdate: 'CASCADE',\n };\n }\n\n // Handle unique constraints\n if (fieldName === 'slug' || fieldName === 'email') {\n column.unique = true;\n }\n\n columns[fieldName] = column;\n }\n\n return columns;\n }\n\n /**\n * Generate index definitions\n */\n private generateIndexes(\n objectDef: SmartObjectDefinition,\n columns: Record<string, ColumnDefinition>,\n ): IndexDefinition[] {\n const indexes: IndexDefinition[] = [];\n const tableName = this.getTableName(objectDef);\n\n // Create indexes for foreign keys\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.foreignKey) {\n indexes.push({\n name: `idx_${tableName}_${columnName}`,\n columns: [columnName],\n description: `Index for foreign key ${columnName}`,\n });\n }\n }\n\n // Create index for updated_at (common query pattern)\n indexes.push({\n name: `idx_${tableName}_updated_at`,\n columns: ['updated_at'],\n description: 'Index for timestamp queries',\n });\n\n // Create unique indexes\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.unique && !columnDef.primaryKey) {\n indexes.push({\n name: `idx_${tableName}_${columnName}_unique`,\n columns: [columnName],\n unique: true,\n description: `Unique index for ${columnName}`,\n });\n }\n }\n\n return indexes;\n }\n\n /**\n * Generate trigger definitions for automatic timestamp updates\n */\n private generateTriggers(\n _objectDef: SmartObjectDefinition,\n tableName: string,\n ): TriggerDefinition[] {\n return [\n {\n name: `trg_${tableName}_updated_at`,\n when: 'BEFORE',\n event: 'UPDATE',\n body: `UPDATE ${quoteIdentifier(tableName)} SET \"updated_at\" = current_timestamp WHERE \"id\" = NEW.\"id\";`,\n description: 'Automatically update updated_at timestamp',\n },\n ];\n }\n\n /**\n * Extract foreign key definitions\n */\n private extractForeignKeys(\n columns: Record<string, ColumnDefinition>,\n ): ForeignKeyDefinition[] {\n const foreignKeys: ForeignKeyDefinition[] = [];\n\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.foreignKey) {\n foreignKeys.push({\n column: columnName,\n referencesTable: columnDef.foreignKey.table,\n referencesColumn: columnDef.foreignKey.column,\n onDelete: columnDef.foreignKey.onDelete,\n onUpdate: columnDef.foreignKey.onUpdate,\n });\n }\n }\n\n return foreignKeys;\n }\n\n /**\n * Extract schema dependencies from foreign keys and inheritance\n */\n private extractDependencies(\n objectDef: SmartObjectDefinition,\n foreignKeys: ForeignKeyDefinition[],\n ): string[] {\n const dependencies = new Set<string>();\n\n // Add dependencies from foreign keys\n for (const fk of foreignKeys) {\n dependencies.add(fk.referencesTable);\n }\n\n // Add dependencies from base class\n if (\n objectDef.extends &&\n objectDef.extends !== 'SmrtObject' &&\n objectDef.extends !== 'SmrtCollection'\n ) {\n dependencies.add(this.classNameToTableName(objectDef.extends));\n }\n\n return Array.from(dependencies);\n }\n\n /**\n * Generate version hash for schema\n */\n private generateVersion(objectDef: SmartObjectDefinition): string {\n const content = JSON.stringify({\n className: objectDef.className,\n fields: objectDef.fields,\n extends: objectDef.extends,\n });\n return createHash('sha256').update(content).digest('hex').substring(0, 8);\n }\n\n /**\n * Get table name from object definition\n */\n private getTableName(objectDef: SmartObjectDefinition): string {\n return this.classNameToTableName(objectDef.className);\n }\n\n /**\n * Convert class name to table name (camelCase to snake_case, pluralized)\n */\n private classNameToTableName(className: string): string {\n return classnameToTablename(className);\n }\n\n /**\n * Extract package name from file path\n */\n private extractPackageName(filePath: string): string {\n const match = filePath.match(/packages\\/([^/]+)/);\n return match ? match[1] : 'unknown';\n }\n\n /**\n * Generate schema definition from ObjectRegistry fields (runtime)\n *\n * This method builds a SchemaDefinition from ObjectRegistry cached fields,\n * enabling schema generation from decorated classes at runtime.\n *\n * @param className - Class name to look up in ObjectRegistry\n * @param tableName - Table name (from SMRT_TABLE_NAME or derived)\n * @param fields - Map of Field definitions from ObjectRegistry\n * @returns Schema definition object\n */\n generateSchemaFromRegistry(\n className: string,\n tableName: string,\n fields: Map<string, any>,\n config?: SchemaGeneratorConfig,\n ): SchemaDefinition {\n const columns: Record<string, ColumnDefinition> = {};\n\n // Check for custom primary key\n let hasCustomPK = false;\n for (const [_fieldName, field] of fields.entries()) {\n if (field._meta?.primaryKey) {\n hasCustomPK = true;\n break;\n }\n }\n\n // Add default SMRT fields if no custom primary key\n if (!hasCustomPK) {\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n description: 'URL-friendly identifier',\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n defaultValue: '',\n description: 'Context for slug scoping',\n };\n }\n\n // Track timestamp fields to avoid duplicates\n let hasCreatedAt = false;\n let hasUpdatedAt = false;\n // Track regular (column-backed) fields that opted into a plain column index\n // via `indexed: true`. FK, unique, and meta fields each go through their\n // own dedicated index emission paths and are excluded from this set.\n const indexedColumns = new Set<string>();\n\n // Add fields from ObjectRegistry\n for (const [fieldName, field] of fields.entries()) {\n // Skip transient fields (non-persisted)\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n const isDefaultSmrtColumn =\n fieldName === 'id' || fieldName === 'slug' || fieldName === 'context';\n\n // Default SMRT columns are added above when we use the standard primary\n // key path. When a class declares a custom primary key, only explicitly\n // declared id/slug/context fields should survive this loop.\n if (\n isDefaultSmrtColumn &&\n (!hasCustomPK || field._meta?.__smrtSystemField === true)\n ) {\n continue;\n }\n\n // Track timestamp fields\n if (fieldName === 'created_at' || fieldName === 'createdAt') {\n if (hasCreatedAt) continue;\n hasCreatedAt = true;\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n continue;\n }\n if (fieldName === 'updated_at' || fieldName === 'updatedAt') {\n if (hasUpdatedAt) continue;\n hasUpdatedAt = true;\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n continue;\n }\n\n // Skip relationship fields that don't create columns\n // oneToMany and manyToMany are relationship metadata, not actual database columns\n // foreignKey DOES create a column (it stores the foreign key ID)\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column (STI only)\n // In CTI mode, meta fields shouldn't be used, but skip them anyway for safety\n if (field.type === 'meta') {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // If _meta.nullable is true, the field can be null regardless of required\n notNull: field._meta?.nullable ? false : field._meta?.required || false,\n primaryKey: field._meta?.primaryKey || false,\n unique: field._meta?.unique || false,\n description: field._meta?.description,\n };\n\n // Get default value\n if (\n field._meta?.default !== undefined &&\n this.shouldEmitDefault(field, field._meta.default)\n ) {\n columnDef.defaultValue = field._meta.default;\n }\n // Note: Removed automatic NOT NULL DEFAULT '' for TEXT columns\n // This was forcing all TEXT fields to be NOT NULL regardless of required option\n // If DuckDB ANY type inference is an issue, it should be handled at the adapter level\n // or with an explicit field option, not by silently changing schema semantics\n\n // Handle foreign keys\n if (field.type === 'foreignKey') {\n // Type cast to access relationship-specific properties\n const relatedName = field.related; // Top-level property\n const onDeleteAction = (field._meta as any)?.onDelete;\n\n if (relatedName) {\n columnDef.foreignKey = {\n table: this.classNameToTableName(relatedName),\n column: 'id',\n onDelete: onDeleteAction || 'CASCADE',\n onUpdate: 'CASCADE',\n };\n }\n }\n\n // Track opt-in column indexes for regular (non-FK, non-unique) fields.\n // FK columns already get auto-indexed below; unique columns produce\n // their own unique index; meta fields go through the jsonPath path.\n const isIndexed =\n field._meta?.indexed === true || (field as any).indexed === true;\n if (\n isIndexed &&\n !columnDef.foreignKey &&\n !columnDef.unique &&\n !columnDef.primaryKey\n ) {\n indexedColumns.add(this.toSnakeCase(fieldName));\n }\n\n columns[this.toSnakeCase(fieldName)] = columnDef;\n }\n\n // Ensure timestamp columns exist\n if (!hasCreatedAt) {\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n }\n if (!hasUpdatedAt) {\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n }\n\n this.reconcileRegistryForeignKeyColumnTypes(\n columns,\n fields,\n config?.registry,\n );\n\n // Generate indexes\n const indexes: IndexDefinition[] = [];\n\n if (!hasCustomPK) {\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n description: 'Primary key index',\n });\n\n const conflictColumns = config?.conflictColumns || ['slug', 'context'];\n const conflictIndexName =\n conflictColumns.length > 2\n ? `${tableName}_${conflictColumns.slice(0, 2).join('_')}_idx`\n : `${tableName}_${conflictColumns.join('_')}_idx`;\n\n indexes.push({\n name: conflictIndexName,\n columns: conflictColumns,\n unique: true,\n description: `Unique conflict index for ${className}`,\n });\n } else {\n // Find custom PK column and create index\n for (const [colName, colDef] of Object.entries(columns)) {\n if (colDef.primaryKey) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Primary key index`,\n });\n break;\n }\n }\n }\n\n // Create indexes for foreign keys\n for (const [colName, colDef] of Object.entries(columns)) {\n if (colDef.foreignKey) {\n indexes.push({\n name: `idx_${tableName}_${colName}`,\n columns: [colName],\n description: `Foreign key index for ${colName}`,\n });\n }\n }\n\n // Emit opt-in column indexes for regular fields tagged with `indexed: true`\n for (const colName of indexedColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Index for ${colName}`,\n });\n }\n\n return {\n tableName,\n columns,\n indexes,\n triggers: [],\n foreignKeys: this.extractForeignKeys(columns),\n dependencies: [],\n version: createHash('sha256')\n .update(JSON.stringify(columns))\n .digest('hex')\n .substring(0, 8),\n packageName: 'runtime',\n baseClass: 'SmrtObject',\n };\n }\n\n /**\n * Generate STI (Single Table Inheritance) schema from ObjectRegistry fields\n *\n * Creates a shared table for an inheritance hierarchy with:\n * - _meta_type: Discriminator column to identify class type\n * - _meta_data: JSON column for flexible field storage\n * - Union of all FK columns from descendants (all nullable)\n * - Partial indexes for FK columns (filtered by _meta_type)\n *\n * @param baseClassName - Base class name for the STI hierarchy\n * @param tableName - Shared table name (from base class)\n * @param fields - Map of Field definitions from base class\n * @returns Schema definition object for STI table\n * @example\n * ```typescript\n * @smrt({ tableStrategy: 'sti' })\n * class Event extends SmrtObject {\n * title: string = '';\n * }\n *\n * @smrt()\n * class Meeting extends Event {\n * roomId = foreignKey(Room);\n * }\n *\n * // Generates single table 'events' with:\n * // - title (from Event)\n * // - room_id (from Meeting, nullable)\n * // - _meta_type TEXT NOT NULL (discriminator)\n * // - _meta_data JSON (flexible storage)\n * ```\n */\n async generateSTISchemaFromRegistry(\n baseClassName: string,\n tableName: string,\n _fields: Map<string, any>,\n config?: SchemaGeneratorConfig,\n ): Promise<SchemaDefinition> {\n const ObjectRegistry =\n config?.registry ?? (await import('../registry.js')).ObjectRegistry;\n const columns: Record<string, ColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n description: 'URL-friendly identifier',\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n defaultValue: '',\n description: 'Context for slug scoping',\n };\n\n // Add STI discriminator column\n columns._meta_type = {\n type: 'TEXT',\n notNull: true,\n description: 'Class type discriminator for STI',\n };\n\n // Add meta column for flexible storage\n columns._meta_data = {\n type: 'JSON',\n notNull: false,\n description: 'Flexible JSON storage for meta() fields',\n };\n\n // Track timestamp fields to avoid duplicates\n let hasCreatedAt = false;\n let hasUpdatedAt = false;\n\n // Get all descendants to aggregate fields\n const descendants = ObjectRegistry.getDescendants(baseClassName);\n const allClassNames = [baseClassName, ...descendants];\n\n // Track FK columns by class for partial indexes\n const fkColumnsByClass = new Map<string, Set<string>>();\n // Track meta fields opted into JSON-path indexing (deduped across STI subtypes)\n const indexedMetaFields = new Set<string>();\n // Track regular-field columns opted into plain column indexing\n const indexedStiColumns = new Set<string>();\n\n // Aggregate fields from base and all descendants\n for (const className of allClassNames) {\n const classFields = await ObjectRegistry.getAllFields(className);\n fkColumnsByClass.set(className, new Set());\n\n for (const [fieldName, field] of classFields.entries()) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Capture indexed meta fields before the skip-meta branch below\n if (\n field.type === 'meta' &&\n (field.indexed === true || field._meta?.indexed === true)\n ) {\n indexedMetaFields.add(fieldName);\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context'\n ) {\n continue;\n }\n\n // Track timestamp fields\n if (fieldName === 'created_at' || fieldName === 'createdAt') {\n if (hasCreatedAt) continue;\n hasCreatedAt = true;\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n continue;\n }\n if (fieldName === 'updated_at' || fieldName === 'updatedAt') {\n if (hasUpdatedAt) continue;\n hasUpdatedAt = true;\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n\n // Check if column already exists (inherited from parent)\n if (columns[columnName]) {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // STI: All columns nullable (union of child fields)\n notNull: false,\n primaryKey: false,\n unique: false,\n description: field._meta?.description,\n };\n\n // Get default value (but not applied in STI - defaults handled by application)\n if (\n field._meta?.default !== undefined &&\n this.shouldEmitDefault(field, field._meta.default)\n ) {\n columnDef.defaultValue = field._meta.default;\n }\n\n // Handle foreign keys\n if (field.type === 'foreignKey') {\n const relatedName = field.related; // Top-level property\n const onDeleteAction = (field._meta as any)?.onDelete;\n\n if (relatedName) {\n columnDef.foreignKey = {\n table: this.classNameToTableName(relatedName),\n column: 'id',\n onDelete: onDeleteAction || 'CASCADE',\n onUpdate: 'CASCADE',\n };\n\n // Track FK column for this class (for partial indexes)\n fkColumnsByClass.get(className)?.add(columnName);\n }\n }\n\n // Track opt-in column indexes for regular STI columns\n const isIndexed =\n field._meta?.indexed === true || (field as any).indexed === true;\n if (isIndexed && !columnDef.foreignKey) {\n indexedStiColumns.add(columnName);\n }\n\n columns[columnName] = columnDef;\n }\n }\n\n // Ensure timestamp columns exist\n if (!hasCreatedAt) {\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n }\n if (!hasUpdatedAt) {\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n }\n\n for (const className of allClassNames) {\n const classFields = await ObjectRegistry.getAllFields(className);\n this.reconcileRegistryForeignKeyColumnTypes(\n columns,\n classFields,\n ObjectRegistry,\n );\n }\n\n // Generate indexes\n const indexes: IndexDefinition[] = [];\n\n // Primary key index\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n description: 'Primary key index',\n });\n\n // Unique index for slug, context, and type (STI variation).\n // STI subclasses share a table, so the discriminator participates in\n // identity — two subtypes can share the same (slug, context). PostgreSQL\n // UPSERT requires the live schema to carry a matching unique index; the\n // migration differ repairs older deployments where this index was created\n // non-unique or never created at all (issue #1165).\n indexes.push({\n name: `${tableName}_slug_context_meta_type_idx`,\n columns: ['slug', 'context', '_meta_type'],\n unique: true,\n description: 'Unique index for slug, context, and type',\n });\n\n // Index on type column (for polymorphic queries)\n indexes.push({\n name: `${tableName}_meta_type_idx`,\n columns: ['_meta_type'],\n description: 'Index for type discriminator queries',\n });\n\n // Partial indexes for FK columns (filtered by type)\n for (const [className, fkColumns] of fkColumnsByClass.entries()) {\n for (const fkColumn of fkColumns) {\n indexes.push({\n name: `idx_${tableName}_${fkColumn}_${className.toLowerCase()}`,\n columns: [fkColumn],\n where: `_meta_type = ${quoteStringLiteral(className)}`,\n description: `Partial index for ${fkColumn} in ${className} rows`,\n });\n }\n }\n\n // JSON-path indexes for @meta({ indexed: true }) fields\n for (const fieldName of indexedMetaFields) {\n indexes.push({\n name: `${tableName}_meta_${this.toSnakeCase(fieldName)}_idx`,\n columns: [],\n jsonPath: { column: '_meta_data', path: fieldName },\n description: `JSON-path index for @meta({ indexed: true }) field ${fieldName}`,\n });\n }\n\n // Plain column indexes for regular STI columns opted in via `indexed: true`\n for (const colName of indexedStiColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Index for ${colName}`,\n });\n }\n\n return {\n tableName,\n columns,\n indexes,\n triggers: [],\n foreignKeys: this.extractForeignKeys(columns),\n dependencies: [],\n version: createHash('sha256')\n .update(JSON.stringify({ columns, baseClassName, descendants }))\n .digest('hex')\n .substring(0, 8),\n packageName: 'runtime',\n baseClass: 'SmrtObject',\n };\n }\n\n /**\n * Generate STI schema from manifest data (build-time, no runtime registry)\n *\n * This method generates STI schema purely from manifest data, without depending\n * on ObjectRegistry. This enables pre-generating schemas at build time for\n * efficient external package consumption.\n *\n * @param baseClassName - Base class name for the STI hierarchy\n * @param tableName - Shared table name (from base class)\n * @param baseFields - Fields from the base class\n * @param manifest - Full manifest containing all objects\n * @returns ManifestSchema for storage in manifest.json\n */\n generateSTISchemaFromManifest(\n baseClassName: string,\n tableName: string,\n _baseFields: Record<string, FieldDefinition>,\n manifest: SmartObjectManifest,\n config?: SchemaGeneratorConfig,\n ): ManifestSchema {\n const columns: Record<string, ManifestColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n default: '',\n };\n\n // Add STI discriminator column\n columns._meta_type = {\n type: 'TEXT',\n notNull: true,\n };\n\n // Add meta column for flexible storage\n columns._meta_data = {\n type: 'JSON',\n notNull: false,\n };\n\n // Timestamp fields\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n // Find all descendants in manifest\n const descendants = this.findDescendantsInManifest(baseClassName, manifest);\n const allClassNames = [baseClassName, ...descendants];\n\n // Track FK columns by class for partial indexes\n const fkColumnsByClass = new Map<string, Set<string>>();\n // Track meta fields opted into JSON-path indexing (deduped across STI subtypes)\n const indexedMetaFields = new Set<string>();\n // Track regular columns opted into plain column indexing\n const indexedStiColumns = new Set<string>();\n\n // Aggregate fields from base and all descendants\n for (const className of allClassNames) {\n const objDef = manifest.objects[className];\n if (!objDef) continue;\n\n fkColumnsByClass.set(className, new Set());\n\n for (const [fieldName, field] of Object.entries(objDef.fields)) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Capture indexed meta fields before the skip-meta branch below\n if (\n field.type === 'meta' &&\n ((field as any).indexed === true ||\n (field as any)._meta?.indexed === true)\n ) {\n indexedMetaFields.add(fieldName);\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context' ||\n fieldName === 'created_at' ||\n fieldName === 'createdAt' ||\n fieldName === 'updated_at' ||\n fieldName === 'updatedAt'\n ) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n\n // Check if column already exists (inherited from parent)\n if (columns[columnName]) {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ManifestColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // STI: All columns nullable (union of child fields)\n notNull: false,\n };\n\n // Get default value\n if (\n field.default !== undefined &&\n this.shouldEmitDefault(field, field.default)\n ) {\n columnDef.default = field.default;\n }\n\n // Track FK columns for this class (for partial indexes)\n if (field.type === 'foreignKey') {\n fkColumnsByClass.get(className)?.add(columnName);\n }\n\n // Track opt-in column indexes for regular STI columns\n const isIndexed =\n (field as any).indexed === true ||\n (field as any)._meta?.indexed === true;\n if (isIndexed && field.type !== 'foreignKey') {\n indexedStiColumns.add(columnName);\n }\n\n columns[columnName] = columnDef;\n }\n }\n\n // Generate indexes\n const indexes: ManifestIndexDefinition[] = [];\n\n // Primary key index\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n });\n\n // Unique index for slug, context, and type (STI variation) — see\n // generateSTISchemaFromRegistry for the rationale.\n indexes.push({\n name: `${tableName}_slug_context_meta_type_idx`,\n columns: ['slug', 'context', '_meta_type'],\n unique: true,\n });\n\n // Index on type column (for polymorphic queries)\n indexes.push({\n name: `${tableName}_meta_type_idx`,\n columns: ['_meta_type'],\n });\n\n // JSON-path indexes for @meta({ indexed: true }) fields\n for (const fieldName of indexedMetaFields) {\n indexes.push({\n name: `${tableName}_meta_${this.toSnakeCase(fieldName)}_idx`,\n columns: [],\n jsonPath: { column: '_meta_data', path: fieldName },\n });\n }\n\n // Plain column indexes for regular STI columns opted in via `indexed: true`\n for (const colName of indexedStiColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n });\n }\n\n // Generate DDL\n const schemaDefinition: SchemaDefinition = {\n tableName,\n columns: this.convertManifestColumnsToSchemaColumns(columns),\n indexes: indexes.map((idx) => ({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n where: idx.where,\n jsonPath: idx.jsonPath,\n })),\n triggers: [],\n foreignKeys: [],\n dependencies: [],\n version: '',\n packageName: '',\n };\n\n const ddl = this.generateSQL(schemaDefinition);\n\n // Generate version hash\n const version = createHash('sha256')\n .update(JSON.stringify({ columns, baseClassName, descendants }))\n .digest('hex')\n .substring(0, 8);\n\n return {\n tableName,\n ddl,\n columns,\n indexes,\n version,\n };\n }\n\n /**\n * Generate CTI (Class Table Inheritance) schema from manifest data\n *\n * @param className - Class name\n * @param tableName - Table name\n * @param fields - Fields from the class\n * @returns ManifestSchema for storage in manifest.json\n */\n generateCTISchemaFromManifest(\n className: string,\n tableName: string,\n fields: Record<string, FieldDefinition>,\n config?: SchemaGeneratorConfig,\n ): ManifestSchema {\n const columns: Record<string, ManifestColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n default: '',\n };\n\n // Timestamp fields\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n // Add class fields\n for (const [fieldName, field] of Object.entries(fields)) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context' ||\n fieldName === 'created_at' ||\n fieldName === 'createdAt' ||\n fieldName === 'updated_at' ||\n fieldName === 'updatedAt'\n ) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ManifestColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n notNull: field._meta?.nullable ? false : field.required || false,\n unique: field._meta?.unique || false,\n };\n\n if (\n field.default !== undefined &&\n this.shouldEmitDefault(field, field.default)\n ) {\n columnDef.default = field.default;\n }\n\n columns[columnName] = columnDef;\n }\n\n // Generate indexes\n const indexes: ManifestIndexDefinition[] = [];\n\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n });\n\n // Use custom conflict columns if provided, otherwise default to slug+context\n const conflictColumns = config?.conflictColumns || ['slug', 'context'];\n const indexName =\n conflictColumns.length > 2\n ? `${tableName}_${conflictColumns.slice(0, 2).join('_')}_idx`\n : `${tableName}_${conflictColumns.join('_')}_idx`;\n\n indexes.push({\n name: indexName,\n columns: conflictColumns,\n unique: true,\n });\n\n // Generate DDL\n const schemaDefinition: SchemaDefinition = {\n tableName,\n columns: this.convertManifestColumnsToSchemaColumns(columns),\n indexes: indexes.map((idx) => ({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n where: idx.where,\n jsonPath: idx.jsonPath,\n })),\n triggers: [],\n foreignKeys: [],\n dependencies: [],\n version: '',\n packageName: '',\n };\n\n const ddl = this.generateSQL(schemaDefinition);\n\n // Generate version hash\n const version = createHash('sha256')\n .update(JSON.stringify({ columns, className }))\n .digest('hex')\n .substring(0, 8);\n\n return {\n tableName,\n ddl,\n columns,\n indexes,\n version,\n };\n }\n\n /**\n * Find all descendants of a class in the manifest\n *\n * Note: Manifest keys are now qualified names (@pkg:ClassName) but `extends` field\n * stores simple PascalCase class names. We need to handle both qualified and simple\n * name lookups.\n *\n * Issue #713: Updated to handle qualified names in manifest keys\n */\n private findDescendantsInManifest(\n baseClassName: string,\n manifest: SmartObjectManifest,\n visited: Set<string> = new Set(),\n ): string[] {\n const descendants: string[] = [];\n\n // Prevent infinite recursion (e.g., class extends same-named class from another package)\n if (visited.has(baseClassName)) return descendants;\n visited.add(baseClassName);\n\n // Extract the simple class name from qualified name if needed\n // e.g., '@happyvertical/smrt-core:PolyEvent' -> 'PolyEvent'\n const simpleBaseClassName = baseClassName.includes(':')\n ? baseClassName.split(':').pop() || baseClassName\n : baseClassName;\n const baseClassLower = simpleBaseClassName.toLowerCase();\n\n for (const [name, obj] of Object.entries(manifest.objects)) {\n // Skip self-references (class extending same-named class from another package)\n if (\n obj.className.toLowerCase() === baseClassLower &&\n obj.extends?.toLowerCase() === baseClassLower\n ) {\n continue;\n }\n // obj.extends is a simple class name (e.g., 'PolyEvent')\n // Compare with the simple (non-qualified) version of the base class name\n if (obj.extends?.toLowerCase() === baseClassLower) {\n descendants.push(name);\n // Recursively find descendants of this class\n // Pass the qualified name (manifest key) for recursive lookup\n descendants.push(\n ...this.findDescendantsInManifest(name, manifest, visited),\n );\n }\n }\n\n return descendants;\n }\n\n /**\n * Convert ManifestColumnDefinition to ColumnDefinition\n */\n private convertManifestColumnsToSchemaColumns(\n manifestColumns: Record<string, ManifestColumnDefinition>,\n ): Record<string, ColumnDefinition> {\n const columns: Record<string, ColumnDefinition> = {};\n\n for (const [name, col] of Object.entries(manifestColumns)) {\n columns[name] = {\n type: col.type as SQLDataType,\n primaryKey: col.primaryKey,\n referenceKind: col.referenceKind,\n notNull: col.notNull,\n unique: col.unique,\n defaultValue: col.default,\n };\n }\n\n return columns;\n }\n\n /**\n * Convert camelCase to snake_case\n */\n private toSnakeCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n }\n\n /**\n * Generate SQL CREATE TABLE statement from schema definition\n *\n * This is the single source of truth for SQL generation, consolidating\n * logic that was previously duplicated across multiple code paths.\n *\n * @param schema - Schema definition object\n * @returns SQL CREATE TABLE statement with indexes\n */\n generateSQL(schema: SchemaDefinition, engine?: DatabaseEngine): string {\n // NOTE: We no longer append indexes to DDL string here.\n // The SDK expects ddl to contain ONLY the CREATE TABLE statement.\n // Indexes are stored separately in schema.indexes as SQL strings\n // and the SDK handles them via syncSchema() or dedicated index creation.\n if (engine) {\n return getDDLStrategy(engine).generateCreateTable(schema);\n }\n\n const { tableName, columns } = schema;\n let sql = `CREATE TABLE IF NOT EXISTS ${quoteIdentifier(tableName)} (\\n`;\n\n for (const [columnName, columnDef] of Object.entries(columns)) {\n const parts = [` ${quoteIdentifier(columnName)} ${columnDef.type}`];\n\n if (columnDef.primaryKey) {\n parts.push('PRIMARY KEY');\n }\n\n if (columnDef.notNull) {\n parts.push('NOT NULL');\n }\n\n if (columnDef.unique && !columnDef.primaryKey) {\n parts.push('UNIQUE');\n }\n\n if (columnDef.defaultValue !== undefined) {\n parts.push(\n `DEFAULT ${this.formatDefaultValue(\n columnDef.defaultValue,\n columnDef.type,\n )}`,\n );\n }\n\n sql += `${parts.join(' ')},\\n`;\n }\n\n return `${sql.slice(0, -2)}\\n);`;\n }\n\n /**\n * Format default value for SQL\n *\n * SQLite doesn't support CAST expressions in DEFAULT values (only literal values are allowed).\n * This method generates DEFAULT values that work with both SQLite and DuckDB.\n *\n * @param value - Default value\n * @param type - Column SQL type\n * @returns Formatted SQL default value expression\n */\n private formatDefaultValue(value: any, type: SQLDataType): string {\n // Delegate to the shared, injection-safe formatter so all DDL paths\n // converge on one set of rules (allowlisted keyword/function defaults\n // instead of \"contains `(`\", type-driven quoting, no string-\"null\" fold).\n // This path is engine-agnostic and never emits CAST expressions, so the\n // output stays valid for SQLite and DuckDB. Non-string TIMESTAMP defaults\n // fall back to lowercase `current_timestamp` to preserve prior output.\n return formatDefaultValueShared(value, type, {\n nonStringTimestampDefault: 'current_timestamp',\n });\n }\n}\n"],"names":["formatDefaultValueShared"],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sources":["../../src/schema/generator.ts"],"sourcesContent":["/**\n * Schema generator for SMRT objects\n * Converts AST field definitions to database schema definitions\n */\n\nimport { createHash } from 'node:crypto';\nimport type {\n FieldDefinition,\n FieldMeta,\n ManifestColumnDefinition,\n ManifestIndexDefinition,\n ManifestSchema,\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types.js';\nimport { classnameToTablename } from '../utils/naming.js';\nimport { getDDLStrategy } from './ddl/index.js';\nimport type { DatabaseEngine } from './ddl/types.js';\nimport {\n formatDefaultValue as formatDefaultValueShared,\n quoteIdentifier,\n quoteStringLiteral,\n} from './sql-identifiers.js';\nimport type {\n ColumnDefinition,\n ForeignKeyDefinition,\n IndexDefinition,\n SchemaDefinition,\n SQLDataType,\n TriggerDefinition,\n} from './types.js';\n\n/**\n * Structural shape of a field as read from either the build-time manifest\n * (`FieldDefinition`) or the runtime ObjectRegistry (`getAllFields()` returns\n * `Map<string, any>` upstream). The schema generator consumes both through a\n * single set of property reads, so this interface captures every field key the\n * generator touches without coupling to either source's exact type.\n *\n * `_meta` carries the structured field-helper metadata (`FieldMeta`); a few\n * legacy fields (`indexed`, `idType`, `__tenancy`) may also appear at the top\n * level depending on the source, so they are declared here too.\n */\ninterface RegistryField {\n type?: FieldDefinition['type'];\n related?: string;\n required?: boolean;\n default?: unknown;\n description?: string;\n transient?: boolean;\n indexed?: boolean;\n idType?: 'uuid' | 'text';\n __tenancy?: FieldMeta['__tenancy'];\n _meta?: FieldMeta;\n}\n\ntype SchemaGeneratorConfig = {\n conflictColumns?: string[];\n idType?: 'uuid' | 'text';\n registry?: {\n getConfig?(className: string): { idType?: 'uuid' | 'text' };\n getDescendants(baseClassName: string): string[];\n getAllFields(className: string): Promise<Map<string, RegistryField>>;\n getSTIBase?(className: string): string | null;\n };\n};\n\nexport class SchemaGenerator {\n /**\n * Generate schema definition from SMRT object definition\n */\n generateSchema(objectDef: SmartObjectDefinition): SchemaDefinition {\n const tableName = this.getTableName(objectDef);\n const columns = this.generateColumns(\n objectDef.fields,\n objectDef.decoratorConfig,\n );\n const indexes = this.generateIndexes(objectDef, columns);\n const triggers = this.generateTriggers(objectDef, tableName);\n const foreignKeys = this.extractForeignKeys(columns);\n const dependencies = this.extractDependencies(objectDef, foreignKeys);\n const version = this.generateVersion(objectDef);\n\n return {\n tableName,\n columns,\n indexes,\n triggers,\n foreignKeys,\n dependencies,\n version,\n packageName: this.extractPackageName(objectDef.filePath),\n baseClass: objectDef.extends,\n };\n }\n\n /**\n * Convert field type to SQL data type\n */\n private mapFieldTypeToSQL(fieldType: FieldDefinition['type']): SQLDataType {\n switch (fieldType) {\n case 'text':\n return 'TEXT';\n case 'integer':\n return 'INTEGER';\n case 'decimal':\n return 'REAL';\n case 'boolean':\n return 'BOOLEAN';\n case 'datetime':\n return 'TIMESTAMP';\n case 'json':\n return 'JSON';\n case 'foreignKey':\n return 'UUID'; // Foreign keys default to UUID, then same-package refs can be reconciled to target idType\n case 'crossPackageRef':\n return 'UUID'; // Cross-package refs are UUID ids with no DDL FK constraint\n default:\n return 'TEXT'; // Default fallback\n }\n }\n\n private getIdColumnType(config?: { idType?: 'uuid' | 'text' }): SQLDataType {\n return config?.idType === 'text' ? 'TEXT' : 'UUID';\n }\n\n private getRelationshipColumnType(field: RegistryField): SQLDataType {\n if (field?._meta?.sqlType) {\n return String(field._meta.sqlType).toUpperCase() as SQLDataType;\n }\n\n if (\n field?.type === 'crossPackageRef' &&\n (field._meta?.idType === 'text' || field.idType === 'text')\n ) {\n return 'TEXT';\n }\n\n return this.mapFieldTypeToSQL(field?.type || 'text');\n }\n\n private getReferenceKind(\n field: RegistryField,\n ): ColumnDefinition['referenceKind'] | undefined {\n if (\n field?.__tenancy?.isTenantIdField ||\n field?._meta?.__tenancy?.isTenantIdField\n ) {\n return 'tenantId';\n }\n\n if (field?.type === 'foreignKey') {\n return 'foreignKey';\n }\n\n if (field?.type === 'crossPackageRef') {\n return 'crossPackageRef';\n }\n\n return undefined;\n }\n\n private shouldEmitDefault(\n field: RegistryField,\n defaultValue: unknown,\n ): boolean {\n return !(\n this.getReferenceKind(field) === 'tenantId' &&\n this.getRelationshipColumnType(field) === 'UUID' &&\n defaultValue === ''\n );\n }\n\n private getRegistryTargetIdColumnType(\n relatedName: string | undefined,\n registry: SchemaGeneratorConfig['registry'] | undefined,\n ): SQLDataType | undefined {\n if (!relatedName || !registry?.getConfig) {\n return undefined;\n }\n\n const targetName = relatedName.split('.')[0];\n const targetNames = [targetName];\n const stiBase = registry.getSTIBase?.(targetName);\n if (stiBase && !targetNames.includes(stiBase)) {\n targetNames.push(stiBase);\n }\n\n for (const name of targetNames) {\n const idType = registry.getConfig(name)?.idType;\n if (idType === 'text') {\n return 'TEXT';\n }\n if (idType === 'uuid') {\n return 'UUID';\n }\n }\n\n return undefined;\n }\n\n private reconcileRegistryForeignKeyColumnTypes(\n columns: Record<string, ColumnDefinition>,\n fields: Map<string, RegistryField>,\n registry: SchemaGeneratorConfig['registry'] | undefined,\n ): void {\n if (!registry?.getConfig) {\n return;\n }\n\n for (const [fieldName, field] of fields.entries()) {\n if (field.type !== 'foreignKey' || field._meta?.sqlType) {\n continue;\n }\n\n const targetIdType = this.getRegistryTargetIdColumnType(\n field.related,\n registry,\n );\n if (!targetIdType) {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n if (columns[columnName]) {\n columns[columnName] = {\n ...columns[columnName],\n type: targetIdType,\n };\n }\n }\n }\n\n /**\n * Generate column definitions\n */\n private generateColumns(\n fields: Record<string, FieldDefinition>,\n config?: { idType?: 'uuid' | 'text' },\n ): Record<string, ColumnDefinition> {\n const columns: Record<string, ColumnDefinition> = {};\n\n // Always include base SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n\n // Add fields from object definition\n for (const [fieldName, fieldDef] of Object.entries(fields)) {\n // Skip id fields as we handle them above\n if (\n fieldName === 'id' ||\n fieldName === 'created_at' ||\n fieldName === 'updated_at'\n ) {\n continue;\n }\n\n // Skip transient fields (non-persisted)\n // NOTE: This filtering logic must match SmrtObject.toJSON()\n // Changes to field filtering should be applied in BOTH places\n if (fieldDef.transient || fieldDef._meta?.transient) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n // oneToMany and manyToMany are relationship metadata, not actual database columns\n // foreignKey DOES create a column (it stores the foreign key ID)\n // NOTE: This must match the filtering in SmrtObject.toJSON()\n if (fieldDef.type === 'oneToMany' || fieldDef.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column (STI only)\n // In CTI mode, meta fields shouldn't be used, but skip them anyway for safety\n if (fieldDef.type === 'meta') {\n continue;\n }\n\n const column: ColumnDefinition = {\n type: this.getRelationshipColumnType(fieldDef),\n referenceKind: this.getReferenceKind(fieldDef),\n // If _meta.nullable is true, the field can be null regardless of required\n // This handles field helpers like text({ required: true, nullable: true })\n notNull: fieldDef._meta?.nullable ? false : fieldDef.required || false,\n unique: fieldDef._meta?.unique || false,\n description: fieldDef.description,\n };\n\n // Handle default values\n if (\n fieldDef.default !== undefined &&\n this.shouldEmitDefault(fieldDef, fieldDef.default)\n ) {\n column.defaultValue = fieldDef.default;\n }\n // Note: Removed automatic NOT NULL DEFAULT '' for TEXT columns\n // This was forcing all TEXT fields to be NOT NULL regardless of required option\n // If DuckDB ANY type inference is an issue, it should be handled at the adapter level\n // or with an explicit field option, not by silently changing schema semantics\n\n // Handle foreign keys\n if (fieldDef.type === 'foreignKey' && fieldDef.related) {\n const [table, columnName = 'id'] = fieldDef.related.split('.');\n column.foreignKey = {\n table,\n column: columnName,\n onDelete: 'CASCADE', // Default behavior\n onUpdate: 'CASCADE',\n };\n }\n\n // Handle unique constraints\n if (fieldName === 'slug' || fieldName === 'email') {\n column.unique = true;\n }\n\n columns[fieldName] = column;\n }\n\n return columns;\n }\n\n /**\n * Generate index definitions\n */\n private generateIndexes(\n objectDef: SmartObjectDefinition,\n columns: Record<string, ColumnDefinition>,\n ): IndexDefinition[] {\n const indexes: IndexDefinition[] = [];\n const tableName = this.getTableName(objectDef);\n\n // Create indexes for foreign keys\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.foreignKey) {\n indexes.push({\n name: `idx_${tableName}_${columnName}`,\n columns: [columnName],\n description: `Index for foreign key ${columnName}`,\n });\n }\n }\n\n // Create index for updated_at (common query pattern)\n indexes.push({\n name: `idx_${tableName}_updated_at`,\n columns: ['updated_at'],\n description: 'Index for timestamp queries',\n });\n\n // Create unique indexes\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.unique && !columnDef.primaryKey) {\n indexes.push({\n name: `idx_${tableName}_${columnName}_unique`,\n columns: [columnName],\n unique: true,\n description: `Unique index for ${columnName}`,\n });\n }\n }\n\n return indexes;\n }\n\n /**\n * Generate trigger definitions for automatic timestamp updates\n */\n private generateTriggers(\n _objectDef: SmartObjectDefinition,\n tableName: string,\n ): TriggerDefinition[] {\n return [\n {\n name: `trg_${tableName}_updated_at`,\n when: 'BEFORE',\n event: 'UPDATE',\n body: `UPDATE ${quoteIdentifier(tableName)} SET \"updated_at\" = current_timestamp WHERE \"id\" = NEW.\"id\";`,\n description: 'Automatically update updated_at timestamp',\n },\n ];\n }\n\n /**\n * Extract foreign key definitions\n */\n private extractForeignKeys(\n columns: Record<string, ColumnDefinition>,\n ): ForeignKeyDefinition[] {\n const foreignKeys: ForeignKeyDefinition[] = [];\n\n for (const [columnName, columnDef] of Object.entries(columns)) {\n if (columnDef.foreignKey) {\n foreignKeys.push({\n column: columnName,\n referencesTable: columnDef.foreignKey.table,\n referencesColumn: columnDef.foreignKey.column,\n onDelete: columnDef.foreignKey.onDelete,\n onUpdate: columnDef.foreignKey.onUpdate,\n });\n }\n }\n\n return foreignKeys;\n }\n\n /**\n * Extract schema dependencies from foreign keys and inheritance\n */\n private extractDependencies(\n objectDef: SmartObjectDefinition,\n foreignKeys: ForeignKeyDefinition[],\n ): string[] {\n const dependencies = new Set<string>();\n\n // Add dependencies from foreign keys\n for (const fk of foreignKeys) {\n dependencies.add(fk.referencesTable);\n }\n\n // Add dependencies from base class\n if (\n objectDef.extends &&\n objectDef.extends !== 'SmrtObject' &&\n objectDef.extends !== 'SmrtCollection'\n ) {\n dependencies.add(this.classNameToTableName(objectDef.extends));\n }\n\n return Array.from(dependencies);\n }\n\n /**\n * Generate version hash for schema\n */\n private generateVersion(objectDef: SmartObjectDefinition): string {\n const content = JSON.stringify({\n className: objectDef.className,\n fields: objectDef.fields,\n extends: objectDef.extends,\n });\n return createHash('sha256').update(content).digest('hex').substring(0, 8);\n }\n\n /**\n * Get table name from object definition\n */\n private getTableName(objectDef: SmartObjectDefinition): string {\n return this.classNameToTableName(objectDef.className);\n }\n\n /**\n * Convert class name to table name (camelCase to snake_case, pluralized)\n */\n private classNameToTableName(className: string): string {\n return classnameToTablename(className);\n }\n\n /**\n * Extract package name from file path\n */\n private extractPackageName(filePath: string): string {\n const match = filePath.match(/packages\\/([^/]+)/);\n return match ? match[1] : 'unknown';\n }\n\n /**\n * Generate schema definition from ObjectRegistry fields (runtime)\n *\n * This method builds a SchemaDefinition from ObjectRegistry cached fields,\n * enabling schema generation from decorated classes at runtime.\n *\n * @param className - Class name to look up in ObjectRegistry\n * @param tableName - Table name (from SMRT_TABLE_NAME or derived)\n * @param fields - Map of Field definitions from ObjectRegistry\n * @returns Schema definition object\n */\n generateSchemaFromRegistry(\n className: string,\n tableName: string,\n fields: Map<string, RegistryField>,\n config?: SchemaGeneratorConfig,\n ): SchemaDefinition {\n const columns: Record<string, ColumnDefinition> = {};\n\n // Check for custom primary key\n let hasCustomPK = false;\n for (const [_fieldName, field] of fields.entries()) {\n if (field._meta?.primaryKey) {\n hasCustomPK = true;\n break;\n }\n }\n\n // Add default SMRT fields if no custom primary key\n if (!hasCustomPK) {\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n description: 'URL-friendly identifier',\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n defaultValue: '',\n description: 'Context for slug scoping',\n };\n }\n\n // Track timestamp fields to avoid duplicates\n let hasCreatedAt = false;\n let hasUpdatedAt = false;\n // Track regular (column-backed) fields that opted into a plain column index\n // via `indexed: true`. FK, unique, and meta fields each go through their\n // own dedicated index emission paths and are excluded from this set.\n const indexedColumns = new Set<string>();\n\n // Add fields from ObjectRegistry\n for (const [fieldName, field] of fields.entries()) {\n // Skip transient fields (non-persisted)\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n const isDefaultSmrtColumn =\n fieldName === 'id' || fieldName === 'slug' || fieldName === 'context';\n\n // Default SMRT columns are added above when we use the standard primary\n // key path. When a class declares a custom primary key, only explicitly\n // declared id/slug/context fields should survive this loop.\n if (\n isDefaultSmrtColumn &&\n (!hasCustomPK || field._meta?.__smrtSystemField === true)\n ) {\n continue;\n }\n\n // Track timestamp fields\n if (fieldName === 'created_at' || fieldName === 'createdAt') {\n if (hasCreatedAt) continue;\n hasCreatedAt = true;\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n continue;\n }\n if (fieldName === 'updated_at' || fieldName === 'updatedAt') {\n if (hasUpdatedAt) continue;\n hasUpdatedAt = true;\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n continue;\n }\n\n // Skip relationship fields that don't create columns\n // oneToMany and manyToMany are relationship metadata, not actual database columns\n // foreignKey DOES create a column (it stores the foreign key ID)\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column (STI only)\n // In CTI mode, meta fields shouldn't be used, but skip them anyway for safety\n if (field.type === 'meta') {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // If _meta.nullable is true, the field can be null regardless of required\n notNull: field._meta?.nullable ? false : field._meta?.required || false,\n primaryKey: field._meta?.primaryKey || false,\n unique: field._meta?.unique || false,\n description: field._meta?.description,\n };\n\n // Get default value\n if (\n field._meta?.default !== undefined &&\n this.shouldEmitDefault(field, field._meta.default)\n ) {\n columnDef.defaultValue = field._meta.default;\n }\n // Note: Removed automatic NOT NULL DEFAULT '' for TEXT columns\n // This was forcing all TEXT fields to be NOT NULL regardless of required option\n // If DuckDB ANY type inference is an issue, it should be handled at the adapter level\n // or with an explicit field option, not by silently changing schema semantics\n\n // Handle foreign keys\n if (field.type === 'foreignKey') {\n // Type cast to access relationship-specific properties\n const relatedName = field.related; // Top-level property\n const onDeleteAction = field._meta?.onDelete;\n\n if (relatedName) {\n columnDef.foreignKey = {\n table: this.classNameToTableName(relatedName),\n column: 'id',\n onDelete: onDeleteAction || 'CASCADE',\n onUpdate: 'CASCADE',\n };\n }\n }\n\n // Track opt-in column indexes for regular (non-FK, non-unique) fields.\n // FK columns already get auto-indexed below; unique columns produce\n // their own unique index; meta fields go through the jsonPath path.\n const isIndexed = field._meta?.indexed === true || field.indexed === true;\n if (\n isIndexed &&\n !columnDef.foreignKey &&\n !columnDef.unique &&\n !columnDef.primaryKey\n ) {\n indexedColumns.add(this.toSnakeCase(fieldName));\n }\n\n columns[this.toSnakeCase(fieldName)] = columnDef;\n }\n\n // Ensure timestamp columns exist\n if (!hasCreatedAt) {\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n }\n if (!hasUpdatedAt) {\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n }\n\n this.reconcileRegistryForeignKeyColumnTypes(\n columns,\n fields,\n config?.registry,\n );\n\n // Generate indexes\n const indexes: IndexDefinition[] = [];\n\n if (!hasCustomPK) {\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n description: 'Primary key index',\n });\n\n const conflictColumns = config?.conflictColumns || ['slug', 'context'];\n const conflictIndexName =\n conflictColumns.length > 2\n ? `${tableName}_${conflictColumns.slice(0, 2).join('_')}_idx`\n : `${tableName}_${conflictColumns.join('_')}_idx`;\n\n indexes.push({\n name: conflictIndexName,\n columns: conflictColumns,\n unique: true,\n description: `Unique conflict index for ${className}`,\n });\n } else {\n // Find custom PK column and create index\n for (const [colName, colDef] of Object.entries(columns)) {\n if (colDef.primaryKey) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Primary key index`,\n });\n break;\n }\n }\n }\n\n // Create indexes for foreign keys\n for (const [colName, colDef] of Object.entries(columns)) {\n if (colDef.foreignKey) {\n indexes.push({\n name: `idx_${tableName}_${colName}`,\n columns: [colName],\n description: `Foreign key index for ${colName}`,\n });\n }\n }\n\n // Emit opt-in column indexes for regular fields tagged with `indexed: true`\n for (const colName of indexedColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Index for ${colName}`,\n });\n }\n\n return {\n tableName,\n columns,\n indexes,\n triggers: [],\n foreignKeys: this.extractForeignKeys(columns),\n dependencies: [],\n version: createHash('sha256')\n .update(JSON.stringify(columns))\n .digest('hex')\n .substring(0, 8),\n packageName: 'runtime',\n baseClass: 'SmrtObject',\n };\n }\n\n /**\n * Generate STI (Single Table Inheritance) schema from ObjectRegistry fields\n *\n * Creates a shared table for an inheritance hierarchy with:\n * - _meta_type: Discriminator column to identify class type\n * - _meta_data: JSON column for flexible field storage\n * - Union of all FK columns from descendants (all nullable)\n * - Partial indexes for FK columns (filtered by _meta_type)\n *\n * @param baseClassName - Base class name for the STI hierarchy\n * @param tableName - Shared table name (from base class)\n * @param fields - Map of Field definitions from base class\n * @returns Schema definition object for STI table\n * @example\n * ```typescript\n * @smrt({ tableStrategy: 'sti' })\n * class Event extends SmrtObject {\n * title: string = '';\n * }\n *\n * @smrt()\n * class Meeting extends Event {\n * roomId = foreignKey(Room);\n * }\n *\n * // Generates single table 'events' with:\n * // - title (from Event)\n * // - room_id (from Meeting, nullable)\n * // - _meta_type TEXT NOT NULL (discriminator)\n * // - _meta_data JSON (flexible storage)\n * ```\n */\n async generateSTISchemaFromRegistry(\n baseClassName: string,\n tableName: string,\n _fields: Map<string, RegistryField>,\n config?: SchemaGeneratorConfig,\n ): Promise<SchemaDefinition> {\n const ObjectRegistry =\n config?.registry ?? (await import('../registry.js')).ObjectRegistry;\n const columns: Record<string, ColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n description: 'Primary identifier',\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n description: 'URL-friendly identifier',\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n defaultValue: '',\n description: 'Context for slug scoping',\n };\n\n // Add STI discriminator column\n columns._meta_type = {\n type: 'TEXT',\n notNull: true,\n description: 'Class type discriminator for STI',\n };\n\n // Add meta column for flexible storage\n columns._meta_data = {\n type: 'JSON',\n notNull: false,\n description: 'Flexible JSON storage for meta() fields',\n };\n\n // Track timestamp fields to avoid duplicates\n let hasCreatedAt = false;\n let hasUpdatedAt = false;\n\n // Get all descendants to aggregate fields\n const descendants = ObjectRegistry.getDescendants(baseClassName);\n const allClassNames = [baseClassName, ...descendants];\n\n // Track FK columns by class for partial indexes\n const fkColumnsByClass = new Map<string, Set<string>>();\n // Track meta fields opted into JSON-path indexing (deduped across STI subtypes)\n const indexedMetaFields = new Set<string>();\n // Track regular-field columns opted into plain column indexing\n const indexedStiColumns = new Set<string>();\n\n // Aggregate fields from base and all descendants\n for (const className of allClassNames) {\n const classFields: Map<string, RegistryField> =\n await ObjectRegistry.getAllFields(className);\n fkColumnsByClass.set(className, new Set());\n\n for (const [fieldName, field] of classFields.entries()) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Capture indexed meta fields before the skip-meta branch below\n if (\n field.type === 'meta' &&\n (field.indexed === true || field._meta?.indexed === true)\n ) {\n indexedMetaFields.add(fieldName);\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context'\n ) {\n continue;\n }\n\n // Track timestamp fields\n if (fieldName === 'created_at' || fieldName === 'createdAt') {\n if (hasCreatedAt) continue;\n hasCreatedAt = true;\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n continue;\n }\n if (fieldName === 'updated_at' || fieldName === 'updatedAt') {\n if (hasUpdatedAt) continue;\n hasUpdatedAt = true;\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n\n // Check if column already exists (inherited from parent)\n if (columns[columnName]) {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // STI: All columns nullable (union of child fields)\n notNull: false,\n primaryKey: false,\n unique: false,\n description: field._meta?.description,\n };\n\n // Get default value (but not applied in STI - defaults handled by application)\n if (\n field._meta?.default !== undefined &&\n this.shouldEmitDefault(field, field._meta.default)\n ) {\n columnDef.defaultValue = field._meta.default;\n }\n\n // Handle foreign keys\n if (field.type === 'foreignKey') {\n const relatedName = field.related; // Top-level property\n const onDeleteAction = field._meta?.onDelete;\n\n if (relatedName) {\n columnDef.foreignKey = {\n table: this.classNameToTableName(relatedName),\n column: 'id',\n onDelete: onDeleteAction || 'CASCADE',\n onUpdate: 'CASCADE',\n };\n\n // Track FK column for this class (for partial indexes)\n fkColumnsByClass.get(className)?.add(columnName);\n }\n }\n\n // Track opt-in column indexes for regular STI columns\n const isIndexed =\n field._meta?.indexed === true || field.indexed === true;\n if (isIndexed && !columnDef.foreignKey) {\n indexedStiColumns.add(columnName);\n }\n\n columns[columnName] = columnDef;\n }\n }\n\n // Ensure timestamp columns exist\n if (!hasCreatedAt) {\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Creation timestamp',\n };\n }\n if (!hasUpdatedAt) {\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n defaultValue: 'current_timestamp',\n description: 'Last update timestamp',\n };\n }\n\n for (const className of allClassNames) {\n const classFields = await ObjectRegistry.getAllFields(className);\n this.reconcileRegistryForeignKeyColumnTypes(\n columns,\n classFields,\n ObjectRegistry,\n );\n }\n\n // Generate indexes\n const indexes: IndexDefinition[] = [];\n\n // Primary key index\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n description: 'Primary key index',\n });\n\n // Unique index for slug, context, and type (STI variation).\n // STI subclasses share a table, so the discriminator participates in\n // identity — two subtypes can share the same (slug, context). PostgreSQL\n // UPSERT requires the live schema to carry a matching unique index; the\n // migration differ repairs older deployments where this index was created\n // non-unique or never created at all (issue #1165).\n indexes.push({\n name: `${tableName}_slug_context_meta_type_idx`,\n columns: ['slug', 'context', '_meta_type'],\n unique: true,\n description: 'Unique index for slug, context, and type',\n });\n\n // Index on type column (for polymorphic queries)\n indexes.push({\n name: `${tableName}_meta_type_idx`,\n columns: ['_meta_type'],\n description: 'Index for type discriminator queries',\n });\n\n // Partial indexes for FK columns (filtered by type)\n for (const [className, fkColumns] of fkColumnsByClass.entries()) {\n for (const fkColumn of fkColumns) {\n indexes.push({\n name: `idx_${tableName}_${fkColumn}_${className.toLowerCase()}`,\n columns: [fkColumn],\n where: `_meta_type = ${quoteStringLiteral(className)}`,\n description: `Partial index for ${fkColumn} in ${className} rows`,\n });\n }\n }\n\n // JSON-path indexes for @meta({ indexed: true }) fields\n for (const fieldName of indexedMetaFields) {\n indexes.push({\n name: `${tableName}_meta_${this.toSnakeCase(fieldName)}_idx`,\n columns: [],\n jsonPath: { column: '_meta_data', path: fieldName },\n description: `JSON-path index for @meta({ indexed: true }) field ${fieldName}`,\n });\n }\n\n // Plain column indexes for regular STI columns opted in via `indexed: true`\n for (const colName of indexedStiColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n description: `Index for ${colName}`,\n });\n }\n\n return {\n tableName,\n columns,\n indexes,\n triggers: [],\n foreignKeys: this.extractForeignKeys(columns),\n dependencies: [],\n version: createHash('sha256')\n .update(JSON.stringify({ columns, baseClassName, descendants }))\n .digest('hex')\n .substring(0, 8),\n packageName: 'runtime',\n baseClass: 'SmrtObject',\n };\n }\n\n /**\n * Generate STI schema from manifest data (build-time, no runtime registry)\n *\n * This method generates STI schema purely from manifest data, without depending\n * on ObjectRegistry. This enables pre-generating schemas at build time for\n * efficient external package consumption.\n *\n * @param baseClassName - Base class name for the STI hierarchy\n * @param tableName - Shared table name (from base class)\n * @param baseFields - Fields from the base class\n * @param manifest - Full manifest containing all objects\n * @returns ManifestSchema for storage in manifest.json\n */\n generateSTISchemaFromManifest(\n baseClassName: string,\n tableName: string,\n _baseFields: Record<string, FieldDefinition>,\n manifest: SmartObjectManifest,\n config?: SchemaGeneratorConfig,\n ): ManifestSchema {\n const columns: Record<string, ManifestColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n default: '',\n };\n\n // Add STI discriminator column\n columns._meta_type = {\n type: 'TEXT',\n notNull: true,\n };\n\n // Add meta column for flexible storage\n columns._meta_data = {\n type: 'JSON',\n notNull: false,\n };\n\n // Timestamp fields\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n // Find all descendants in manifest\n const descendants = this.findDescendantsInManifest(baseClassName, manifest);\n const allClassNames = [baseClassName, ...descendants];\n\n // Track FK columns by class for partial indexes\n const fkColumnsByClass = new Map<string, Set<string>>();\n // Track meta fields opted into JSON-path indexing (deduped across STI subtypes)\n const indexedMetaFields = new Set<string>();\n // Track regular columns opted into plain column indexing\n const indexedStiColumns = new Set<string>();\n\n // Aggregate fields from base and all descendants\n for (const className of allClassNames) {\n const objDef = manifest.objects[className];\n if (!objDef) continue;\n\n fkColumnsByClass.set(className, new Set());\n\n for (const [fieldName, field] of Object.entries(objDef.fields)) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Capture indexed meta fields before the skip-meta branch below.\n // `indexed` is normally carried in `_meta`, but tolerate a legacy\n // top-level flag too — RegistryField models both placements.\n const indexedField: RegistryField = field;\n if (\n field.type === 'meta' &&\n (indexedField.indexed === true || field._meta?.indexed === true)\n ) {\n indexedMetaFields.add(fieldName);\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context' ||\n fieldName === 'created_at' ||\n fieldName === 'createdAt' ||\n fieldName === 'updated_at' ||\n fieldName === 'updatedAt'\n ) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields - they're stored in _meta_data JSONB column\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n\n // Check if column already exists (inherited from parent)\n if (columns[columnName]) {\n continue;\n }\n\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ManifestColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n // STI: All columns nullable (union of child fields)\n notNull: false,\n };\n\n // Get default value\n if (\n field.default !== undefined &&\n this.shouldEmitDefault(field, field.default)\n ) {\n columnDef.default = field.default;\n }\n\n // Track FK columns for this class (for partial indexes)\n if (field.type === 'foreignKey') {\n fkColumnsByClass.get(className)?.add(columnName);\n }\n\n // Track opt-in column indexes for regular STI columns\n const isIndexed =\n indexedField.indexed === true || field._meta?.indexed === true;\n if (isIndexed && field.type !== 'foreignKey') {\n indexedStiColumns.add(columnName);\n }\n\n columns[columnName] = columnDef;\n }\n }\n\n // Generate indexes\n const indexes: ManifestIndexDefinition[] = [];\n\n // Primary key index\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n });\n\n // Unique index for slug, context, and type (STI variation) — see\n // generateSTISchemaFromRegistry for the rationale.\n indexes.push({\n name: `${tableName}_slug_context_meta_type_idx`,\n columns: ['slug', 'context', '_meta_type'],\n unique: true,\n });\n\n // Index on type column (for polymorphic queries)\n indexes.push({\n name: `${tableName}_meta_type_idx`,\n columns: ['_meta_type'],\n });\n\n // JSON-path indexes for @meta({ indexed: true }) fields\n for (const fieldName of indexedMetaFields) {\n indexes.push({\n name: `${tableName}_meta_${this.toSnakeCase(fieldName)}_idx`,\n columns: [],\n jsonPath: { column: '_meta_data', path: fieldName },\n });\n }\n\n // Plain column indexes for regular STI columns opted in via `indexed: true`\n for (const colName of indexedStiColumns) {\n indexes.push({\n name: `${tableName}_${colName}_idx`,\n columns: [colName],\n });\n }\n\n // Generate DDL\n const schemaDefinition: SchemaDefinition = {\n tableName,\n columns: this.convertManifestColumnsToSchemaColumns(columns),\n indexes: indexes.map((idx) => ({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n where: idx.where,\n jsonPath: idx.jsonPath,\n })),\n triggers: [],\n foreignKeys: [],\n dependencies: [],\n version: '',\n packageName: '',\n };\n\n const ddl = this.generateSQL(schemaDefinition);\n\n // Generate version hash\n const version = createHash('sha256')\n .update(JSON.stringify({ columns, baseClassName, descendants }))\n .digest('hex')\n .substring(0, 8);\n\n return {\n tableName,\n ddl,\n columns,\n indexes,\n version,\n };\n }\n\n /**\n * Generate CTI (Class Table Inheritance) schema from manifest data\n *\n * @param className - Class name\n * @param tableName - Table name\n * @param fields - Fields from the class\n * @returns ManifestSchema for storage in manifest.json\n */\n generateCTISchemaFromManifest(\n className: string,\n tableName: string,\n fields: Record<string, FieldDefinition>,\n config?: SchemaGeneratorConfig,\n ): ManifestSchema {\n const columns: Record<string, ManifestColumnDefinition> = {};\n\n // Add default SMRT fields\n columns.id = {\n type: this.getIdColumnType(config),\n primaryKey: true,\n referenceKind: 'id',\n notNull: true,\n };\n\n columns.slug = {\n type: 'TEXT',\n notNull: true,\n };\n\n columns.context = {\n type: 'TEXT',\n notNull: true,\n default: '',\n };\n\n // Timestamp fields\n columns.created_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n columns.updated_at = {\n type: 'TIMESTAMP',\n notNull: true,\n default: 'current_timestamp',\n };\n\n // Add class fields\n for (const [fieldName, field] of Object.entries(fields)) {\n // Skip transient fields\n if (field.transient || field._meta?.transient) {\n continue;\n }\n\n // Skip default fields already added\n if (\n fieldName === 'id' ||\n fieldName === 'slug' ||\n fieldName === 'context' ||\n fieldName === 'created_at' ||\n fieldName === 'createdAt' ||\n fieldName === 'updated_at' ||\n fieldName === 'updatedAt'\n ) {\n continue;\n }\n\n // Skip relationship fields that don't create columns\n if (field.type === 'oneToMany' || field.type === 'manyToMany') {\n continue;\n }\n\n // Skip meta fields\n if (field.type === 'meta') {\n continue;\n }\n\n const columnName = this.toSnakeCase(fieldName);\n const sqlType = this.getRelationshipColumnType(field);\n\n const columnDef: ManifestColumnDefinition = {\n type: sqlType,\n referenceKind: this.getReferenceKind(field),\n notNull: field._meta?.nullable ? false : field.required || false,\n unique: field._meta?.unique || false,\n };\n\n if (\n field.default !== undefined &&\n this.shouldEmitDefault(field, field.default)\n ) {\n columnDef.default = field.default;\n }\n\n columns[columnName] = columnDef;\n }\n\n // Generate indexes\n const indexes: ManifestIndexDefinition[] = [];\n\n indexes.push({\n name: `${tableName}_id_idx`,\n columns: ['id'],\n });\n\n // Use custom conflict columns if provided, otherwise default to slug+context\n const conflictColumns = config?.conflictColumns || ['slug', 'context'];\n const indexName =\n conflictColumns.length > 2\n ? `${tableName}_${conflictColumns.slice(0, 2).join('_')}_idx`\n : `${tableName}_${conflictColumns.join('_')}_idx`;\n\n indexes.push({\n name: indexName,\n columns: conflictColumns,\n unique: true,\n });\n\n // Generate DDL\n const schemaDefinition: SchemaDefinition = {\n tableName,\n columns: this.convertManifestColumnsToSchemaColumns(columns),\n indexes: indexes.map((idx) => ({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n where: idx.where,\n jsonPath: idx.jsonPath,\n })),\n triggers: [],\n foreignKeys: [],\n dependencies: [],\n version: '',\n packageName: '',\n };\n\n const ddl = this.generateSQL(schemaDefinition);\n\n // Generate version hash\n const version = createHash('sha256')\n .update(JSON.stringify({ columns, className }))\n .digest('hex')\n .substring(0, 8);\n\n return {\n tableName,\n ddl,\n columns,\n indexes,\n version,\n };\n }\n\n /**\n * Find all descendants of a class in the manifest\n *\n * Note: Manifest keys are now qualified names (@pkg:ClassName) but `extends` field\n * stores simple PascalCase class names. We need to handle both qualified and simple\n * name lookups.\n *\n * Issue #713: Updated to handle qualified names in manifest keys\n */\n private findDescendantsInManifest(\n baseClassName: string,\n manifest: SmartObjectManifest,\n visited: Set<string> = new Set(),\n ): string[] {\n const descendants: string[] = [];\n\n // Prevent infinite recursion (e.g., class extends same-named class from another package)\n if (visited.has(baseClassName)) return descendants;\n visited.add(baseClassName);\n\n // Extract the simple class name from qualified name if needed\n // e.g., '@happyvertical/smrt-core:PolyEvent' -> 'PolyEvent'\n const simpleBaseClassName = baseClassName.includes(':')\n ? baseClassName.split(':').pop() || baseClassName\n : baseClassName;\n const baseClassLower = simpleBaseClassName.toLowerCase();\n\n for (const [name, obj] of Object.entries(manifest.objects)) {\n // Skip self-references (class extending same-named class from another package)\n if (\n obj.className.toLowerCase() === baseClassLower &&\n obj.extends?.toLowerCase() === baseClassLower\n ) {\n continue;\n }\n // obj.extends is a simple class name (e.g., 'PolyEvent')\n // Compare with the simple (non-qualified) version of the base class name\n if (obj.extends?.toLowerCase() === baseClassLower) {\n descendants.push(name);\n // Recursively find descendants of this class\n // Pass the qualified name (manifest key) for recursive lookup\n descendants.push(\n ...this.findDescendantsInManifest(name, manifest, visited),\n );\n }\n }\n\n return descendants;\n }\n\n /**\n * Convert ManifestColumnDefinition to ColumnDefinition\n */\n private convertManifestColumnsToSchemaColumns(\n manifestColumns: Record<string, ManifestColumnDefinition>,\n ): Record<string, ColumnDefinition> {\n const columns: Record<string, ColumnDefinition> = {};\n\n for (const [name, col] of Object.entries(manifestColumns)) {\n columns[name] = {\n type: col.type as SQLDataType,\n primaryKey: col.primaryKey,\n referenceKind: col.referenceKind,\n notNull: col.notNull,\n unique: col.unique,\n defaultValue: col.default,\n };\n }\n\n return columns;\n }\n\n /**\n * Convert camelCase to snake_case\n */\n private toSnakeCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n }\n\n /**\n * Generate SQL CREATE TABLE statement from schema definition\n *\n * This is the single source of truth for SQL generation, consolidating\n * logic that was previously duplicated across multiple code paths.\n *\n * @param schema - Schema definition object\n * @returns SQL CREATE TABLE statement with indexes\n */\n generateSQL(schema: SchemaDefinition, engine?: DatabaseEngine): string {\n // NOTE: We no longer append indexes to DDL string here.\n // The SDK expects ddl to contain ONLY the CREATE TABLE statement.\n // Indexes are stored separately in schema.indexes as SQL strings\n // and the SDK handles them via syncSchema() or dedicated index creation.\n if (engine) {\n return getDDLStrategy(engine).generateCreateTable(schema);\n }\n\n const { tableName, columns } = schema;\n let sql = `CREATE TABLE IF NOT EXISTS ${quoteIdentifier(tableName)} (\\n`;\n\n for (const [columnName, columnDef] of Object.entries(columns)) {\n const parts = [` ${quoteIdentifier(columnName)} ${columnDef.type}`];\n\n if (columnDef.primaryKey) {\n parts.push('PRIMARY KEY');\n }\n\n if (columnDef.notNull) {\n parts.push('NOT NULL');\n }\n\n if (columnDef.unique && !columnDef.primaryKey) {\n parts.push('UNIQUE');\n }\n\n if (columnDef.defaultValue !== undefined) {\n parts.push(\n `DEFAULT ${this.formatDefaultValue(\n columnDef.defaultValue,\n columnDef.type,\n )}`,\n );\n }\n\n sql += `${parts.join(' ')},\\n`;\n }\n\n return `${sql.slice(0, -2)}\\n);`;\n }\n\n /**\n * Format default value for SQL\n *\n * SQLite doesn't support CAST expressions in DEFAULT values (only literal values are allowed).\n * This method generates DEFAULT values that work with both SQLite and DuckDB.\n *\n * @param value - Default value\n * @param type - Column SQL type\n * @returns Formatted SQL default value expression\n */\n private formatDefaultValue(value: unknown, type: SQLDataType): string {\n // Delegate to the shared, injection-safe formatter so all DDL paths\n // converge on one set of rules (allowlisted keyword/function defaults\n // instead of \"contains `(`\", type-driven quoting, no string-\"null\" fold).\n // This path is engine-agnostic and never emits CAST expressions, so the\n // output stays valid for SQLite and DuckDB. Non-string TIMESTAMP defaults\n // fall back to lowercase `current_timestamp` to preserve prior output.\n return formatDefaultValueShared(value, type, {\n nonStringTimestampDefault: 'current_timestamp',\n });\n }\n}\n"],"names":["formatDefaultValueShared"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ColumnDefinition, SchemaDefinition, SchemaOverride } from './types.js';
1
+ import { ColumnDefinition, IndexDefinition, SchemaDefinition, SchemaOverride, TriggerDefinition } from './types.js';
2
2
  export declare class SchemaOverrideSystem {
3
3
  /**
4
4
  * Apply schema override to base schema
@@ -10,9 +10,9 @@ export declare class SchemaOverrideSystem {
10
10
  static createOverride(tableName: string, packageName: string, extensions: {
11
11
  addColumns?: Record<string, ColumnDefinition>;
12
12
  removeColumns?: string[];
13
- addIndexes?: Array<any>;
13
+ addIndexes?: IndexDefinition[];
14
14
  removeIndexes?: string[];
15
- addTriggers?: Array<any>;
15
+ addTriggers?: TriggerDefinition[];
16
16
  removeTriggers?: string[];
17
17
  }): SchemaOverride;
18
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"override-system.d.ts","sourceRoot":"","sources":["../../src/schema/override-system.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,qBAAa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,aAAa,CAClB,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,cAAc,GACvB,gBAAgB;IAiEnB;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC9C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,UAAU,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,GACA,cAAc;IAQjB;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,cAAc,EAAE,GAC1B,gBAAgB;IAenB;;OAEG;IACH,MAAM,CAAC,2BAA2B,IAAI,cAAc;IAmEpD;;OAEG;IACH,MAAM,CAAC,2BAA2B,IAAI,cAAc;IA4CpD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAuBtC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAoBjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAUnC"}
1
+ {"version":3,"file":"override-system.d.ts","sourceRoot":"","sources":["../../src/schema/override-system.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,qBAAa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,aAAa,CAClB,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,cAAc,GACvB,gBAAgB;IAiEnB;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC9C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;QAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;QAClC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,GACA,cAAc;IAQjB;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,cAAc,EAAE,GAC1B,gBAAgB;IAenB;;OAEG;IACH,MAAM,CAAC,2BAA2B,IAAI,cAAc;IAmEpD;;OAEG;IACH,MAAM,CAAC,2BAA2B,IAAI,cAAc;IA4CpD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAuBtC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAoBjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAUnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema-aggregator.d.ts","sourceRoot":"","sources":["../../src/schema/schema-aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC5C,yBAAyB;IACzB,KAAK,EAAE;QACL,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEhC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiID;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,iBAAiB;IAoE5D;;OAEG;IACH,OAAO,CAAC,YAAY;IA2CpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IA4DtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAuCpB"}
1
+ {"version":3,"file":"schema-aggregator.d.ts","sourceRoot":"","sources":["../../src/schema/schema-aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC5C,yBAAyB;IACzB,KAAK,EAAE;QACL,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEhC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiID;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,iBAAiB;IAoE5D;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IA4DtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAuCpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema-manager.d.ts","sourceRoot":"","sources":["../../src/schema/schema-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAuB;IAGtC,OAAO,CAAC,MAAM,CAAkC;gBAEpC,EAAE,EAAE,iBAAiB,EAAE,OAAO,GAAE,oBAAyB;IAkBrE;;;;;;;OAOG;IACG,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6G1D;;;;;;;;;OASG;YACW,kBAAkB;IAwChC;;;;;;;;;;;;;OAaG;YACW,iBAAiB;IAqE/B,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9D;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB;IASxD;;OAEG;IACH,SAAS,IAAI,cAAc;IAI3B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CA4C3B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,iBAAiB,EACrB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,aAAa,CAEf"}
1
+ {"version":3,"file":"schema-manager.d.ts","sourceRoot":"","sources":["../../src/schema/schema-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAiBnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAuB;IAGtC,OAAO,CAAC,MAAM,CAAkC;gBAEpC,EAAE,EAAE,iBAAiB,EAAE,OAAO,GAAE,oBAAyB;IAkBrE;;;;;;;OAOG;IACG,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmH1D;;;;;;;;;OASG;YACW,kBAAkB;IAoChC;;;;;;;;;;;;;OAaG;YACW,iBAAiB;IAqE/B,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9D;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB;IASxD;;OAEG;IACH,SAAS,IAAI,cAAc;IAI3B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CA4C3B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,iBAAiB,EACrB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,aAAa,CAEf"}
@@ -1,5 +1,12 @@
1
1
  import { createLogger } from "@happyvertical/logger";
2
2
  import { detectEngine, getDDLStrategy } from "./ddl/index.js";
3
+ function extractRows(result) {
4
+ if (Array.isArray(result)) {
5
+ return result;
6
+ }
7
+ const rows = result?.rows;
8
+ return Array.isArray(rows) ? rows : [];
9
+ }
3
10
  class SchemaManager {
4
11
  db;
5
12
  engine;
@@ -45,7 +52,8 @@ class SchemaManager {
45
52
  indexes: strategy.generateIndexes(schema),
46
53
  triggers: strategy.generateTriggers(schema)
47
54
  };
48
- if (this.db.syncSchema) {
55
+ const dbWithSync = this.db;
56
+ if (dbWithSync.syncSchema) {
49
57
  const fullSchema = [
50
58
  ddl.createTable,
51
59
  ...ddl.indexes,
@@ -58,7 +66,7 @@ class SchemaManager {
58
66
  );
59
67
  }
60
68
  try {
61
- await this.db.syncSchema(fullSchema);
69
+ await dbWithSync.syncSchema(fullSchema);
62
70
  const createdSuccessfully = await this.db.tableExists(tableName);
63
71
  if (createdSuccessfully) {
64
72
  if (this.options.debug) {
@@ -123,7 +131,7 @@ class SchemaManager {
123
131
  "SELECT column_name FROM information_schema.columns WHERE table_name = $1",
124
132
  tableName
125
133
  );
126
- const rows = Array.isArray(result) ? result : result?.rows ?? [];
134
+ const rows = extractRows(result);
127
135
  for (const row of rows) {
128
136
  columns.add(row.column_name);
129
137
  }
@@ -131,7 +139,7 @@ class SchemaManager {
131
139
  const result = await this.db.query(
132
140
  `PRAGMA table_info(${this.quoteIdentifier(tableName)})`
133
141
  );
134
- const rows = Array.isArray(result) ? result : result?.rows ?? [];
142
+ const rows = extractRows(result);
135
143
  for (const row of rows) {
136
144
  columns.add(row.name);
137
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schema-manager.js","sources":["../../src/schema/schema-manager.ts"],"sourcesContent":["/**\n * Schema Manager - Direct DDL Execution for SMRT\n *\n * SMRT handles ALL database maintenance directly.\n * SDK SQL remains a pure query/CRUD layer.\n *\n * This module replaces the use of SDK's syncSchema() with direct DDL execution\n * using engine-specific DDL strategies.\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n type DatabaseEngine,\n detectEngine,\n type EngineSpecificDDL,\n getDDLStrategy,\n} from './ddl/index.js';\nimport type { SchemaDefinition } from './types.js';\n\n/**\n * Schema Manager Options\n */\nexport interface SchemaManagerOptions {\n /** Force engine type (overrides auto-detection) */\n engine?: DatabaseEngine;\n /** Whether to skip triggers (useful for DuckDB-backed JSON) */\n skipTriggers?: boolean;\n /** Log DDL statements before execution */\n debug?: boolean;\n}\n\n/**\n * Schema Manager\n *\n * Handles direct DDL execution for database schema management.\n * Replaces SDK's syncSchema() with SMRT-controlled schema creation.\n */\nexport class SchemaManager {\n private db: DatabaseInterface;\n private engine: DatabaseEngine;\n private options: SchemaManagerOptions;\n // Per-instance logger: the `debug` option must actually emit debug traces, so\n // the level follows it (a fixed level: 'info' would filter every debug call).\n private logger: ReturnType<typeof createLogger>;\n\n constructor(db: DatabaseInterface, options: SchemaManagerOptions = {}) {\n this.db = db;\n this.options = options;\n this.logger = createLogger({ level: options.debug ? 'debug' : 'info' });\n\n // Detect or use provided engine\n if (options.engine) {\n this.engine = options.engine;\n } else if ((db as any).exportTable) {\n // JSON adapter detected (has unique exportTable method)\n // JSON adapter uses DuckDB internally, but native UUID values do not\n // round-trip through the SDK row objects as canonical UUID strings.\n this.engine = 'json';\n } else {\n this.engine = detectEngine(db.url);\n }\n }\n\n /**\n * Ensure a table exists with the correct schema\n *\n * If table doesn't exist, creates it with DDL from the engine-specific strategy.\n * If table exists but is missing columns, adds them via ALTER TABLE ADD COLUMN.\n *\n * @param schema - The schema definition\n */\n async ensureTable(schema: SchemaDefinition): Promise<void> {\n const { tableName } = schema;\n\n // Check if table already exists\n const exists = await this.db.tableExists(tableName);\n if (exists) {\n // Table exists — check for missing columns and add them\n // This handles the case where a table was created with a partial schema\n // (e.g., base SmrtObject fields only) and needs additional columns\n await this.addMissingColumns(tableName, schema);\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" already exists, checked for missing columns`,\n );\n }\n return;\n }\n\n // Generate DDL using engine-specific strategy\n const strategy = getDDLStrategy(this.engine);\n const ddl: EngineSpecificDDL = {\n createTable: strategy.generateCreateTable(schema),\n indexes: strategy.generateIndexes(schema),\n triggers: strategy.generateTriggers(schema),\n };\n\n // Prefer adapter's syncSchema if available (handles adapter-specific transformations)\n // This is critical for JSON adapter which needs to convert UNIQUE indexes to\n // inline constraints for DuckDB compatibility\n if ((this.db as any).syncSchema) {\n // Combine DDL into single schema string for adapter's syncSchema\n const fullSchema = [\n ddl.createTable,\n ...ddl.indexes,\n ...(this.options.skipTriggers ? [] : ddl.triggers),\n ].join(';\\n');\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Using adapter syncSchema for \"${tableName}\"`,\n { fullSchema },\n );\n }\n\n try {\n await (this.db as any).syncSchema(fullSchema);\n\n // FIX #735: Verify table was actually created\n // Some adapters (notably PostgreSQL) may silently fail to create tables\n // when syncSchema returns without error but doesn't execute the DDL\n const createdSuccessfully = await this.db.tableExists(tableName);\n if (createdSuccessfully) {\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" created via adapter syncSchema`,\n );\n }\n return;\n }\n\n // Table wasn't created - fall through to direct DDL execution\n this.logger.warn(\n `[SchemaManager] syncSchema returned but table \"${tableName}\" doesn't exist, falling back to direct DDL`,\n );\n } catch (syncError) {\n // syncSchema failed - fall through to direct DDL execution\n this.logger.warn(\n `[SchemaManager] syncSchema failed for \"${tableName}\", falling back to direct DDL`,\n { error: syncError },\n );\n }\n }\n\n // Fallback: Execute DDL directly (for adapters without syncSchema)\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Creating table \"${tableName}\" for ${this.engine} (direct DDL)`,\n { createTable: ddl.createTable },\n );\n }\n\n await this.db.query(ddl.createTable);\n\n // Execute indexes\n for (const indexSQL of ddl.indexes) {\n if (this.options.debug) {\n this.logger.debug(`[SchemaManager] Creating index`, { indexSQL });\n }\n await this.db.query(indexSQL);\n }\n\n // Execute triggers (unless skipped)\n if (!this.options.skipTriggers) {\n for (const triggerSQL of ddl.triggers) {\n if (this.options.debug) {\n this.logger.debug(`[SchemaManager] Creating trigger`, { triggerSQL });\n }\n await this.db.query(triggerSQL);\n }\n }\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" created successfully`,\n );\n }\n }\n\n /**\n * Get existing column names from a database table\n *\n * Uses engine-appropriate introspection:\n * - SQLite/DuckDB: PRAGMA table_info\n * - PostgreSQL: information_schema.columns\n *\n * @param tableName - Name of the table to inspect\n * @returns Set of existing column names (lowercase)\n */\n private async getExistingColumns(tableName: string): Promise<Set<string>> {\n const columns = new Set<string>();\n\n try {\n if (this.engine === 'postgres') {\n const result = await this.db.query(\n 'SELECT column_name FROM information_schema.columns WHERE table_name = $1',\n tableName,\n );\n const rows = Array.isArray(result)\n ? result\n : ((result as any)?.rows ?? []);\n for (const row of rows) {\n columns.add(row.column_name);\n }\n } else {\n // SQLite and DuckDB use PRAGMA\n const result = await this.db.query(\n `PRAGMA table_info(${this.quoteIdentifier(tableName)})`,\n );\n const rows = Array.isArray(result)\n ? result\n : ((result as any)?.rows ?? []);\n for (const row of rows) {\n columns.add(row.name);\n }\n }\n } catch (error) {\n // If introspection fails, return empty set (no columns will be added)\n if (this.options.debug) {\n this.logger.warn(\n `[SchemaManager] Failed to introspect columns for \"${tableName}\"`,\n { error },\n );\n }\n }\n\n return columns;\n }\n\n /**\n * Add missing columns to an existing table via ALTER TABLE ADD COLUMN\n *\n * Compares the schema's expected columns against the table's actual columns\n * and adds any that are missing. This handles the race condition where a table\n * is created with base fields by one code path, then a later code path needs\n * additional columns from a more complete schema.\n *\n * SQLite limitation: ALTER TABLE ADD COLUMN cannot add NOT NULL columns\n * without a DEFAULT value. We relax NOT NULL for such columns.\n *\n * @param tableName - Name of the existing table\n * @param schema - The full schema definition with expected columns\n */\n private async addMissingColumns(\n tableName: string,\n schema: SchemaDefinition,\n ): Promise<void> {\n if (!schema.columns || Object.keys(schema.columns).length === 0) {\n return;\n }\n\n const existingColumns = await this.getExistingColumns(tableName);\n if (existingColumns.size === 0) {\n // Introspection failed or returned no columns — skip to avoid errors\n return;\n }\n\n const strategy = getDDLStrategy(this.engine);\n let addedCount = 0;\n\n for (const [colName, colDef] of Object.entries(schema.columns)) {\n if (existingColumns.has(colName)) {\n continue; // Column already exists\n }\n\n // SQLite limitation: ALTER TABLE ADD COLUMN cannot have NOT NULL\n // without a DEFAULT value. Relax NOT NULL for such columns.\n const safeDef = { ...colDef };\n if (\n safeDef.notNull &&\n safeDef.defaultValue === undefined &&\n !safeDef.primaryKey\n ) {\n safeDef.notNull = false;\n }\n\n // Cannot add PRIMARY KEY columns via ALTER TABLE\n if (safeDef.primaryKey) {\n continue;\n }\n\n const colSQL = strategy.generateColumnDefinition(colName, safeDef);\n const alterSQL = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD COLUMN ${colSQL}`;\n\n try {\n await this.db.query(alterSQL);\n addedCount++;\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Added column \"${colName}\" to \"${tableName}\"`,\n );\n }\n } catch (error) {\n // Column might already exist (race condition) or other issue\n // Log and continue — don't fail the entire operation\n if (this.options.debug) {\n this.logger.warn(\n `[SchemaManager] Failed to add column \"${colName}\" to \"${tableName}\"`,\n { error },\n );\n }\n }\n }\n\n if (addedCount > 0 && this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Added ${addedCount} missing column(s) to \"${tableName}\"`,\n );\n }\n }\n\n private quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n }\n\n /**\n * Create multiple tables with dependency ordering\n *\n * @param schemas - Array of schema definitions\n */\n async ensureTables(schemas: SchemaDefinition[]): Promise<void> {\n // Sort by dependencies (topological sort)\n const sorted = this.sortByDependencies(schemas);\n\n for (const schema of sorted) {\n await this.ensureTable(schema);\n }\n }\n\n /**\n * Generate DDL without executing (useful for debugging/preview)\n *\n * @param schema - The schema definition\n * @returns Engine-specific DDL\n */\n generateDDL(schema: SchemaDefinition): EngineSpecificDDL {\n const strategy = getDDLStrategy(this.engine);\n return {\n createTable: strategy.generateCreateTable(schema),\n indexes: strategy.generateIndexes(schema),\n triggers: strategy.generateTriggers(schema),\n };\n }\n\n /**\n * Get the detected/configured database engine\n */\n getEngine(): DatabaseEngine {\n return this.engine;\n }\n\n /**\n * Sort schemas by dependencies (topological sort)\n *\n * Ensures tables are created in the correct order based on foreign key dependencies.\n */\n private sortByDependencies(schemas: SchemaDefinition[]): SchemaDefinition[] {\n const byName = new Map<string, SchemaDefinition>();\n const sorted: SchemaDefinition[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n // Index by table name\n for (const schema of schemas) {\n byName.set(schema.tableName, schema);\n }\n\n // DFS topological sort\n const visit = (tableName: string) => {\n if (visited.has(tableName)) return;\n if (visiting.has(tableName)) {\n // Circular dependency - continue anyway (FK might be nullable)\n this.logger.warn(\n `[SchemaManager] Circular dependency detected involving ${tableName}`,\n );\n return;\n }\n\n const schema = byName.get(tableName);\n if (!schema) return; // External dependency, skip\n\n visiting.add(tableName);\n\n // Visit dependencies first\n for (const dep of schema.dependencies || []) {\n visit(dep);\n }\n\n visiting.delete(tableName);\n visited.add(tableName);\n sorted.push(schema);\n };\n\n // Visit all schemas\n for (const schema of schemas) {\n visit(schema.tableName);\n }\n\n return sorted;\n }\n}\n\n/**\n * Create a SchemaManager instance\n *\n * @param db - Database interface\n * @param options - Optional configuration\n * @returns SchemaManager instance\n */\nexport function createSchemaManager(\n db: DatabaseInterface,\n options?: SchemaManagerOptions,\n): SchemaManager {\n return new SchemaManager(db, options);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema-manager.js","sources":["../../src/schema/schema-manager.ts"],"sourcesContent":["/**\n * Schema Manager - Direct DDL Execution for SMRT\n *\n * SMRT handles ALL database maintenance directly.\n * SDK SQL remains a pure query/CRUD layer.\n *\n * This module replaces the use of SDK's syncSchema() with direct DDL execution\n * using engine-specific DDL strategies.\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n type DatabaseEngine,\n detectEngine,\n type EngineSpecificDDL,\n getDDLStrategy,\n} from './ddl/index.js';\nimport type { SchemaDefinition } from './types.js';\n\n/**\n * Normalize a `db.query` result into an array of rows.\n *\n * Adapters return either a bare row array or a `{ rows }` envelope. This\n * mirrors the prior inline `Array.isArray(result) ? result : result?.rows ?? []`\n * narrowing while keeping the row shape typed for callers.\n */\nfunction extractRows<Row>(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result as Row[];\n }\n const rows = (result as { rows?: unknown } | null | undefined)?.rows;\n return Array.isArray(rows) ? (rows as Row[]) : [];\n}\n\n/**\n * Schema Manager Options\n */\nexport interface SchemaManagerOptions {\n /** Force engine type (overrides auto-detection) */\n engine?: DatabaseEngine;\n /** Whether to skip triggers (useful for DuckDB-backed JSON) */\n skipTriggers?: boolean;\n /** Log DDL statements before execution */\n debug?: boolean;\n}\n\n/**\n * Schema Manager\n *\n * Handles direct DDL execution for database schema management.\n * Replaces SDK's syncSchema() with SMRT-controlled schema creation.\n */\nexport class SchemaManager {\n private db: DatabaseInterface;\n private engine: DatabaseEngine;\n private options: SchemaManagerOptions;\n // Per-instance logger: the `debug` option must actually emit debug traces, so\n // the level follows it (a fixed level: 'info' would filter every debug call).\n private logger: ReturnType<typeof createLogger>;\n\n constructor(db: DatabaseInterface, options: SchemaManagerOptions = {}) {\n this.db = db;\n this.options = options;\n this.logger = createLogger({ level: options.debug ? 'debug' : 'info' });\n\n // Detect or use provided engine\n if (options.engine) {\n this.engine = options.engine;\n } else if ((db as { exportTable?: unknown }).exportTable) {\n // JSON adapter detected (has unique exportTable method)\n // JSON adapter uses DuckDB internally, but native UUID values do not\n // round-trip through the SDK row objects as canonical UUID strings.\n this.engine = 'json';\n } else {\n this.engine = detectEngine(db.url);\n }\n }\n\n /**\n * Ensure a table exists with the correct schema\n *\n * If table doesn't exist, creates it with DDL from the engine-specific strategy.\n * If table exists but is missing columns, adds them via ALTER TABLE ADD COLUMN.\n *\n * @param schema - The schema definition\n */\n async ensureTable(schema: SchemaDefinition): Promise<void> {\n const { tableName } = schema;\n\n // Check if table already exists\n const exists = await this.db.tableExists(tableName);\n if (exists) {\n // Table exists — check for missing columns and add them\n // This handles the case where a table was created with a partial schema\n // (e.g., base SmrtObject fields only) and needs additional columns\n await this.addMissingColumns(tableName, schema);\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" already exists, checked for missing columns`,\n );\n }\n return;\n }\n\n // Generate DDL using engine-specific strategy\n const strategy = getDDLStrategy(this.engine);\n const ddl: EngineSpecificDDL = {\n createTable: strategy.generateCreateTable(schema),\n indexes: strategy.generateIndexes(schema),\n triggers: strategy.generateTriggers(schema),\n };\n\n // Prefer adapter's syncSchema if available (handles adapter-specific transformations)\n // This is critical for JSON adapter which needs to convert UNIQUE indexes to\n // inline constraints for DuckDB compatibility\n // Adapters that support direct DDL sync expose an optional `syncSchema`\n // method beyond the base `DatabaseInterface`; narrow to it here so both the\n // capability check and the call preserve `this.db` as the receiver.\n const dbWithSync = this.db as DatabaseInterface & {\n syncSchema?: (schema: string) => Promise<void>;\n };\n if (dbWithSync.syncSchema) {\n // Combine DDL into single schema string for adapter's syncSchema\n const fullSchema = [\n ddl.createTable,\n ...ddl.indexes,\n ...(this.options.skipTriggers ? [] : ddl.triggers),\n ].join(';\\n');\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Using adapter syncSchema for \"${tableName}\"`,\n { fullSchema },\n );\n }\n\n try {\n await dbWithSync.syncSchema(fullSchema);\n\n // FIX #735: Verify table was actually created\n // Some adapters (notably PostgreSQL) may silently fail to create tables\n // when syncSchema returns without error but doesn't execute the DDL\n const createdSuccessfully = await this.db.tableExists(tableName);\n if (createdSuccessfully) {\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" created via adapter syncSchema`,\n );\n }\n return;\n }\n\n // Table wasn't created - fall through to direct DDL execution\n this.logger.warn(\n `[SchemaManager] syncSchema returned but table \"${tableName}\" doesn't exist, falling back to direct DDL`,\n );\n } catch (syncError) {\n // syncSchema failed - fall through to direct DDL execution\n this.logger.warn(\n `[SchemaManager] syncSchema failed for \"${tableName}\", falling back to direct DDL`,\n { error: syncError },\n );\n }\n }\n\n // Fallback: Execute DDL directly (for adapters without syncSchema)\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Creating table \"${tableName}\" for ${this.engine} (direct DDL)`,\n { createTable: ddl.createTable },\n );\n }\n\n await this.db.query(ddl.createTable);\n\n // Execute indexes\n for (const indexSQL of ddl.indexes) {\n if (this.options.debug) {\n this.logger.debug(`[SchemaManager] Creating index`, { indexSQL });\n }\n await this.db.query(indexSQL);\n }\n\n // Execute triggers (unless skipped)\n if (!this.options.skipTriggers) {\n for (const triggerSQL of ddl.triggers) {\n if (this.options.debug) {\n this.logger.debug(`[SchemaManager] Creating trigger`, { triggerSQL });\n }\n await this.db.query(triggerSQL);\n }\n }\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Table \"${tableName}\" created successfully`,\n );\n }\n }\n\n /**\n * Get existing column names from a database table\n *\n * Uses engine-appropriate introspection:\n * - SQLite/DuckDB: PRAGMA table_info\n * - PostgreSQL: information_schema.columns\n *\n * @param tableName - Name of the table to inspect\n * @returns Set of existing column names (lowercase)\n */\n private async getExistingColumns(tableName: string): Promise<Set<string>> {\n const columns = new Set<string>();\n\n try {\n if (this.engine === 'postgres') {\n const result = await this.db.query(\n 'SELECT column_name FROM information_schema.columns WHERE table_name = $1',\n tableName,\n );\n const rows = extractRows<{ column_name: string }>(result);\n for (const row of rows) {\n columns.add(row.column_name);\n }\n } else {\n // SQLite and DuckDB use PRAGMA\n const result = await this.db.query(\n `PRAGMA table_info(${this.quoteIdentifier(tableName)})`,\n );\n const rows = extractRows<{ name: string }>(result);\n for (const row of rows) {\n columns.add(row.name);\n }\n }\n } catch (error) {\n // If introspection fails, return empty set (no columns will be added)\n if (this.options.debug) {\n this.logger.warn(\n `[SchemaManager] Failed to introspect columns for \"${tableName}\"`,\n { error },\n );\n }\n }\n\n return columns;\n }\n\n /**\n * Add missing columns to an existing table via ALTER TABLE ADD COLUMN\n *\n * Compares the schema's expected columns against the table's actual columns\n * and adds any that are missing. This handles the race condition where a table\n * is created with base fields by one code path, then a later code path needs\n * additional columns from a more complete schema.\n *\n * SQLite limitation: ALTER TABLE ADD COLUMN cannot add NOT NULL columns\n * without a DEFAULT value. We relax NOT NULL for such columns.\n *\n * @param tableName - Name of the existing table\n * @param schema - The full schema definition with expected columns\n */\n private async addMissingColumns(\n tableName: string,\n schema: SchemaDefinition,\n ): Promise<void> {\n if (!schema.columns || Object.keys(schema.columns).length === 0) {\n return;\n }\n\n const existingColumns = await this.getExistingColumns(tableName);\n if (existingColumns.size === 0) {\n // Introspection failed or returned no columns — skip to avoid errors\n return;\n }\n\n const strategy = getDDLStrategy(this.engine);\n let addedCount = 0;\n\n for (const [colName, colDef] of Object.entries(schema.columns)) {\n if (existingColumns.has(colName)) {\n continue; // Column already exists\n }\n\n // SQLite limitation: ALTER TABLE ADD COLUMN cannot have NOT NULL\n // without a DEFAULT value. Relax NOT NULL for such columns.\n const safeDef = { ...colDef };\n if (\n safeDef.notNull &&\n safeDef.defaultValue === undefined &&\n !safeDef.primaryKey\n ) {\n safeDef.notNull = false;\n }\n\n // Cannot add PRIMARY KEY columns via ALTER TABLE\n if (safeDef.primaryKey) {\n continue;\n }\n\n const colSQL = strategy.generateColumnDefinition(colName, safeDef);\n const alterSQL = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD COLUMN ${colSQL}`;\n\n try {\n await this.db.query(alterSQL);\n addedCount++;\n\n if (this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Added column \"${colName}\" to \"${tableName}\"`,\n );\n }\n } catch (error) {\n // Column might already exist (race condition) or other issue\n // Log and continue — don't fail the entire operation\n if (this.options.debug) {\n this.logger.warn(\n `[SchemaManager] Failed to add column \"${colName}\" to \"${tableName}\"`,\n { error },\n );\n }\n }\n }\n\n if (addedCount > 0 && this.options.debug) {\n this.logger.debug(\n `[SchemaManager] Added ${addedCount} missing column(s) to \"${tableName}\"`,\n );\n }\n }\n\n private quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n }\n\n /**\n * Create multiple tables with dependency ordering\n *\n * @param schemas - Array of schema definitions\n */\n async ensureTables(schemas: SchemaDefinition[]): Promise<void> {\n // Sort by dependencies (topological sort)\n const sorted = this.sortByDependencies(schemas);\n\n for (const schema of sorted) {\n await this.ensureTable(schema);\n }\n }\n\n /**\n * Generate DDL without executing (useful for debugging/preview)\n *\n * @param schema - The schema definition\n * @returns Engine-specific DDL\n */\n generateDDL(schema: SchemaDefinition): EngineSpecificDDL {\n const strategy = getDDLStrategy(this.engine);\n return {\n createTable: strategy.generateCreateTable(schema),\n indexes: strategy.generateIndexes(schema),\n triggers: strategy.generateTriggers(schema),\n };\n }\n\n /**\n * Get the detected/configured database engine\n */\n getEngine(): DatabaseEngine {\n return this.engine;\n }\n\n /**\n * Sort schemas by dependencies (topological sort)\n *\n * Ensures tables are created in the correct order based on foreign key dependencies.\n */\n private sortByDependencies(schemas: SchemaDefinition[]): SchemaDefinition[] {\n const byName = new Map<string, SchemaDefinition>();\n const sorted: SchemaDefinition[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n // Index by table name\n for (const schema of schemas) {\n byName.set(schema.tableName, schema);\n }\n\n // DFS topological sort\n const visit = (tableName: string) => {\n if (visited.has(tableName)) return;\n if (visiting.has(tableName)) {\n // Circular dependency - continue anyway (FK might be nullable)\n this.logger.warn(\n `[SchemaManager] Circular dependency detected involving ${tableName}`,\n );\n return;\n }\n\n const schema = byName.get(tableName);\n if (!schema) return; // External dependency, skip\n\n visiting.add(tableName);\n\n // Visit dependencies first\n for (const dep of schema.dependencies || []) {\n visit(dep);\n }\n\n visiting.delete(tableName);\n visited.add(tableName);\n sorted.push(schema);\n };\n\n // Visit all schemas\n for (const schema of schemas) {\n visit(schema.tableName);\n }\n\n return sorted;\n }\n}\n\n/**\n * Create a SchemaManager instance\n *\n * @param db - Database interface\n * @param options - Optional configuration\n * @returns SchemaManager instance\n */\nexport function createSchemaManager(\n db: DatabaseInterface,\n options?: SchemaManagerOptions,\n): SchemaManager {\n return new SchemaManager(db, options);\n}\n"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ export interface ColumnDefinition {
14
14
  referenceKind?: 'id' | 'foreignKey' | 'crossPackageRef' | 'tenantId';
15
15
  unique?: boolean;
16
16
  notNull?: boolean;
17
- defaultValue?: any;
17
+ defaultValue?: unknown;
18
18
  foreignKey?: {
19
19
  table: string;
20
20
  column: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,WAAW,GAKX,MAAM,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,aAAa,CAAC,EAAE,IAAI,GAAG,YAAY,GAAG,iBAAiB,GAAG,UAAU,CAAC;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;QAC/C,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;KAChD,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACxC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC/C,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ,GACR,aAAa,CAAC;AAElB;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,qCAAqC;IACrC,UAAU,EAAE,IAAI,CAAC;IACjB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,sDAAsD;IACtD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mCAAmC;IACnC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+BAA+B;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,aAAa,EAAE,OAAO,CAAC;IACvB,yDAAyD;IACzD,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,+DAA+D;IAC/D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,+CAA+C;IAC/C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gCAAgC;IAChC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,UAAU,EACN,eAAe,GACf,aAAa,GACb,eAAe,GACf,eAAe,CAAC;IACpB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qBAAqB;IACrB,IAAI,EACA,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,WAAW,GACX,YAAY,GACZ,eAAe,GACf,cAAc,CAAC;IACnB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,uCAAuC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2BAA2B;IAC3B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,oDAAoD;IACpD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iCAAiC;IACjC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,OAAO,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import { DatabaseInterface } from '@happyvertical/sql';
2
+ import { SmrtObject } from '../object.js';
3
+ import { FieldDefinition } from '../scanner/types.js';
2
4
  import { DatabaseEngine } from './ddl/types.js';
3
5
  export { isJsonPathIndex, renderIndexTarget } from './index-utils.js';
4
6
  /**
@@ -15,7 +17,10 @@ export { isJsonPathIndex, renderIndexTarget } from './index-utils.js';
15
17
  * @param providedFields - Optional fields map (used during registration)
16
18
  * @returns SQL schema creation statement with CREATE TABLE and CREATE INDEX statements
17
19
  */
18
- export declare function generateSchema(ClassType: new (...args: any[]) => any, providedFields?: Map<string, any>, options?: {
20
+ export declare function generateSchema(ClassType: {
21
+ new (...args: never[]): SmrtObject;
22
+ readonly name: string;
23
+ }, providedFields?: Map<string, FieldDefinition>, options?: {
19
24
  engine?: DatabaseEngine;
20
25
  }): Promise<string>;
21
26
  /**