@happyvertical/smrt-core 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +124 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +265 -0
- package/bin/smrt-prebuild.js +26 -0
- package/dist/__tests__/fixtures/advisor-test-classes.d.ts +28 -0
- package/dist/__tests__/fixtures/advisor-test-classes.d.ts.map +1 -0
- package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts +12 -0
- package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts.map +1 -0
- package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts +28 -0
- package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts.map +1 -0
- package/dist/__tests__/fixtures/inheritance-test-classes.d.ts +43 -0
- package/dist/__tests__/fixtures/inheritance-test-classes.d.ts.map +1 -0
- package/dist/__tests__/fixtures/mcp-integration-test-classes.d.ts +18 -0
- package/dist/__tests__/fixtures/mcp-integration-test-classes.d.ts.map +1 -0
- package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts +15 -0
- package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts.map +1 -0
- package/dist/__tests__/fixtures/object-spec-test-classes.d.ts +13 -0
- package/dist/__tests__/fixtures/object-spec-test-classes.d.ts.map +1 -0
- package/dist/__tests__/fixtures/registry-test-classes.d.ts +23 -0
- package/dist/__tests__/fixtures/registry-test-classes.d.ts.map +1 -0
- package/dist/adapters/ai-usage.d.ts +23 -0
- package/dist/adapters/ai-usage.d.ts.map +1 -0
- package/dist/adapters/ai-usage.js +105 -0
- package/dist/adapters/ai-usage.js.map +1 -0
- package/dist/adapters/cost-rates.d.ts +20 -0
- package/dist/adapters/cost-rates.d.ts.map +1 -0
- package/dist/adapters/cost-rates.js +40 -0
- package/dist/adapters/cost-rates.js.map +1 -0
- package/dist/adapters/index.d.ts +19 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/metrics.d.ts +111 -0
- package/dist/adapters/metrics.d.ts.map +1 -0
- package/dist/adapters/metrics.js +169 -0
- package/dist/adapters/metrics.js.map +1 -0
- package/dist/adapters/pubsub.d.ts +124 -0
- package/dist/adapters/pubsub.d.ts.map +1 -0
- package/dist/adapters/pubsub.js +121 -0
- package/dist/adapters/pubsub.js.map +1 -0
- package/dist/browser.d.ts +32 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +68 -0
- package/dist/browser.js.map +1 -0
- package/dist/child-accessors.d.ts +27 -0
- package/dist/child-accessors.d.ts.map +1 -0
- package/dist/child-accessors.js +35 -0
- package/dist/child-accessors.js.map +1 -0
- package/dist/class.d.ts +313 -0
- package/dist/class.d.ts.map +1 -0
- package/dist/class.js +896 -0
- package/dist/class.js.map +1 -0
- package/dist/collection-cache.d.ts +110 -0
- package/dist/collection-cache.d.ts.map +1 -0
- package/dist/collection-cache.js +187 -0
- package/dist/collection-cache.js.map +1 -0
- package/dist/collection.d.ts +894 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +1987 -0
- package/dist/collection.js.map +1 -0
- package/dist/config/global-config.d.ts +3 -0
- package/dist/config/global-config.d.ts.map +1 -0
- package/dist/config/global-config.js +19 -0
- package/dist/config/global-config.js.map +1 -0
- package/dist/config.d.ts +145 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/consumer-plugin/index.d.ts +22 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -0
- package/dist/consumer-plugin/index.js +452 -0
- package/dist/consumer-plugin/index.js.map +1 -0
- package/dist/consumer-plugin.d.ts +8 -0
- package/dist/consumer-plugin.d.ts.map +1 -0
- package/dist/consumer-plugin.js +5 -0
- package/dist/consumer-plugin.js.map +1 -0
- package/dist/database.d.ts +95 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +32 -0
- package/dist/database.js.map +1 -0
- package/dist/decorators/compatibility.d.ts +14 -0
- package/dist/decorators/compatibility.d.ts.map +1 -0
- package/dist/decorators/compatibility.js +111 -0
- package/dist/decorators/compatibility.js.map +1 -0
- package/dist/decorators/index.d.ts +381 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +104 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/dispatch/bus.d.ts +306 -0
- package/dist/dispatch/bus.d.ts.map +1 -0
- package/dist/dispatch/bus.js +583 -0
- package/dist/dispatch/bus.js.map +1 -0
- package/dist/dispatch/collections/DispatchSubscriptions.d.ts +79 -0
- package/dist/dispatch/collections/DispatchSubscriptions.d.ts.map +1 -0
- package/dist/dispatch/collections/DispatchSubscriptions.js +243 -0
- package/dist/dispatch/collections/DispatchSubscriptions.js.map +1 -0
- package/dist/dispatch/collections/Dispatches.d.ts +98 -0
- package/dist/dispatch/collections/Dispatches.d.ts.map +1 -0
- package/dist/dispatch/collections/Dispatches.js +358 -0
- package/dist/dispatch/collections/Dispatches.js.map +1 -0
- package/dist/dispatch/index.d.ts +47 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/models/Dispatch.d.ts +101 -0
- package/dist/dispatch/models/Dispatch.d.ts.map +1 -0
- package/dist/dispatch/models/Dispatch.js +162 -0
- package/dist/dispatch/models/Dispatch.js.map +1 -0
- package/dist/dispatch/models/DispatchSubscription.d.ts +83 -0
- package/dist/dispatch/models/DispatchSubscription.d.ts.map +1 -0
- package/dist/dispatch/models/DispatchSubscription.js +112 -0
- package/dist/dispatch/models/DispatchSubscription.js.map +1 -0
- package/dist/dispatch/tenant-resolver.d.ts +98 -0
- package/dist/dispatch/tenant-resolver.d.ts.map +1 -0
- package/dist/dispatch/tenant-resolver.js +32 -0
- package/dist/dispatch/tenant-resolver.js.map +1 -0
- package/dist/dispatch/types.d.ts +149 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/embeddings/hash.d.ts +33 -0
- package/dist/embeddings/hash.d.ts.map +1 -0
- package/dist/embeddings/hash.js +37 -0
- package/dist/embeddings/hash.js.map +1 -0
- package/dist/embeddings/index.d.ts +36 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/provider.d.ts +75 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +170 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/embeddings/similarity.d.ts +47 -0
- package/dist/embeddings/similarity.d.ts.map +1 -0
- package/dist/embeddings/similarity.js +64 -0
- package/dist/embeddings/similarity.js.map +1 -0
- package/dist/embeddings/storage.d.ts +125 -0
- package/dist/embeddings/storage.d.ts.map +1 -0
- package/dist/embeddings/storage.js +283 -0
- package/dist/embeddings/storage.js.map +1 -0
- package/dist/embeddings/types.d.ts +250 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/errors.d.ts +363 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +669 -0
- package/dist/errors.js.map +1 -0
- package/dist/generators/cli.d.ts +162 -0
- package/dist/generators/cli.d.ts.map +1 -0
- package/dist/generators/cli.js +462 -0
- package/dist/generators/cli.js.map +1 -0
- package/dist/generators/index.d.ts +13 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/mcp-runtime-template.d.ts +60 -0
- package/dist/generators/mcp-runtime-template.d.ts.map +1 -0
- package/dist/generators/mcp-runtime-template.js +509 -0
- package/dist/generators/mcp-runtime-template.js.map +1 -0
- package/dist/generators/mcp.d.ts +231 -0
- package/dist/generators/mcp.d.ts.map +1 -0
- package/dist/generators/mcp.js +1220 -0
- package/dist/generators/mcp.js.map +1 -0
- package/dist/generators/rest.d.ts +171 -0
- package/dist/generators/rest.d.ts.map +1 -0
- package/dist/generators/rest.js +591 -0
- package/dist/generators/rest.js.map +1 -0
- package/dist/generators/swagger.d.ts +21 -0
- package/dist/generators/swagger.d.ts.map +1 -0
- package/dist/generators/swagger.js +307 -0
- package/dist/generators/swagger.js.map +1 -0
- package/dist/generators/tenant-gate.d.ts +74 -0
- package/dist/generators/tenant-gate.d.ts.map +1 -0
- package/dist/generators/tenant-gate.js +15 -0
- package/dist/generators/tenant-gate.js.map +1 -0
- package/dist/generators.d.ts +8 -0
- package/dist/generators.d.ts.map +1 -0
- package/dist/generators.js +19 -0
- package/dist/generators.js.map +1 -0
- package/dist/hierarchical.d.ts +103 -0
- package/dist/hierarchical.d.ts.map +1 -0
- package/dist/hierarchical.js +184 -0
- package/dist/hierarchical.js.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +202 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors.d.ts +251 -0
- package/dist/interceptors.d.ts.map +1 -0
- package/dist/interceptors.js +259 -0
- package/dist/interceptors.js.map +1 -0
- package/dist/junction.d.ts +99 -0
- package/dist/junction.d.ts.map +1 -0
- package/dist/junction.js +136 -0
- package/dist/junction.js.map +1 -0
- package/dist/knowledge.d.ts +11 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +310 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/lazy-config.d.ts +160 -0
- package/dist/lazy-config.d.ts.map +1 -0
- package/dist/lazy-config.js +146 -0
- package/dist/lazy-config.js.map +1 -0
- package/dist/manifest/discover-base-classes.d.ts +78 -0
- package/dist/manifest/discover-base-classes.d.ts.map +1 -0
- package/dist/manifest/discover-base-classes.js +85 -0
- package/dist/manifest/discover-base-classes.js.map +1 -0
- package/dist/manifest/discover-smrt-packages.d.ts +48 -0
- package/dist/manifest/discover-smrt-packages.d.ts.map +1 -0
- package/dist/manifest/discover-smrt-packages.js +361 -0
- package/dist/manifest/discover-smrt-packages.js.map +1 -0
- package/dist/manifest/generator.d.ts +93 -0
- package/dist/manifest/generator.d.ts.map +1 -0
- package/dist/manifest/generator.js +380 -0
- package/dist/manifest/generator.js.map +1 -0
- package/dist/manifest/index.d.ts +16 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +51 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/manager.d.ts +51 -0
- package/dist/manifest/manager.d.ts.map +1 -0
- package/dist/manifest/manager.js +89 -0
- package/dist/manifest/manager.js.map +1 -0
- package/dist/manifest/manifest-loader.d.ts +187 -0
- package/dist/manifest/manifest-loader.d.ts.map +1 -0
- package/dist/manifest/manifest-loader.js +847 -0
- package/dist/manifest/manifest-loader.js.map +1 -0
- package/dist/manifest/sources/composite.d.ts +22 -0
- package/dist/manifest/sources/composite.d.ts.map +1 -0
- package/dist/manifest/sources/composite.js +60 -0
- package/dist/manifest/sources/composite.js.map +1 -0
- package/dist/manifest/sources/embedded.d.ts +7 -0
- package/dist/manifest/sources/embedded.d.ts.map +1 -0
- package/dist/manifest/sources/embedded.js +30 -0
- package/dist/manifest/sources/embedded.js.map +1 -0
- package/dist/manifest/sources/explicit-paths.d.ts +17 -0
- package/dist/manifest/sources/explicit-paths.d.ts.map +1 -0
- package/dist/manifest/sources/explicit-paths.js +35 -0
- package/dist/manifest/sources/explicit-paths.js.map +1 -0
- package/dist/manifest/sources/fallback.d.ts +25 -0
- package/dist/manifest/sources/fallback.d.ts.map +1 -0
- package/dist/manifest/sources/fallback.js +63 -0
- package/dist/manifest/sources/fallback.js.map +1 -0
- package/dist/manifest/sources/index.d.ts +17 -0
- package/dist/manifest/sources/index.d.ts.map +1 -0
- package/dist/manifest/sources/local-test.d.ts +7 -0
- package/dist/manifest/sources/local-test.d.ts.map +1 -0
- package/dist/manifest/sources/local-test.js +21 -0
- package/dist/manifest/sources/local-test.js.map +1 -0
- package/dist/manifest/sources/static.d.ts +7 -0
- package/dist/manifest/sources/static.d.ts.map +1 -0
- package/dist/manifest/sources/static.js +19 -0
- package/dist/manifest/sources/static.js.map +1 -0
- package/dist/manifest/sources/test.d.ts +7 -0
- package/dist/manifest/sources/test.d.ts.map +1 -0
- package/dist/manifest/sources/test.js +21 -0
- package/dist/manifest/sources/test.js.map +1 -0
- package/dist/manifest/sources/types.d.ts +79 -0
- package/dist/manifest/sources/types.d.ts.map +1 -0
- package/dist/manifest/sources/types.js +61 -0
- package/dist/manifest/sources/types.js.map +1 -0
- package/dist/manifest/static-manifest.d.ts +4 -0
- package/dist/manifest/static-manifest.d.ts.map +1 -0
- package/dist/manifest/static-manifest.js +1535 -0
- package/dist/manifest/static-manifest.js.map +1 -0
- package/dist/manifest/store.d.ts +111 -0
- package/dist/manifest/store.d.ts.map +1 -0
- package/dist/manifest/store.js +431 -0
- package/dist/manifest/store.js.map +1 -0
- package/dist/manifest/test-manifest-loader.d.ts +3 -0
- package/dist/manifest/test-manifest-loader.d.ts.map +1 -0
- package/dist/manifest/test-manifest-stub.d.ts +4 -0
- package/dist/manifest/test-manifest-stub.d.ts.map +1 -0
- package/dist/manifest/test-manifest-stub.js +80013 -0
- package/dist/manifest/test-manifest-stub.js.map +1 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +20 -0
- package/dist/manifest.js.map +1 -0
- package/dist/manifest.json +1489 -0
- package/dist/mcp-advisor/index.d.ts +499 -0
- package/dist/mcp-advisor/index.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/add-ai-methods.d.ts +6 -0
- package/dist/mcp-advisor/tools/add-ai-methods.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/configure-decorators.d.ts +6 -0
- package/dist/mcp-advisor/tools/configure-decorators.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/generate-collection.d.ts +6 -0
- package/dist/mcp-advisor/tools/generate-collection.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/generate-field-definitions.d.ts +6 -0
- package/dist/mcp-advisor/tools/generate-field-definitions.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/generate-smrt-class.d.ts +6 -0
- package/dist/mcp-advisor/tools/generate-smrt-class.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/get-object-config.d.ts +6 -0
- package/dist/mcp-advisor/tools/get-object-config.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/get-object-schema.d.ts +10 -0
- package/dist/mcp-advisor/tools/get-object-schema.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/list-registered-objects.d.ts +9 -0
- package/dist/mcp-advisor/tools/list-registered-objects.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/preview-api-endpoints.d.ts +9 -0
- package/dist/mcp-advisor/tools/preview-api-endpoints.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/preview-mcp-tools.d.ts +9 -0
- package/dist/mcp-advisor/tools/preview-mcp-tools.d.ts.map +1 -0
- package/dist/mcp-advisor/tools/validate-smrt-object.d.ts +6 -0
- package/dist/mcp-advisor/tools/validate-smrt-object.d.ts.map +1 -0
- package/dist/mcp-advisor/types.d.ts +209 -0
- package/dist/mcp-advisor/types.d.ts.map +1 -0
- package/dist/migrations/backfill-tracker.d.ts +84 -0
- package/dist/migrations/backfill-tracker.d.ts.map +1 -0
- package/dist/migrations/backfill-tracker.js +118 -0
- package/dist/migrations/backfill-tracker.js.map +1 -0
- package/dist/migrations/checksum.d.ts +43 -0
- package/dist/migrations/checksum.d.ts.map +1 -0
- package/dist/migrations/checksum.js +32 -0
- package/dist/migrations/checksum.js.map +1 -0
- package/dist/migrations/differ.d.ts +186 -0
- package/dist/migrations/differ.d.ts.map +1 -0
- package/dist/migrations/differ.js +601 -0
- package/dist/migrations/differ.js.map +1 -0
- package/dist/migrations/generator.d.ts +133 -0
- package/dist/migrations/generator.d.ts.map +1 -0
- package/dist/migrations/generator.js +328 -0
- package/dist/migrations/generator.js.map +1 -0
- package/dist/migrations/index.d.ts +20 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/orchestrate.d.ts +148 -0
- package/dist/migrations/orchestrate.d.ts.map +1 -0
- package/dist/migrations/orchestrate.js +118 -0
- package/dist/migrations/orchestrate.js.map +1 -0
- package/dist/migrations/tracker.d.ts +134 -0
- package/dist/migrations/tracker.d.ts.map +1 -0
- package/dist/migrations/tracker.js +624 -0
- package/dist/migrations/tracker.js.map +1 -0
- package/dist/migrations/types.d.ts +221 -0
- package/dist/migrations/types.d.ts.map +1 -0
- package/dist/migrations.d.ts +7 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +26 -0
- package/dist/migrations.js.map +1 -0
- package/dist/node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js +56 -0
- package/dist/node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js.map +1 -0
- package/dist/node_modules/.pnpm/brace-expansion@5.0.5/node_modules/brace-expansion/dist/esm/index.js +163 -0
- package/dist/node_modules/.pnpm/brace-expansion@5.0.5/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/assert-valid-pattern.js +13 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js +654 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/brace-expressions.js +111 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/escape.js +10 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/escape.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js +824 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js +10 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js.map +1 -0
- package/dist/object.d.ts +1202 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +2731 -0
- package/dist/object.js.map +1 -0
- package/dist/polymorphic-association.d.ts +69 -0
- package/dist/polymorphic-association.d.ts.map +1 -0
- package/dist/polymorphic-association.js +96 -0
- package/dist/polymorphic-association.js.map +1 -0
- package/dist/prebuild/cli.d.ts +7 -0
- package/dist/prebuild/cli.d.ts.map +1 -0
- package/dist/prebuild/cli.js +29 -0
- package/dist/prebuild/cli.js.map +1 -0
- package/dist/prebuild/index.d.ts +22 -0
- package/dist/prebuild/index.d.ts.map +1 -0
- package/dist/prebuild/index.js +239 -0
- package/dist/prebuild/index.js.map +1 -0
- package/dist/prebuild.d.ts +8 -0
- package/dist/prebuild.d.ts.map +1 -0
- package/dist/prebuild.js +6 -0
- package/dist/prebuild.js.map +1 -0
- package/dist/registry/cache-config.d.ts +13 -0
- package/dist/registry/cache-config.d.ts.map +1 -0
- package/dist/registry/cache-config.js +17 -0
- package/dist/registry/cache-config.js.map +1 -0
- package/dist/registry/class-registration.d.ts +31 -0
- package/dist/registry/class-registration.d.ts.map +1 -0
- package/dist/registry/class-registration.js +1074 -0
- package/dist/registry/class-registration.js.map +1 -0
- package/dist/registry/collection-resolution.d.ts +45 -0
- package/dist/registry/collection-resolution.d.ts.map +1 -0
- package/dist/registry/collection-resolution.js +121 -0
- package/dist/registry/collection-resolution.js.map +1 -0
- package/dist/registry/collision-policy.d.ts +179 -0
- package/dist/registry/collision-policy.d.ts.map +1 -0
- package/dist/registry/collision-policy.js +153 -0
- package/dist/registry/collision-policy.js.map +1 -0
- package/dist/registry/diagnostics.d.ts +58 -0
- package/dist/registry/diagnostics.d.ts.map +1 -0
- package/dist/registry/diagnostics.js +54 -0
- package/dist/registry/diagnostics.js.map +1 -0
- package/dist/registry/embedding-manager.d.ts +23 -0
- package/dist/registry/embedding-manager.d.ts.map +1 -0
- package/dist/registry/embedding-manager.js +62 -0
- package/dist/registry/embedding-manager.js.map +1 -0
- package/dist/registry/index.d.ts +13 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/inheritance-resolver.d.ts +13 -0
- package/dist/registry/inheritance-resolver.d.ts.map +1 -0
- package/dist/registry/inheritance-resolver.js +244 -0
- package/dist/registry/inheritance-resolver.js.map +1 -0
- package/dist/registry/manifest-field-merge.d.ts +4 -0
- package/dist/registry/manifest-field-merge.d.ts.map +1 -0
- package/dist/registry/manifest-field-merge.js +82 -0
- package/dist/registry/manifest-field-merge.js.map +1 -0
- package/dist/registry/name-resolver.d.ts +102 -0
- package/dist/registry/name-resolver.d.ts.map +1 -0
- package/dist/registry/name-resolver.js +241 -0
- package/dist/registry/name-resolver.js.map +1 -0
- package/dist/registry/relationship-graph.d.ts +16 -0
- package/dist/registry/relationship-graph.d.ts.map +1 -0
- package/dist/registry/relationship-graph.js +79 -0
- package/dist/registry/relationship-graph.js.map +1 -0
- package/dist/registry/schema-builder.d.ts +113 -0
- package/dist/registry/schema-builder.d.ts.map +1 -0
- package/dist/registry/schema-builder.js +474 -0
- package/dist/registry/schema-builder.js.map +1 -0
- package/dist/registry/shared-state.d.ts +62 -0
- package/dist/registry/shared-state.d.ts.map +1 -0
- package/dist/registry/shared-state.js +135 -0
- package/dist/registry/shared-state.js.map +1 -0
- package/dist/registry/types.d.ts +667 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/validator.d.ts +13 -0
- package/dist/registry/validator.d.ts.map +1 -0
- package/dist/registry/validator.js +138 -0
- package/dist/registry/validator.js.map +1 -0
- package/dist/registry.d.ts +1358 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +2301 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime/client.d.ts +34 -0
- package/dist/runtime/client.d.ts.map +1 -0
- package/dist/runtime/client.js +104 -0
- package/dist/runtime/client.js.map +1 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/mcp.d.ts +47 -0
- package/dist/runtime/mcp.d.ts.map +1 -0
- package/dist/runtime/mcp.js +72 -0
- package/dist/runtime/mcp.js.map +1 -0
- package/dist/runtime/server.d.ts +92 -0
- package/dist/runtime/server.d.ts.map +1 -0
- package/dist/runtime/server.js +390 -0
- package/dist/runtime/server.js.map +1 -0
- package/dist/runtime/types.d.ts +58 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +10 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scanner/import-scanner.d.ts +7 -0
- package/dist/scanner/import-scanner.d.ts.map +1 -0
- package/dist/scanner/index.d.ts +12 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/manifest-generator.d.ts +304 -0
- package/dist/scanner/manifest-generator.d.ts.map +1 -0
- package/dist/scanner/manifest-generator.js +1707 -0
- package/dist/scanner/manifest-generator.js.map +1 -0
- package/dist/scanner/test-file-patterns.d.ts +18 -0
- package/dist/scanner/test-file-patterns.d.ts.map +1 -0
- package/dist/scanner/test-file-patterns.js +16 -0
- package/dist/scanner/test-file-patterns.js.map +1 -0
- package/dist/scanner/types.d.ts +313 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/scanner.d.ts +6 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +6 -0
- package/dist/scanner.js.map +1 -0
- package/dist/schema/code-generator.d.ts +53 -0
- package/dist/schema/code-generator.d.ts.map +1 -0
- package/dist/schema/ddl/base-strategy.d.ts +80 -0
- package/dist/schema/ddl/base-strategy.d.ts.map +1 -0
- package/dist/schema/ddl/base-strategy.js +240 -0
- package/dist/schema/ddl/base-strategy.js.map +1 -0
- package/dist/schema/ddl/duckdb-strategy.d.ts +33 -0
- package/dist/schema/ddl/duckdb-strategy.d.ts.map +1 -0
- package/dist/schema/ddl/duckdb-strategy.js +74 -0
- package/dist/schema/ddl/duckdb-strategy.js.map +1 -0
- package/dist/schema/ddl/index.d.ts +53 -0
- package/dist/schema/ddl/index.d.ts.map +1 -0
- package/dist/schema/ddl/index.js +80 -0
- package/dist/schema/ddl/index.js.map +1 -0
- package/dist/schema/ddl/json-duckdb-strategy.d.ts +8 -0
- package/dist/schema/ddl/json-duckdb-strategy.d.ts.map +1 -0
- package/dist/schema/ddl/json-duckdb-strategy.js +14 -0
- package/dist/schema/ddl/json-duckdb-strategy.js.map +1 -0
- package/dist/schema/ddl/postgres-strategy.d.ts +29 -0
- package/dist/schema/ddl/postgres-strategy.d.ts.map +1 -0
- package/dist/schema/ddl/postgres-strategy.js +102 -0
- package/dist/schema/ddl/postgres-strategy.js.map +1 -0
- package/dist/schema/ddl/sqlite-strategy.d.ts +38 -0
- package/dist/schema/ddl/sqlite-strategy.d.ts.map +1 -0
- package/dist/schema/ddl/sqlite-strategy.js +74 -0
- package/dist/schema/ddl/sqlite-strategy.js.map +1 -0
- package/dist/schema/ddl/types.d.ts +114 -0
- package/dist/schema/ddl/types.d.ts.map +1 -0
- package/dist/schema/generator.d.ts +176 -0
- package/dist/schema/generator.d.ts.map +1 -0
- package/dist/schema/generator.js +1076 -0
- package/dist/schema/generator.js.map +1 -0
- package/dist/schema/index-utils.d.ts +19 -0
- package/dist/schema/index-utils.d.ts.map +1 -0
- package/dist/schema/index-utils.js +32 -0
- package/dist/schema/index-utils.js.map +1 -0
- package/dist/schema/index.d.ts +13 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/override-system.d.ts +43 -0
- package/dist/schema/override-system.d.ts.map +1 -0
- package/dist/schema/schema-aggregator.d.ts +112 -0
- package/dist/schema/schema-aggregator.d.ts.map +1 -0
- package/dist/schema/schema-manager.d.ts +95 -0
- package/dist/schema/schema-manager.d.ts.map +1 -0
- package/dist/schema/schema-manager.js +283 -0
- package/dist/schema/schema-manager.js.map +1 -0
- package/dist/schema/sql-identifiers.d.ts +107 -0
- package/dist/schema/sql-identifiers.d.ts.map +1 -0
- package/dist/schema/sql-identifiers.js +190 -0
- package/dist/schema/sql-identifiers.js.map +1 -0
- package/dist/schema/table-verifier.d.ts +10 -0
- package/dist/schema/table-verifier.d.ts.map +1 -0
- package/dist/schema/table-verifier.js +37 -0
- package/dist/schema/table-verifier.js.map +1 -0
- package/dist/schema/types.d.ts +241 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/utils.d.ts +32 -0
- package/dist/schema/utils.d.ts.map +1 -0
- package/dist/schema/utils.js +134 -0
- package/dist/schema/utils.js.map +1 -0
- package/dist/scripts/create-wrappers.js +89 -0
- package/dist/scripts/generate-manifest.js +155 -0
- package/dist/scripts/generate-test-manifest.js +77 -0
- package/dist/scripts/migrate-datetime-to-timestamp.ts +310 -0
- package/dist/scripts/prepack.js +49 -0
- package/dist/signals/bus.d.ts +64 -0
- package/dist/signals/bus.d.ts.map +1 -0
- package/dist/signals/bus.js +102 -0
- package/dist/signals/bus.js.map +1 -0
- package/dist/signals/index.d.ts +11 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/sanitizer.d.ts +54 -0
- package/dist/signals/sanitizer.d.ts.map +1 -0
- package/dist/signals/sanitizer.js +111 -0
- package/dist/signals/sanitizer.js.map +1 -0
- package/dist/smrt-knowledge.json +335 -0
- package/dist/system/compatibility.d.ts +8 -0
- package/dist/system/compatibility.d.ts.map +1 -0
- package/dist/system/compatibility.js +409 -0
- package/dist/system/compatibility.js.map +1 -0
- package/dist/system/index.d.ts +9 -0
- package/dist/system/index.d.ts.map +1 -0
- package/dist/system/schema.d.ts +69 -0
- package/dist/system/schema.d.ts.map +1 -0
- package/dist/system/schema.js +271 -0
- package/dist/system/schema.js.map +1 -0
- package/dist/system/types.d.ts +135 -0
- package/dist/system/types.d.ts.map +1 -0
- package/dist/system-fields.d.ts +44 -0
- package/dist/system-fields.d.ts.map +1 -0
- package/dist/system-fields.js +55 -0
- package/dist/system-fields.js.map +1 -0
- package/dist/table-cache.d.ts +28 -0
- package/dist/table-cache.d.ts.map +1 -0
- package/dist/table-cache.js +21 -0
- package/dist/table-cache.js.map +1 -0
- package/dist/test-utils.d.ts +140 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/testing/database.d.ts +73 -0
- package/dist/testing/database.d.ts.map +1 -0
- package/dist/testing/database.js +204 -0
- package/dist/testing/database.js.map +1 -0
- package/dist/testing/index.d.ts +21 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +5 -0
- package/dist/testing.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/tool-executor.d.ts +101 -0
- package/dist/tools/tool-executor.d.ts.map +1 -0
- package/dist/tools/tool-executor.js +142 -0
- package/dist/tools/tool-executor.js.map +1 -0
- package/dist/tools/tool-generator.d.ts +54 -0
- package/dist/tools/tool-generator.d.ts.map +1 -0
- package/dist/tools/tool-generator.js +121 -0
- package/dist/tools/tool-generator.js.map +1 -0
- package/dist/utils/chunk.d.ts +32 -0
- package/dist/utils/chunk.d.ts.map +1 -0
- package/dist/utils/chunk.js +14 -0
- package/dist/utils/chunk.js.map +1 -0
- package/dist/utils/import-workspace-module.d.ts +8 -0
- package/dist/utils/import-workspace-module.d.ts.map +1 -0
- package/dist/utils/import-workspace-module.js +81 -0
- package/dist/utils/import-workspace-module.js.map +1 -0
- package/dist/utils/json.d.ts +102 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +43 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/lru-cache.d.ts +69 -0
- package/dist/utils/lru-cache.d.ts.map +1 -0
- package/dist/utils/lru-cache.js +100 -0
- package/dist/utils/lru-cache.js.map +1 -0
- package/dist/utils/naming.d.ts +16 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/naming.js +23 -0
- package/dist/utils/naming.js.map +1 -0
- package/dist/utils/qualified-names.d.ts +122 -0
- package/dist/utils/qualified-names.d.ts.map +1 -0
- package/dist/utils/qualified-names.js +82 -0
- package/dist/utils/qualified-names.js.map +1 -0
- package/dist/utils/scanner-module.d.ts +37 -0
- package/dist/utils/scanner-module.d.ts.map +1 -0
- package/dist/utils.d.ts +177 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +185 -0
- package/dist/utils.js.map +1 -0
- package/dist/vite-plugin/import-build-aware.d.ts +68 -0
- package/dist/vite-plugin/import-build-aware.d.ts.map +1 -0
- package/dist/vite-plugin/import-build-aware.js +72 -0
- package/dist/vite-plugin/import-build-aware.js.map +1 -0
- package/dist/vite-plugin/index.d.ts +59 -0
- package/dist/vite-plugin/index.d.ts.map +1 -0
- package/dist/vite-plugin/index.js +1400 -0
- package/dist/vite-plugin/index.js.map +1 -0
- package/dist/vite-plugin/sveltekit-generator.d.ts +66 -0
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -0
- package/dist/vite-plugin/sveltekit-generator.js +1375 -0
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -0
- package/dist/vite-plugin/templates/default-ui.ts +432 -0
- package/dist/vite-plugin/templates/default.html +206 -0
- package/dist/vite-plugin.d.ts +8 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +11 -0
- package/dist/vite-plugin.js.map +1 -0
- package/package.json +208 -0
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DatabaseEngine } from './ddl/types.js';
|
|
2
|
+
import { IndexDefinition } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render the SQL target of a CREATE INDEX statement.
|
|
5
|
+
*
|
|
6
|
+
* For ordinary indexes this is a comma-separated, double-quoted column list.
|
|
7
|
+
* For JSON-path indexes (introduced by `@meta({ indexed: true })`) it is the
|
|
8
|
+
* dialect-specific expression that points into a JSONB column.
|
|
9
|
+
*
|
|
10
|
+
* @param index - The index definition (may carry `jsonPath`)
|
|
11
|
+
* @param engine - The target database dialect
|
|
12
|
+
* @returns The contents of the trailing `(...)` of the CREATE INDEX statement
|
|
13
|
+
*/
|
|
14
|
+
export declare function renderIndexTarget(index: Pick<IndexDefinition, 'columns' | 'jsonPath'>, engine: DatabaseEngine): string;
|
|
15
|
+
/**
|
|
16
|
+
* True if the index has a valid jsonPath target.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isJsonPathIndex(index: Pick<IndexDefinition, 'jsonPath'>): boolean;
|
|
19
|
+
//# sourceMappingURL=index-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-utils.d.ts","sourceRoot":"","sources":["../../src/schema/index-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,UAAU,CAAC,EACpD,MAAM,EAAE,cAAc,GACrB,MAAM,CAiCR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GACvC,OAAO,CAET"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isSafeIdentifier, isSafeIdentifierPath, quoteIdentifier, quoteStringLiteral } from "./sql-identifiers.js";
|
|
2
|
+
function renderIndexTarget(index, engine) {
|
|
3
|
+
if (index.jsonPath?.column && index.jsonPath.path) {
|
|
4
|
+
const col = index.jsonPath.column;
|
|
5
|
+
const path = index.jsonPath.path;
|
|
6
|
+
if (!isSafeIdentifier(col)) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
`[index-utils] Unsafe JSON-path index column "${col}": must be a simple identifier`
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
if (!isSafeIdentifierPath(path)) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`[index-utils] Unsafe JSON-path index path "${path}": must be a simple (dotted) identifier`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (engine === "sqlite") {
|
|
17
|
+
return `json_extract(${quoteIdentifier(col)}, ${quoteStringLiteral(
|
|
18
|
+
`$.${path}`
|
|
19
|
+
)})`;
|
|
20
|
+
}
|
|
21
|
+
return `(${quoteIdentifier(col)}->>${quoteStringLiteral(path)})`;
|
|
22
|
+
}
|
|
23
|
+
return (index.columns ?? []).map((c) => quoteIdentifier(c)).join(", ");
|
|
24
|
+
}
|
|
25
|
+
function isJsonPathIndex(index) {
|
|
26
|
+
return !!(index.jsonPath?.column && index.jsonPath.path);
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
isJsonPathIndex,
|
|
30
|
+
renderIndexTarget
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=index-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-utils.js","sources":["../../src/schema/index-utils.ts"],"sourcesContent":["/**\n * Index-rendering helpers shared across DDL strategies, schema aggregator,\n * and the migration generator/differ.\n *\n * IMPORTANT: this module must remain a pure utility with **type-only\n * imports** to avoid introducing a cycle with `registry.ts` /\n * `collection.ts`. Don't add runtime imports that pull SmrtClass /\n * SmrtCollection / ObjectRegistry through here.\n */\n\nimport type { DatabaseEngine } from './ddl/types.js';\nimport {\n isSafeIdentifier,\n isSafeIdentifierPath,\n quoteIdentifier,\n quoteStringLiteral,\n} from './sql-identifiers.js';\nimport type { IndexDefinition } from './types.js';\n\n/**\n * Render the SQL target of a CREATE INDEX statement.\n *\n * For ordinary indexes this is a comma-separated, double-quoted column list.\n * For JSON-path indexes (introduced by `@meta({ indexed: true })`) it is the\n * dialect-specific expression that points into a JSONB column.\n *\n * @param index - The index definition (may carry `jsonPath`)\n * @param engine - The target database dialect\n * @returns The contents of the trailing `(...)` of the CREATE INDEX statement\n */\nexport function renderIndexTarget(\n index: Pick<IndexDefinition, 'columns' | 'jsonPath'>,\n engine: DatabaseEngine,\n): string {\n if (index.jsonPath?.column && index.jsonPath.path) {\n const col = index.jsonPath.column;\n const path = index.jsonPath.path;\n // The column is interpolated as an identifier and the path as a SQL string\n // literal. Validate both against an identifier allowlist (these are\n // developer-controlled `@meta` field names) so a malformed name can't\n // smuggle structure into the expression even after escaping.\n if (!isSafeIdentifier(col)) {\n throw new Error(\n `[index-utils] Unsafe JSON-path index column \"${col}\": must be a simple identifier`,\n );\n }\n if (!isSafeIdentifierPath(path)) {\n throw new Error(\n `[index-utils] Unsafe JSON-path index path \"${path}\": must be a simple (dotted) identifier`,\n );\n }\n if (engine === 'sqlite') {\n // SQLite's json_extract is a function call — no extra wrapping needed.\n return `json_extract(${quoteIdentifier(col)}, ${quoteStringLiteral(\n `$.${path}`,\n )})`;\n }\n // Postgres / DuckDB JSON path access via `->>`. PostgreSQL requires\n // operator expressions in index elements to be parenthesized — the\n // outer `()` in `CREATE INDEX ... ON tbl (...)` is the column list, so\n // the expression itself needs its own parens. Returning the wrapped\n // form here keeps the rule local to this helper and works on DuckDB\n // (extra parens are harmless).\n return `(${quoteIdentifier(col)}->>${quoteStringLiteral(path)})`;\n }\n return (index.columns ?? []).map((c) => quoteIdentifier(c)).join(', ');\n}\n\n/**\n * True if the index has a valid jsonPath target.\n */\nexport function isJsonPathIndex(\n index: Pick<IndexDefinition, 'jsonPath'>,\n): boolean {\n return !!(index.jsonPath?.column && index.jsonPath.path);\n}\n"],"names":[],"mappings":";AA8BO,SAAS,kBACd,OACA,QACQ;AACR,MAAI,MAAM,UAAU,UAAU,MAAM,SAAS,MAAM;AACjD,UAAM,MAAM,MAAM,SAAS;AAC3B,UAAM,OAAO,MAAM,SAAS;AAK5B,QAAI,CAAC,iBAAiB,GAAG,GAAG;AAC1B,YAAM,IAAI;AAAA,QACR,gDAAgD,GAAG;AAAA,MAAA;AAAA,IAEvD;AACA,QAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,8CAA8C,IAAI;AAAA,MAAA;AAAA,IAEtD;AACA,QAAI,WAAW,UAAU;AAEvB,aAAO,gBAAgB,gBAAgB,GAAG,CAAC,KAAK;AAAA,QAC9C,KAAK,IAAI;AAAA,MAAA,CACV;AAAA,IACH;AAOA,WAAO,IAAI,gBAAgB,GAAG,CAAC,MAAM,mBAAmB,IAAI,CAAC;AAAA,EAC/D;AACA,UAAQ,MAAM,WAAW,CAAA,GAAI,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC,EAAE,KAAK,IAAI;AACvE;AAKO,SAAS,gBACd,OACS;AACT,SAAO,CAAC,EAAE,MAAM,UAAU,UAAU,MAAM,SAAS;AACrD;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema generation module exports
|
|
3
|
+
*/
|
|
4
|
+
export { SchemaCodeGenerator } from './code-generator.js';
|
|
5
|
+
export * from './ddl/index.js';
|
|
6
|
+
export { SchemaGenerator } from './generator.js';
|
|
7
|
+
export { SchemaOverrideSystem } from './override-system.js';
|
|
8
|
+
export type { AggregatedTable, AggregateOptions, AggregationResult, } from './schema-aggregator.js';
|
|
9
|
+
export { SchemaAggregator } from './schema-aggregator.js';
|
|
10
|
+
export { createSchemaManager, SchemaManager } from './schema-manager.js';
|
|
11
|
+
export type { ColumnDefinition, ForeignKeyDefinition, IndexDefinition, SchemaDefinition, SchemaManifest, SchemaMigration, SchemaOverride, TriggerDefinition, } from './types.js';
|
|
12
|
+
export * from './types.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzE,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ColumnDefinition, SchemaDefinition, SchemaOverride } from './types.js';
|
|
2
|
+
export declare class SchemaOverrideSystem {
|
|
3
|
+
/**
|
|
4
|
+
* Apply schema override to base schema
|
|
5
|
+
*/
|
|
6
|
+
static applyOverride(baseSchema: SchemaDefinition, override: SchemaOverride): SchemaDefinition;
|
|
7
|
+
/**
|
|
8
|
+
* Create a schema override for extending a base schema
|
|
9
|
+
*/
|
|
10
|
+
static createOverride(tableName: string, packageName: string, extensions: {
|
|
11
|
+
addColumns?: Record<string, ColumnDefinition>;
|
|
12
|
+
removeColumns?: string[];
|
|
13
|
+
addIndexes?: Array<any>;
|
|
14
|
+
removeIndexes?: string[];
|
|
15
|
+
addTriggers?: Array<any>;
|
|
16
|
+
removeTriggers?: string[];
|
|
17
|
+
}): SchemaOverride;
|
|
18
|
+
/**
|
|
19
|
+
* Merge multiple schema overrides
|
|
20
|
+
*/
|
|
21
|
+
static mergeOverrides(baseSchema: SchemaDefinition, overrides: SchemaOverride[]): SchemaDefinition;
|
|
22
|
+
/**
|
|
23
|
+
* Create praeco-specific content schema override
|
|
24
|
+
*/
|
|
25
|
+
static createPraecoContentOverride(): SchemaOverride;
|
|
26
|
+
/**
|
|
27
|
+
* Create praeco-specific meeting schema override
|
|
28
|
+
*/
|
|
29
|
+
static createPraecoMeetingOverride(): SchemaOverride;
|
|
30
|
+
/**
|
|
31
|
+
* Generate version for overridden schema
|
|
32
|
+
*/
|
|
33
|
+
private static generateOverrideVersion;
|
|
34
|
+
/**
|
|
35
|
+
* Extract foreign keys from columns
|
|
36
|
+
*/
|
|
37
|
+
private static extractForeignKeys;
|
|
38
|
+
/**
|
|
39
|
+
* Extract dependencies from schema
|
|
40
|
+
*/
|
|
41
|
+
private static extractDependencies;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=override-system.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { SmartObjectManifest } from '../scanner/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Aggregated table information including DDL, indexes, and source tracking.
|
|
4
|
+
*/
|
|
5
|
+
export interface AggregatedTable {
|
|
6
|
+
/** Table name */
|
|
7
|
+
tableName: string;
|
|
8
|
+
/** CREATE TABLE statement (most comprehensive version for STI tables) */
|
|
9
|
+
ddl: string;
|
|
10
|
+
/** CREATE INDEX statements (deduplicated across sources) */
|
|
11
|
+
indexes: string[];
|
|
12
|
+
/** Package:className sources that contribute to this table */
|
|
13
|
+
sources: string[];
|
|
14
|
+
/** Schema definition metadata */
|
|
15
|
+
columns?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of schema aggregation across packages.
|
|
19
|
+
*/
|
|
20
|
+
export interface AggregationResult {
|
|
21
|
+
/** Aggregated tables keyed by table name */
|
|
22
|
+
tables: Map<string, AggregatedTable>;
|
|
23
|
+
/** Combined SQL string (CREATE TABLE + CREATE INDEX statements) */
|
|
24
|
+
sql: string;
|
|
25
|
+
/** Loaded manifests keyed by package name */
|
|
26
|
+
manifests: Map<string, SmartObjectManifest>;
|
|
27
|
+
/** Summary statistics */
|
|
28
|
+
stats: {
|
|
29
|
+
packagesLoaded: number;
|
|
30
|
+
packagesSkipped: number;
|
|
31
|
+
totalObjects: number;
|
|
32
|
+
uniqueTables: number;
|
|
33
|
+
stiTables: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for schema aggregation.
|
|
38
|
+
*/
|
|
39
|
+
export interface AggregateOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Explicit list of packages to scan. If omitted, auto-discovers
|
|
42
|
+
* installed `@happyvertical/smrt-*` packages from `node_modules`
|
|
43
|
+
* via `discoverSmrtPackages()`.
|
|
44
|
+
*/
|
|
45
|
+
packages?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* Additional local filesystem paths to check for manifests,
|
|
48
|
+
* keyed by package name. Useful for development when local
|
|
49
|
+
* packages have newer schemas than node_modules.
|
|
50
|
+
*/
|
|
51
|
+
localPaths?: Record<string, string>;
|
|
52
|
+
/**
|
|
53
|
+
* Skip collection tables and infrastructure tables.
|
|
54
|
+
* Useful for generating minimal schemas for lightweight deployments.
|
|
55
|
+
*/
|
|
56
|
+
minimal?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Table name patterns to skip in minimal mode.
|
|
59
|
+
* Defaults to common infrastructure tables.
|
|
60
|
+
*/
|
|
61
|
+
minimalSkipPatterns?: RegExp[];
|
|
62
|
+
/**
|
|
63
|
+
* Specific table names to skip in minimal mode.
|
|
64
|
+
*/
|
|
65
|
+
minimalSkipTables?: string[];
|
|
66
|
+
/**
|
|
67
|
+
* SQL dialect for the output. Affects PRAGMA statements and syntax.
|
|
68
|
+
* @default 'postgres'
|
|
69
|
+
*/
|
|
70
|
+
dialect?: 'postgres' | 'sqlite';
|
|
71
|
+
/** Log progress to console */
|
|
72
|
+
verbose?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Aggregates database schemas from multiple SMRT package manifests.
|
|
76
|
+
*
|
|
77
|
+
* Handles the complete workflow of discovering packages, loading manifests,
|
|
78
|
+
* extracting DDL, deduplicating STI tables, and producing combined SQL.
|
|
79
|
+
*/
|
|
80
|
+
export declare class SchemaAggregator {
|
|
81
|
+
/**
|
|
82
|
+
* Aggregate schemas from SMRT packages.
|
|
83
|
+
*
|
|
84
|
+
* @param options - Aggregation options
|
|
85
|
+
* @returns Aggregated schemas with combined SQL
|
|
86
|
+
*/
|
|
87
|
+
aggregate(options?: AggregateOptions): AggregationResult;
|
|
88
|
+
/**
|
|
89
|
+
* Load a manifest from local path or node_modules.
|
|
90
|
+
*/
|
|
91
|
+
private loadManifest;
|
|
92
|
+
/**
|
|
93
|
+
* Extract schemas from manifests, deduplicating STI tables.
|
|
94
|
+
*
|
|
95
|
+
* For STI tables (shared by multiple classes across packages),
|
|
96
|
+
* keeps the most comprehensive DDL (largest) and merges indexes.
|
|
97
|
+
*/
|
|
98
|
+
private extractSchemas;
|
|
99
|
+
/**
|
|
100
|
+
* Format an index definition into a CREATE INDEX statement.
|
|
101
|
+
*/
|
|
102
|
+
private formatIndexDdl;
|
|
103
|
+
/**
|
|
104
|
+
* Apply minimal filtering to remove infrastructure/collection tables.
|
|
105
|
+
*/
|
|
106
|
+
private applyMinimalFilter;
|
|
107
|
+
/**
|
|
108
|
+
* Generate combined SQL from aggregated tables.
|
|
109
|
+
*/
|
|
110
|
+
private generateSQL;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=schema-aggregator.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { DatabaseEngine, EngineSpecificDDL } from './ddl/index.js';
|
|
3
|
+
import { SchemaDefinition } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Schema Manager Options
|
|
6
|
+
*/
|
|
7
|
+
export interface SchemaManagerOptions {
|
|
8
|
+
/** Force engine type (overrides auto-detection) */
|
|
9
|
+
engine?: DatabaseEngine;
|
|
10
|
+
/** Whether to skip triggers (useful for DuckDB-backed JSON) */
|
|
11
|
+
skipTriggers?: boolean;
|
|
12
|
+
/** Log DDL statements before execution */
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Schema Manager
|
|
17
|
+
*
|
|
18
|
+
* Handles direct DDL execution for database schema management.
|
|
19
|
+
* Replaces SDK's syncSchema() with SMRT-controlled schema creation.
|
|
20
|
+
*/
|
|
21
|
+
export declare class SchemaManager {
|
|
22
|
+
private db;
|
|
23
|
+
private engine;
|
|
24
|
+
private options;
|
|
25
|
+
private logger;
|
|
26
|
+
constructor(db: DatabaseInterface, options?: SchemaManagerOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Ensure a table exists with the correct schema
|
|
29
|
+
*
|
|
30
|
+
* If table doesn't exist, creates it with DDL from the engine-specific strategy.
|
|
31
|
+
* If table exists but is missing columns, adds them via ALTER TABLE ADD COLUMN.
|
|
32
|
+
*
|
|
33
|
+
* @param schema - The schema definition
|
|
34
|
+
*/
|
|
35
|
+
ensureTable(schema: SchemaDefinition): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Get existing column names from a database table
|
|
38
|
+
*
|
|
39
|
+
* Uses engine-appropriate introspection:
|
|
40
|
+
* - SQLite/DuckDB: PRAGMA table_info
|
|
41
|
+
* - PostgreSQL: information_schema.columns
|
|
42
|
+
*
|
|
43
|
+
* @param tableName - Name of the table to inspect
|
|
44
|
+
* @returns Set of existing column names (lowercase)
|
|
45
|
+
*/
|
|
46
|
+
private getExistingColumns;
|
|
47
|
+
/**
|
|
48
|
+
* Add missing columns to an existing table via ALTER TABLE ADD COLUMN
|
|
49
|
+
*
|
|
50
|
+
* Compares the schema's expected columns against the table's actual columns
|
|
51
|
+
* and adds any that are missing. This handles the race condition where a table
|
|
52
|
+
* is created with base fields by one code path, then a later code path needs
|
|
53
|
+
* additional columns from a more complete schema.
|
|
54
|
+
*
|
|
55
|
+
* SQLite limitation: ALTER TABLE ADD COLUMN cannot add NOT NULL columns
|
|
56
|
+
* without a DEFAULT value. We relax NOT NULL for such columns.
|
|
57
|
+
*
|
|
58
|
+
* @param tableName - Name of the existing table
|
|
59
|
+
* @param schema - The full schema definition with expected columns
|
|
60
|
+
*/
|
|
61
|
+
private addMissingColumns;
|
|
62
|
+
private quoteIdentifier;
|
|
63
|
+
/**
|
|
64
|
+
* Create multiple tables with dependency ordering
|
|
65
|
+
*
|
|
66
|
+
* @param schemas - Array of schema definitions
|
|
67
|
+
*/
|
|
68
|
+
ensureTables(schemas: SchemaDefinition[]): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Generate DDL without executing (useful for debugging/preview)
|
|
71
|
+
*
|
|
72
|
+
* @param schema - The schema definition
|
|
73
|
+
* @returns Engine-specific DDL
|
|
74
|
+
*/
|
|
75
|
+
generateDDL(schema: SchemaDefinition): EngineSpecificDDL;
|
|
76
|
+
/**
|
|
77
|
+
* Get the detected/configured database engine
|
|
78
|
+
*/
|
|
79
|
+
getEngine(): DatabaseEngine;
|
|
80
|
+
/**
|
|
81
|
+
* Sort schemas by dependencies (topological sort)
|
|
82
|
+
*
|
|
83
|
+
* Ensures tables are created in the correct order based on foreign key dependencies.
|
|
84
|
+
*/
|
|
85
|
+
private sortByDependencies;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a SchemaManager instance
|
|
89
|
+
*
|
|
90
|
+
* @param db - Database interface
|
|
91
|
+
* @param options - Optional configuration
|
|
92
|
+
* @returns SchemaManager instance
|
|
93
|
+
*/
|
|
94
|
+
export declare function createSchemaManager(db: DatabaseInterface, options?: SchemaManagerOptions): SchemaManager;
|
|
95
|
+
//# sourceMappingURL=schema-manager.d.ts.map
|
|
@@ -0,0 +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"}
|