@happyvertical/smrt-core 0.42.7 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/AGENTS.md +35 -2
  2. package/agents/schema-paths.md +37 -15
  3. package/dist/cascade.d.ts +7 -6
  4. package/dist/cascade.d.ts.map +1 -1
  5. package/dist/cascade.js +19 -21
  6. package/dist/cascade.js.map +1 -1
  7. package/dist/class.d.ts +10 -0
  8. package/dist/class.d.ts.map +1 -1
  9. package/dist/class.js +21 -0
  10. package/dist/class.js.map +1 -1
  11. package/dist/decorators/index.d.ts +50 -15
  12. package/dist/decorators/index.d.ts.map +1 -1
  13. package/dist/decorators/index.js +23 -11
  14. package/dist/decorators/index.js.map +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -1
  18. package/dist/manifest/static-manifest.d.ts.map +1 -1
  19. package/dist/manifest/static-manifest.js +17 -1
  20. package/dist/manifest/static-manifest.js.map +1 -1
  21. package/dist/manifest/store.js +1 -1
  22. package/dist/manifest/store.js.map +1 -1
  23. package/dist/manifest.json +20 -1
  24. package/dist/migrations/differ.d.ts +2 -0
  25. package/dist/migrations/differ.d.ts.map +1 -1
  26. package/dist/migrations/differ.js +103 -0
  27. package/dist/migrations/differ.js.map +1 -1
  28. package/dist/migrations/generator.d.ts.map +1 -1
  29. package/dist/migrations/generator.js +26 -2
  30. package/dist/migrations/generator.js.map +1 -1
  31. package/dist/migrations/orchestrate.d.ts.map +1 -1
  32. package/dist/migrations/orchestrate.js +4 -1
  33. package/dist/migrations/orchestrate.js.map +1 -1
  34. package/dist/object.d.ts +4 -4
  35. package/dist/object.js +4 -4
  36. package/dist/object.js.map +1 -1
  37. package/dist/registry/schema-builder.d.ts +6 -0
  38. package/dist/registry/schema-builder.d.ts.map +1 -1
  39. package/dist/registry/schema-builder.js +80 -8
  40. package/dist/registry/schema-builder.js.map +1 -1
  41. package/dist/registry.d.ts +5 -7
  42. package/dist/registry.d.ts.map +1 -1
  43. package/dist/registry.js +6 -8
  44. package/dist/registry.js.map +1 -1
  45. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  46. package/dist/scanner/manifest-generator.js +64 -18
  47. package/dist/scanner/manifest-generator.js.map +1 -1
  48. package/dist/scanner/types.d.ts +7 -1
  49. package/dist/scanner/types.d.ts.map +1 -1
  50. package/dist/scanner/types.js.map +1 -1
  51. package/dist/schema/ddl/base-strategy.d.ts.map +1 -1
  52. package/dist/schema/ddl/base-strategy.js +2 -0
  53. package/dist/schema/ddl/base-strategy.js.map +1 -1
  54. package/dist/schema/ddl/duckdb-strategy.d.ts +1 -0
  55. package/dist/schema/ddl/duckdb-strategy.d.ts.map +1 -1
  56. package/dist/schema/ddl/duckdb-strategy.js +23 -1
  57. package/dist/schema/ddl/duckdb-strategy.js.map +1 -1
  58. package/dist/schema/ddl/postgres-strategy.js +1 -1
  59. package/dist/schema/foreign-key-ddl.d.ts +16 -0
  60. package/dist/schema/foreign-key-ddl.d.ts.map +1 -0
  61. package/dist/schema/foreign-key-ddl.js +85 -0
  62. package/dist/schema/foreign-key-ddl.js.map +1 -0
  63. package/dist/schema/foreign-key-planner.d.ts +18 -0
  64. package/dist/schema/foreign-key-planner.d.ts.map +1 -0
  65. package/dist/schema/foreign-key-planner.js +109 -0
  66. package/dist/schema/foreign-key-planner.js.map +1 -0
  67. package/dist/schema/foreign-key-policy.d.ts +21 -0
  68. package/dist/schema/foreign-key-policy.d.ts.map +1 -0
  69. package/dist/schema/foreign-key-policy.js +41 -0
  70. package/dist/schema/foreign-key-policy.js.map +1 -0
  71. package/dist/schema/generator.d.ts +3 -0
  72. package/dist/schema/generator.d.ts.map +1 -1
  73. package/dist/schema/generator.js +65 -13
  74. package/dist/schema/generator.js.map +1 -1
  75. package/dist/schema/index.d.ts +3 -0
  76. package/dist/schema/index.d.ts.map +1 -1
  77. package/dist/schema/index.js +4 -1
  78. package/dist/schema/manifest-schema.d.ts.map +1 -1
  79. package/dist/schema/manifest-schema.js +21 -3
  80. package/dist/schema/manifest-schema.js.map +1 -1
  81. package/dist/schema/schema-aggregator.d.ts +7 -1
  82. package/dist/schema/schema-aggregator.d.ts.map +1 -1
  83. package/dist/schema/schema-aggregator.js +54 -9
  84. package/dist/schema/schema-aggregator.js.map +1 -1
  85. package/dist/schema/schema-manager.d.ts +1 -6
  86. package/dist/schema/schema-manager.d.ts.map +1 -1
  87. package/dist/schema/schema-manager.js +26 -30
  88. package/dist/schema/schema-manager.js.map +1 -1
  89. package/dist/schema/types.d.ts +12 -5
  90. package/dist/schema/types.d.ts.map +1 -1
  91. package/dist/schema/utils.d.ts +1 -1
  92. package/dist/schema/utils.d.ts.map +1 -1
  93. package/dist/schema/utils.js +15 -1
  94. package/dist/schema/utils.js.map +1 -1
  95. package/dist/schema.js +4 -1
  96. package/dist/smrt-knowledge.json +18 -8
  97. package/dist/testing/database.d.ts +11 -1
  98. package/dist/testing/database.d.ts.map +1 -1
  99. package/dist/testing/database.js +80 -9
  100. package/dist/testing/database.js.map +1 -1
  101. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","names":[],"sources":["../../src/testing/database.ts"],"sourcesContent":["/**\n * Test database utilities for SMRT framework\n *\n * Provides `getTestDatabase()` which creates an in-memory database with all\n * registered SMRT object schemas. Uses the same schema generation logic as\n * the migration system to ensure consistency between test and production.\n *\n * @example\n * ```typescript\n * import { getTestDatabase } from '@happyvertical/smrt-core/testing';\n *\n * beforeEach(async () => {\n * const db = await getTestDatabase();\n * collection = await MyCollection.create({ db });\n * });\n * ```\n */\n\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { getDatabase } from '@happyvertical/sql';\nimport { ensurePostgresChangeFeedAppendFunction } from '../change-feed.js';\nimport {\n type CollectionRegistrationLookup,\n isCollectionRegistration,\n resolveCollectionItemClassName,\n resolveRelatedRegistration,\n} from '../registry/collection-resolution.js';\nimport { ObjectRegistry } from '../registry.js';\nimport { detectEngine } from '../schema/ddl/index.js';\nimport { SchemaGenerator } from '../schema/generator.js';\nimport { ensureLegacySystemTableCompatibility } from '../system/compatibility.js';\nimport { getSystemTableDDL } from '../system/schema.js';\n\ntype TestDatabaseConnectionOptions = Parameters<typeof getDatabase>[0] & {\n __smrtSkipVitestSchemaPreparation?: boolean;\n};\n\nfunction resolveSTIBaseRegistration(className: string, stiBaseName: string) {\n const registered = ObjectRegistry.getClass(className);\n\n if (stiBaseName.includes(':')) {\n return ObjectRegistry.getClass(stiBaseName);\n }\n\n if (registered?.packageName) {\n const samePackageBase = ObjectRegistry.getClassInPackage(\n registered.packageName,\n stiBaseName,\n );\n if (samePackageBase) {\n return samePackageBase;\n }\n }\n\n return ObjectRegistry.getClass(stiBaseName);\n}\n\nfunction resolveSTIBaseLookupName(\n className: string,\n stiBaseName: string,\n): string {\n const stiBase = resolveSTIBaseRegistration(className, stiBaseName);\n return stiBase?.qualifiedName || stiBase?.name || stiBaseName;\n}\n\nfunction isSTIChild(className: string): boolean {\n const stiBaseName = ObjectRegistry.getSTIBase(className);\n if (!stiBaseName) {\n return false;\n }\n\n const registered = ObjectRegistry.getClass(className);\n const stiBase = resolveSTIBaseRegistration(className, stiBaseName);\n\n if (registered && stiBase) {\n return registered !== stiBase;\n }\n\n return stiBaseName !== className;\n}\n\ntype RegisteredSchemaClass = NonNullable<\n ReturnType<typeof ObjectRegistry.getClass>\n>;\n\nconst collectionRegistrationLookup: CollectionRegistrationLookup = {\n findClass: (className) => ObjectRegistry.getClass(className),\n findClassInPackage: (packageName, className) =>\n ObjectRegistry.getClassInPackage(packageName, className),\n getInheritanceChain: (className) =>\n ObjectRegistry.getInheritanceChain(className),\n};\n\nfunction resolveCollectionSchemaClassName(\n className: string,\n registered: RegisteredSchemaClass,\n): string {\n const itemClassName = resolveCollectionItemClassName(\n className,\n registered,\n collectionRegistrationLookup,\n );\n if (itemClassName) {\n const itemRegistration = resolveRelatedRegistration(\n itemClassName,\n registered,\n collectionRegistrationLookup,\n );\n const itemLookupName =\n itemRegistration?.qualifiedName ||\n itemRegistration?.name ||\n itemClassName;\n const stiBase = ObjectRegistry.getSTIBase(itemLookupName);\n return stiBase\n ? resolveSTIBaseLookupName(itemLookupName, stiBase)\n : itemLookupName;\n }\n\n const tableName =\n registered.schema?.tableName ||\n registered.config.tableName ||\n ObjectRegistry.getTableName(className);\n if (!tableName) {\n return className;\n }\n\n const collectionPackage = registered.packageName;\n\n for (const candidate of ObjectRegistry.getAllClasses().values()) {\n if (\n candidate === registered ||\n isCollectionRegistration(\n candidate.qualifiedName || candidate.name,\n candidate,\n collectionRegistrationLookup,\n )\n ) {\n continue;\n }\n\n const candidateTableName =\n candidate.schema?.tableName || candidate.config.tableName;\n if (candidateTableName !== tableName) {\n continue;\n }\n\n if (\n collectionPackage &&\n candidate.packageName &&\n candidate.packageName !== collectionPackage\n ) {\n continue;\n }\n\n const candidateLookupName = candidate.qualifiedName || candidate.name;\n const stiBase = ObjectRegistry.getSTIBase(candidateLookupName);\n return stiBase\n ? resolveSTIBaseLookupName(candidateLookupName, stiBase)\n : candidateLookupName;\n }\n\n return className;\n}\n\n/**\n * Options for creating a test database\n */\nexport interface TestDatabaseOptions {\n /**\n * Database type (default: 'sqlite')\n * - 'sqlite': SQLite database\n * - 'json': JSON adapter (stores data as JSON files with DuckDB for querying)\n * - 'duckdb': Native DuckDB database\n */\n type?: 'sqlite' | 'json' | 'duckdb';\n\n /**\n * Database URL (default: ':memory:')\n * Use ':memory:' for in-memory databases (fastest for tests)\n * Or provide a file path for persistent test databases\n */\n url?: string;\n\n /**\n * Pre-existing database to initialize schemas in.\n * If provided, `type` and `url` are ignored.\n */\n db?: DatabaseInterface;\n\n /**\n * Specific classes to setup schemas for.\n * If not provided, sets up schemas for all registered classes.\n */\n classes?: string[];\n\n /**\n * Whether to include system tables (default: true)\n * System tables include _smrt_contexts, _smrt_migrations, etc.\n */\n includeSystemTables?: boolean;\n}\n\nfunction resolveRequestedSchemaClassName(className: string): string {\n const registered = ObjectRegistry.getClass(className);\n if (!registered) {\n return className;\n }\n\n if (\n !isCollectionRegistration(\n className,\n registered,\n collectionRegistrationLookup,\n )\n ) {\n const stiBase = ObjectRegistry.getSTIBase(className);\n return stiBase ? resolveSTIBaseLookupName(className, stiBase) : className;\n }\n\n return resolveCollectionSchemaClassName(className, registered);\n}\n\nfunction resolveRequestedSchemaClassNames(classNames: string[]): string[] {\n const resolved: string[] = [];\n const seen = new Set<string>();\n\n for (const className of classNames) {\n const schemaClassName = resolveRequestedSchemaClassName(className);\n if (seen.has(schemaClassName)) {\n continue;\n }\n\n seen.add(schemaClassName);\n resolved.push(schemaClassName);\n }\n\n return resolved;\n}\n\n/**\n * Creates an in-memory test database with schemas pre-created\n *\n * This utility is designed for testing. It creates an in-memory database\n * and initializes all registered SMRT object schemas using the **same\n * schema generation logic** as the production migration system.\n *\n * **Key features:**\n * - Uses `SchemaGenerator.generateSQL()` - the single source of truth for DDL\n * - Handles STI (Single Table Inheritance) correctly\n * - Creates system tables for framework functionality\n * - Safe for parallel test execution (each call creates isolated instance)\n *\n * @param options - Configuration options\n * @returns Promise resolving to configured DatabaseInterface\n *\n * @example\n * ```typescript\n * // Basic usage - all registered schemas\n * const db = await getTestDatabase();\n *\n * // Specific classes only\n * const db = await getTestDatabase({ classes: ['Council', 'Meeting'] });\n *\n * // JSON adapter instead of SQLite\n * const db = await getTestDatabase({ type: 'json' });\n *\n * // Native DuckDB adapter\n * const db = await getTestDatabase({ type: 'duckdb', url: ':memory:' });\n *\n * // File-based database for persistent tests\n * const db = await getTestDatabase({ type: 'sqlite', url: '/tmp/test.db' });\n *\n * // Initialize schemas in an existing database\n * const myDb = await getDatabase({ type: 'sqlite', url: ':memory:' });\n * await getTestDatabase({ db: myDb });\n *\n * // Skip system tables (rare use case)\n * const db = await getTestDatabase({ includeSystemTables: false });\n * ```\n */\nexport async function getTestDatabase(\n options: TestDatabaseOptions = {},\n): Promise<DatabaseInterface> {\n const {\n type = 'sqlite',\n url = ':memory:',\n db: existingDb,\n classes,\n includeSystemTables = true,\n } = options;\n\n // Use existing database or create new one\n const db =\n existingDb ??\n (await getDatabase({\n type,\n url,\n __smrtSkipVitestSchemaPreparation: true,\n } as TestDatabaseConnectionOptions));\n\n // Initialize system tables (same as production)\n if (includeSystemTables) {\n await initializeSystemTables(db);\n }\n\n // Get class names to setup\n const classNames = resolveRequestedSchemaClassNames(\n classes ?? ObjectRegistry.getQualifiedClassNames(),\n );\n\n // Skip if no classes registered\n if (classNames.length === 0) {\n return db;\n }\n\n // Use the same schema generation as production\n const schemaGenerator = new SchemaGenerator();\n const ddlEngine =\n type === 'json' ||\n typeof (db as { exportTable?: unknown }).exportTable === 'function'\n ? 'json'\n : type === 'duckdb'\n ? 'duckdb'\n : 'sqlite';\n\n // Track created tables to avoid duplicates (STI base classes)\n const createdTables = new Set<string>();\n\n for (const className of classNames) {\n // R11: the registration carries idType (native uuid vs text); read it\n // below when building runtimeSchemaConfig.\n const registered = ObjectRegistry.getClass(className);\n // Skip STI children - their schema is part of the base class table.\n // main (#1324): isSTIChild() compares RegisteredClass *identity* rather\n // than raw strings, so it stays correct under R5-canon (getSTIBase returns\n // qualified names) while also handling collection/override registrations.\n if (isSTIChild(className)) {\n continue;\n }\n\n const tableName = ObjectRegistry.getTableName(className);\n if (!tableName || createdTables.has(tableName)) {\n continue;\n }\n\n const fields = await ObjectRegistry.getAllFields(className);\n const strategy = ObjectRegistry.getTableStrategy(className);\n // Mirrors `schema/utils.ts`: this bag is rebuilt by hand, so every `@smrt()`\n // option the generator reads has to be listed or tests silently diverge\n // from the production schema. `indexes` (#2357) was missing from both.\n const runtimeSchemaConfig = {\n conflictColumns: ObjectRegistry.getConflictColumns(className),\n idType: registered?.config.idType,\n indexes: registered?.config.indexes,\n registry: ObjectRegistry,\n };\n\n // Generate schema through the registry paths. Production (`manifest.json`\n // and therefore `smrt db:migrate`) uses the manifest paths\n // (`generateSTISchemaFromManifest` / `generateCTISchemaFromManifest`);\n // the two families are held to the same column and index sets by\n // `src/schema/schema-path-parity.test.ts` (#2359) — do not assume they\n // agree by construction.\n const schema =\n strategy === 'sti'\n ? await schemaGenerator.generateSTISchemaFromRegistry(\n className,\n tableName,\n fields,\n runtimeSchemaConfig,\n )\n : schemaGenerator.generateSchemaFromRegistry(\n className,\n tableName,\n fields,\n runtimeSchemaConfig,\n );\n\n // Generate DDL using generateSQL() - the single source of truth\n const ddl = schemaGenerator.generateSQL(schema, ddlEngine);\n\n try {\n await db.query(ddl);\n createdTables.add(tableName);\n\n // Create indexes (use DDL strategy so jsonPath / where / etc. render)\n const ddlStrategy = (\n await import('../schema/ddl/index.js')\n ).getDDLStrategy(ddlEngine);\n const indexStatements = ddlStrategy.generateIndexes(schema);\n for (const indexSQL of indexStatements) {\n try {\n await db.query(indexSQL);\n } catch (indexError) {\n // Log but don't fail on index creation errors\n // Some indexes may fail if columns don't exist (STI meta fields)\n console.warn(\n `[getTestDatabase] Warning: Failed to create index: ${indexError instanceof Error ? indexError.message : String(indexError)} (SQL: ${indexSQL})`,\n );\n }\n }\n } catch (error) {\n // Provide helpful error message for table creation failures\n throw new Error(\n `[getTestDatabase] Failed to create table '${tableName}' for class '${className}': ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n }\n\n return db;\n}\n\n/**\n * Initialize SMRT system tables in a database\n *\n * System tables use _smrt_ prefix and store framework metadata.\n * All statements use `IF NOT EXISTS` for idempotency.\n *\n * @param db - Database interface to initialize\n */\nasync function initializeSystemTables(db: DatabaseInterface): Promise<void> {\n await ensureLegacySystemTableCompatibility(db);\n\n const configuredDb = db as DatabaseInterface & {\n config?: { type?: string; url?: string };\n type?: string;\n };\n const engine = detectEngine(\n db.url || configuredDb.config?.url || '',\n configuredDb.type || configuredDb.config?.type,\n );\n\n // Split multi-statement SQL into individual statements\n const allStatements: string[] = [];\n for (const multiStatementSQL of getSystemTableDDL(engine)) {\n const statements = multiStatementSQL\n .split(';')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n allStatements.push(...statements);\n }\n\n // Use db.query() — system tables use CREATE TABLE/INDEX IF NOT EXISTS\n // which databases handle natively without per-column existence checks.\n for (const statement of allStatements) {\n await db.query(statement);\n }\n\n // PostgreSQL keeps the best-effort append boundary in a function that must\n // be executed whole rather than included in semicolon-split portable DDL.\n await ensurePostgresChangeFeedAppendFunction(db);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"database.js","names":[],"sources":["../../src/testing/database.ts"],"sourcesContent":["/**\n * Test database utilities for SMRT framework\n *\n * Provides `getTestDatabase()` which creates an in-memory database with all\n * registered SMRT object schemas. Uses the same schema generation logic as\n * the migration system to ensure consistency between test and production.\n *\n * @example\n * ```typescript\n * import { getTestDatabase } from '@happyvertical/smrt-core/testing';\n *\n * beforeEach(async () => {\n * const db = await getTestDatabase();\n * collection = await MyCollection.create({ db });\n * });\n * ```\n */\n\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { getDatabase } from '@happyvertical/sql';\nimport { ensurePostgresChangeFeedAppendFunction } from '../change-feed.js';\nimport {\n type CollectionRegistrationLookup,\n isCollectionRegistration,\n resolveCollectionItemClassName,\n resolveRelatedRegistration,\n} from '../registry/collection-resolution.js';\nimport { ObjectRegistry } from '../registry.js';\nimport { detectEngine } from '../schema/ddl/index.js';\nimport {\n schemaForeignKeys,\n schemaForeignKeysForEngine,\n} from '../schema/foreign-key-ddl.js';\nimport { planForeignKeyCreation } from '../schema/foreign-key-planner.js';\nimport { SchemaGenerator } from '../schema/generator.js';\nimport type { SchemaDefinition } from '../schema/types.js';\nimport { ensureLegacySystemTableCompatibility } from '../system/compatibility.js';\nimport { getSystemTableDDL } from '../system/schema.js';\n\ntype TestDatabaseConnectionOptions = Parameters<typeof getDatabase>[0] & {\n __smrtSkipVitestSchemaPreparation?: boolean;\n};\n\nfunction resolveSTIBaseRegistration(className: string, stiBaseName: string) {\n const registered = ObjectRegistry.getClass(className);\n\n if (stiBaseName.includes(':')) {\n return ObjectRegistry.getClass(stiBaseName);\n }\n\n if (registered?.packageName) {\n const samePackageBase = ObjectRegistry.getClassInPackage(\n registered.packageName,\n stiBaseName,\n );\n if (samePackageBase) {\n return samePackageBase;\n }\n }\n\n return ObjectRegistry.getClass(stiBaseName);\n}\n\nfunction resolveSTIBaseLookupName(\n className: string,\n stiBaseName: string,\n): string {\n const stiBase = resolveSTIBaseRegistration(className, stiBaseName);\n return stiBase?.qualifiedName || stiBase?.name || stiBaseName;\n}\n\nfunction isSTIChild(className: string): boolean {\n const stiBaseName = ObjectRegistry.getSTIBase(className);\n if (!stiBaseName) {\n return false;\n }\n\n const registered = ObjectRegistry.getClass(className);\n const stiBase = resolveSTIBaseRegistration(className, stiBaseName);\n\n if (registered && stiBase) {\n return registered !== stiBase;\n }\n\n return stiBaseName !== className;\n}\n\ntype RegisteredSchemaClass = NonNullable<\n ReturnType<typeof ObjectRegistry.getClass>\n>;\n\nconst collectionRegistrationLookup: CollectionRegistrationLookup = {\n findClass: (className) => ObjectRegistry.getClass(className),\n findClassInPackage: (packageName, className) =>\n ObjectRegistry.getClassInPackage(packageName, className),\n getInheritanceChain: (className) =>\n ObjectRegistry.getInheritanceChain(className),\n};\n\nfunction resolveCollectionSchemaClassName(\n className: string,\n registered: RegisteredSchemaClass,\n): string {\n const itemClassName = resolveCollectionItemClassName(\n className,\n registered,\n collectionRegistrationLookup,\n );\n if (itemClassName) {\n const itemRegistration = resolveRelatedRegistration(\n itemClassName,\n registered,\n collectionRegistrationLookup,\n );\n const itemLookupName =\n itemRegistration?.qualifiedName ||\n itemRegistration?.name ||\n itemClassName;\n const stiBase = ObjectRegistry.getSTIBase(itemLookupName);\n return stiBase\n ? resolveSTIBaseLookupName(itemLookupName, stiBase)\n : itemLookupName;\n }\n\n const tableName =\n registered.schema?.tableName ||\n registered.config.tableName ||\n ObjectRegistry.getTableName(className);\n if (!tableName) {\n return className;\n }\n\n const collectionPackage = registered.packageName;\n\n for (const candidate of ObjectRegistry.getAllClasses().values()) {\n if (\n candidate === registered ||\n isCollectionRegistration(\n candidate.qualifiedName || candidate.name,\n candidate,\n collectionRegistrationLookup,\n )\n ) {\n continue;\n }\n\n const candidateTableName =\n candidate.schema?.tableName || candidate.config.tableName;\n if (candidateTableName !== tableName) {\n continue;\n }\n\n if (\n collectionPackage &&\n candidate.packageName &&\n candidate.packageName !== collectionPackage\n ) {\n continue;\n }\n\n const candidateLookupName = candidate.qualifiedName || candidate.name;\n const stiBase = ObjectRegistry.getSTIBase(candidateLookupName);\n return stiBase\n ? resolveSTIBaseLookupName(candidateLookupName, stiBase)\n : candidateLookupName;\n }\n\n return className;\n}\n\n/**\n * Options for creating a test database\n */\nexport interface TestDatabaseOptions {\n /**\n * Database type (default: 'sqlite')\n * - 'sqlite': SQLite database\n * - 'json': JSON adapter (stores data as JSON files with DuckDB for querying)\n * - 'duckdb': Native DuckDB database\n * - 'postgres': PostgreSQL database (normally supplied through `db`)\n */\n type?: 'sqlite' | 'json' | 'duckdb' | 'postgres';\n\n /**\n * Database URL (default: ':memory:')\n * Use ':memory:' for in-memory databases (fastest for tests)\n * Or provide a file path for persistent test databases\n */\n url?: string;\n\n /**\n * Pre-existing database to initialize schemas in.\n * If provided, `type` and `url` are ignored.\n */\n db?: DatabaseInterface;\n\n /**\n * Specific classes to setup schemas for.\n * If not provided, sets up schemas for all registered classes.\n */\n classes?: string[];\n\n /**\n * Whether to include system tables (default: true)\n * System tables include _smrt_contexts, _smrt_migrations, etc.\n */\n includeSystemTables?: boolean;\n\n /**\n * Explicitly omit physical FK constraints for adapter/query tests whose\n * subject is unrelated to referential enforcement. Defaults to `false`.\n * This is required (and deliberately noisy at the call site) when a DuckDB\n * fixture uses generated `ON UPDATE CASCADE`, which DuckDB cannot enforce.\n */\n omitForeignKeyConstraints?: boolean;\n}\n\n/** Resolve the DDL dialect used when preparing an existing test database. */\nexport function resolveTestDatabaseDDLEngine(\n type: TestDatabaseOptions['type'],\n db: DatabaseInterface,\n inferFromDatabase = false,\n): 'sqlite' | 'json' | 'duckdb' | 'postgres' {\n // When this helper created the adapter, the requested type is authoritative.\n // Native DuckDB and JSON-on-DuckDB both expose exportTable(), so capability\n // inference must not override an explicit native DuckDB request.\n if (!inferFromDatabase) {\n return type ?? 'sqlite';\n }\n\n const configuredDb = db as DatabaseInterface & {\n config?: { type?: string; url?: string };\n type?: string;\n exportTable?: unknown;\n inferSchemaFromJSON?: unknown;\n getTableLoadErrors?: unknown;\n };\n\n if (\n typeof configuredDb.inferSchemaFromJSON === 'function' ||\n typeof configuredDb.getTableLoadErrors === 'function'\n ) {\n return 'json';\n }\n\n if (typeof configuredDb.exportTable === 'function') {\n // The native DuckDB adapter exposes schema evolution capabilities that the\n // JSON adapter does not. Keep exportTable-only test doubles compatible with\n // the historical JSON structural marker.\n if (\n typeof configuredDb.getTableSchema === 'function' &&\n typeof configuredDb.alterTable?.addColumn === 'function'\n ) {\n return 'duckdb';\n }\n return 'json';\n }\n\n return detectEngine(\n db.url || configuredDb.config?.url || '',\n configuredDb.type || configuredDb.config?.type,\n );\n}\n\nfunction omitTestForeignKeyConstraints(\n schema: SchemaDefinition,\n): SchemaDefinition {\n const foreignKeyTargets = new Set(\n schemaForeignKeys(schema).map((foreignKey) => foreignKey.referencesTable),\n );\n return {\n ...schema,\n columns: Object.fromEntries(\n Object.entries(schema.columns).map(([name, column]) => [\n name,\n column.foreignKey ? { ...column, foreignKey: undefined } : column,\n ]),\n ),\n foreignKeys: [],\n dependencies: schema.dependencies.filter(\n (dependency) => !foreignKeyTargets.has(dependency),\n ),\n };\n}\n\nfunction resolveRequestedSchemaClassName(className: string): string {\n const registered = ObjectRegistry.getClass(className);\n if (!registered) {\n return className;\n }\n\n if (\n !isCollectionRegistration(\n className,\n registered,\n collectionRegistrationLookup,\n )\n ) {\n const stiBase = ObjectRegistry.getSTIBase(className);\n return stiBase ? resolveSTIBaseLookupName(className, stiBase) : className;\n }\n\n return resolveCollectionSchemaClassName(className, registered);\n}\n\nfunction resolveRequestedSchemaClassNames(classNames: string[]): string[] {\n const resolved: string[] = [];\n const seen = new Set<string>();\n\n for (const className of classNames) {\n const schemaClassName = resolveRequestedSchemaClassName(className);\n if (seen.has(schemaClassName)) {\n continue;\n }\n\n seen.add(schemaClassName);\n resolved.push(schemaClassName);\n }\n\n return resolved;\n}\n\n/**\n * Creates an in-memory test database with schemas pre-created\n *\n * This utility is designed for testing. It creates an in-memory database\n * and initializes all registered SMRT object schemas using the **same\n * schema generation logic** as the production migration system.\n *\n * **Key features:**\n * - Uses `SchemaGenerator.generateSQL()` - the single source of truth for DDL\n * - Handles STI (Single Table Inheritance) correctly\n * - Creates system tables for framework functionality\n * - Safe for parallel test execution (each call creates isolated instance)\n *\n * @param options - Configuration options\n * @returns Promise resolving to configured DatabaseInterface\n *\n * @example\n * ```typescript\n * // Basic usage - all registered schemas\n * const db = await getTestDatabase();\n *\n * // Specific classes only\n * const db = await getTestDatabase({ classes: ['Council', 'Meeting'] });\n *\n * // JSON adapter instead of SQLite\n * const db = await getTestDatabase({ type: 'json' });\n *\n * // Native DuckDB adapter\n * const db = await getTestDatabase({ type: 'duckdb', url: ':memory:' });\n *\n * // File-based database for persistent tests\n * const db = await getTestDatabase({ type: 'sqlite', url: '/tmp/test.db' });\n *\n * // Initialize schemas in an existing database\n * const myDb = await getDatabase({ type: 'sqlite', url: ':memory:' });\n * await getTestDatabase({ db: myDb });\n *\n * // Skip system tables (rare use case)\n * const db = await getTestDatabase({ includeSystemTables: false });\n * ```\n */\nexport async function getTestDatabase(\n options: TestDatabaseOptions = {},\n): Promise<DatabaseInterface> {\n const {\n type,\n url = ':memory:',\n db: existingDb,\n classes,\n includeSystemTables = true,\n omitForeignKeyConstraints = false,\n } = options;\n\n // Use existing database or create new one\n const db =\n existingDb ??\n (await getDatabase({\n type: type ?? 'sqlite',\n url,\n __smrtSkipVitestSchemaPreparation: true,\n } as TestDatabaseConnectionOptions));\n\n // Initialize system tables (same as production)\n if (includeSystemTables) {\n await initializeSystemTables(db);\n }\n\n // Get class names to setup\n const classNames = resolveRequestedSchemaClassNames(\n classes ?? ObjectRegistry.getQualifiedClassNames(),\n );\n\n // Skip if no classes registered\n if (classNames.length === 0) {\n return db;\n }\n\n // Use the same schema generation as production\n const schemaGenerator = new SchemaGenerator();\n const ddlEngine = resolveTestDatabaseDDLEngine(\n type,\n db,\n existingDb !== undefined,\n );\n\n // Collect every table before executing DDL so dependency ordering and cycle\n // handling are identical to production migration/schema paths (#2413).\n const schemas = new Map<\n string,\n { schema: SchemaDefinition; className: string }\n >();\n const authoritativeSchemas = ObjectRegistry.getAllSchemasAsDefinitions();\n\n for (const className of classNames) {\n // R11: the registration carries idType (native uuid vs text); read it\n // below when building runtimeSchemaConfig.\n const registered = ObjectRegistry.getClass(className);\n // Skip STI children - their schema is part of the base class table.\n // main (#1324): isSTIChild() compares RegisteredClass *identity* rather\n // than raw strings, so it stays correct under R5-canon (getSTIBase returns\n // qualified names) while also handling collection/override registrations.\n if (isSTIChild(className)) {\n continue;\n }\n\n const tableName = ObjectRegistry.getTableName(className);\n if (!tableName || schemas.has(tableName)) {\n continue;\n }\n\n const fields = await ObjectRegistry.getAllFields(className);\n const strategy = ObjectRegistry.getTableStrategy(className);\n // Mirrors `schema/utils.ts`: this bag is rebuilt by hand, so every `@smrt()`\n // option the generator reads has to be listed or tests silently diverge\n // from the production schema. `indexes` (#2357) was missing from both.\n const runtimeSchemaConfig = {\n conflictColumns: ObjectRegistry.getConflictColumns(className),\n idType: registered?.config.idType,\n indexes: registered?.config.indexes,\n registry: ObjectRegistry,\n };\n\n // Generate schema through the registry paths. Production (`manifest.json`\n // and therefore `smrt db:migrate`) uses the manifest paths\n // (`generateSTISchemaFromManifest` / `generateCTISchemaFromManifest`);\n // the two families are held to the same column and index sets by\n // `src/schema/schema-path-parity.test.ts` (#2359) — do not assume they\n // agree by construction.\n const schema =\n strategy === 'sti'\n ? await schemaGenerator.generateSTISchemaFromRegistry(\n className,\n tableName,\n fields,\n runtimeSchemaConfig,\n )\n : schemaGenerator.generateSchemaFromRegistry(\n className,\n tableName,\n fields,\n runtimeSchemaConfig,\n );\n\n // Manifest registrations can carry explicit FK actions that differ from\n // decorator defaults. The deterministic merged table schema preserves\n // those authoritative actions while still backfilling runtime-only fields.\n const authoritativeSchema = authoritativeSchemas[tableName];\n const effectiveColumns = authoritativeSchema\n ? Object.fromEntries(\n Object.entries(schema.columns).map(([name, column]) => {\n const manifestColumn = authoritativeSchema.columns[name];\n return [\n name,\n manifestColumn\n ? { ...column, foreignKey: manifestColumn.foreignKey }\n : column,\n ];\n }),\n )\n : schema.columns;\n const effectiveForeignKeys = schemaForeignKeys({\n columns: effectiveColumns,\n foreignKeys: [],\n });\n const effectiveSchema: SchemaDefinition = {\n ...schema,\n columns: effectiveColumns,\n foreignKeys: effectiveForeignKeys,\n dependencies: effectiveForeignKeys\n .map((foreignKey) => foreignKey.referencesTable)\n .filter((dependency) => dependency !== tableName),\n };\n\n schemas.set(tableName, {\n schema: omitForeignKeyConstraints\n ? omitTestForeignKeyConstraints(effectiveSchema)\n : effectiveSchema,\n className,\n });\n }\n\n // Explicitly requested test classes still need their registered parents.\n // Add the authoritative dependency closure so a child-only request cannot\n // emit a physical reference to a table this helper never creates.\n const addDependencies = (schema: SchemaDefinition): void => {\n for (const foreignKey of schemaForeignKeysForEngine(schema, ddlEngine)) {\n if (schemas.has(foreignKey.referencesTable)) continue;\n const dependency = authoritativeSchemas[foreignKey.referencesTable];\n if (!dependency) continue;\n const effectiveDependency = omitForeignKeyConstraints\n ? omitTestForeignKeyConstraints(dependency)\n : dependency;\n schemas.set(dependency.tableName, {\n schema: effectiveDependency,\n className: dependency.tableName,\n });\n addDependencies(effectiveDependency);\n }\n };\n for (const { schema } of [...schemas.values()]) addDependencies(schema);\n\n const tablePlan = planForeignKeyCreation(\n [...schemas.values()].map(({ schema }) => schema),\n ddlEngine,\n );\n const ddlStrategy = (await import('../schema/ddl/index.js')).getDDLStrategy(\n ddlEngine,\n );\n\n for (const schema of tablePlan.schemas) {\n const className = schemas.get(schema.tableName)?.className ?? 'unknown';\n const ddl = schemaGenerator.generateSQL(schema, ddlEngine);\n\n try {\n await db.query(ddl);\n\n // Create indexes (use DDL strategy so jsonPath / where / etc. render)\n const indexStatements = ddlStrategy.generateIndexes(schema);\n for (const indexSQL of indexStatements) {\n try {\n await db.query(indexSQL);\n } catch (indexError) {\n // Log but don't fail on index creation errors\n // Some indexes may fail if columns don't exist (STI meta fields)\n console.warn(\n `[getTestDatabase] Warning: Failed to create index: ${indexError instanceof Error ? indexError.message : String(indexError)} (SQL: ${indexSQL})`,\n );\n }\n }\n } catch (error) {\n // Provide helpful error message for table creation failures\n throw new Error(\n `[getTestDatabase] Failed to create table '${schema.tableName}' for class '${className}': ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n }\n\n for (const statement of tablePlan.deferredStatements) {\n try {\n await db.query(statement);\n } catch (error) {\n throw new Error(\n `[getTestDatabase] Failed to add deferred foreign-key constraint: ${error instanceof Error ? error.message : String(error)} (SQL: ${statement})`,\n { cause: error },\n );\n }\n }\n\n return db;\n}\n\n/**\n * Initialize SMRT system tables in a database\n *\n * System tables use _smrt_ prefix and store framework metadata.\n * All statements use `IF NOT EXISTS` for idempotency.\n *\n * @param db - Database interface to initialize\n */\nasync function initializeSystemTables(db: DatabaseInterface): Promise<void> {\n await ensureLegacySystemTableCompatibility(db);\n\n const configuredDb = db as DatabaseInterface & {\n config?: { type?: string; url?: string };\n type?: string;\n };\n const engine = detectEngine(\n db.url || configuredDb.config?.url || '',\n configuredDb.type || configuredDb.config?.type,\n );\n\n // Split multi-statement SQL into individual statements\n const allStatements: string[] = [];\n for (const multiStatementSQL of getSystemTableDDL(engine)) {\n const statements = multiStatementSQL\n .split(';')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n allStatements.push(...statements);\n }\n\n // Use db.query() — system tables use CREATE TABLE/INDEX IF NOT EXISTS\n // which databases handle natively without per-column existence checks.\n for (const statement of allStatements) {\n await db.query(statement);\n }\n\n // PostgreSQL keeps the best-effort append boundary in a function that must\n // be executed whole rather than included in semicolon-split portable DDL.\n await ensurePostgresChangeFeedAppendFunction(db);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-core",
3
- "version": "0.42.7",
3
+ "version": "0.43.1",
4
4
  "description": "Core AI agent framework with standardized collections, object-relational mapping, and code generators",
5
5
  "author": "HappyVertical",
6
6
  "type": "module",
@@ -164,9 +164,9 @@
164
164
  "tsx": "^4.23.0",
165
165
  "typescript": "5.9.3",
166
166
  "yaml": "^2.9.0",
167
- "@happyvertical/smrt-config": "0.42.7",
168
- "@happyvertical/smrt-types": "0.42.7",
169
- "@happyvertical/smrt-scanner": "0.42.7"
167
+ "@happyvertical/smrt-scanner": "0.43.1",
168
+ "@happyvertical/smrt-config": "0.43.1",
169
+ "@happyvertical/smrt-types": "0.43.1"
170
170
  },
171
171
  "peerDependencies": {
172
172
  "@huggingface/transformers": ">=3.0.0 <4.0.0",