@warlock.js/cascade 4.0.174 → 4.1.2
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/README.md +6 -5
- package/bin/cascadejs +3 -0
- package/esm/cli/commands/migrate-export-sql.mjs +48 -0
- package/esm/cli/commands/migrate-export-sql.mjs.map +1 -0
- package/esm/cli/commands/migrate-list.mjs +26 -0
- package/esm/cli/commands/migrate-list.mjs.map +1 -0
- package/esm/cli/commands/migrate-rollback.mjs +50 -0
- package/esm/cli/commands/migrate-rollback.mjs.map +1 -0
- package/esm/cli/commands/migrate.mjs +65 -0
- package/esm/cli/commands/migrate.mjs.map +1 -0
- package/esm/cli/connection-from-env.mjs +181 -0
- package/esm/cli/connection-from-env.mjs.map +1 -0
- package/esm/cli/index.mjs +31 -0
- package/esm/cli/index.mjs.map +1 -0
- package/esm/cli/load-migrations.mjs +78 -0
- package/esm/cli/load-migrations.mjs.map +1 -0
- package/esm/cli/printers.mjs +57 -0
- package/esm/cli/printers.mjs.map +1 -0
- package/esm/cli/setup-logger.mjs +30 -0
- package/esm/cli/setup-logger.mjs.map +1 -0
- package/esm/cli/with-cli-connection.mjs +39 -0
- package/esm/cli/with-cli-connection.mjs.map +1 -0
- package/esm/cli.d.mts +1 -0
- package/esm/cli.mjs +26 -0
- package/esm/cli.mjs.map +1 -0
- package/esm/context/database-data-source-context.d.mts +32 -0
- package/esm/context/database-data-source-context.d.mts.map +1 -0
- package/esm/context/database-data-source-context.mjs +35 -0
- package/esm/context/database-data-source-context.mjs.map +1 -0
- package/esm/context/database-transaction-context.d.mts +38 -0
- package/esm/context/database-transaction-context.d.mts.map +1 -0
- package/esm/context/database-transaction-context.mjs +47 -0
- package/esm/context/database-transaction-context.mjs.map +1 -0
- package/esm/contracts/database-driver.contract.d.mts +443 -0
- package/esm/contracts/database-driver.contract.d.mts.map +1 -0
- package/esm/contracts/database-id-generator.contract.d.mts +109 -0
- package/esm/contracts/database-id-generator.contract.d.mts.map +1 -0
- package/esm/contracts/database-remover.contract.d.mts +108 -0
- package/esm/contracts/database-remover.contract.d.mts.map +1 -0
- package/esm/contracts/database-restorer.contract.d.mts +145 -0
- package/esm/contracts/database-restorer.contract.d.mts.map +1 -0
- package/esm/contracts/database-writer.contract.d.mts +123 -0
- package/esm/contracts/database-writer.contract.d.mts.map +1 -0
- package/esm/contracts/driver-blueprint.contract.d.mts +52 -0
- package/esm/contracts/driver-blueprint.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +9 -0
- package/esm/contracts/migration-driver.contract.d.mts +476 -0
- package/esm/contracts/migration-driver.contract.d.mts.map +1 -0
- package/esm/contracts/query-builder.contract.d.mts +1663 -0
- package/esm/contracts/query-builder.contract.d.mts.map +1 -0
- package/esm/contracts/sync-adapter.contract.d.mts +49 -0
- package/esm/contracts/sync-adapter.contract.d.mts.map +1 -0
- package/esm/data-source/data-source-registry.d.mts +111 -0
- package/esm/data-source/data-source-registry.d.mts.map +1 -0
- package/esm/data-source/data-source-registry.mjs +142 -0
- package/esm/data-source/data-source-registry.mjs.map +1 -0
- package/esm/data-source/data-source.d.mts +160 -0
- package/esm/data-source/data-source.d.mts.map +1 -0
- package/esm/data-source/data-source.mjs +87 -0
- package/esm/data-source/data-source.mjs.map +1 -0
- package/esm/database-dirty-tracker.d.mts +254 -0
- package/esm/database-dirty-tracker.d.mts.map +1 -0
- package/esm/database-dirty-tracker.mjs +356 -0
- package/esm/database-dirty-tracker.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-blueprint.mjs +54 -0
- package/esm/drivers/mongodb/mongodb-blueprint.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-driver.d.mts +334 -0
- package/esm/drivers/mongodb/mongodb-driver.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-driver.mjs +716 -0
- package/esm/drivers/mongodb/mongodb-driver.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-id-generator.d.mts +120 -0
- package/esm/drivers/mongodb/mongodb-id-generator.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-id-generator.mjs +141 -0
- package/esm/drivers/mongodb/mongodb-id-generator.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.d.mts +322 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.mjs +531 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-builder.d.mts +1117 -0
- package/esm/drivers/mongodb/mongodb-query-builder.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-builder.mjs +1828 -0
- package/esm/drivers/mongodb/mongodb-query-builder.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-operations.d.mts +230 -0
- package/esm/drivers/mongodb/mongodb-query-operations.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-operations.mjs +275 -0
- package/esm/drivers/mongodb/mongodb-query-operations.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-parser.d.mts +263 -0
- package/esm/drivers/mongodb/mongodb-query-parser.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-parser.mjs +965 -0
- package/esm/drivers/mongodb/mongodb-query-parser.mjs.map +1 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts +78 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts.map +1 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.mjs +118 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.mjs.map +1 -0
- package/esm/drivers/mongodb/types.d.mts +43 -0
- package/esm/drivers/mongodb/types.d.mts.map +1 -0
- package/esm/drivers/postgres/index.d.mts +8 -0
- package/esm/drivers/postgres/index.mjs +9 -0
- package/esm/drivers/postgres/postgres-blueprint.d.mts +60 -0
- package/esm/drivers/postgres/postgres-blueprint.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-blueprint.mjs +105 -0
- package/esm/drivers/postgres/postgres-blueprint.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-dialect.d.mts +144 -0
- package/esm/drivers/postgres/postgres-dialect.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-dialect.mjs +227 -0
- package/esm/drivers/postgres/postgres-dialect.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-driver.d.mts +424 -0
- package/esm/drivers/postgres/postgres-driver.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-driver.mjs +845 -0
- package/esm/drivers/postgres/postgres-driver.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-migration-driver.d.mts +393 -0
- package/esm/drivers/postgres/postgres-migration-driver.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-migration-driver.mjs +760 -0
- package/esm/drivers/postgres/postgres-migration-driver.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-query-builder.d.mts +399 -0
- package/esm/drivers/postgres/postgres-query-builder.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-query-builder.mjs +1105 -0
- package/esm/drivers/postgres/postgres-query-builder.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-query-parser.d.mts +351 -0
- package/esm/drivers/postgres/postgres-query-parser.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-query-parser.mjs +796 -0
- package/esm/drivers/postgres/postgres-query-parser.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-sql-serializer.mjs +260 -0
- package/esm/drivers/postgres/postgres-sql-serializer.mjs.map +1 -0
- package/esm/drivers/postgres/postgres-sync-adapter.d.mts +79 -0
- package/esm/drivers/postgres/postgres-sync-adapter.d.mts.map +1 -0
- package/esm/drivers/postgres/postgres-sync-adapter.mjs +162 -0
- package/esm/drivers/postgres/postgres-sync-adapter.mjs.map +1 -0
- package/esm/drivers/postgres/types.d.mts +105 -0
- package/esm/drivers/postgres/types.d.mts.map +1 -0
- package/esm/drivers/sql/sql-dialect.contract.d.mts +221 -0
- package/esm/drivers/sql/sql-dialect.contract.d.mts.map +1 -0
- package/esm/drivers/sql/sql-types.d.mts +150 -0
- package/esm/drivers/sql/sql-types.d.mts.map +1 -0
- package/esm/errors/missing-data-source.error.d.mts +25 -0
- package/esm/errors/missing-data-source.error.d.mts.map +1 -0
- package/esm/errors/missing-data-source.error.mjs +31 -0
- package/esm/errors/missing-data-source.error.mjs.map +1 -0
- package/esm/errors/transaction-rollback.error.d.mts +23 -0
- package/esm/errors/transaction-rollback.error.d.mts.map +1 -0
- package/esm/errors/transaction-rollback.error.mjs +29 -0
- package/esm/errors/transaction-rollback.error.mjs.map +1 -0
- package/esm/events/model-events.d.mts +234 -0
- package/esm/events/model-events.d.mts.map +1 -0
- package/esm/events/model-events.mjs +254 -0
- package/esm/events/model-events.mjs.map +1 -0
- package/esm/expressions/aggregate-expressions.d.mts +224 -0
- package/esm/expressions/aggregate-expressions.d.mts.map +1 -0
- package/esm/expressions/aggregate-expressions.mjs +232 -0
- package/esm/expressions/aggregate-expressions.mjs.map +1 -0
- package/esm/index.d.mts +67 -0
- package/esm/index.mjs +53 -0
- package/esm/migration/column-builder.d.mts +420 -0
- package/esm/migration/column-builder.d.mts.map +1 -0
- package/esm/migration/column-builder.mjs +532 -0
- package/esm/migration/column-builder.mjs.map +1 -0
- package/esm/migration/column-helpers.d.mts +280 -0
- package/esm/migration/column-helpers.d.mts.map +1 -0
- package/esm/migration/column-helpers.mjs +376 -0
- package/esm/migration/column-helpers.mjs.map +1 -0
- package/esm/migration/foreign-key-builder.d.mts +106 -0
- package/esm/migration/foreign-key-builder.d.mts.map +1 -0
- package/esm/migration/foreign-key-builder.mjs +126 -0
- package/esm/migration/foreign-key-builder.mjs.map +1 -0
- package/esm/migration/index.d.mts +6 -0
- package/esm/migration/index.mjs +7 -0
- package/esm/migration/migration-runner.d.mts +279 -0
- package/esm/migration/migration-runner.d.mts.map +1 -0
- package/esm/migration/migration-runner.mjs +662 -0
- package/esm/migration/migration-runner.mjs.map +1 -0
- package/esm/migration/migration.d.mts +2035 -0
- package/esm/migration/migration.d.mts.map +1 -0
- package/esm/migration/migration.mjs +2083 -0
- package/esm/migration/migration.mjs.map +1 -0
- package/esm/migration/sql-grammar.mjs +115 -0
- package/esm/migration/sql-grammar.mjs.map +1 -0
- package/esm/migration/sql-serializer.d.mts +26 -0
- package/esm/migration/sql-serializer.d.mts.map +1 -0
- package/esm/migration/sql-serializer.mjs +26 -0
- package/esm/migration/sql-serializer.mjs.map +1 -0
- package/esm/migration/types.d.mts +136 -0
- package/esm/migration/types.d.mts.map +1 -0
- package/esm/model/methods/accessor-methods.mjs +54 -0
- package/esm/model/methods/accessor-methods.mjs.map +1 -0
- package/esm/model/methods/delete-methods.mjs +16 -0
- package/esm/model/methods/delete-methods.mjs.map +1 -0
- package/esm/model/methods/dirty-methods.mjs +20 -0
- package/esm/model/methods/dirty-methods.mjs.map +1 -0
- package/esm/model/methods/hydration-methods.mjs +51 -0
- package/esm/model/methods/hydration-methods.mjs.map +1 -0
- package/esm/model/methods/instance-event-methods.mjs +22 -0
- package/esm/model/methods/instance-event-methods.mjs.map +1 -0
- package/esm/model/methods/meta-methods.mjs +36 -0
- package/esm/model/methods/meta-methods.mjs.map +1 -0
- package/esm/model/methods/pivot-methods.mjs +48 -0
- package/esm/model/methods/pivot-methods.mjs.map +1 -0
- package/esm/model/methods/query-methods.mjs +121 -0
- package/esm/model/methods/query-methods.mjs.map +1 -0
- package/esm/model/methods/restore-methods.mjs +16 -0
- package/esm/model/methods/restore-methods.mjs.map +1 -0
- package/esm/model/methods/scope-methods.mjs +20 -0
- package/esm/model/methods/scope-methods.mjs.map +1 -0
- package/esm/model/methods/serialization-methods.mjs +20 -0
- package/esm/model/methods/serialization-methods.mjs.map +1 -0
- package/esm/model/methods/static-event-methods.mjs +37 -0
- package/esm/model/methods/static-event-methods.mjs.map +1 -0
- package/esm/model/methods/write-methods.mjs +69 -0
- package/esm/model/methods/write-methods.mjs.map +1 -0
- package/esm/model/model.d.mts +1778 -0
- package/esm/model/model.d.mts.map +1 -0
- package/esm/model/model.mjs +1762 -0
- package/esm/model/model.mjs.map +1 -0
- package/esm/model/model.types.d.mts +47 -0
- package/esm/model/model.types.d.mts.map +1 -0
- package/esm/model/register-model.d.mts +140 -0
- package/esm/model/register-model.d.mts.map +1 -0
- package/esm/model/register-model.mjs +175 -0
- package/esm/model/register-model.mjs.map +1 -0
- package/esm/model/relation-decorators.d.mts +88 -0
- package/esm/model/relation-decorators.d.mts.map +1 -0
- package/esm/model/relation-decorators.mjs +191 -0
- package/esm/model/relation-decorators.mjs.map +1 -0
- package/esm/operations/database.d.mts +46 -0
- package/esm/operations/database.d.mts.map +1 -0
- package/esm/operations/database.mjs +40 -0
- package/esm/operations/database.mjs.map +1 -0
- package/esm/operations/index.d.mts +2 -0
- package/esm/operations/index.mjs +4 -0
- package/esm/operations/migrations.d.mts +71 -0
- package/esm/operations/migrations.d.mts.map +1 -0
- package/esm/operations/migrations.mjs +70 -0
- package/esm/operations/migrations.mjs.map +1 -0
- package/esm/query-builder/query-builder.d.mts +564 -0
- package/esm/query-builder/query-builder.d.mts.map +1 -0
- package/esm/query-builder/query-builder.mjs +1097 -0
- package/esm/query-builder/query-builder.mjs.map +1 -0
- package/esm/relations/index.d.mts +4 -0
- package/esm/relations/index.mjs +5 -0
- package/esm/relations/key-conventions.mjs +119 -0
- package/esm/relations/key-conventions.mjs.map +1 -0
- package/esm/relations/pivot-operations.d.mts +155 -0
- package/esm/relations/pivot-operations.d.mts.map +1 -0
- package/esm/relations/pivot-operations.mjs +232 -0
- package/esm/relations/pivot-operations.mjs.map +1 -0
- package/esm/relations/relation-hydrator.d.mts +55 -0
- package/esm/relations/relation-hydrator.d.mts.map +1 -0
- package/esm/relations/relation-hydrator.mjs +52 -0
- package/esm/relations/relation-hydrator.mjs.map +1 -0
- package/esm/relations/relation-loader.d.mts +190 -0
- package/esm/relations/relation-loader.d.mts.map +1 -0
- package/esm/relations/relation-loader.mjs +416 -0
- package/esm/relations/relation-loader.mjs.map +1 -0
- package/esm/relations/types.d.mts +317 -0
- package/esm/relations/types.d.mts.map +1 -0
- package/esm/remover/database-remover.d.mts +104 -0
- package/esm/remover/database-remover.d.mts.map +1 -0
- package/esm/remover/database-remover.mjs +174 -0
- package/esm/remover/database-remover.mjs.map +1 -0
- package/esm/restorer/database-restorer.d.mts +135 -0
- package/esm/restorer/database-restorer.d.mts.map +1 -0
- package/esm/restorer/database-restorer.mjs +316 -0
- package/esm/restorer/database-restorer.mjs.map +1 -0
- package/esm/sql-database-dirty-tracker.d.mts +17 -0
- package/esm/sql-database-dirty-tracker.d.mts.map +1 -0
- package/esm/sql-database-dirty-tracker.mjs +20 -0
- package/esm/sql-database-dirty-tracker.mjs.map +1 -0
- package/esm/sync/model-events.mjs +46 -0
- package/esm/sync/model-events.mjs.map +1 -0
- package/esm/sync/model-sync-operation.d.mts +159 -0
- package/esm/sync/model-sync-operation.d.mts.map +1 -0
- package/esm/sync/model-sync-operation.mjs +257 -0
- package/esm/sync/model-sync-operation.mjs.map +1 -0
- package/esm/sync/model-sync.d.mts +126 -0
- package/esm/sync/model-sync.d.mts.map +1 -0
- package/esm/sync/model-sync.mjs +157 -0
- package/esm/sync/model-sync.mjs.map +1 -0
- package/esm/sync/sync-context.d.mts +69 -0
- package/esm/sync/sync-context.d.mts.map +1 -0
- package/esm/sync/sync-context.mjs +95 -0
- package/esm/sync/sync-context.mjs.map +1 -0
- package/esm/sync/sync-manager.d.mts +213 -0
- package/esm/sync/sync-manager.d.mts.map +1 -0
- package/esm/sync/sync-manager.mjs +597 -0
- package/esm/sync/sync-manager.mjs.map +1 -0
- package/esm/sync/types.d.mts +215 -0
- package/esm/sync/types.d.mts.map +1 -0
- package/esm/types.d.mts +423 -0
- package/esm/types.d.mts.map +1 -0
- package/esm/utils/connect-to-database.d.mts +328 -0
- package/esm/utils/connect-to-database.d.mts.map +1 -0
- package/esm/utils/connect-to-database.mjs +130 -0
- package/esm/utils/connect-to-database.mjs.map +1 -0
- package/esm/utils/database-writer.utils.d.mts +18 -0
- package/esm/utils/database-writer.utils.d.mts.map +1 -0
- package/esm/utils/database-writer.utils.mjs +25 -0
- package/esm/utils/database-writer.utils.mjs.map +1 -0
- package/esm/utils/define-model.d.mts +185 -0
- package/esm/utils/define-model.d.mts.map +1 -0
- package/esm/utils/define-model.mjs +105 -0
- package/esm/utils/define-model.mjs.map +1 -0
- package/esm/utils/is-valid-date-value.mjs +22 -0
- package/esm/utils/is-valid-date-value.mjs.map +1 -0
- package/esm/utils/once-connected.d.mts +150 -0
- package/esm/utils/once-connected.d.mts.map +1 -0
- package/esm/utils/once-connected.mjs +203 -0
- package/esm/utils/once-connected.mjs.map +1 -0
- package/esm/validation/database-seal-plugins.d.mts +1 -0
- package/esm/validation/database-seal-plugins.mjs +11 -0
- package/esm/validation/database-seal-plugins.mjs.map +1 -0
- package/esm/validation/database-writer-validation-error.d.mts +101 -0
- package/esm/validation/database-writer-validation-error.d.mts.map +1 -0
- package/esm/validation/database-writer-validation-error.mjs +153 -0
- package/esm/validation/database-writer-validation-error.mjs.map +1 -0
- package/esm/validation/index.d.mts +2 -0
- package/esm/validation/index.mjs +4 -0
- package/esm/validation/mutators/embed-mutator.mjs +26 -0
- package/esm/validation/mutators/embed-mutator.mjs.map +1 -0
- package/esm/validation/plugins/database-rules-plugin.d.mts +28 -0
- package/esm/validation/plugins/database-rules-plugin.d.mts.map +1 -0
- package/esm/validation/plugins/database-rules-plugin.mjs +43 -0
- package/esm/validation/plugins/database-rules-plugin.mjs.map +1 -0
- package/esm/validation/plugins/embed-validator-plugin.d.mts +17 -0
- package/esm/validation/plugins/embed-validator-plugin.d.mts.map +1 -0
- package/esm/validation/plugins/embed-validator-plugin.mjs +20 -0
- package/esm/validation/plugins/embed-validator-plugin.mjs.map +1 -0
- package/esm/validation/rules/database-model-rule.mjs +32 -0
- package/esm/validation/rules/database-model-rule.mjs.map +1 -0
- package/esm/validation/rules/exists-rule.mjs +29 -0
- package/esm/validation/rules/exists-rule.mjs.map +1 -0
- package/esm/validation/rules/unique-rule.mjs +43 -0
- package/esm/validation/rules/unique-rule.mjs.map +1 -0
- package/esm/validation/transformers/embed-model-transformer.mjs +17 -0
- package/esm/validation/transformers/embed-model-transformer.mjs.map +1 -0
- package/esm/validation/types.d.mts +43 -0
- package/esm/validation/types.d.mts.map +1 -0
- package/esm/validation/validators/embed-validator.d.mts +25 -0
- package/esm/validation/validators/embed-validator.d.mts.map +1 -0
- package/esm/validation/validators/embed-validator.mjs +42 -0
- package/esm/validation/validators/embed-validator.mjs.map +1 -0
- package/esm/writer/database-writer.d.mts +178 -0
- package/esm/writer/database-writer.d.mts.map +1 -0
- package/esm/writer/database-writer.mjs +317 -0
- package/esm/writer/database-writer.mjs.map +1 -0
- package/llms-full.txt +2027 -0
- package/llms.txt +23 -0
- package/package.json +60 -51
- package/skills/README.md +65 -0
- package/skills/aggregate-data/SKILL.md +102 -0
- package/skills/cascade-basics/SKILL.md +93 -0
- package/skills/configure-delete-strategy/SKILL.md +126 -0
- package/skills/define-model/SKILL.md +170 -0
- package/skills/define-relations/SKILL.md +171 -0
- package/skills/manage-data-sources/SKILL.md +140 -0
- package/skills/manage-transactions/SKILL.md +118 -0
- package/skills/paginate-results/SKILL.md +122 -0
- package/skills/perform-atomic-ops/SKILL.md +98 -0
- package/skills/query-data/SKILL.md +168 -0
- package/skills/run-cascade-cli/SKILL.md +125 -0
- package/skills/search-by-vector/SKILL.md +127 -0
- package/skills/subscribe-to-model-events/SKILL.md +148 -0
- package/skills/track-changes/SKILL.md +109 -0
- package/skills/write-migration/SKILL.md +144 -0
- package/cjs/context/database-data-source-context.d.ts +0 -29
- package/cjs/context/database-data-source-context.d.ts.map +0 -1
- package/cjs/context/database-data-source-context.js +0 -28
- package/cjs/context/database-data-source-context.js.map +0 -1
- package/cjs/context/database-transaction-context.d.ts +0 -35
- package/cjs/context/database-transaction-context.d.ts.map +0 -1
- package/cjs/context/database-transaction-context.js +0 -40
- package/cjs/context/database-transaction-context.js.map +0 -1
- package/cjs/contracts/database-driver.contract.d.ts +0 -450
- package/cjs/contracts/database-driver.contract.d.ts.map +0 -1
- package/cjs/contracts/database-id-generator.contract.d.ts +0 -109
- package/cjs/contracts/database-id-generator.contract.d.ts.map +0 -1
- package/cjs/contracts/database-remover.contract.d.ts +0 -104
- package/cjs/contracts/database-remover.contract.d.ts.map +0 -1
- package/cjs/contracts/database-restorer.contract.d.ts +0 -143
- package/cjs/contracts/database-restorer.contract.d.ts.map +0 -1
- package/cjs/contracts/database-writer.contract.d.ts +0 -119
- package/cjs/contracts/database-writer.contract.d.ts.map +0 -1
- package/cjs/contracts/driver-blueprint.contract.d.ts +0 -49
- package/cjs/contracts/driver-blueprint.contract.d.ts.map +0 -1
- package/cjs/contracts/index.d.ts +0 -10
- package/cjs/contracts/index.d.ts.map +0 -1
- package/cjs/contracts/migration-driver.contract.d.ts +0 -522
- package/cjs/contracts/migration-driver.contract.d.ts.map +0 -1
- package/cjs/contracts/query-builder.contract.d.ts +0 -1609
- package/cjs/contracts/query-builder.contract.d.ts.map +0 -1
- package/cjs/contracts/sync-adapter.contract.d.ts +0 -58
- package/cjs/contracts/sync-adapter.contract.d.ts.map +0 -1
- package/cjs/data-source/data-source-registry.d.ts +0 -108
- package/cjs/data-source/data-source-registry.d.ts.map +0 -1
- package/cjs/data-source/data-source-registry.js +0 -145
- package/cjs/data-source/data-source-registry.js.map +0 -1
- package/cjs/data-source/data-source.d.ts +0 -147
- package/cjs/data-source/data-source.d.ts.map +0 -1
- package/cjs/data-source/data-source.js +0 -83
- package/cjs/data-source/data-source.js.map +0 -1
- package/cjs/database-dirty-tracker.d.ts +0 -252
- package/cjs/database-dirty-tracker.d.ts.map +0 -1
- package/cjs/database-dirty-tracker.js +0 -386
- package/cjs/database-dirty-tracker.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-blueprint.d.ts +0 -30
- package/cjs/drivers/mongodb/mongodb-blueprint.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-blueprint.js +0 -51
- package/cjs/drivers/mongodb/mongodb-blueprint.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-driver.d.ts +0 -325
- package/cjs/drivers/mongodb/mongodb-driver.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-driver.js +0 -845
- package/cjs/drivers/mongodb/mongodb-driver.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-id-generator.d.ts +0 -116
- package/cjs/drivers/mongodb/mongodb-id-generator.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-id-generator.js +0 -149
- package/cjs/drivers/mongodb/mongodb-id-generator.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-migration-driver.d.ts +0 -317
- package/cjs/drivers/mongodb/mongodb-migration-driver.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-migration-driver.js +0 -666
- package/cjs/drivers/mongodb/mongodb-migration-driver.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-builder.d.ts +0 -1122
- package/cjs/drivers/mongodb/mongodb-query-builder.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-builder.js +0 -1988
- package/cjs/drivers/mongodb/mongodb-query-builder.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-operations.d.ts +0 -226
- package/cjs/drivers/mongodb/mongodb-query-operations.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-operations.js +0 -270
- package/cjs/drivers/mongodb/mongodb-query-operations.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-parser.d.ts +0 -262
- package/cjs/drivers/mongodb/mongodb-query-parser.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-query-parser.js +0 -1351
- package/cjs/drivers/mongodb/mongodb-query-parser.js.map +0 -1
- package/cjs/drivers/mongodb/mongodb-sync-adapter.d.ts +0 -79
- package/cjs/drivers/mongodb/mongodb-sync-adapter.d.ts.map +0 -1
- package/cjs/drivers/mongodb/mongodb-sync-adapter.js +0 -146
- package/cjs/drivers/mongodb/mongodb-sync-adapter.js.map +0 -1
- package/cjs/drivers/mongodb/types.d.ts +0 -43
- package/cjs/drivers/mongodb/types.d.ts.map +0 -1
- package/cjs/drivers/postgres/index.d.ts +0 -16
- package/cjs/drivers/postgres/index.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-blueprint.d.ts +0 -64
- package/cjs/drivers/postgres/postgres-blueprint.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-blueprint.js +0 -121
- package/cjs/drivers/postgres/postgres-blueprint.js.map +0 -1
- package/cjs/drivers/postgres/postgres-dialect.d.ts +0 -136
- package/cjs/drivers/postgres/postgres-dialect.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-dialect.js +0 -268
- package/cjs/drivers/postgres/postgres-dialect.js.map +0 -1
- package/cjs/drivers/postgres/postgres-driver.d.ts +0 -432
- package/cjs/drivers/postgres/postgres-driver.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-driver.js +0 -1008
- package/cjs/drivers/postgres/postgres-driver.js.map +0 -1
- package/cjs/drivers/postgres/postgres-migration-driver.d.ts +0 -397
- package/cjs/drivers/postgres/postgres-migration-driver.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-migration-driver.js +0 -900
- package/cjs/drivers/postgres/postgres-migration-driver.js.map +0 -1
- package/cjs/drivers/postgres/postgres-query-builder.d.ts +0 -254
- package/cjs/drivers/postgres/postgres-query-builder.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-query-builder.js +0 -933
- package/cjs/drivers/postgres/postgres-query-builder.js.map +0 -1
- package/cjs/drivers/postgres/postgres-query-parser.d.ts +0 -328
- package/cjs/drivers/postgres/postgres-query-parser.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-query-parser.js +0 -868
- package/cjs/drivers/postgres/postgres-query-parser.js.map +0 -1
- package/cjs/drivers/postgres/postgres-sql-serializer.d.ts +0 -37
- package/cjs/drivers/postgres/postgres-sql-serializer.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-sql-serializer.js +0 -400
- package/cjs/drivers/postgres/postgres-sql-serializer.js.map +0 -1
- package/cjs/drivers/postgres/postgres-sync-adapter.d.ts +0 -83
- package/cjs/drivers/postgres/postgres-sync-adapter.d.ts.map +0 -1
- package/cjs/drivers/postgres/postgres-sync-adapter.js +0 -204
- package/cjs/drivers/postgres/postgres-sync-adapter.js.map +0 -1
- package/cjs/drivers/postgres/types.d.ts +0 -144
- package/cjs/drivers/postgres/types.d.ts.map +0 -1
- package/cjs/drivers/sql/index.d.ts +0 -10
- package/cjs/drivers/sql/index.d.ts.map +0 -1
- package/cjs/drivers/sql/sql-dialect.contract.d.ts +0 -204
- package/cjs/drivers/sql/sql-dialect.contract.d.ts.map +0 -1
- package/cjs/drivers/sql/sql-types.d.ts +0 -202
- package/cjs/drivers/sql/sql-types.d.ts.map +0 -1
- package/cjs/errors/missing-data-source.error.d.ts +0 -22
- package/cjs/errors/missing-data-source.error.d.ts.map +0 -1
- package/cjs/errors/missing-data-source.error.js +0 -29
- package/cjs/errors/missing-data-source.error.js.map +0 -1
- package/cjs/errors/transaction-rollback.error.d.ts +0 -20
- package/cjs/errors/transaction-rollback.error.d.ts.map +0 -1
- package/cjs/errors/transaction-rollback.error.js +0 -27
- package/cjs/errors/transaction-rollback.error.js.map +0 -1
- package/cjs/events/model-events.d.ts +0 -231
- package/cjs/events/model-events.d.ts.map +0 -1
- package/cjs/events/model-events.js +0 -259
- package/cjs/events/model-events.js.map +0 -1
- package/cjs/expressions/aggregate-expressions.d.ts +0 -215
- package/cjs/expressions/aggregate-expressions.d.ts.map +0 -1
- package/cjs/expressions/aggregate-expressions.js +0 -221
- package/cjs/expressions/aggregate-expressions.js.map +0 -1
- package/cjs/expressions/index.d.ts +0 -2
- package/cjs/expressions/index.d.ts.map +0 -1
- package/cjs/index.d.ts +0 -45
- package/cjs/index.d.ts.map +0 -1
- package/cjs/index.js +0 -1
- package/cjs/index.js.map +0 -1
- package/cjs/migration/column-builder.d.ts +0 -417
- package/cjs/migration/column-builder.d.ts.map +0 -1
- package/cjs/migration/column-builder.js +0 -586
- package/cjs/migration/column-builder.js.map +0 -1
- package/cjs/migration/column-helpers.d.ts +0 -275
- package/cjs/migration/column-helpers.d.ts.map +0 -1
- package/cjs/migration/column-helpers.js +0 -389
- package/cjs/migration/column-helpers.js.map +0 -1
- package/cjs/migration/foreign-key-builder.d.ts +0 -103
- package/cjs/migration/foreign-key-builder.d.ts.map +0 -1
- package/cjs/migration/foreign-key-builder.js +0 -121
- package/cjs/migration/foreign-key-builder.js.map +0 -1
- package/cjs/migration/index.d.ts +0 -7
- package/cjs/migration/index.d.ts.map +0 -1
- package/cjs/migration/migration-runner.d.ts +0 -278
- package/cjs/migration/migration-runner.d.ts.map +0 -1
- package/cjs/migration/migration-runner.js +0 -815
- package/cjs/migration/migration-runner.js.map +0 -1
- package/cjs/migration/migration.d.ts +0 -1988
- package/cjs/migration/migration.d.ts.map +0 -1
- package/cjs/migration/migration.js +0 -2162
- package/cjs/migration/migration.js.map +0 -1
- package/cjs/migration/sql-grammar.d.ts +0 -61
- package/cjs/migration/sql-grammar.d.ts.map +0 -1
- package/cjs/migration/sql-grammar.js +0 -164
- package/cjs/migration/sql-grammar.js.map +0 -1
- package/cjs/migration/sql-serializer.d.ts +0 -22
- package/cjs/migration/sql-serializer.d.ts.map +0 -1
- package/cjs/migration/sql-serializer.js +0 -26
- package/cjs/migration/sql-serializer.js.map +0 -1
- package/cjs/migration/types.d.ts +0 -155
- package/cjs/migration/types.d.ts.map +0 -1
- package/cjs/model/methods/accessor-methods.d.ts +0 -13
- package/cjs/model/methods/accessor-methods.d.ts.map +0 -1
- package/cjs/model/methods/accessor-methods.js +0 -51
- package/cjs/model/methods/accessor-methods.js.map +0 -1
- package/cjs/model/methods/delete-methods.d.ts +0 -10
- package/cjs/model/methods/delete-methods.d.ts.map +0 -1
- package/cjs/model/methods/delete-methods.js +0 -10
- package/cjs/model/methods/delete-methods.js.map +0 -1
- package/cjs/model/methods/dirty-methods.d.ts +0 -10
- package/cjs/model/methods/dirty-methods.d.ts.map +0 -1
- package/cjs/model/methods/dirty-methods.js +0 -15
- package/cjs/model/methods/dirty-methods.js.map +0 -1
- package/cjs/model/methods/hydration-methods.d.ts +0 -10
- package/cjs/model/methods/hydration-methods.d.ts.map +0 -1
- package/cjs/model/methods/hydration-methods.js +0 -57
- package/cjs/model/methods/hydration-methods.js.map +0 -1
- package/cjs/model/methods/instance-event-methods.d.ts +0 -7
- package/cjs/model/methods/instance-event-methods.d.ts.map +0 -1
- package/cjs/model/methods/instance-event-methods.js +0 -15
- package/cjs/model/methods/instance-event-methods.js.map +0 -1
- package/cjs/model/methods/meta-methods.d.ts +0 -7
- package/cjs/model/methods/meta-methods.d.ts.map +0 -1
- package/cjs/model/methods/meta-methods.js +0 -78
- package/cjs/model/methods/meta-methods.js.map +0 -1
- package/cjs/model/methods/query-methods.d.ts +0 -24
- package/cjs/model/methods/query-methods.d.ts.map +0 -1
- package/cjs/model/methods/query-methods.js +0 -164
- package/cjs/model/methods/query-methods.js.map +0 -1
- package/cjs/model/methods/restore-methods.d.ts +0 -10
- package/cjs/model/methods/restore-methods.d.ts.map +0 -1
- package/cjs/model/methods/restore-methods.js +0 -13
- package/cjs/model/methods/restore-methods.js.map +0 -1
- package/cjs/model/methods/scope-methods.d.ts +0 -7
- package/cjs/model/methods/scope-methods.d.ts.map +0 -1
- package/cjs/model/methods/scope-methods.js +0 -15
- package/cjs/model/methods/scope-methods.js.map +0 -1
- package/cjs/model/methods/serialization-methods.d.ts +0 -3
- package/cjs/model/methods/serialization-methods.d.ts.map +0 -1
- package/cjs/model/methods/serialization-methods.js +0 -27
- package/cjs/model/methods/serialization-methods.js.map +0 -1
- package/cjs/model/methods/static-event-methods.d.ts +0 -9
- package/cjs/model/methods/static-event-methods.d.ts.map +0 -1
- package/cjs/model/methods/static-event-methods.js +0 -29
- package/cjs/model/methods/static-event-methods.js.map +0 -1
- package/cjs/model/methods/write-methods.d.ts +0 -10
- package/cjs/model/methods/write-methods.d.ts.map +0 -1
- package/cjs/model/methods/write-methods.js +0 -52
- package/cjs/model/methods/write-methods.js.map +0 -1
- package/cjs/model/model.d.ts +0 -1647
- package/cjs/model/model.d.ts.map +0 -1
- package/cjs/model/model.js +0 -1657
- package/cjs/model/model.js.map +0 -1
- package/cjs/model/model.types.d.ts +0 -44
- package/cjs/model/model.types.d.ts.map +0 -1
- package/cjs/model/register-model.d.ts +0 -81
- package/cjs/model/register-model.d.ts.map +0 -1
- package/cjs/model/register-model.js +0 -94
- package/cjs/model/register-model.js.map +0 -1
- package/cjs/query-builder/query-builder.d.ts +0 -556
- package/cjs/query-builder/query-builder.d.ts.map +0 -1
- package/cjs/query-builder/query-builder.js +0 -1070
- package/cjs/query-builder/query-builder.js.map +0 -1
- package/cjs/relations/helpers.d.ts +0 -156
- package/cjs/relations/helpers.d.ts.map +0 -1
- package/cjs/relations/helpers.js +0 -202
- package/cjs/relations/helpers.js.map +0 -1
- package/cjs/relations/index.d.ts +0 -35
- package/cjs/relations/index.d.ts.map +0 -1
- package/cjs/relations/pivot-operations.d.ts +0 -160
- package/cjs/relations/pivot-operations.d.ts.map +0 -1
- package/cjs/relations/pivot-operations.js +0 -293
- package/cjs/relations/pivot-operations.js.map +0 -1
- package/cjs/relations/relation-hydrator.d.ts +0 -68
- package/cjs/relations/relation-hydrator.d.ts.map +0 -1
- package/cjs/relations/relation-hydrator.js +0 -81
- package/cjs/relations/relation-hydrator.js.map +0 -1
- package/cjs/relations/relation-loader.d.ts +0 -194
- package/cjs/relations/relation-loader.d.ts.map +0 -1
- package/cjs/relations/relation-loader.js +0 -466
- package/cjs/relations/relation-loader.js.map +0 -1
- package/cjs/relations/types.d.ts +0 -306
- package/cjs/relations/types.d.ts.map +0 -1
- package/cjs/remover/database-remover.d.ts +0 -100
- package/cjs/remover/database-remover.d.ts.map +0 -1
- package/cjs/remover/database-remover.js +0 -214
- package/cjs/remover/database-remover.js.map +0 -1
- package/cjs/restorer/database-restorer.d.ts +0 -131
- package/cjs/restorer/database-restorer.d.ts.map +0 -1
- package/cjs/restorer/database-restorer.js +0 -434
- package/cjs/restorer/database-restorer.js.map +0 -1
- package/cjs/sql-database-dirty-tracker.d.ts +0 -13
- package/cjs/sql-database-dirty-tracker.d.ts.map +0 -1
- package/cjs/sql-database-dirty-tracker.js +0 -14
- package/cjs/sql-database-dirty-tracker.js.map +0 -1
- package/cjs/sync/index.d.ts +0 -12
- package/cjs/sync/index.d.ts.map +0 -1
- package/cjs/sync/model-events.d.ts +0 -62
- package/cjs/sync/model-events.d.ts.map +0 -1
- package/cjs/sync/model-events.js +0 -49
- package/cjs/sync/model-events.js.map +0 -1
- package/cjs/sync/model-sync-operation.d.ts +0 -163
- package/cjs/sync/model-sync-operation.d.ts.map +0 -1
- package/cjs/sync/model-sync-operation.js +0 -292
- package/cjs/sync/model-sync-operation.js.map +0 -1
- package/cjs/sync/model-sync.d.ts +0 -130
- package/cjs/sync/model-sync.d.ts.map +0 -1
- package/cjs/sync/model-sync.js +0 -178
- package/cjs/sync/model-sync.js.map +0 -1
- package/cjs/sync/sync-context.d.ts +0 -70
- package/cjs/sync/sync-context.d.ts.map +0 -1
- package/cjs/sync/sync-context.js +0 -101
- package/cjs/sync/sync-context.js.map +0 -1
- package/cjs/sync/sync-manager.d.ts +0 -213
- package/cjs/sync/sync-manager.d.ts.map +0 -1
- package/cjs/sync/sync-manager.js +0 -689
- package/cjs/sync/sync-manager.js.map +0 -1
- package/cjs/sync/types.d.ts +0 -289
- package/cjs/sync/types.d.ts.map +0 -1
- package/cjs/test-migrations/test-enhanced-features.migration.d.ts +0 -15
- package/cjs/test-migrations/test-enhanced-features.migration.d.ts.map +0 -1
- package/cjs/types.d.ts +0 -371
- package/cjs/types.d.ts.map +0 -1
- package/cjs/utils/connect-to-database.d.ts +0 -307
- package/cjs/utils/connect-to-database.d.ts.map +0 -1
- package/cjs/utils/connect-to-database.js +0 -130
- package/cjs/utils/connect-to-database.js.map +0 -1
- package/cjs/utils/database-writer.utils.d.ts +0 -15
- package/cjs/utils/database-writer.utils.d.ts.map +0 -1
- package/cjs/utils/database-writer.utils.js +0 -14
- package/cjs/utils/database-writer.utils.js.map +0 -1
- package/cjs/utils/define-model.js +0 -100
- package/cjs/utils/define-model.js.map +0 -1
- package/cjs/utils/is-valid-date-value.d.ts +0 -5
- package/cjs/utils/is-valid-date-value.d.ts.map +0 -1
- package/cjs/utils/is-valid-date-value.js +0 -25
- package/cjs/utils/is-valid-date-value.js.map +0 -1
- package/cjs/utils/once-connected.d.ts +0 -146
- package/cjs/utils/once-connected.d.ts.map +0 -1
- package/cjs/utils/once-connected.js +0 -251
- package/cjs/utils/once-connected.js.map +0 -1
- package/cjs/validation/database-seal-plugins.d.ts +0 -12
- package/cjs/validation/database-seal-plugins.d.ts.map +0 -1
- package/cjs/validation/database-seal-plugins.js +0 -1
- package/cjs/validation/database-seal-plugins.js.map +0 -1
- package/cjs/validation/database-writer-validation-error.d.ts +0 -97
- package/cjs/validation/database-writer-validation-error.d.ts.map +0 -1
- package/cjs/validation/database-writer-validation-error.js +0 -160
- package/cjs/validation/database-writer-validation-error.js.map +0 -1
- package/cjs/validation/index.d.ts +0 -3
- package/cjs/validation/index.d.ts.map +0 -1
- package/cjs/validation/mutators/embed-mutator.d.ts +0 -9
- package/cjs/validation/mutators/embed-mutator.d.ts.map +0 -1
- package/cjs/validation/mutators/embed-mutator.js +0 -33
- package/cjs/validation/mutators/embed-mutator.js.map +0 -1
- package/cjs/validation/plugins/embed-validator-plugin.d.ts +0 -24
- package/cjs/validation/plugins/embed-validator-plugin.d.ts.map +0 -1
- package/cjs/validation/plugins/embed-validator-plugin.js +0 -18
- package/cjs/validation/plugins/embed-validator-plugin.js.map +0 -1
- package/cjs/validation/rules/database-model-rule.d.ts +0 -7
- package/cjs/validation/rules/database-model-rule.d.ts.map +0 -1
- package/cjs/validation/rules/database-model-rule.js +0 -27
- package/cjs/validation/rules/database-model-rule.js.map +0 -1
- package/cjs/validation/transformers/embed-model-transformer.d.ts +0 -3
- package/cjs/validation/transformers/embed-model-transformer.d.ts.map +0 -1
- package/cjs/validation/transformers/embed-model-transformer.js +0 -18
- package/cjs/validation/transformers/embed-model-transformer.js.map +0 -1
- package/cjs/validation/validators/embed-validator.d.ts +0 -21
- package/cjs/validation/validators/embed-validator.d.ts.map +0 -1
- package/cjs/validation/validators/embed-validator.js +0 -43
- package/cjs/validation/validators/embed-validator.js.map +0 -1
- package/cjs/writer/database-writer.d.ts +0 -174
- package/cjs/writer/database-writer.d.ts.map +0 -1
- package/cjs/writer/database-writer.js +0 -400
- package/cjs/writer/database-writer.js.map +0 -1
- package/esm/context/database-data-source-context.d.ts +0 -29
- package/esm/context/database-data-source-context.d.ts.map +0 -1
- package/esm/context/database-data-source-context.js +0 -28
- package/esm/context/database-data-source-context.js.map +0 -1
- package/esm/context/database-transaction-context.d.ts +0 -35
- package/esm/context/database-transaction-context.d.ts.map +0 -1
- package/esm/context/database-transaction-context.js +0 -40
- package/esm/context/database-transaction-context.js.map +0 -1
- package/esm/contracts/database-driver.contract.d.ts +0 -450
- package/esm/contracts/database-driver.contract.d.ts.map +0 -1
- package/esm/contracts/database-id-generator.contract.d.ts +0 -109
- package/esm/contracts/database-id-generator.contract.d.ts.map +0 -1
- package/esm/contracts/database-remover.contract.d.ts +0 -104
- package/esm/contracts/database-remover.contract.d.ts.map +0 -1
- package/esm/contracts/database-restorer.contract.d.ts +0 -143
- package/esm/contracts/database-restorer.contract.d.ts.map +0 -1
- package/esm/contracts/database-writer.contract.d.ts +0 -119
- package/esm/contracts/database-writer.contract.d.ts.map +0 -1
- package/esm/contracts/driver-blueprint.contract.d.ts +0 -49
- package/esm/contracts/driver-blueprint.contract.d.ts.map +0 -1
- package/esm/contracts/index.d.ts +0 -10
- package/esm/contracts/index.d.ts.map +0 -1
- package/esm/contracts/migration-driver.contract.d.ts +0 -522
- package/esm/contracts/migration-driver.contract.d.ts.map +0 -1
- package/esm/contracts/query-builder.contract.d.ts +0 -1609
- package/esm/contracts/query-builder.contract.d.ts.map +0 -1
- package/esm/contracts/sync-adapter.contract.d.ts +0 -58
- package/esm/contracts/sync-adapter.contract.d.ts.map +0 -1
- package/esm/data-source/data-source-registry.d.ts +0 -108
- package/esm/data-source/data-source-registry.d.ts.map +0 -1
- package/esm/data-source/data-source-registry.js +0 -145
- package/esm/data-source/data-source-registry.js.map +0 -1
- package/esm/data-source/data-source.d.ts +0 -147
- package/esm/data-source/data-source.d.ts.map +0 -1
- package/esm/data-source/data-source.js +0 -83
- package/esm/data-source/data-source.js.map +0 -1
- package/esm/database-dirty-tracker.d.ts +0 -252
- package/esm/database-dirty-tracker.d.ts.map +0 -1
- package/esm/database-dirty-tracker.js +0 -386
- package/esm/database-dirty-tracker.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-blueprint.d.ts +0 -30
- package/esm/drivers/mongodb/mongodb-blueprint.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-blueprint.js +0 -51
- package/esm/drivers/mongodb/mongodb-blueprint.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-driver.d.ts +0 -325
- package/esm/drivers/mongodb/mongodb-driver.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-driver.js +0 -845
- package/esm/drivers/mongodb/mongodb-driver.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-id-generator.d.ts +0 -116
- package/esm/drivers/mongodb/mongodb-id-generator.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-id-generator.js +0 -149
- package/esm/drivers/mongodb/mongodb-id-generator.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-migration-driver.d.ts +0 -317
- package/esm/drivers/mongodb/mongodb-migration-driver.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-migration-driver.js +0 -666
- package/esm/drivers/mongodb/mongodb-migration-driver.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-builder.d.ts +0 -1122
- package/esm/drivers/mongodb/mongodb-query-builder.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-builder.js +0 -1988
- package/esm/drivers/mongodb/mongodb-query-builder.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-operations.d.ts +0 -226
- package/esm/drivers/mongodb/mongodb-query-operations.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-operations.js +0 -270
- package/esm/drivers/mongodb/mongodb-query-operations.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-parser.d.ts +0 -262
- package/esm/drivers/mongodb/mongodb-query-parser.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-query-parser.js +0 -1351
- package/esm/drivers/mongodb/mongodb-query-parser.js.map +0 -1
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.ts +0 -79
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.ts.map +0 -1
- package/esm/drivers/mongodb/mongodb-sync-adapter.js +0 -146
- package/esm/drivers/mongodb/mongodb-sync-adapter.js.map +0 -1
- package/esm/drivers/mongodb/types.d.ts +0 -43
- package/esm/drivers/mongodb/types.d.ts.map +0 -1
- package/esm/drivers/postgres/index.d.ts +0 -16
- package/esm/drivers/postgres/index.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-blueprint.d.ts +0 -64
- package/esm/drivers/postgres/postgres-blueprint.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-blueprint.js +0 -121
- package/esm/drivers/postgres/postgres-blueprint.js.map +0 -1
- package/esm/drivers/postgres/postgres-dialect.d.ts +0 -136
- package/esm/drivers/postgres/postgres-dialect.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-dialect.js +0 -268
- package/esm/drivers/postgres/postgres-dialect.js.map +0 -1
- package/esm/drivers/postgres/postgres-driver.d.ts +0 -432
- package/esm/drivers/postgres/postgres-driver.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-driver.js +0 -1008
- package/esm/drivers/postgres/postgres-driver.js.map +0 -1
- package/esm/drivers/postgres/postgres-migration-driver.d.ts +0 -397
- package/esm/drivers/postgres/postgres-migration-driver.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-migration-driver.js +0 -900
- package/esm/drivers/postgres/postgres-migration-driver.js.map +0 -1
- package/esm/drivers/postgres/postgres-query-builder.d.ts +0 -254
- package/esm/drivers/postgres/postgres-query-builder.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-query-builder.js +0 -933
- package/esm/drivers/postgres/postgres-query-builder.js.map +0 -1
- package/esm/drivers/postgres/postgres-query-parser.d.ts +0 -328
- package/esm/drivers/postgres/postgres-query-parser.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-query-parser.js +0 -868
- package/esm/drivers/postgres/postgres-query-parser.js.map +0 -1
- package/esm/drivers/postgres/postgres-sql-serializer.d.ts +0 -37
- package/esm/drivers/postgres/postgres-sql-serializer.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-sql-serializer.js +0 -400
- package/esm/drivers/postgres/postgres-sql-serializer.js.map +0 -1
- package/esm/drivers/postgres/postgres-sync-adapter.d.ts +0 -83
- package/esm/drivers/postgres/postgres-sync-adapter.d.ts.map +0 -1
- package/esm/drivers/postgres/postgres-sync-adapter.js +0 -204
- package/esm/drivers/postgres/postgres-sync-adapter.js.map +0 -1
- package/esm/drivers/postgres/types.d.ts +0 -144
- package/esm/drivers/postgres/types.d.ts.map +0 -1
- package/esm/drivers/sql/index.d.ts +0 -10
- package/esm/drivers/sql/index.d.ts.map +0 -1
- package/esm/drivers/sql/sql-dialect.contract.d.ts +0 -204
- package/esm/drivers/sql/sql-dialect.contract.d.ts.map +0 -1
- package/esm/drivers/sql/sql-types.d.ts +0 -202
- package/esm/drivers/sql/sql-types.d.ts.map +0 -1
- package/esm/errors/missing-data-source.error.d.ts +0 -22
- package/esm/errors/missing-data-source.error.d.ts.map +0 -1
- package/esm/errors/missing-data-source.error.js +0 -29
- package/esm/errors/missing-data-source.error.js.map +0 -1
- package/esm/errors/transaction-rollback.error.d.ts +0 -20
- package/esm/errors/transaction-rollback.error.d.ts.map +0 -1
- package/esm/errors/transaction-rollback.error.js +0 -27
- package/esm/errors/transaction-rollback.error.js.map +0 -1
- package/esm/events/model-events.d.ts +0 -231
- package/esm/events/model-events.d.ts.map +0 -1
- package/esm/events/model-events.js +0 -259
- package/esm/events/model-events.js.map +0 -1
- package/esm/expressions/aggregate-expressions.d.ts +0 -215
- package/esm/expressions/aggregate-expressions.d.ts.map +0 -1
- package/esm/expressions/aggregate-expressions.js +0 -221
- package/esm/expressions/aggregate-expressions.js.map +0 -1
- package/esm/expressions/index.d.ts +0 -2
- package/esm/expressions/index.d.ts.map +0 -1
- package/esm/index.d.ts +0 -45
- package/esm/index.d.ts.map +0 -1
- package/esm/index.js +0 -1
- package/esm/index.js.map +0 -1
- package/esm/migration/column-builder.d.ts +0 -417
- package/esm/migration/column-builder.d.ts.map +0 -1
- package/esm/migration/column-builder.js +0 -586
- package/esm/migration/column-builder.js.map +0 -1
- package/esm/migration/column-helpers.d.ts +0 -275
- package/esm/migration/column-helpers.d.ts.map +0 -1
- package/esm/migration/column-helpers.js +0 -389
- package/esm/migration/column-helpers.js.map +0 -1
- package/esm/migration/foreign-key-builder.d.ts +0 -103
- package/esm/migration/foreign-key-builder.d.ts.map +0 -1
- package/esm/migration/foreign-key-builder.js +0 -121
- package/esm/migration/foreign-key-builder.js.map +0 -1
- package/esm/migration/index.d.ts +0 -7
- package/esm/migration/index.d.ts.map +0 -1
- package/esm/migration/migration-runner.d.ts +0 -278
- package/esm/migration/migration-runner.d.ts.map +0 -1
- package/esm/migration/migration-runner.js +0 -815
- package/esm/migration/migration-runner.js.map +0 -1
- package/esm/migration/migration.d.ts +0 -1988
- package/esm/migration/migration.d.ts.map +0 -1
- package/esm/migration/migration.js +0 -2162
- package/esm/migration/migration.js.map +0 -1
- package/esm/migration/sql-grammar.d.ts +0 -61
- package/esm/migration/sql-grammar.d.ts.map +0 -1
- package/esm/migration/sql-grammar.js +0 -164
- package/esm/migration/sql-grammar.js.map +0 -1
- package/esm/migration/sql-serializer.d.ts +0 -22
- package/esm/migration/sql-serializer.d.ts.map +0 -1
- package/esm/migration/sql-serializer.js +0 -26
- package/esm/migration/sql-serializer.js.map +0 -1
- package/esm/migration/types.d.ts +0 -155
- package/esm/migration/types.d.ts.map +0 -1
- package/esm/model/methods/accessor-methods.d.ts +0 -13
- package/esm/model/methods/accessor-methods.d.ts.map +0 -1
- package/esm/model/methods/accessor-methods.js +0 -51
- package/esm/model/methods/accessor-methods.js.map +0 -1
- package/esm/model/methods/delete-methods.d.ts +0 -10
- package/esm/model/methods/delete-methods.d.ts.map +0 -1
- package/esm/model/methods/delete-methods.js +0 -10
- package/esm/model/methods/delete-methods.js.map +0 -1
- package/esm/model/methods/dirty-methods.d.ts +0 -10
- package/esm/model/methods/dirty-methods.d.ts.map +0 -1
- package/esm/model/methods/dirty-methods.js +0 -15
- package/esm/model/methods/dirty-methods.js.map +0 -1
- package/esm/model/methods/hydration-methods.d.ts +0 -10
- package/esm/model/methods/hydration-methods.d.ts.map +0 -1
- package/esm/model/methods/hydration-methods.js +0 -57
- package/esm/model/methods/hydration-methods.js.map +0 -1
- package/esm/model/methods/instance-event-methods.d.ts +0 -7
- package/esm/model/methods/instance-event-methods.d.ts.map +0 -1
- package/esm/model/methods/instance-event-methods.js +0 -15
- package/esm/model/methods/instance-event-methods.js.map +0 -1
- package/esm/model/methods/meta-methods.d.ts +0 -7
- package/esm/model/methods/meta-methods.d.ts.map +0 -1
- package/esm/model/methods/meta-methods.js +0 -78
- package/esm/model/methods/meta-methods.js.map +0 -1
- package/esm/model/methods/query-methods.d.ts +0 -24
- package/esm/model/methods/query-methods.d.ts.map +0 -1
- package/esm/model/methods/query-methods.js +0 -164
- package/esm/model/methods/query-methods.js.map +0 -1
- package/esm/model/methods/restore-methods.d.ts +0 -10
- package/esm/model/methods/restore-methods.d.ts.map +0 -1
- package/esm/model/methods/restore-methods.js +0 -13
- package/esm/model/methods/restore-methods.js.map +0 -1
- package/esm/model/methods/scope-methods.d.ts +0 -7
- package/esm/model/methods/scope-methods.d.ts.map +0 -1
- package/esm/model/methods/scope-methods.js +0 -15
- package/esm/model/methods/scope-methods.js.map +0 -1
- package/esm/model/methods/serialization-methods.d.ts +0 -3
- package/esm/model/methods/serialization-methods.d.ts.map +0 -1
- package/esm/model/methods/serialization-methods.js +0 -27
- package/esm/model/methods/serialization-methods.js.map +0 -1
- package/esm/model/methods/static-event-methods.d.ts +0 -9
- package/esm/model/methods/static-event-methods.d.ts.map +0 -1
- package/esm/model/methods/static-event-methods.js +0 -29
- package/esm/model/methods/static-event-methods.js.map +0 -1
- package/esm/model/methods/write-methods.d.ts +0 -10
- package/esm/model/methods/write-methods.d.ts.map +0 -1
- package/esm/model/methods/write-methods.js +0 -52
- package/esm/model/methods/write-methods.js.map +0 -1
- package/esm/model/model.d.ts +0 -1647
- package/esm/model/model.d.ts.map +0 -1
- package/esm/model/model.js +0 -1657
- package/esm/model/model.js.map +0 -1
- package/esm/model/model.types.d.ts +0 -44
- package/esm/model/model.types.d.ts.map +0 -1
- package/esm/model/register-model.d.ts +0 -81
- package/esm/model/register-model.d.ts.map +0 -1
- package/esm/model/register-model.js +0 -94
- package/esm/model/register-model.js.map +0 -1
- package/esm/query-builder/query-builder.d.ts +0 -556
- package/esm/query-builder/query-builder.d.ts.map +0 -1
- package/esm/query-builder/query-builder.js +0 -1070
- package/esm/query-builder/query-builder.js.map +0 -1
- package/esm/relations/helpers.d.ts +0 -156
- package/esm/relations/helpers.d.ts.map +0 -1
- package/esm/relations/helpers.js +0 -202
- package/esm/relations/helpers.js.map +0 -1
- package/esm/relations/index.d.ts +0 -35
- package/esm/relations/index.d.ts.map +0 -1
- package/esm/relations/pivot-operations.d.ts +0 -160
- package/esm/relations/pivot-operations.d.ts.map +0 -1
- package/esm/relations/pivot-operations.js +0 -293
- package/esm/relations/pivot-operations.js.map +0 -1
- package/esm/relations/relation-hydrator.d.ts +0 -68
- package/esm/relations/relation-hydrator.d.ts.map +0 -1
- package/esm/relations/relation-hydrator.js +0 -81
- package/esm/relations/relation-hydrator.js.map +0 -1
- package/esm/relations/relation-loader.d.ts +0 -194
- package/esm/relations/relation-loader.d.ts.map +0 -1
- package/esm/relations/relation-loader.js +0 -466
- package/esm/relations/relation-loader.js.map +0 -1
- package/esm/relations/types.d.ts +0 -306
- package/esm/relations/types.d.ts.map +0 -1
- package/esm/remover/database-remover.d.ts +0 -100
- package/esm/remover/database-remover.d.ts.map +0 -1
- package/esm/remover/database-remover.js +0 -214
- package/esm/remover/database-remover.js.map +0 -1
- package/esm/restorer/database-restorer.d.ts +0 -131
- package/esm/restorer/database-restorer.d.ts.map +0 -1
- package/esm/restorer/database-restorer.js +0 -434
- package/esm/restorer/database-restorer.js.map +0 -1
- package/esm/sql-database-dirty-tracker.d.ts +0 -13
- package/esm/sql-database-dirty-tracker.d.ts.map +0 -1
- package/esm/sql-database-dirty-tracker.js +0 -14
- package/esm/sql-database-dirty-tracker.js.map +0 -1
- package/esm/sync/index.d.ts +0 -12
- package/esm/sync/index.d.ts.map +0 -1
- package/esm/sync/model-events.d.ts +0 -62
- package/esm/sync/model-events.d.ts.map +0 -1
- package/esm/sync/model-events.js +0 -49
- package/esm/sync/model-events.js.map +0 -1
- package/esm/sync/model-sync-operation.d.ts +0 -163
- package/esm/sync/model-sync-operation.d.ts.map +0 -1
- package/esm/sync/model-sync-operation.js +0 -292
- package/esm/sync/model-sync-operation.js.map +0 -1
- package/esm/sync/model-sync.d.ts +0 -130
- package/esm/sync/model-sync.d.ts.map +0 -1
- package/esm/sync/model-sync.js +0 -178
- package/esm/sync/model-sync.js.map +0 -1
- package/esm/sync/sync-context.d.ts +0 -70
- package/esm/sync/sync-context.d.ts.map +0 -1
- package/esm/sync/sync-context.js +0 -101
- package/esm/sync/sync-context.js.map +0 -1
- package/esm/sync/sync-manager.d.ts +0 -213
- package/esm/sync/sync-manager.d.ts.map +0 -1
- package/esm/sync/sync-manager.js +0 -689
- package/esm/sync/sync-manager.js.map +0 -1
- package/esm/sync/types.d.ts +0 -289
- package/esm/sync/types.d.ts.map +0 -1
- package/esm/test-migrations/test-enhanced-features.migration.d.ts +0 -15
- package/esm/test-migrations/test-enhanced-features.migration.d.ts.map +0 -1
- package/esm/types.d.ts +0 -371
- package/esm/types.d.ts.map +0 -1
- package/esm/utils/connect-to-database.d.ts +0 -307
- package/esm/utils/connect-to-database.d.ts.map +0 -1
- package/esm/utils/connect-to-database.js +0 -130
- package/esm/utils/connect-to-database.js.map +0 -1
- package/esm/utils/database-writer.utils.d.ts +0 -15
- package/esm/utils/database-writer.utils.d.ts.map +0 -1
- package/esm/utils/database-writer.utils.js +0 -14
- package/esm/utils/database-writer.utils.js.map +0 -1
- package/esm/utils/define-model.js +0 -100
- package/esm/utils/define-model.js.map +0 -1
- package/esm/utils/is-valid-date-value.d.ts +0 -5
- package/esm/utils/is-valid-date-value.d.ts.map +0 -1
- package/esm/utils/is-valid-date-value.js +0 -25
- package/esm/utils/is-valid-date-value.js.map +0 -1
- package/esm/utils/once-connected.d.ts +0 -146
- package/esm/utils/once-connected.d.ts.map +0 -1
- package/esm/utils/once-connected.js +0 -251
- package/esm/utils/once-connected.js.map +0 -1
- package/esm/validation/database-seal-plugins.d.ts +0 -12
- package/esm/validation/database-seal-plugins.d.ts.map +0 -1
- package/esm/validation/database-seal-plugins.js +0 -1
- package/esm/validation/database-seal-plugins.js.map +0 -1
- package/esm/validation/database-writer-validation-error.d.ts +0 -97
- package/esm/validation/database-writer-validation-error.d.ts.map +0 -1
- package/esm/validation/database-writer-validation-error.js +0 -160
- package/esm/validation/database-writer-validation-error.js.map +0 -1
- package/esm/validation/index.d.ts +0 -3
- package/esm/validation/index.d.ts.map +0 -1
- package/esm/validation/mutators/embed-mutator.d.ts +0 -9
- package/esm/validation/mutators/embed-mutator.d.ts.map +0 -1
- package/esm/validation/mutators/embed-mutator.js +0 -33
- package/esm/validation/mutators/embed-mutator.js.map +0 -1
- package/esm/validation/plugins/embed-validator-plugin.d.ts +0 -24
- package/esm/validation/plugins/embed-validator-plugin.d.ts.map +0 -1
- package/esm/validation/plugins/embed-validator-plugin.js +0 -18
- package/esm/validation/plugins/embed-validator-plugin.js.map +0 -1
- package/esm/validation/rules/database-model-rule.d.ts +0 -7
- package/esm/validation/rules/database-model-rule.d.ts.map +0 -1
- package/esm/validation/rules/database-model-rule.js +0 -27
- package/esm/validation/rules/database-model-rule.js.map +0 -1
- package/esm/validation/transformers/embed-model-transformer.d.ts +0 -3
- package/esm/validation/transformers/embed-model-transformer.d.ts.map +0 -1
- package/esm/validation/transformers/embed-model-transformer.js +0 -18
- package/esm/validation/transformers/embed-model-transformer.js.map +0 -1
- package/esm/validation/validators/embed-validator.d.ts +0 -21
- package/esm/validation/validators/embed-validator.d.ts.map +0 -1
- package/esm/validation/validators/embed-validator.js +0 -43
- package/esm/validation/validators/embed-validator.js.map +0 -1
- package/esm/writer/database-writer.d.ts +0 -174
- package/esm/writer/database-writer.d.ts.map +0 -1
- package/esm/writer/database-writer.js +0 -400
- package/esm/writer/database-writer.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.mjs","names":[],"sources":["../../../../../../@warlock.js/cascade/src/model/model.ts"],"sourcesContent":["import { type GenericObject } from \"@mongez/reinforcements\";\nimport type { ObjectValidator } from \"@warlock.js/seal\";\nimport type {\n DriverContract,\n PaginationOptions,\n PaginationResult,\n RemoverResult,\n UpdateOperations,\n WriterOptions,\n} from \"../contracts\";\nimport { QueryBuilderContract, WhereCallback, WhereObject, WhereOperator } from \"../contracts\";\nimport type { DataSource } from \"../data-source/data-source\";\nimport { DatabaseDirtyTracker } from \"../database-dirty-tracker\";\nimport type { ModelEventListener, ModelEventName } from \"../events/model-events\";\nimport { ModelEvents } from \"../events/model-events\";\nimport type { PivotOperations } from \"../relations/pivot-operations\";\nimport type { ModelSnapshot } from \"../relations/relation-hydrator\";\nimport { attachLoadedRelation, RelationLoader } from \"../relations/relation-loader\";\nimport type {\n LoadedRelationResult,\n PivotData,\n PivotIds,\n RelationDefinition,\n} from \"../relations/types\";\nimport { modelSync } from \"../sync/model-sync\";\nimport type { ModelSyncOperationContract } from \"../sync/types\";\nimport type { DeleteStrategy, StrictMode } from \"../types\";\nimport {\n decrementField,\n getBooleanField,\n getFieldValue,\n getNumberField,\n getOnlyFields,\n getStringField,\n hasField,\n incrementField,\n mergeFields,\n setFieldValue,\n unsetFields,\n} from \"./methods/accessor-methods\";\nimport { deleteOneRecord, deleteRecords, destroyModel } from \"./methods/delete-methods\";\nimport {\n checkHasChanges,\n checkIsDirty,\n getDirtyColumns,\n getDirtyColumnsWithValues,\n getRemovedColumns,\n} from \"./methods/dirty-methods\";\nimport {\n cloneModel,\n deepFreezeObject,\n hydrateModel,\n modelFromSnapshot,\n modelToSnapshot,\n replaceModelData,\n serializeModel,\n} from \"./methods/hydration-methods\";\nimport {\n emitModelEvent,\n offModelEvent,\n onceModelEvent,\n onModelEvent,\n} from \"./methods/instance-event-methods\";\nimport {\n applyDefaultsToModel,\n generateModelNextId,\n performAtomicDecrement,\n performAtomicIncrement,\n performAtomicUpdate,\n} from \"./methods/meta-methods\";\nimport { attachPivotRelation, detachPivotRelation, pivotRelation } from \"./methods/pivot-methods\";\nimport {\n buildNewQueryBuilder,\n buildQuery,\n countRecords,\n decreaseField,\n findAll,\n findAndReplaceRecord,\n findAndUpdateRecords,\n findById,\n findFirst,\n findLast,\n findLatest,\n findOneAndDeleteRecord,\n findOneAndUpdateRecord,\n increaseField,\n paginateRecords,\n performAtomic,\n resolveDataSource,\n updateById,\n} from \"./methods/query-methods\";\nimport { restoreAllRecords, restoreRecord } from \"./methods/restore-methods\";\nimport {\n addGlobalModelScope,\n addLocalModelScope,\n removeGlobalModelScope,\n removeLocalModelScope,\n} from \"./methods/scope-methods\";\nimport { modelToJSON } from \"./methods/serialization-methods\";\nimport {\n cleanupModelEvents,\n getGlobalEvents,\n getModelEvents,\n offStaticEvent,\n onceStaticEvent,\n onStaticEvent,\n} from \"./methods/static-event-methods\";\nimport {\n createManyRecords,\n createRecord,\n findOrCreateRecord,\n saveModel,\n upsertRecord,\n} from \"./methods/write-methods\";\nimport type {\n ChildModel,\n GlobalScopeDefinition,\n GlobalScopeOptions,\n LocalScopeCallback,\n ModelSchema,\n} from \"./model.types\";\nimport { getAllModelsFromRegistry, getModelFromRegistry } from \"./register-model\";\nexport type {\n ChildModel,\n GlobalScopeDefinition,\n GlobalScopeOptions,\n LocalScopeCallback,\n ModelSchema,\n ScopeTiming,\n} from \"./model.types\";\n\n/**\n * Base class that powers all Cascade models.\n *\n * Provides:\n * - Type-safe value accessors with dot-notation support (get, set, has, unset, merge)\n * - Automatic dirty tracking for efficient partial updates\n * - Lifecycle event hooks (saving, created, deleting, etc.)\n * - Integration with the data-source registry for multi-database support\n * - Support for both per-model and global event listeners\n *\n * @template TSchema - The shape of the model's underlying data\n *\n * @example\n * ```typescript\n * interface UserSchema {\n * id: number;\n * name: string;\n * email: string;\n * }\n *\n * class User extends Model<UserSchema> {\n * public static table = \"users\";\n * }\n *\n * const user = new User({ name: \"Alice\" });\n * user.set(\"email\", \"alice@example.com\");\n * console.log(user.hasChanges()); // true\n * ```\n */\nexport abstract class Model<TSchema extends ModelSchema = ModelSchema> {\n /**\n * The database table or collection name associated with this model.\n *\n * Must be defined by each concrete model subclass.\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static table = \"users\";\n * }\n * ```\n */\n public static table: string;\n\n /**\n * Resource for this model.\n * It is a class that holds a toJSON function\n * Called when the model is being converted to JSON (by calling toJSON or JSON.stringify(model))\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static resource = UserResource;\n * }\n * ```\n */\n public static resource?: any;\n\n /**\n * Resource columns\n * Define what columns should be sent to the resource (if any) when converting to JSON\n */\n public static resourceColumns?: string[];\n\n /**\n * JSON keys for this model.\n * This could be used if resource is not passed\n * It will select only these keys from the model\n * @example\n * ```typescript\n * class User extends Model {\n * public static toJsonColumns = [\"id\", \"name\"];\n * }\n * ```\n */\n public static toJsonColumns?: string[];\n\n /**\n * Data source reference for this model.\n *\n * Can be:\n * - A string name registered in the data-source registry\n * - A DataSource instance\n * - Undefined (falls back to the default data source)\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static dataSource = \"primary\";\n * }\n * ```\n */\n public static dataSource?: string | DataSource;\n\n /**\n * Query builder class\n */\n public static builder?: new (...args: any[]) => QueryBuilderContract<Model>;\n\n /**\n * Primary key field name used to identify records.\n *\n * @default \"id\"\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static primaryKey = \"_id\"; // MongoDB\n * }\n *\n * class Product extends Model {\n * public static primaryKey = \"id\"; // SQL\n * }\n * ```\n */\n public static primaryKey: string = \"id\";\n\n /**\n * Embeded fields when document is Being embeded\n */\n public static embed?: string[];\n\n /**\n * Validation and casting schema using @warlock.js/seal.\n *\n * Defines validation rules and data transformations for the model.\n * Used automatically during save operations.\n *\n * @example\n * ```typescript\n * import { v } from \"@warlock.js/seal\";\n *\n * class User extends Model {\n * public static schema = v.object({\n * name: v.string().required().trim(),\n * age: v.number().min(0).max(120),\n * email: v.string().email().required().toLowerCase(),\n * createdAt: v.date().default(() => new Date()),\n * });\n * }\n * ```\n */\n public static schema?: ObjectValidator;\n\n /**\n * Strict mode behavior for unknown fields.\n *\n * - `\"strip\"`: Remove unknown fields silently (default, recommended for APIs)\n * - `\"fail\"`: Throw validation error on unknown fields (strict validation)\n * - `\"allow\"`: Allow unknown fields to pass through (permissive)\n *\n * @default \"strip\"\n *\n * @example\n * ```typescript\n * import { Model, type StrictMode } from \"@warlock.js/cascade\";\n *\n * class User extends Model {\n * public static strictMode: StrictMode = \"fail\"; // Throw on unknown fields\n * }\n *\n * const user = new User({ name: \"Alice\", unknownField: \"value\" });\n * await user.save(); // DatabaseWriterValidationError: unknown field\n * ```\n */\n public static strictMode: StrictMode = \"strip\";\n\n /**\n * Auto-generate incremental `id` field on insert (NoSQL only).\n *\n * When enabled, the ID generator creates a sequential integer ID\n * separate from the database's native ID (_id for MongoDB).\n *\n * **Note:** SQL databases use native AUTO_INCREMENT and don't need this.\n *\n * @default true\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static autoGenerateId = true;\n * }\n *\n * const user = new User({ name: \"Alice\" });\n * await user.save();\n * console.log(user.get(\"_id\")); // ObjectId(\"...\") - MongoDB\n * console.log(user.get(\"id\")); // 1 - Generated\n * ```\n */\n public static autoGenerateId = true;\n\n /**\n * Initial ID value for the first record.\n *\n * If not set, defaults to 1 or uses `randomInitialId`.\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static initialId = 1000; // Start from 1000\n * }\n * ```\n */\n public static initialId?: number;\n\n /**\n * Randomly generate the initial ID.\n *\n * Can be:\n * - `true`: Generate random ID between 10000-499999\n * - Function: Custom random ID generator\n * - `false`: Use `initialId` or default to 1\n *\n * @default false\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static randomInitialId = true; // Random 10000-499999\n * }\n *\n * class Product extends Model {\n * public static randomInitialId = () => Math.floor(Math.random() * 1000000);\n * }\n * ```\n */\n public static randomInitialId?: boolean | (() => number);\n\n /**\n * Amount to increment ID by for each new record.\n *\n * If not set, defaults to 1 or uses `randomIncrement`.\n *\n * @default 1\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static incrementIdBy = 5; // Increment by 5\n * }\n * ```\n */\n public static incrementIdBy?: number = 1;\n\n /**\n * Randomly generate the increment amount.\n *\n * Can be:\n * - `true`: Generate random increment between 1-10\n * - Function: Custom random increment generator\n * - `false`: Use `incrementIdBy` or default to 1\n *\n * @default false\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static randomIncrement = true; // Random 1-10\n * }\n *\n * class Product extends Model {\n * public static randomIncrement = () => Math.floor(Math.random() * 100);\n * }\n * ```\n */\n public static randomIncrement?: boolean | (() => number);\n\n /**\n * Created at column name.\n */\n public static createdAtColumn?: string | false;\n\n /**\n * Updated at column name.\n */\n public static updatedAtColumn?: string | false;\n\n /**\n * Delete strategy for this model.\n *\n * Controls how models are deleted:\n * - `\"trash\"` - Moves to trash collection, then deletes\n * - `\"permanent\"` - Direct deletion (hard delete)\n * - `\"soft\"` - Sets deletedAt timestamp (soft delete)\n *\n * Can be overridden by destroy() options.\n * Falls back to data source default if not set.\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static deleteStrategy: DeleteStrategy = \"soft\";\n * }\n * ```\n */\n public static deleteStrategy?: DeleteStrategy;\n\n /**\n * Column name for soft delete timestamp.\n *\n * Used when delete strategy is \"soft\".\n *\n * @default \"deletedAt\"\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static deletedAtColumn = \"archivedAt\";\n * }\n * ```\n */\n public static deletedAtColumn: string | false = \"deletedAt\";\n\n /**\n * Trash table/collection name override.\n *\n * If not set, defaults to `{table}Trash` or data source default.\n * Used when delete strategy is \"trash\".\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static trashTable = \"userRecycleBin\";\n * }\n * ```\n */\n public static trashTable?: string;\n\n /**\n * Global scopes that are automatically applied to all queries.\n * These scopes are inherited by child models.\n */\n public static globalScopes = new Map<string, GlobalScopeDefinition>();\n\n /**\n * Local scopes that can be manually applied to queries.\n * These are reusable query snippets that developers opt into.\n */\n public static localScopes = new Map<string, LocalScopeCallback>();\n\n /**\n * Relation definitions for this model.\n *\n * Define relationships to other models using helper functions:\n * - `hasMany()` - One-to-many (User has many Posts)\n * - `hasOne()` - One-to-one (User has one Profile)\n * - `belongsTo()` - Inverse of hasMany/hasOne (Post belongs to User)\n * - `belongsToMany()` - Many-to-many with pivot table (User has many Roles)\n *\n * @example\n * ```typescript\n * import { hasMany, belongsTo, belongsToMany, hasOne } from \"@warlock.js/cascade\";\n *\n * class User extends Model {\n * public posts?: Post[]; // Optional: for TypeScript autocomplete\n *\n * static relations = {\n * posts: hasMany(\"Post\"),\n * profile: hasOne(\"Profile\"),\n * organization: belongsTo(\"Organization\"),\n * roles: belongsToMany(\"Role\", { pivot: \"user_roles\" }),\n * };\n * }\n *\n * // Usage:\n * const users = await User.query().with(\"posts\").get();\n * console.log(users[0].posts); // Post[]\n * ```\n */\n public static relations: Readonly<Record<string, RelationDefinition>> = {};\n\n /**\n * Flag indicating whether this model instance represents a new (unsaved) record.\n *\n * - `true`: The model has not been persisted to the database yet\n * - `false`: The model represents an existing database record\n *\n * This flag is used by the writer to determine whether to perform an insert or update.\n */\n public isNew = true;\n\n /**\n * The raw mutable data backing this model instance.\n *\n * All field accessors (get, set, merge, etc.) operate on this object.\n */\n public data: TSchema;\n\n /**\n * Dirty tracker that monitors changes to the model's data.\n *\n * Tracks:\n * - Which fields have been modified (dirty columns)\n * - Which fields have been removed\n * - Original vs. current values for each dirty field\n *\n * Used by the writer to generate efficient partial update payloads.\n */\n public readonly dirtyTracker: DatabaseDirtyTracker;\n\n /**\n * Model instance events.\n * Allows registering listeners for lifecycle events on this specific instance.\n */\n public events: ModelEvents<any> = new ModelEvents();\n\n /**\n * Map of loaded relations for this model instance.\n *\n * Populated automatically when using `with()` for eager loading,\n * or when calling `load()` for lazy loading.\n *\n * @example\n * ```typescript\n * const user = await User.query().with(\"posts\").first();\n * console.log(user.loadedRelations.get(\"posts\")); // Post[]\n *\n * // Also accessible as direct properties:\n * console.log(user.posts); // Post[]\\n * ```\n */\n public loadedRelations: Map<string, any> = new Map();\n\n /**\n * Column name for active status.\n */\n protected isActiveColumn = \"isActive\";\n\n /**\n * Constructs a new model instance with optional initial data.\n *\n * Initializes the dirty tracker with a snapshot of the provided data.\n *\n * @param initialData - Partial data to populate the model\n *\n * @example\n * ```typescript\n * const user = new User({ name: \"Alice\", email: \"alice@example.com\" });\n * ```\n */\n public constructor(initialData: Partial<TSchema> = {}) {\n this.data = initialData as TSchema;\n this.dirtyTracker = this.self().getDriver().getDirtyTracker(this.data);\n }\n\n /**\n * Lazily load one or more relations for this model instance.\n *\n * This method loads relations on-demand after the model has been fetched.\n * The loaded relations are attached directly to the model instance and\n * also stored in `loadedRelations` map.\n *\n * @param relations - Relation name(s) to load\n * @returns This model instance for chaining\n *\n * @example\n * ```typescript\n * const user = await User.first();\n *\n * // Load single relation\n * await user.load(\"posts\");\n * console.log(user.posts); // Post[]\n *\n * // Load multiple relations\n * await user.load(\"posts\", \"organization\");\n *\n * // Chain with other operations\n * const posts = await user.load(\"posts\").then(() => user.posts);\n * ```\n */\n public async load(...relations: string[]): Promise<this> {\n const ModelClass = this.constructor as ChildModel<Model>;\n const loader = new RelationLoader([this], ModelClass);\n await loader.load(relations);\n return this;\n }\n\n /**\n * Check if a relation has been loaded.\n *\n * @param relationName - Name of the relation to check\n * @returns True if the relation has been loaded\n *\n * @example\n * ```typescript\n * const user = await User.first();\n *\n * console.log(user.isLoaded(\"posts\")); // false\n * await user.load(\"posts\");\n * console.log(user.isLoaded(\"posts\")); // true\n * ```\n */\n\n public isLoaded(relationName: string): boolean {\n return this.loadedRelations.has(relationName);\n }\n\n /**\n * Set relation manually\n *\n * @param relationName\n * @param relationData\n */\n public setRelation(relationName: string, relationData: LoadedRelationResult): void {\n attachLoadedRelation(this, relationName, relationData);\n }\n\n /**\n * Get a loaded relation by name.\n *\n * Returns undefined if the relation has not been loaded.\n *\n * @param relationName - Name of the relation to get\n * @returns The loaded relation data, or undefined\n *\n * @example\n * ```typescript\n * const user = await User.query().with(\"posts\").first();\n *\n * const posts = user.getRelation<Post[]>(\"posts\");\n * console.log(posts?.length);\n * ```\n */\n public getRelation<TRelation = any>(relationName: string): TRelation | undefined {\n return this.loadedRelations.get(relationName) as TRelation | undefined;\n }\n\n /**\n * Get a model class by its name from the global registry.\n *\n * Models must be decorated with @RegisterModel() to be available in the registry.\n *\n * @param name - The model class name\n * @returns The model class or undefined if not found\n *\n * @example\n * ```typescript\n * const UserModel = Model.getModel(\"User\");\n * if (UserModel) {\n * const user = await UserModel.find(1);\n * }\n * ```\n */\n public static getModel(name: string) {\n return getModelFromRegistry(name);\n }\n\n /**\n * Get all registered models from the global registry.\n *\n * Only models decorated with @RegisterModel() will appear here.\n *\n * @returns A Map of all registered model classes by name\n *\n * @example\n * ```typescript\n * const allModels = Model.getAllModels();\n * for (const [name, ModelClass] of allModels) {\n * console.log(`Found model: ${name} with table: ${ModelClass.table}`);\n * }\n * ```\n */\n public static getAllModels() {\n return getAllModelsFromRegistry();\n }\n\n // ============================================================================\n // STATIC SYNC METHODS\n // ============================================================================\n\n /**\n * Create a sync operation for a single embedded document.\n *\n * When this model is updated, the target model's field\n * will be updated with the embedded data.\n *\n * @param TargetModel - Target model class that receives data\n * @param targetField - Field path in target model\n * @returns Sync operation for chaining configuration\n *\n * @example\n * ```typescript\n * // When Category updates, update Product.category\n * Category.sync(Product, \"category\");\n * ```\n */\n public static sync<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n TargetModel: ChildModel<Model>,\n targetField: string,\n ): ModelSyncOperationContract {\n return modelSync.sync(this, TargetModel, targetField);\n }\n\n /**\n * Create a sync operation for an array of embedded documents.\n *\n * When this model is updated, the corresponding element\n * in the target model's array field will be updated.\n *\n * @param TargetModel - Target model class that receives data\n * @param targetField - Array field path in target model\n * @returns Sync operation for chaining configuration\n *\n * @example\n * ```typescript\n * // When Tag updates, update Post.tags[i] where tags[i].id matches\n * Tag.syncMany(Post, \"tags\").identifyBy(\"id\");\n * ```\n */\n public static syncMany<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n TargetModel: ChildModel<Model>,\n targetField: string,\n ): ModelSyncOperationContract {\n return modelSync.syncMany(this, TargetModel, targetField);\n }\n\n /**\n * Get model id\n */\n public get id(): number | string {\n return this.get(\"id\");\n }\n\n /**\n * String-typed accessor for the model's primary id.\n *\n * The underlying `id` field is `string | number` (MongoDB's ObjectId-as-string\n * vs SQL's auto-increment integer), which forces consumers to write\n * `string | number` everywhere they pass an id around. This getter narrows\n * the contract to `string` so callers can write functions that accept a\n * single id type without leaking the engine difference.\n *\n * The name `uuid` is historical — it does NOT validate or coerce the value\n * to a UUID. It simply returns the id, typed as a string.\n *\n * @example\n * ```typescript\n * function shareLink(modelId: string) { ... }\n * shareLink(user.uuid); // works regardless of whether the underlying id is\n * // a Mongo ObjectId string or a SQL integer\n * ```\n */\n public get uuid(): string {\n return this.get(\"id\");\n }\n\n /**\n * Retrieves a field value from the model's data.\n *\n * Supports both top-level keys and dot-notation paths for nested access.\n *\n * @param field - The field name or dot-notation path (e.g., \"address.city\")\n * @param defaultValue - Value to return if the field is missing\n * @returns The field value or the default value if not found\n *\n * @example\n * ```typescript\n * user.get(\"name\"); // \"Alice\"\n * user.get(\"address.city\", \"Unknown\"); // \"Unknown\" if address.city is missing\n * ```\n */\n public get<TKey extends keyof TSchema & string>(field: TKey): TSchema[TKey];\n public get<TKey extends keyof TSchema & string>(\n field: TKey,\n defaultValue: TSchema[TKey],\n ): TSchema[TKey];\n public get<Type extends unknown = any>(field: string): Type;\n public get<Type extends unknown = any>(field: string, defaultValue: Type): Type;\n public get(field: string, defaultValue?: unknown): any {\n return getFieldValue(this, field, defaultValue);\n }\n\n /**\n * Get only the values of the given fields\n */\n public only<TKey extends keyof TSchema & string>(fields: TKey[]): Record<TKey, TSchema[TKey]>;\n public only(fields: string[]): Record<string, unknown>;\n public only(fields: string[]): Record<string, unknown> {\n return getOnlyFields(this, fields);\n }\n\n /**\n * Get a string value\n */\n public string(key: string, defaultValue?: string): string | undefined {\n return getStringField(this, key, defaultValue);\n }\n\n /**\n * Get a number value\n */\n public number(key: string, defaultValue?: number): number | undefined {\n return getNumberField(this, key, defaultValue);\n }\n\n /**\n * Get a boolean value\n */\n public boolean(key: string, defaultValue?: boolean): boolean | undefined {\n return getBooleanField(this, key, defaultValue);\n }\n\n /**\n * Sets a field value in the model's data and marks it as dirty.\n *\n * Supports both top-level keys and dot-notation paths for nested assignment.\n * Automatically updates the dirty tracker to reflect the change.\n *\n * @param field - The field name or dot-notation path (e.g., \"address.city\")\n * @param value - The value to assign\n * @returns The model instance for method chaining\n *\n * @example\n * ```typescript\n * user.set(\"name\", \"Bob\").set(\"address.city\", \"NYC\");\n * ```\n */\n public set<TKey extends keyof TSchema & string>(field: TKey, value: TSchema[TKey]): this;\n public set(field: string, value: unknown): this;\n public set(field: string, value: unknown): this {\n return setFieldValue(this, field, value) as this;\n }\n\n /**\n * Checks whether a field exists in the model's data.\n *\n * Supports both top-level keys and dot-notation paths.\n *\n * @param field - The field name or dot-notation path\n * @returns `true` if the field exists, `false` otherwise\n *\n * @example\n * ```typescript\n * user.has(\"name\"); // true\n * user.has(\"address.zipCode\"); // false\n * ```\n */\n public has<TKey extends keyof TSchema & string>(field: TKey): boolean;\n public has(field: string): boolean;\n public has(field: string): boolean {\n return hasField(this, field);\n }\n\n /**\n * Increment the given field by the given amount\n */\n public increment<TKey extends keyof TSchema & string>(field: TKey, amount: number): this;\n public increment(field: string, amount?: number): this;\n public increment(field: string, amount?: number): this {\n return incrementField(this, field, amount) as this;\n }\n\n /**\n * Decrement the given field by the given amount\n */\n public decrement<TKey extends keyof TSchema & string>(field: TKey, amount: number): this;\n public decrement(field: string, amount?: number): this;\n public decrement(field: string, amount?: number): this {\n return decrementField(this, field, amount) as this;\n }\n\n /**\n * Removes one or more fields from the model's data and marks them as removed.\n *\n * Supports both top-level keys and dot-notation paths.\n * Automatically updates the dirty tracker to reflect the removal.\n *\n * @param fields - One or more field names or dot-notation paths to remove\n * @returns The model instance for method chaining\n *\n * @example\n * ```typescript\n * user.unset(\"tempField\", \"address.oldZip\");\n * ```\n */\n public unset(...fields: (keyof TSchema & string)[]): this;\n public unset(...fields: string[]): this;\n public unset(...fields: string[]): this {\n return unsetFields(this, ...fields) as this;\n }\n\n /**\n * Merges new values into the model's data and marks changed fields as dirty.\n *\n * Performs a deep merge, preserving existing nested structures.\n * Automatically updates the dirty tracker to reflect all changes.\n *\n * @param values - Partial data to merge into the model\n * @returns The model instance for method chaining\n *\n * @example\n * ```typescript\n * user.merge({ name: \"Charlie\", address: { city: \"LA\" } });\n * ```\n */\n public merge(values: Partial<TSchema>): this;\n public merge(values: Record<string, unknown>): this;\n public merge(values: Record<string, unknown>): this {\n return mergeFields(this, values) as this;\n }\n\n /**\n * Perform atomoic update from current model instance\n * Please note that it would require the id to be existing in the current\n * model instance\n * @returns number of affected records\n */\n public async atomicUpdate(operations: Record<string, unknown>): Promise<number> {\n return performAtomicUpdate(this, operations);\n }\n\n /**\n * Perform atomic increment\n * This would issue a query update and update the given field without\n * saving the model\n */\n public async atomicIncrement<T extends keyof TSchema & string>(\n field: T,\n amount: number = 1,\n ): Promise<number> {\n return performAtomicIncrement(this, field, amount);\n }\n\n /**\n * Perform atomic decrement\n * This would issue a query update and update the given field without\n * saving the model\n */\n public async atomicDecrement<T extends keyof TSchema & string>(\n field: T,\n amount: number = 1,\n ): Promise<number> {\n return performAtomicDecrement(this, field, amount);\n }\n\n /**\n * Determine if current model is active\n */\n public get isActive(): boolean {\n return this.get<boolean>(this.isActiveColumn);\n }\n\n /**\n * Get created at date\n */\n public get createdAt(): Date | undefined {\n const createdAtColumn = this.self().createdAtColumn;\n\n if (!createdAtColumn) return;\n\n return this.get<Date>(createdAtColumn);\n }\n\n /**\n * Get updated at date\n */\n public get updatedAt(): Date | undefined {\n const updatedAtColumn = this.self().updatedAtColumn;\n\n if (!updatedAtColumn) return;\n\n return this.get<Date>(updatedAtColumn);\n }\n\n /**\n * Check if current model record is created by the given user model\n */\n public isCreatedBy(user: Model | GenericObject): boolean {\n return this.get(`createdBy.id`) === user.id;\n }\n\n /**\n * Checks whether the model's data has changed since instantiation or last reset.\n *\n * @returns `true` if any fields have been modified or removed, `false` otherwise\n *\n * @example\n * ```typescript\n * const user = new User({ name: \"Alice\" });\n * user.hasChanges(); // false\n * user.set(\"name\", \"Bob\");\n * user.hasChanges(); // true\n * ```\n */\n public hasChanges(): boolean {\n return checkHasChanges(this);\n }\n\n /**\n * Check if the given column has been modified.\n *\n * @param column - The column name to check\n * @returns `true` if the column has been modified, `false` otherwise\n *\n * @example\n * ```typescript\n * user.set(\"name\", \"Bob\");\n * user.isDirty(\"name\"); // true\n * ```\n */\n public isDirty(column: string): boolean {\n return checkIsDirty(this, column);\n }\n\n /**\n * Retrieves all dirty columns with their old and new values.\n *\n * @returns A record mapping each dirty column to its previous and current value\n *\n * @example\n * ```typescript\n * user.set(\"name\", \"Bob\");\n * user.getDirtyColumnsWithValues();\n * // { name: { oldValue: \"Alice\", newValue: \"Bob\" } }\n * ```\n */\n public getDirtyColumnsWithValues(): Record<string, { oldValue: unknown; newValue: unknown }> {\n return getDirtyColumnsWithValues(this);\n }\n\n /**\n * Lists all columns that have been removed from the model's data.\n *\n * @returns An array of field names that were present initially but have been unset\n *\n * @example\n * ```typescript\n * user.unset(\"tempField\");\n * user.getRemovedColumns(); // [\"tempField\"]\n * ```\n */\n public getRemovedColumns(): string[] {\n return getRemovedColumns(this);\n }\n\n /**\n * Lists all columns that have been modified since instantiation or last reset.\n *\n * @returns An array of field names that have changed\n *\n * @example\n * ```typescript\n * user.set(\"name\", \"Bob\");\n * user.getDirtyColumns(); // [\"name\"]\n * ```\n */\n public getDirtyColumns(): string[] {\n return getDirtyColumns(this);\n }\n\n /**\n * Emits a lifecycle event to both per-model and global listeners.\n *\n * This method is public so that external services (like the writer) can trigger\n * lifecycle events when appropriate.\n *\n * @param event - The event name (e.g., \"saving\", \"created\", \"deleting\")\n * @param context - Optional context data to pass to listeners\n *\n * @example\n * ```typescript\n * await user.emitEvent(\"saving\");\n * await user.emitEvent(\"validated\", { errors: [] });\n * ```\n */\n public async emitEvent<TContext = unknown>(\n event: ModelEventName,\n context?: TContext,\n ): Promise<void> {\n return emitModelEvent(this, event, context);\n }\n\n /**\n * Register a listener for a model lifecycle event on this instance.\n *\n * @param event - Event name (e.g., \"saving\", \"updated\")\n * @param listener - Callback function\n * @returns Unsubscribe function\n */\n public on<TContext = unknown>(\n event: ModelEventName,\n listener: ModelEventListener<this, TContext>,\n ): () => void {\n return onModelEvent(this, event, listener as any);\n }\n\n /**\n * Register a one-time listener for a model lifecycle event on this instance.\n *\n * @param event - Event name\n * @param listener - Callback function\n * @returns Unsubscribe function\n */\n public once<TContext = unknown>(\n event: ModelEventName,\n listener: ModelEventListener<this, TContext>,\n ): () => void {\n return onceModelEvent(this, event, listener as any);\n }\n\n /**\n * Remove a listener from this instance.\n *\n * @param event - Event name\n * @param listener - Callback function to remove\n */\n public off<TContext = unknown>(\n event: ModelEventName,\n listener: ModelEventListener<this, TContext>,\n ): void {\n offModelEvent(this, event, listener as any);\n }\n\n /**\n * Resolves the data source associated with this model.\n *\n * Resolution order:\n * 1. If `dataSource` is a string, looks it up in the data-source registry\n * 2. If `dataSource` is a DataSource instance, returns it directly\n * 3. Otherwise, returns the default data source from the registry\n *\n * @returns The resolved DataSource instance\n * @throws Error if no data source is found\n *\n * @example\n * ```typescript\n * class User extends Model {\n * public static dataSource = \"primary\";\n * }\n *\n * const ds = User.getDataSource();\n * ```\n */\n public static getDataSource(): DataSource {\n return resolveDataSource(this as any);\n }\n\n /**\n * Get driver instance\n */\n public static getDriver(): DriverContract {\n return this.getDataSource().driver;\n }\n\n /**\n * Generate next id and set it to current model's id\n */\n public async generateNextId(): Promise<number | string> {\n return generateModelNextId(this);\n }\n\n /**\n * Apply model defaults from data source configuration.\n *\n * This is called automatically by getDataSource() the first time\n * a model accesses its data source. Defaults are only applied if\n * the model doesn't already have its own value set.\n *\n * The hierarchy is:\n * 1. Model static property (highest priority - skipped here)\n * 2. Database config modelDefaults (passed here)\n * 3. Driver modelDefaults (merged before passing here)\n * 4. Framework defaults (fallback values in the code)\n *\n * @param defaults - Model default configuration from data source\n */\n public static applyModelDefaults(defaults: any): void {\n applyDefaultsToModel(this, defaults);\n }\n\n /**\n * Add a global scope that is automatically applied to all queries.\n *\n * Global scopes are inherited by child models and applied before query execution.\n * Use for security filters, multi-tenancy, soft deletes, etc.\n *\n * @param name - Unique name for the scope\n * @param callback - Function that modifies the query\n * @param options - Scope options (timing: 'before' | 'after')\n *\n * @example\n * ```typescript\n * // Multi-tenancy scope\n * Model.addGlobalScope('tenant', (query) => {\n * query.where('tenantId', getCurrentTenant());\n * }, { timing: 'before' });\n *\n * // Soft delete scope\n * User.addGlobalScope('notDeleted', (query) => {\n * query.whereNull('deletedAt');\n * });\n * ```\n */\n public static addGlobalScope(\n name: string,\n callback: (query: QueryBuilderContract) => void,\n options: GlobalScopeOptions = {},\n ): void {\n addGlobalModelScope(this as any, name, callback, options);\n }\n\n /**\n * Remove a global scope by name.\n *\n * @param name - Name of the scope to remove\n *\n * @example\n * ```typescript\n * Model.removeGlobalScope('tenant');\n * ```\n */\n public static removeGlobalScope(name: string): void {\n removeGlobalModelScope(this as any, name);\n }\n\n /**\n * Add a local scope that can be manually applied to queries.\n *\n * Local scopes are reusable query snippets that developers opt into.\n * They are not automatically applied.\n *\n * @param name - Unique name for the scope\n * @param callback - Function that modifies the query\n *\n * @example\n * ```typescript\n * // Define reusable scopes\n * User.addScope('active', (query) => {\n * query.where('isActive', true);\n * });\n *\n * User.addScope('admins', (query) => {\n * query.where('role', 'admin');\n * });\n *\n * // Use explicitly\n * await User.query().scope('active').get();\n * await User.query().scope('admins').get();\n * ```\n */\n public static addScope(name: string, callback: LocalScopeCallback): void {\n addLocalModelScope(this as any, name, callback);\n }\n\n /**\n * Remove a local scope by name.\n *\n * @param name - Name of the scope to remove\n *\n * @example\n * ```typescript\n * User.removeScope('active');\n * ```\n */\n public static removeScope(name: string): void {\n removeLocalModelScope(this as any, name);\n }\n\n /**\n * Create a new query builder for this model\n */\n public static query<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ): QueryBuilderContract<TModel> {\n return buildQuery(this, Model);\n }\n\n // Short hand for the query builder method with\n /**\n * Eagerly load one or more relations with the query results.\n *\n * Relations are loaded in separate optimized queries to prevent N+1 problems.\n * The loaded relations are attached to each model instance.\n *\n * @param relation - Single relation name to load\n * @returns Query builder for chaining\n *\n * @example\n * ```typescript\n * // Load single relation\n * const user = await User.query().with(\"posts\").find(1);\n * console.log(user.posts); // Post[]\n *\n * // Load multiple relations\n * const user = await User.query().with(\"posts\", \"organization\").find(1);\n *\n * // Load nested relations\n * const user = await User.query().with(\"posts.comments.author\").find(1);\n * ```\n */\n public static with<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relation: string,\n ): QueryBuilderContract<TModel>;\n\n /**\n * Eagerly load multiple relations.\n *\n * @param relations - Relation names to load\n * @returns Query builder for chaining\n */\n public static with<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ...relations: string[]\n ): QueryBuilderContract<TModel>;\n\n /**\n * Eagerly load a relation with a constraint callback.\n *\n * The callback receives the relation query builder, allowing you to\n * add conditions, ordering, or limits to the related query.\n *\n * @param relation - Relation name to load\n * @param constraint - Callback to configure the relation query\n * @returns Query builder for chaining\n *\n * @example\n * ```typescript\n * const user = await User.query()\n * .with(\"posts\", (query) => {\n * query.where(\"isPublished\", true)\n * .orderBy(\"createdAt\", \"desc\")\n * .limit(5);\n * })\n * .find(1);\n * ```\n */\n public static with<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relation: string,\n constraint: (query: QueryBuilderContract) => void,\n ): QueryBuilderContract<TModel>;\n\n /**\n * Eagerly load multiple relations with constraints.\n *\n * Pass an object where keys are relation names and values are either:\n * - `true` to load without constraints\n * - A callback function to configure the relation query\n *\n * @param relations - Object mapping relation names to constraints\n * @returns Query builder for chaining\n *\n * @example\n * ```typescript\n * const user = await User.query()\n * .with({\n * posts: (query) => query.where(\"isPublished\", true),\n * organization: true,\n * roles: (query) => query.orderBy(\"priority\"),\n * })\n * .find(1);\n * ```\n */\n public static with<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relations: Record<string, boolean | ((query: QueryBuilderContract) => void)>,\n ): QueryBuilderContract<TModel>;\n\n public static with<TModel extends Model = Model>(this: ChildModel<TModel>, ...args: any[]) {\n return this.query().with(...args);\n }\n\n /**\n * Add a count of related records as a virtual field on each result row.\n *\n * Each relation produces a `${relationName}Count` column by default. Use\n * the `\"name as alias\"` shorthand or the object form to customise the\n * output alias or apply per-relation where-clause constraints.\n *\n * @param relation - Relation name (optionally with `as <alias>`)\n * @returns Query builder for chaining\n *\n * @example\n * ```typescript\n * const users = await User.withCount(\"posts\").get();\n * console.log(users[0].postsCount); // number\n * ```\n */\n public static withCount<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relation: string,\n ): QueryBuilderContract<TModel>;\n\n /**\n * Add counts for multiple relations at once.\n *\n * @example\n * ```typescript\n * await User.withCount(\"posts\", \"comments\", \"followers\").get();\n * ```\n */\n public static withCount<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ...relations: string[]\n ): QueryBuilderContract<TModel>;\n\n /**\n * Add counts for multiple relations supplied as an array.\n */\n public static withCount<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relations: string[],\n ): QueryBuilderContract<TModel>;\n\n /**\n * Add counts with optional per-relation constraints and alias overrides.\n *\n * Values may be `true`, an alias string, or a callback that applies\n * where-clauses inside the count subquery. Use the `as <alias>` shorthand\n * in the key to count the same relation more than once.\n *\n * @example\n * ```typescript\n * await Post.withCount({\n * comments: true,\n * \"comments as approvedCount\": (q) => q.where(\"approved\", true),\n * tags: \"tagCount\",\n * }).get();\n * ```\n */\n public static withCount<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n relations: Record<string, true | string | ((query: QueryBuilderContract) => void)>,\n ): QueryBuilderContract<TModel>;\n\n public static withCount<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ...args: any[]\n ): QueryBuilderContract<TModel> {\n return this.query().withCount(...args);\n }\n\n /**\n * Load relations using database JOINs in a single query.\n *\n * Unlike `with()` which uses separate queries, `joinWith()` uses\n * LEFT JOIN (SQL) or $lookup (MongoDB) to fetch related data\n * in a single query. The related data is hydrated into proper\n * model instances and attached to the main model.\n *\n * Best for: belongsTo and hasOne relations where you need\n * efficient single-query loading.\n *\n * @param relations - Relation names to load via JOIN\n * @returns Query builder for chaining\n *\n * @example\n * ```typescript\n * // Single relation\n * const post = await Post.joinWith(\"author\").first();\n * console.log(post.author); // User model instance\n * console.log(post.data); // { id, title, authorId } - no author data\n *\n * // Multiple relations\n * const post = await Post.joinWith(\"author\", \"category\").first();\n * ```\n */\n public static joinWith<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ...relations: string[]\n ): QueryBuilderContract<TModel> {\n return this.query().joinWith(...relations);\n }\n\n /**\n * Create new query builder.\n *\n * If the model has a static `builder` property set to a query builder class,\n * it will be instantiated instead of the default driver query builder.\n *\n * @example\n * ```typescript\n * class UserQueryBuilder<T = User> extends MongoQueryBuilder<T> {\n * active() { return this.where(\"isActive\", true); }\n * }\n *\n * class User extends Model {\n * static builder = UserQueryBuilder; // That's it! ✨\n * }\n *\n * // Now User.query() returns UserQueryBuilder<User> with autocomplete!\n * ```\n */\n public static newQueryBuilder<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ): QueryBuilderContract<TModel> {\n return buildNewQueryBuilder(this);\n }\n\n /**\n * Get First matched record for the given filter\n */\n public static async first<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<TModel | null> {\n return findFirst(this, filter);\n }\n\n /**\n * Get last matched record for the given filter\n */\n public static async last<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<TModel | null> {\n return findLast(this, filter);\n }\n\n /**\n * Use where clause directly\n */\n public static where<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n field: string,\n value: unknown,\n ): QueryBuilderContract<TModel>;\n public static where<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n field: string,\n operator: WhereOperator,\n value: unknown,\n ): QueryBuilderContract<TModel>;\n public static where<TModel extends Model = Model>(\n this: (new (...args: any[]) => TModel) &\n Pick<typeof Model, \"query\" | \"getDataSource\" | \"table\">,\n conditions: WhereObject,\n ): QueryBuilderContract<TModel>;\n public static where<TModel extends Model = Model>(\n this: (new (...args: any[]) => TModel) &\n Pick<typeof Model, \"query\" | \"getDataSource\" | \"table\">,\n callback: WhereCallback<TModel>,\n ): QueryBuilderContract<TModel>;\n public static where<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ...args: any[]\n ): QueryBuilderContract<TModel> {\n return (this.query().where as any)(...args);\n }\n\n /**\n * Count the number of records in the table\n * @param filter - The filter to apply to the query\n */\n public static count<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<number> {\n return countRecords(this, filter);\n }\n\n /**\n * Find record by id\n */\n public static async find<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n id: string | number,\n ): Promise<TModel | null> {\n return findById(this, id);\n }\n\n /**\n * Get all records from the table\n *\n * @param filter - The filter to apply to the query\n * @returns All records from the table\n */\n public static async all<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<TModel[]> {\n return findAll(this, filter);\n }\n\n /**\n * Perform pagination\n */\n public static async paginate<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n options: PaginationOptions & {\n filter?: Record<string, unknown>;\n } = {},\n ): Promise<PaginationResult<TModel>> {\n return paginateRecords(this, options);\n }\n\n /**\n * Get latest records from the table\n *\n * @param filter - The filter to apply to the query\n */\n public static async latest<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<TModel[]> {\n return findLatest(this, filter);\n }\n\n /**\n * Increment the given field by the given amount using atomic update\n *\n * @example ```typescript\n * // Increase age by 1 for user id 1\n * User.increment({id: 1}, \"age\", 1);\n * // Increase age by 1 and views by 2 for user id 1\n * User.increment({id: 1}, {age: 1, views: 2});\n * ```\n */\n public static increase<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n ): Promise<number> {\n return increaseField(this, filter, field, amount);\n }\n\n /**\n * Decrement the given field by the given amount using atomic update\n * @example ```typescript\n * // Decrease age by 1 for user id 1\n * User.decrement({id: 1}, \"age\", 1);\n * // Decrease age by 1 and views by 2 for user id 1\n * User.decrement({id: 1}, {age: 1, views: 2});\n * ```\n */\n public static decrease<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n ): Promise<number> {\n return decreaseField(this, filter, field, amount);\n }\n\n /**\n * Perform atomic operation\n * Example\n *\n * ```typescript\n * const user = await User.atomic({id: 1}, {$inc: {age: 1}})\n * Returns user model with updated age\n */\n public static async atomic<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n operations: UpdateOperations,\n ): Promise<number> {\n return performAtomic(this, filter, operations);\n }\n\n /**\n * Perform an atomic update for the given id\n */\n public static async update<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n id: string | number,\n data: Record<string, unknown>,\n ): Promise<number> {\n return updateById(this, id, data);\n }\n\n /**\n * Find one and update multiple records that matches the provided filter and return the updated record\n * @param filter - Filter conditions\n * @param update - Update operations ($set, $unset, $inc)\n * @returns The updated records\n */\n public static async findAndUpdate<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: UpdateOperations,\n ): Promise<TModel[]> {\n return findAndUpdateRecords(this, filter, update);\n }\n\n /**\n * Find one and update a single record that matches the provided filter and return the updated record\n * @param filter - Filter conditions\n * @param update - Update operations ($set, $unset, $inc)\n * @returns The updated record or null\n */\n public static async findOneAndUpdate<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: UpdateOperations,\n ): Promise<TModel | null> {\n return findOneAndUpdateRecord(this, filter, update);\n }\n\n /**\n * Find and replace the entire document that matches the provided filter and return the replaced document\n */\n public static async findAndReplace<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n document: Record<string, unknown>,\n ): Promise<TModel | null> {\n return findAndReplaceRecord(this, filter, document);\n }\n\n /**\n * Destroy (delete) the current model instance from the database.\n *\n * Emits lifecycle events:\n * - `deleting` - Before deletion\n * - `deleted` - After successful deletion\n *\n * @param options - Destroy options (strategy override, skipEvents)\n * @throws {Error} If the model is new (not saved) or if deletion fails\n *\n * @example\n * ```typescript\n * const user = await User.find(1);\n * await user.destroy(); // Uses default strategy\n * await user.destroy({ strategy: \"permanent\" }); // Override strategy\n * await user.destroy({ skipEvents: true }); // Silent delete\n * ```\n */\n public async destroy(options?: {\n strategy?: DeleteStrategy;\n skipEvents?: boolean;\n }): Promise<RemoverResult> {\n return destroyModel(this, options);\n }\n\n /**\n * Attach one or more related records to a `belongsToMany` pivot table.\n *\n * Thin wrapper over `createPivotOperations(this, relation).attach(ids, pivotData)`.\n * Throws if the named relation is not a `belongsToMany` relation.\n *\n * @example\n * ```typescript\n * await post.attach(\"tags\", [1, 2, 3]);\n * await post.attach(\"tags\", [4], { addedBy: currentUserId });\n * ```\n */\n public async attach(relation: string, ids: PivotIds, pivotData?: PivotData): Promise<void> {\n return attachPivotRelation(this, relation, ids, pivotData);\n }\n\n /**\n * Detach related records from a `belongsToMany` pivot table. Omit `ids`\n * to detach every row for this side of the relation.\n *\n * Thin wrapper over `createPivotOperations(this, relation).detach(ids)`.\n * Throws if the named relation is not a `belongsToMany` relation.\n *\n * @example\n * ```typescript\n * await post.detach(\"tags\", [2]);\n * await post.detach(\"tags\"); // detach all\n * ```\n */\n public async detach(relation: string, ids?: PivotIds): Promise<void> {\n return detachPivotRelation(this, relation, ids);\n }\n\n /**\n * Get the pivot-operations handle for a `belongsToMany` relation.\n *\n * Returns a `PivotOperations` object exposing `attach` / `detach` /\n * `sync` / `toggle` for the named relation's pivot table. Routing every\n * pivot mutation through `model.pivot(relation)` keeps the join-table\n * `sync` distinct from `Model.sync(Target, field)` (the denormalization\n * feature). Throws if the named relation is not a `belongsToMany` relation.\n *\n * @example\n * ```typescript\n * await post.pivot(\"tags\").attach([1, 2, 3]);\n * await post.pivot(\"tags\").sync([1, 3, 5]); // replace the whole set\n * await post.pivot(\"tags\").toggle([1, 7]); // flip each\n * ```\n */\n public pivot(relation: string): PivotOperations {\n return pivotRelation(this, relation);\n }\n\n /**\n * Get the class constructor from an instance.\n *\n * This helper method allows instance methods to access static properties\n * and methods of the model class in a type-safe way.\n *\n * @returns The model class constructor\n *\n * @example\n * ```typescript\n * const constructor = this.self();\n * const table = constructor.table;\n * await constructor.deleteOne({ id: 1 });\n * ```\n */\n public self<TModel extends Model = this>(): ChildModel<TModel> {\n return this.constructor as any as ChildModel<TModel>;\n }\n\n /**\n * Creates an immutable clone of the model with its current state.\n *\n * The cloned model:\n * - Contains a deep copy of all current data\n * - Has frozen (immutable) data that cannot be modified\n * - Preserves the `isNew` flag from the original\n * - Has no dirty changes (clean state)\n * - Cannot be saved or modified\n *\n * This is useful for:\n * - Creating snapshots of model state\n * - Passing read-only model data to other parts of the application\n * - Preventing accidental mutations\n * - Maintaining historical records\n *\n * @returns A new immutable model instance with the current state\n *\n * @example\n * ```typescript\n * const user = new User({ name: \"Alice\", email: \"alice@example.com\" });\n * await user.save();\n *\n * // Create an immutable snapshot\n * const snapshot = user.clone();\n *\n * // This will throw an error because the clone is immutable\n * snapshot.set(\"name\", \"Bob\"); // TypeError: Cannot assign to read only property\n *\n * // Original can still be modified\n * user.set(\"name\", \"Bob\");\n * await user.save();\n * ```\n */\n public clone(): this {\n return cloneModel(this);\n }\n\n /**\n * Recursively freezes an object and all its nested properties.\n *\n * @param obj - The object to freeze\n * @returns The frozen object\n */\n public deepFreeze<T>(obj: T): T {\n return deepFreezeObject(obj);\n }\n\n /**\n * Get table name\n */\n public getTableName(): string {\n return this.self().table;\n }\n\n /**\n * Get primary key name\n */\n public getPrimaryKey(): string {\n return this.self().primaryKey;\n }\n\n /**\n * Get model schema\n */\n public getSchema() {\n return this.self().schema;\n }\n\n /**\n * Check if schema has the given key\n */\n public schemaHas(key: string): boolean {\n return this.self().schema?.schema[key] !== undefined;\n }\n\n /**\n * Get strict mode\n */\n public getStrictMode(): StrictMode {\n return this.self().strictMode;\n }\n\n /**\n * Get data source (Connection)\n */\n public getConnection(): DataSource {\n return this.self().getDataSource();\n }\n\n /**\n * Delete all matching documents from the table.\n */\n public static async delete<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<number> {\n return deleteRecords(this, filter);\n }\n\n /**\n * Delete a single matching document from the table.\n */\n public static async deleteOne<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n ): Promise<number> {\n return deleteOneRecord(this, filter);\n }\n\n /**\n * Restore a single deleted record by its ID.\n *\n * Automatically detects whether the record was deleted via \"trash\" or \"soft\" strategy.\n * Handles ID conflicts based on options.\n *\n * @param id - The primary key value of the record to restore\n * @param options - Restorer options (onIdConflict, skipEvents)\n * @returns The restored model instance\n *\n * @throws {Error} If record not found in trash or soft-deleted records\n * @throws {Error} If ID conflict and onIdConflict is \"fail\"\n *\n * @example\n * ```typescript\n * // Restore with default options (assign new ID if conflict)\n * const user = await User.restore(123);\n *\n * // Restore and fail if ID conflict\n * const user = await User.restore(123, { onIdConflict: \"fail\" });\n *\n * // Silent restore (skip events)\n * const user = await User.restore(123, { skipEvents: true });\n * ```\n */\n public static async restore<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n id: string | number,\n options?: {\n onIdConflict?: \"fail\" | \"assignNew\";\n skipEvents?: boolean;\n },\n ): Promise<TModel> {\n return restoreRecord(this, id, options);\n }\n\n /**\n * Restore all deleted records for the model's table.\n *\n * Restores all records from the trash table (if using trash strategy)\n * or all soft-deleted records (if using soft strategy).\n *\n * @param options - Restorer options (onIdConflict, skipEvents)\n * @returns Array of restored model instances\n *\n * @example\n * ```typescript\n * // Restore all with default options\n * const users = await User.restoreAll();\n *\n * // Restore all and fail on any ID conflict\n * const users = await User.restoreAll({ onIdConflict: \"fail\" });\n * ```\n */\n public static async restoreAll<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n options?: {\n onIdConflict?: \"fail\" | \"assignNew\";\n skipEvents?: boolean;\n },\n ): Promise<TModel[]> {\n return restoreAllRecords(this, options);\n }\n\n /**\n * Create a new record in database and return the model instance.\n *\n * The data type is automatically inferred from the model's schema type.\n *\n * @param data - Partial data matching the model's schema type\n * @returns The created model instance\n *\n * @example\n * ```typescript\n * // TypeScript automatically infers UserSchema from User model\n * const user = await User.create({\n * name: \"Alice\",\n * email: \"alice@example.com\",\n * age: 30\n * });\n * // Type: User (with UserSchema inferred)\n * ```\n */\n public static async create<\n TModel extends Model = Model,\n TSchema extends ModelSchema = TModel extends Model<infer S> ? S : ModelSchema,\n >(this: ChildModel<TModel>, data: Partial<TSchema>): Promise<TModel> {\n return createRecord(this, data);\n }\n\n /**\n * Create many documents and return an array of created models\n */\n public static async createMany<\n TModel extends Model = Model,\n TSchema extends ModelSchema = TModel extends Model<infer S> ? S : ModelSchema,\n >(this: ChildModel<TModel>, data: Partial<TSchema>[]): Promise<TModel[]> {\n return createManyRecords(this, data);\n }\n\n /**\n * Find a record or create it if not found.\n *\n * Does NOT update existing records - returns them as-is.\n * Useful when you want to ensure a record exists without modifying it.\n *\n * @param filter - Conditions to find by\n * @param data - Data to create if not found (merged with filter)\n * @returns Promise resolving to found or created model\n *\n * @example\n * ```typescript\n * // Ensure default admin exists (don't modify if exists)\n * const admin = await User.findOrCreate(\n * { email: \"admin@example.com\" },\n * { email: \"admin@example.com\", name: \"Admin\", role: \"admin\" }\n * );\n * // If admin exists, returns existing (password unchanged)\n * // If not found, creates new admin\n * ```\n */\n public static async findOrCreate<\n TModel extends Model = Model,\n TSchema extends ModelSchema = TModel extends Model<infer S> ? S : ModelSchema,\n >(this: ChildModel<TModel>, filter: Partial<TSchema>, data: Partial<TSchema>): Promise<TModel> {\n return findOrCreateRecord(this, filter, data);\n }\n\n /**\n * Upsert (insert or update) a record atomically.\n *\n * Uses the driver's native upsert operation for atomic insert-or-update.\n * More efficient than updateOrCreate as it's a single database operation.\n *\n * Includes full Model features:\n * - ID generation (if creating)\n * - createdAt timestamp (if creating)\n * - updatedAt timestamp (always)\n * - Validation & casting\n * - Lifecycle events\n *\n * @param filter - Conditions to find by (used for conflict detection)\n * @param data - Data to update or create (merged with filter)\n * @param options - Upsert options (conflictColumns for PostgreSQL, etc.)\n * @returns Promise resolving to upserted model\n *\n * @example\n * ```typescript\n * // PostgreSQL: upsert on unique email\n * const user = await User.upsert(\n * { email: \"user@example.com\" },\n * {\n * email: \"user@example.com\",\n * name: \"John Updated\",\n * lastSyncedAt: new Date()\n * },\n * { conflictColumns: [\"email\"] }\n * );\n *\n * // MongoDB: upsert by filter\n * const user = await User.upsert(\n * { externalId: \"ext-123\" },\n * {\n * externalId: \"ext-123\",\n * name: \"John Updated\",\n * email: \"john.new@example.com\"\n * }\n * );\n * ```\n */\n public static async upsert<\n TModel extends Model = Model,\n TSchema extends ModelSchema = TModel extends Model<infer S> ? S : ModelSchema,\n >(\n this: ChildModel<TModel>,\n filter: Partial<TSchema>,\n data: Partial<TSchema>,\n options?: Record<string, unknown>,\n ): Promise<TModel> {\n return upsertRecord(this, filter, data, options);\n }\n\n /**\n * Update a record or create it if not found (upsert).\n *\n * @deprecated Use `upsert()` instead for better performance and atomicity.\n * This method is kept for backward compatibility but uses upsert internally.\n *\n * @param filter - Conditions to find by\n * @param data - Data to update or create (merged with filter)\n * @returns Promise resolving to updated or created model\n */\n public static async updateOrCreate<\n TModel extends Model = Model,\n TSchema extends ModelSchema = TModel extends Model<infer S> ? S : ModelSchema,\n >(\n this: ChildModel<TModel>,\n filter: Partial<TSchema>,\n data: Partial<TSchema>,\n options?: Record<string, unknown>,\n ): Promise<TModel> {\n // Use upsert internally for better performance\n return await (this as any).upsert(filter, data, options);\n }\n\n /**\n * Find one and delete a record that matches the filter and return the deleted record.\n *\n * @param filter - Filter conditions\n * @param options - Optional delete options\n * @returns The deleted model instance or null if not found\n *\n * @example\n * ```typescript\n * const deleted = await User.findOneAndDelete({ id: 1 });\n * if (deleted) {\n * console.log('Deleted user:', deleted.get('name'));\n * }\n * ```\n */\n public static async findOneAndDelete<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n filter: Record<string, unknown>,\n options?: Record<string, unknown>,\n ): Promise<TModel | null> {\n return findOneAndDeleteRecord(this, filter, options);\n }\n\n /**\n * Returns embedded data for sync operations.\n * Excludes internal MongoDB fields and ensures proper date serialization.\n *\n * @returns Embedded data object suitable for syncing\n *\n * @example\n * ```typescript\n * const user = await User.find(1);\n * const embedData = user.embedData;\n * // Returns: { id: 1, name: \"Alice\", email: \"alice@example.com\", ... }\n * // Excludes: _id\n * ```\n */\n public get embedData(): Record<string, unknown> {\n return this.self().embed ? this.only(this.self().embed as any) : this.data;\n }\n\n /**\n * Tear down framework-level registrations attached to this Model class.\n *\n * Called by Warlock's HMR machinery when a model file (or any file in its\n * dependency graph) is reloaded. Removes the event listeners and registry\n * entries the Model installed at module-load time so the reloaded class\n * does not double-register.\n *\n * The `$` prefix marks this as framework-internal — application code should\n * not call this. It is part of the public surface only because the HMR\n * system needs to invoke it from outside the Model class.\n *\n * @internal\n */\n public static $cleanup() {\n cleanupModelEvents(this);\n }\n\n /**\n * Accesses the event emitter dedicated to this model constructor.\n *\n * Each model subclass gets its own isolated event emitter, allowing you to\n * register lifecycle hooks that only apply to that specific model.\n *\n * @returns The ModelEvents instance for this model constructor\n *\n * @example\n * ```typescript\n * User.events().onSaving((user) => {\n * console.log(\"User is being saved:\", user);\n * });\n * ```\n */\n public static events<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n ): ModelEvents<TModel> {\n return getModelEvents<TModel>(this);\n }\n\n /**\n * Registers an event listener for this model constructor.\n *\n * Convenience shorthand for `Model.events().on(...)`.\n *\n * @param event - The event name (e.g., \"saving\", \"created\")\n * @param listener - The callback to invoke when the event fires\n * @returns An unsubscribe function\n *\n * @example\n * ```typescript\n * const unsubscribe = User.on(\"saving\", (user) => {\n * console.log(\"Saving user:\", user);\n * });\n * ```\n */\n public static on<TModel extends Model = Model, TContext = unknown>(\n this: ChildModel<TModel>,\n event: ModelEventName,\n listener: ModelEventListener<TModel, TContext>,\n ): () => void {\n return onStaticEvent<TModel, TContext>(this, event, listener);\n }\n\n /**\n * Registers a one-time event listener for this model constructor.\n *\n * The listener will automatically unsubscribe after its first invocation.\n * Convenience shorthand for `Model.events().once(...)`.\n *\n * @param event - The event name (e.g., \"saving\", \"created\")\n * @param listener - The callback to invoke when the event fires\n * @returns An unsubscribe function\n *\n * @example\n * ```typescript\n * User.once(\"created\", (user) => {\n * console.log(\"First user created:\", user);\n * });\n * ```\n */\n public static once<TModel extends Model = Model, TContext = unknown>(\n this: ChildModel<TModel>,\n event: ModelEventName,\n listener: ModelEventListener<TModel, TContext>,\n ): () => void {\n return onceStaticEvent<TModel, TContext>(this, event, listener);\n }\n\n /**\n * Removes an event listener from this model constructor.\n *\n * Convenience shorthand for `Model.events().off(...)`.\n *\n * @param event - The event name\n * @param listener - The callback to remove\n *\n * @example\n * ```typescript\n * const listener = (user) => console.log(user);\n * User.on(\"saving\", listener);\n * User.off(\"saving\", listener);\n * ```\n */\n public static off<TModel extends Model = Model, TContext = unknown>(\n this: ChildModel<TModel>,\n event: ModelEventName,\n listener: ModelEventListener<TModel, TContext>,\n ): void {\n offStaticEvent<TModel, TContext>(this, event, listener);\n }\n\n /**\n * Accesses the global event emitter shared by all model instances.\n *\n * Use this for cross-cutting concerns like auditing, logging, or injecting\n * common fields (e.g., `createdBy`, `updatedBy`) across all models.\n *\n * @returns The global ModelEvents instance\n *\n * @example\n * ```typescript\n * Model.globalEvents().onSaving((model) => {\n * model.set(\"updatedAt\", new Date());\n * });\n * ```\n */\n public static globalEvents(): ModelEvents<Model> {\n return getGlobalEvents();\n }\n\n /**\n * Replace the model's data entirely.\n *\n * Used internally by the writer after validation to update the model\n * with validated/casted data.\n *\n * **Warning:** This replaces all data and updates the dirty tracker.\n * Use with caution in application code.\n *\n * @param data - New data to replace current data\n *\n * @example\n * ```typescript\n * // Internal usage by writer\n * model.replaceData(validatedData);\n * ```\n */\n public replaceData(data: Record<string, unknown>): void {\n replaceModelData(this, data);\n }\n\n /**\n * Save the model to the database.\n *\n * Performs insert if `isNew === true`, otherwise performs update.\n * Automatically validates, casts, generates IDs, and emits lifecycle events.\n *\n * **Features:**\n * - Validation via @warlock.js/seal schema\n * - Data casting (string → number, etc.)\n * - ID generation (NoSQL only)\n * - Partial updates (only changed fields)\n * - Lifecycle events (validating, saving, created/updated, saved)\n *\n * @param data - Optional data to merge before saving\n * @param options - Save options\n * @returns The model instance for method chaining\n *\n * @throws {ValidationError} If validation fails\n * @throws {Error} If database operation fails\n *\n * @example\n * ```typescript\n * // Simple save\n * const user = new User({ name: \"Alice\" });\n * await user.save();\n *\n * // Merge data before saving\n * await user.save({ age: 31, email: \"alice@example.com\" });\n *\n * // Silent save (no events)\n * await user.save(null, { skipEvents: true });\n *\n * // Skip validation\n * await user.save(null, { skipValidation: true });\n *\n * // Method chaining\n * await user.set(\"name\", \"Bob\").save();\n * ```\n */\n public async save(options?: WriterOptions & { merge?: Partial<TSchema> }): Promise<this> {\n return saveModel(this as any, options) as Promise<this>;\n }\n\n /**\n * Serialize the model data for storage in the database.\n *\n * Uses the driver's `serialize` to apply driver-specific type transformations\n * (e.g. Date → ISO string, BigInt → string for Postgres).\n *\n * **Not** the same as `toSnapshot` — this is a DB write concern, not a cache concern.\n */\n public serialize() {\n return serializeModel(this);\n }\n\n /**\n * Produce a plain-object snapshot of this model suitable for cache storage.\n *\n * - `data`: The model's own fields, serialized via the driver (handles Dates, BigInt, ObjectId).\n * - `relations`: Each entry in `loadedRelations` recursively snapshotted via `toSnapshot`.\n * A relation that was loaded but resolved to `null` is stored as `null` (not omitted),\n * so that `fromSnapshot` can distinguish \"loaded + null\" from \"never loaded\".\n *\n * Use `Model.fromSnapshot(snapshot)` to reconstruct.\n *\n * @example\n * ```typescript\n * await cache.set(key, chat.toSnapshot());\n * ```\n */\n public toSnapshot(): ModelSnapshot {\n return modelToSnapshot(this);\n }\n\n /**\n * Reconstruct a model instance (with relations) from a cache snapshot.\n *\n * Counterpart to `toSnapshot`. Applies driver deserialization (e.g. ISO string → Date)\n * and recursively hydrates any nested relation snapshots via `RelationHydrator`.\n *\n * @example\n * ```typescript\n * const snapshot = await cache.get(key);\n * const chat = Chat.fromSnapshot(snapshot);\n * chat.unit; // Unit model instance, fully hydrated\n * ```\n */\n public static fromSnapshot<TModel extends Model>(\n this: ChildModel<TModel>,\n snapshot: ModelSnapshot,\n ): TModel {\n return modelFromSnapshot(this, snapshot);\n }\n\n /**\n * Create a model instance from raw data (no relations).\n *\n * This is the data-only hydration path, used by the query builder when\n * converting a raw DB row into a model instance. Relations are NOT restored\n * here — use `fromSnapshot` when restoring from a cache snapshot that\n * includes relation data.\n *\n * @example\n * ```typescript\n * // Query builder internals:\n * const user = User.hydrate(rawRow);\n * ```\n */\n public static hydrate<TModel extends Model = Model>(\n this: ChildModel<TModel>,\n data: Record<string, unknown>,\n ): TModel {\n return hydrateModel(this, data);\n }\n\n /**\n * Convert the model into JSON\n */\n public toJSON() {\n return modelToJSON(this);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Model } from "./model.mjs";
|
|
2
|
+
import { QueryBuilderContract } from "../contracts/query-builder.contract.mjs";
|
|
3
|
+
//#region ../../@warlock.js/cascade/src/model/model.types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Timing control for global scopes
|
|
6
|
+
*/
|
|
7
|
+
type ScopeTiming = "before" | "after";
|
|
8
|
+
/**
|
|
9
|
+
* Global scope definition with callback and timing
|
|
10
|
+
*/
|
|
11
|
+
type GlobalScopeDefinition = {
|
|
12
|
+
callback: (query: QueryBuilderContract) => void;
|
|
13
|
+
timing: ScopeTiming;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Local scope callback function
|
|
17
|
+
*/
|
|
18
|
+
type LocalScopeCallback = (query: QueryBuilderContract, ...args: any[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Options for adding global scopes
|
|
21
|
+
*/
|
|
22
|
+
type GlobalScopeOptions = {
|
|
23
|
+
timing?: ScopeTiming;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Generic schema type representing the structure of model data.
|
|
27
|
+
*/
|
|
28
|
+
type ModelSchema = Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* Represents the static side of a model subclass.
|
|
31
|
+
*
|
|
32
|
+
* Used for `this`-typed static methods so TypeScript can infer the concrete
|
|
33
|
+
* subclass and return the correct model type from static factory methods like
|
|
34
|
+
* `find()`, `create()`, `query()`, etc.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* public static async find<TModel extends Model>(
|
|
39
|
+
* this: ChildModel<TModel>,
|
|
40
|
+
* id: number,
|
|
41
|
+
* ): Promise<TModel | null>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
type ChildModel<TModel extends Model> = (new (...args: any[]) => TModel) & Pick<typeof Model, "table" | "primaryKey" | "dataSource" | "schema" | "strictMode" | "autoGenerateId" | "initialId" | "randomInitialId" | "incrementIdBy" | "resource" | "resourceColumns" | "toJsonColumns" | "randomIncrement" | "getDataSource" | "getDriver" | "query" | "find" | "first" | "last" | "all" | "latest" | "count" | "where" | "increase" | "decrease" | "atomic" | "events" | "on" | "once" | "off" | "globalEvents" | "delete" | "deleteOne" | "deleteStrategy" | "trashTable" | "restore" | "restoreAll" | "deletedAtColumn" | "createdAtColumn" | "updatedAtColumn" | "create" | "createMany" | "sync" | "embed" | "syncMany" | "addGlobalScope" | "removeGlobalScope" | "addScope" | "removeScope" | "localScopes" | "globalScopes" | "relations" | "newQueryBuilder" | "builder" | "findAndUpdate" | "findOneAndUpdate" | "hydrate" | "fromSnapshot" | "findAndReplace" | "findOneAndDelete" | "findOrCreate">;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ChildModel, GlobalScopeDefinition, GlobalScopeOptions, LocalScopeCallback, ModelSchema, ScopeTiming };
|
|
47
|
+
//# sourceMappingURL=model.types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.types.d.mts","names":[],"sources":["../../../../../../@warlock.js/cascade/src/model/model.types.ts"],"mappings":";;;;;;KAMY,WAAA;;;;KAKA,qBAAA;EACV,QAAA,GAAW,KAAA,EAAO,oBAAA;EAClB,MAAA,EAAQ,WAAW;AAAA;;;;KAMT,kBAAA,IAAsB,KAAA,EAAO,oBAAoB,KAAK,IAAA;;;;KAKtD,kBAAA;EACV,MAAA,GAAS,WAAW;AAAA;;;;KAMV,WAAA,GAAc,MAAM;;;AAZsC;AAKtE;;;;AACsB;AAMtB;;;;AAAgC;AAiBhC;;KAAY,UAAA,gBAA0B,KAAA,aAAkB,IAAA,YAAgB,MAAA,IACtE,IAAA,QACS,KAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { ChildModel, ModelSchema } from "./model.types.mjs";
|
|
2
|
+
import { Model } from "./model.mjs";
|
|
3
|
+
import { Lazy } from "@mongez/reinforcements";
|
|
4
|
+
|
|
5
|
+
//#region ../../@warlock.js/cascade/src/model/register-model.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Any way a relation target can be expressed: a string name registered
|
|
8
|
+
* via `@RegisterModel()`, a direct class reference, or a `lazy(() => X)`
|
|
9
|
+
* deferred class reference (for cycle-prone pairs).
|
|
10
|
+
*
|
|
11
|
+
* The lazy variant is typed as `Lazy<unknown>` (not `Lazy<ChildModel<Model>>`)
|
|
12
|
+
* because `RelationDefinition.model` storage uses the same broader shape —
|
|
13
|
+
* keeping the parameter type aligned avoids forcing every call site to
|
|
14
|
+
* narrow before invoking the resolver. The helpers cast the resolved
|
|
15
|
+
* class to `ChildModel<Model>` internally; the user's `lazy(() => X)`
|
|
16
|
+
* call already guarantees the shape at the source.
|
|
17
|
+
*/
|
|
18
|
+
type ModelRef = ChildModel<Model> | string | Lazy<unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* Options for the RegisterModel decorator
|
|
21
|
+
*/
|
|
22
|
+
type RegisterModelOptions = {
|
|
23
|
+
/**
|
|
24
|
+
* Custom name for the model in the global registry.
|
|
25
|
+
* If not provided, uses the class name.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* @RegisterModel({ name: "CustomUser" })
|
|
30
|
+
* export class User extends Model {}
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
name?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Class decorator that registers a model in the global registry.
|
|
37
|
+
*
|
|
38
|
+
* This is an opt-in mechanism that allows models to be referenced by string name
|
|
39
|
+
* instead of direct class imports, helping avoid circular dependencies.
|
|
40
|
+
*
|
|
41
|
+
* Uses the **TC39 Stage 3 decorator** signature (standard since TypeScript 5.0).
|
|
42
|
+
* Requires `experimentalDecorators: false` (or unset) in `tsconfig.json`.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Optional configuration for registration
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // Auto-capture class name
|
|
49
|
+
* @RegisterModel()
|
|
50
|
+
* export class User extends Model {
|
|
51
|
+
* static table = "users";
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* // Custom name
|
|
55
|
+
* @RegisterModel({ name: "UserModel" })
|
|
56
|
+
* export class User extends Model {
|
|
57
|
+
* static table = "users";
|
|
58
|
+
* }
|
|
59
|
+
*
|
|
60
|
+
* // Later, retrieve by name:
|
|
61
|
+
* const UserModel = getModelFromRegistry("User");
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
declare function RegisterModel(options?: RegisterModelOptions): <T extends ChildModel<Model>>(value: T, context: ClassDecoratorContext<T>) => T;
|
|
65
|
+
declare function registerModelInRegistry(name: string, model: ChildModel<Model>): void;
|
|
66
|
+
/**
|
|
67
|
+
* Get a model class by its name from the global registry.
|
|
68
|
+
*
|
|
69
|
+
* @param name - The model class name
|
|
70
|
+
* @returns The model class or undefined if not found
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const UserModel = getModelFromRegistry("User");
|
|
75
|
+
* if (UserModel) {
|
|
76
|
+
* const user = await UserModel.find(1);
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function getModelFromRegistry(name: string): ChildModel<Model<ModelSchema>> | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Get all registered models from the global registry.
|
|
83
|
+
*
|
|
84
|
+
* @returns A Map of all registered model classes by name
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const allModels = getAllModelsFromRegistry();
|
|
89
|
+
* for (const [name, ModelClass] of allModels) {
|
|
90
|
+
* console.log(`Found model: ${name}`);
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function getAllModelsFromRegistry(): Map<string, ChildModel<Model<ModelSchema>>>;
|
|
95
|
+
/**
|
|
96
|
+
* Clean up all models from register
|
|
97
|
+
*/
|
|
98
|
+
declare function cleanupModelsRegistery(): void;
|
|
99
|
+
declare function removeModelFromRegistery(name: string): void;
|
|
100
|
+
declare function resolveModelClass(model: ModelRef): ChildModel<Model>;
|
|
101
|
+
/**
|
|
102
|
+
* Like `resolveModelClass`, but returns `undefined` instead of asserting
|
|
103
|
+
* a non-null result when a string ref isn't in the registry. Use this
|
|
104
|
+
* at call sites that already handle the missing-model case explicitly
|
|
105
|
+
* (e.g. join builders that throw their own contextual error).
|
|
106
|
+
*/
|
|
107
|
+
declare function tryResolveModelClass(model: ModelRef | undefined): ChildModel<Model> | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Read the model's registered name from any `ModelRef`. Used by
|
|
110
|
+
* convention helpers (`inferPivotTable`, `inferPivotKey`) that derive
|
|
111
|
+
* table / column names from the related model's class name.
|
|
112
|
+
*
|
|
113
|
+
* For string refs the value passes through. For class and lazy refs
|
|
114
|
+
* the class's `.name` is returned — same string the registry would
|
|
115
|
+
* key the class under, so conventions stay consistent across ref shapes.
|
|
116
|
+
*/
|
|
117
|
+
declare function resolveModelName(model: ModelRef): string;
|
|
118
|
+
/**
|
|
119
|
+
* Walk every registered model and verify that every relation declared on it
|
|
120
|
+
* points at another registered model. Throws fast at boot with a clear error
|
|
121
|
+
* naming the unresolved target — much better signal than the runtime
|
|
122
|
+
* "Model not found" thrown deep inside a query.
|
|
123
|
+
*
|
|
124
|
+
* Call this once during app bootstrap, after every `@RegisterModel`-decorated
|
|
125
|
+
* model module has been imported.
|
|
126
|
+
*
|
|
127
|
+
* @returns The number of relations verified (success case)
|
|
128
|
+
* @throws Error listing every unresolved relation target if any are missing
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* // Inside your app bootstrap, after model imports:
|
|
133
|
+
* import { verifyRegisteredRelations } from "@warlock.js/cascade";
|
|
134
|
+
* verifyRegisteredRelations();
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
declare function verifyRegisteredRelations(): number;
|
|
138
|
+
//#endregion
|
|
139
|
+
export { ModelRef, RegisterModel, RegisterModelOptions, cleanupModelsRegistery, getAllModelsFromRegistry, getModelFromRegistry, registerModelInRegistry, removeModelFromRegistery, resolveModelClass, resolveModelName, tryResolveModelClass, verifyRegisteredRelations };
|
|
140
|
+
//# sourceMappingURL=register-model.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-model.d.mts","names":[],"sources":["../../../../../../@warlock.js/cascade/src/model/register-model.ts"],"mappings":";;;;;;;;AAiBA;;;;;;;;;KAAY,QAAA,GAAW,UAAA,CAAW,KAAA,aAAkB,IAAA;;;AAAI;KAK5C,oBAAA;EAAoB;;;AAW1B;AAsCN;;;;;;EAtCE,IAAI;AAAA;;;;;;;;;;;;;;;;;AAuCyF;AAiD/F;;;;;;;;;AAA8E;AAkB9E;;iBApEgB,aAAA,CAAc,OAAA,GAAU,oBAAA,cACX,UAAA,CAAW,KAAA,GAAQ,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,qBAAA,CAAsB,CAAA,MAAK,CAAA;AAAA,iBAiD9E,uBAAA,CAAwB,IAAA,UAAc,KAAA,EAAO,UAAU,CAAC,KAAA;;;;;;;;;;AAkBvB;AAiBjD;;;;iBAjBgB,oBAAA,CAAqB,IAAA,WAAY,UAAA,CAAA,KAAA,CAAb,WAAA;;;;;;;;;;AAiBI;AAOxC;;;iBAPgB,wBAAA,CAAA,GAAwB,GAAA,SAAA,UAAA,CAAA,KAAA,CAAA,WAAA;AAOF;AAItC;;AAJsC,iBAAtB,sBAAA,CAAA;AAAA,iBAIA,wBAAA,CAAyB,IAAY;AAAA,iBAIrC,iBAAA,CAAkB,KAAA,EAAO,QAAA,GAAW,UAAA,CAAW,KAAA;AAA/D;;;;;;AAAA,iBAagB,oBAAA,CACd,KAAA,EAAO,QAAA,eACN,UAAA,CAAW,KAAA;;;;;;;AAfsD;AAapE;;iBAmBgB,gBAAA,CAAiB,KAAe,EAAR,QAAQ;;;;;;;;;;;AAjB7B;AAiBnB;;;;AAAgD;AA0BhD;;;iBAAgB,yBAAA,CAAA"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { RELATION_METADATA_KEY } from "./relation-decorators.mjs";
|
|
2
|
+
import { isLazy } from "@mongez/reinforcements";
|
|
3
|
+
|
|
4
|
+
//#region ../../@warlock.js/cascade/src/model/register-model.ts
|
|
5
|
+
/**
|
|
6
|
+
* Global model registry that maps model class names to their constructors.
|
|
7
|
+
* This allows for string-based model references to avoid circular dependencies.
|
|
8
|
+
*/
|
|
9
|
+
const modelsRegistry = /* @__PURE__ */ new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Class decorator that registers a model in the global registry.
|
|
12
|
+
*
|
|
13
|
+
* This is an opt-in mechanism that allows models to be referenced by string name
|
|
14
|
+
* instead of direct class imports, helping avoid circular dependencies.
|
|
15
|
+
*
|
|
16
|
+
* Uses the **TC39 Stage 3 decorator** signature (standard since TypeScript 5.0).
|
|
17
|
+
* Requires `experimentalDecorators: false` (or unset) in `tsconfig.json`.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Optional configuration for registration
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Auto-capture class name
|
|
24
|
+
* @RegisterModel()
|
|
25
|
+
* export class User extends Model {
|
|
26
|
+
* static table = "users";
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* // Custom name
|
|
30
|
+
* @RegisterModel({ name: "UserModel" })
|
|
31
|
+
* export class User extends Model {
|
|
32
|
+
* static table = "users";
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* // Later, retrieve by name:
|
|
36
|
+
* const UserModel = getModelFromRegistry("User");
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function RegisterModel(options) {
|
|
40
|
+
return function(value, context) {
|
|
41
|
+
if (context.kind !== "class") throw new Error(`@RegisterModel can only be applied to classes — got "${context.kind}".`);
|
|
42
|
+
const modelName = options?.name || (context.name ?? value.name);
|
|
43
|
+
if (!modelName) throw new Error("@RegisterModel decorator: Unable to determine model name. Please provide a name in options or ensure your class has a name.");
|
|
44
|
+
if (modelsRegistry.has(modelName)) console.warn(`⚠️ Model "${modelName}" is already registered. This will overwrite the previous registration.`);
|
|
45
|
+
const decoratorRelations = context.metadata?.[RELATION_METADATA_KEY];
|
|
46
|
+
if (decoratorRelations && Object.keys(decoratorRelations).length > 0) value.relations = {
|
|
47
|
+
...Object.prototype.hasOwnProperty.call(value, "relations") ? value.relations : { ...value.relations ?? {} },
|
|
48
|
+
...decoratorRelations
|
|
49
|
+
};
|
|
50
|
+
modelsRegistry.set(modelName, value);
|
|
51
|
+
return value;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function registerModelInRegistry(name, model) {
|
|
55
|
+
modelsRegistry.set(name, model);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get a model class by its name from the global registry.
|
|
59
|
+
*
|
|
60
|
+
* @param name - The model class name
|
|
61
|
+
* @returns The model class or undefined if not found
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const UserModel = getModelFromRegistry("User");
|
|
66
|
+
* if (UserModel) {
|
|
67
|
+
* const user = await UserModel.find(1);
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function getModelFromRegistry(name) {
|
|
72
|
+
return modelsRegistry.get(name);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all registered models from the global registry.
|
|
76
|
+
*
|
|
77
|
+
* @returns A Map of all registered model classes by name
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const allModels = getAllModelsFromRegistry();
|
|
82
|
+
* for (const [name, ModelClass] of allModels) {
|
|
83
|
+
* console.log(`Found model: ${name}`);
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
function getAllModelsFromRegistry() {
|
|
88
|
+
return new Map(modelsRegistry);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Clean up all models from register
|
|
92
|
+
*/
|
|
93
|
+
function cleanupModelsRegistery() {
|
|
94
|
+
modelsRegistry.clear();
|
|
95
|
+
}
|
|
96
|
+
function removeModelFromRegistery(name) {
|
|
97
|
+
modelsRegistry.delete(name);
|
|
98
|
+
}
|
|
99
|
+
function resolveModelClass(model) {
|
|
100
|
+
if (typeof model === "string") return getModelFromRegistry(model);
|
|
101
|
+
if (isLazy(model)) return model.resolve();
|
|
102
|
+
return model;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Like `resolveModelClass`, but returns `undefined` instead of asserting
|
|
106
|
+
* a non-null result when a string ref isn't in the registry. Use this
|
|
107
|
+
* at call sites that already handle the missing-model case explicitly
|
|
108
|
+
* (e.g. join builders that throw their own contextual error).
|
|
109
|
+
*/
|
|
110
|
+
function tryResolveModelClass(model) {
|
|
111
|
+
if (model === void 0) return void 0;
|
|
112
|
+
if (typeof model === "string") return getModelFromRegistry(model);
|
|
113
|
+
if (isLazy(model)) return model.resolve();
|
|
114
|
+
return model;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Read the model's registered name from any `ModelRef`. Used by
|
|
118
|
+
* convention helpers (`inferPivotTable`, `inferPivotKey`) that derive
|
|
119
|
+
* table / column names from the related model's class name.
|
|
120
|
+
*
|
|
121
|
+
* For string refs the value passes through. For class and lazy refs
|
|
122
|
+
* the class's `.name` is returned — same string the registry would
|
|
123
|
+
* key the class under, so conventions stay consistent across ref shapes.
|
|
124
|
+
*/
|
|
125
|
+
function resolveModelName(model) {
|
|
126
|
+
if (typeof model === "string") return model;
|
|
127
|
+
if (isLazy(model)) return model.resolve().name;
|
|
128
|
+
return model.name;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Walk every registered model and verify that every relation declared on it
|
|
132
|
+
* points at another registered model. Throws fast at boot with a clear error
|
|
133
|
+
* naming the unresolved target — much better signal than the runtime
|
|
134
|
+
* "Model not found" thrown deep inside a query.
|
|
135
|
+
*
|
|
136
|
+
* Call this once during app bootstrap, after every `@RegisterModel`-decorated
|
|
137
|
+
* model module has been imported.
|
|
138
|
+
*
|
|
139
|
+
* @returns The number of relations verified (success case)
|
|
140
|
+
* @throws Error listing every unresolved relation target if any are missing
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* // Inside your app bootstrap, after model imports:
|
|
145
|
+
* import { verifyRegisteredRelations } from "@warlock.js/cascade";
|
|
146
|
+
* verifyRegisteredRelations();
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
function verifyRegisteredRelations() {
|
|
150
|
+
const failures = [];
|
|
151
|
+
let verifiedCount = 0;
|
|
152
|
+
for (const [callerName, ModelClass] of modelsRegistry) {
|
|
153
|
+
const relations = ModelClass.relations;
|
|
154
|
+
if (!relations) continue;
|
|
155
|
+
for (const [relationName, definition] of Object.entries(relations)) {
|
|
156
|
+
verifiedCount++;
|
|
157
|
+
const targetName = definition.model;
|
|
158
|
+
if (typeof targetName !== "string") continue;
|
|
159
|
+
if (!modelsRegistry.has(targetName)) failures.push({
|
|
160
|
+
caller: callerName,
|
|
161
|
+
relation: relationName,
|
|
162
|
+
target: targetName
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (failures.length > 0) {
|
|
167
|
+
const list = failures.map((f) => ` - ${f.caller}.${f.relation} → "${f.target}" is not registered`).join("\n");
|
|
168
|
+
throw new Error(`verifyRegisteredRelations: ${failures.length} unresolved relation target(s):\n${list}\nEach target must be decorated with @RegisterModel() and imported before bootstrap.`);
|
|
169
|
+
}
|
|
170
|
+
return verifiedCount;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
export { RegisterModel, cleanupModelsRegistery, getAllModelsFromRegistry, getModelFromRegistry, registerModelInRegistry, removeModelFromRegistery, resolveModelClass, resolveModelName, tryResolveModelClass, verifyRegisteredRelations };
|
|
175
|
+
//# sourceMappingURL=register-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-model.mjs","names":[],"sources":["../../../../../../@warlock.js/cascade/src/model/register-model.ts"],"sourcesContent":["import { isLazy, type Lazy } from \"@mongez/reinforcements\";\nimport type { RelationDefinition } from \"../relations/types\";\nimport type { ChildModel, Model } from \"./model\";\nimport { RELATION_METADATA_KEY } from \"./relation-decorators\";\n\n/**\n * Any way a relation target can be expressed: a string name registered\n * via `@RegisterModel()`, a direct class reference, or a `lazy(() => X)`\n * deferred class reference (for cycle-prone pairs).\n *\n * The lazy variant is typed as `Lazy<unknown>` (not `Lazy<ChildModel<Model>>`)\n * because `RelationDefinition.model` storage uses the same broader shape —\n * keeping the parameter type aligned avoids forcing every call site to\n * narrow before invoking the resolver. The helpers cast the resolved\n * class to `ChildModel<Model>` internally; the user's `lazy(() => X)`\n * call already guarantees the shape at the source.\n */\nexport type ModelRef = ChildModel<Model> | string | Lazy<unknown>;\n\n/**\n * Options for the RegisterModel decorator\n */\nexport type RegisterModelOptions = {\n /**\n * Custom name for the model in the global registry.\n * If not provided, uses the class name.\n *\n * @example\n * ```typescript\n * @RegisterModel({ name: \"CustomUser\" })\n * export class User extends Model {}\n * ```\n */\n name?: string;\n};\n\n/**\n * Global model registry that maps model class names to their constructors.\n * This allows for string-based model references to avoid circular dependencies.\n */\nconst modelsRegistry = new Map<string, ChildModel<Model>>();\n\n/**\n * Class decorator that registers a model in the global registry.\n *\n * This is an opt-in mechanism that allows models to be referenced by string name\n * instead of direct class imports, helping avoid circular dependencies.\n *\n * Uses the **TC39 Stage 3 decorator** signature (standard since TypeScript 5.0).\n * Requires `experimentalDecorators: false` (or unset) in `tsconfig.json`.\n *\n * @param options - Optional configuration for registration\n *\n * @example\n * ```typescript\n * // Auto-capture class name\n * @RegisterModel()\n * export class User extends Model {\n * static table = \"users\";\n * }\n *\n * // Custom name\n * @RegisterModel({ name: \"UserModel\" })\n * export class User extends Model {\n * static table = \"users\";\n * }\n *\n * // Later, retrieve by name:\n * const UserModel = getModelFromRegistry(\"User\");\n * ```\n */\nexport function RegisterModel(options?: RegisterModelOptions) {\n return function <T extends ChildModel<Model>>(value: T, context: ClassDecoratorContext<T>): T {\n if (context.kind !== \"class\") {\n throw new Error(`@RegisterModel can only be applied to classes — got \"${context.kind}\".`);\n }\n\n const modelName = options?.name || (context.name ?? value.name);\n\n if (!modelName) {\n throw new Error(\n \"@RegisterModel decorator: Unable to determine model name. \" +\n \"Please provide a name in options or ensure your class has a name.\",\n );\n }\n\n if (modelsRegistry.has(modelName)) {\n console.warn(\n `⚠️ Model \"${modelName}\" is already registered. ` +\n `This will overwrite the previous registration.`,\n );\n }\n\n // Hoist relation definitions stashed by `@BelongsTo` / `@HasMany` /\n // etc. on this class's decorator-metadata bag onto the class's static\n // `relations` map. Field-decorator initializers are instance-level in\n // TC39 stage 3 — they never fire for class-level operations like\n // `Model.withCount(\"rel\")`. Reading via shared `context.metadata` is\n // the right hand-off point because all field decorators have already\n // run by the time the class decorator executes.\n const decoratorRelations = context.metadata?.[RELATION_METADATA_KEY] as\n | Record<string, RelationDefinition>\n | undefined;\n\n if (decoratorRelations && Object.keys(decoratorRelations).length > 0) {\n const ownRelations = Object.prototype.hasOwnProperty.call(value, \"relations\")\n ? (value as unknown as { relations: Record<string, RelationDefinition> }).relations\n : { ...((value as unknown as { relations?: Record<string, RelationDefinition> }).relations ?? {}) };\n\n (value as unknown as { relations: Record<string, RelationDefinition> }).relations = {\n ...ownRelations,\n ...decoratorRelations,\n };\n }\n\n modelsRegistry.set(modelName, value);\n\n return value;\n };\n}\n\nexport function registerModelInRegistry(name: string, model: ChildModel<Model>) {\n modelsRegistry.set(name, model);\n}\n\n/**\n * Get a model class by its name from the global registry.\n *\n * @param name - The model class name\n * @returns The model class or undefined if not found\n *\n * @example\n * ```typescript\n * const UserModel = getModelFromRegistry(\"User\");\n * if (UserModel) {\n * const user = await UserModel.find(1);\n * }\n * ```\n */\nexport function getModelFromRegistry(name: string) {\n return modelsRegistry.get(name);\n}\n\n/**\n * Get all registered models from the global registry.\n *\n * @returns A Map of all registered model classes by name\n *\n * @example\n * ```typescript\n * const allModels = getAllModelsFromRegistry();\n * for (const [name, ModelClass] of allModels) {\n * console.log(`Found model: ${name}`);\n * }\n * ```\n */\nexport function getAllModelsFromRegistry() {\n return new Map(modelsRegistry);\n}\n\n/**\n * Clean up all models from register\n */\nexport function cleanupModelsRegistery() {\n modelsRegistry.clear();\n}\n\nexport function removeModelFromRegistery(name: string) {\n modelsRegistry.delete(name);\n}\n\nexport function resolveModelClass(model: ModelRef): ChildModel<Model> {\n if (typeof model === \"string\") return getModelFromRegistry(model)!;\n if (isLazy(model)) return model.resolve() as ChildModel<Model>;\n\n return model;\n}\n\n/**\n * Like `resolveModelClass`, but returns `undefined` instead of asserting\n * a non-null result when a string ref isn't in the registry. Use this\n * at call sites that already handle the missing-model case explicitly\n * (e.g. join builders that throw their own contextual error).\n */\nexport function tryResolveModelClass(\n model: ModelRef | undefined,\n): ChildModel<Model> | undefined {\n if (model === undefined) return undefined;\n if (typeof model === \"string\") return getModelFromRegistry(model);\n if (isLazy(model)) return model.resolve() as ChildModel<Model>;\n\n return model;\n}\n\n/**\n * Read the model's registered name from any `ModelRef`. Used by\n * convention helpers (`inferPivotTable`, `inferPivotKey`) that derive\n * table / column names from the related model's class name.\n *\n * For string refs the value passes through. For class and lazy refs\n * the class's `.name` is returned — same string the registry would\n * key the class under, so conventions stay consistent across ref shapes.\n */\nexport function resolveModelName(model: ModelRef): string {\n if (typeof model === \"string\") return model;\n if (isLazy(model)) return (model.resolve() as ChildModel<Model>).name;\n\n return model.name;\n}\n\n/**\n * Walk every registered model and verify that every relation declared on it\n * points at another registered model. Throws fast at boot with a clear error\n * naming the unresolved target — much better signal than the runtime\n * \"Model not found\" thrown deep inside a query.\n *\n * Call this once during app bootstrap, after every `@RegisterModel`-decorated\n * model module has been imported.\n *\n * @returns The number of relations verified (success case)\n * @throws Error listing every unresolved relation target if any are missing\n *\n * @example\n * ```typescript\n * // Inside your app bootstrap, after model imports:\n * import { verifyRegisteredRelations } from \"@warlock.js/cascade\";\n * verifyRegisteredRelations();\n * ```\n */\nexport function verifyRegisteredRelations(): number {\n type RelationDef = { type: string; model: string };\n const failures: Array<{ caller: string; relation: string; target: string }> = [];\n\n let verifiedCount = 0;\n\n for (const [callerName, ModelClass] of modelsRegistry) {\n const relations = (ModelClass as { relations?: Record<string, RelationDef> }).relations;\n\n if (!relations) {\n continue;\n }\n\n for (const [relationName, definition] of Object.entries(relations)) {\n verifiedCount++;\n const targetName = definition.model;\n\n if (typeof targetName !== \"string\") {\n // Direct class reference or `lazy(() => X)` — class binding is\n // captured by the decorator at definition time; can't drift.\n continue;\n }\n\n if (!modelsRegistry.has(targetName)) {\n failures.push({ caller: callerName, relation: relationName, target: targetName });\n }\n }\n }\n\n if (failures.length > 0) {\n const list = failures\n .map((f) => ` - ${f.caller}.${f.relation} → \"${f.target}\" is not registered`)\n .join(\"\\n\");\n throw new Error(\n `verifyRegisteredRelations: ${failures.length} unresolved relation target(s):\\n${list}\\n` +\n `Each target must be decorated with @RegisterModel() and imported before bootstrap.`,\n );\n }\n\n return verifiedCount;\n}\n"],"mappings":";;;;;;;;AAwCA,MAAM,iCAAiB,IAAI,IAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+B1D,SAAgB,cAAc,SAAgC;CAC5D,OAAO,SAAuC,OAAU,SAAsC;EAC5F,IAAI,QAAQ,SAAS,SACnB,MAAM,IAAI,MAAM,wDAAwD,QAAQ,KAAK,GAAG;EAG1F,MAAM,YAAY,SAAS,SAAS,QAAQ,QAAQ,MAAM;EAE1D,IAAI,CAAC,WACH,MAAM,IAAI,MACR,6HAEF;EAGF,IAAI,eAAe,IAAI,SAAS,GAC9B,QAAQ,KACN,cAAc,UAAU,wEAE1B;EAUF,MAAM,qBAAqB,QAAQ,WAAW;EAI9C,IAAI,sBAAsB,OAAO,KAAK,kBAAkB,EAAE,SAAS,GAKjE,AAAC,MAAuE,YAAY;GAClF,GALmB,OAAO,UAAU,eAAe,KAAK,OAAO,WAAW,IACvE,MAAuE,YACxE,EAAE,GAAK,MAAwE,aAAa,CAAC,EAAG;GAIlG,GAAG;EACL;EAGF,eAAe,IAAI,WAAW,KAAK;EAEnC,OAAO;CACT;AACF;AAEA,SAAgB,wBAAwB,MAAc,OAA0B;CAC9E,eAAe,IAAI,MAAM,KAAK;AAChC;;;;;;;;;;;;;;;AAgBA,SAAgB,qBAAqB,MAAc;CACjD,OAAO,eAAe,IAAI,IAAI;AAChC;;;;;;;;;;;;;;AAeA,SAAgB,2BAA2B;CACzC,OAAO,IAAI,IAAI,cAAc;AAC/B;;;;AAKA,SAAgB,yBAAyB;CACvC,eAAe,MAAM;AACvB;AAEA,SAAgB,yBAAyB,MAAc;CACrD,eAAe,OAAO,IAAI;AAC5B;AAEA,SAAgB,kBAAkB,OAAoC;CACpE,IAAI,OAAO,UAAU,UAAU,OAAO,qBAAqB,KAAK;CAChE,IAAI,OAAO,KAAK,GAAG,OAAO,MAAM,QAAQ;CAExC,OAAO;AACT;;;;;;;AAQA,SAAgB,qBACd,OAC+B;CAC/B,IAAI,UAAU,QAAW,OAAO;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO,qBAAqB,KAAK;CAChE,IAAI,OAAO,KAAK,GAAG,OAAO,MAAM,QAAQ;CAExC,OAAO;AACT;;;;;;;;;;AAWA,SAAgB,iBAAiB,OAAyB;CACxD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,KAAK,GAAG,OAAQ,MAAM,QAAQ,EAAwB;CAEjE,OAAO,MAAM;AACf;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,4BAAoC;CAElD,MAAM,WAAwE,CAAC;CAE/E,IAAI,gBAAgB;CAEpB,KAAK,MAAM,CAAC,YAAY,eAAe,gBAAgB;EACrD,MAAM,YAAa,WAA2D;EAE9E,IAAI,CAAC,WACH;EAGF,KAAK,MAAM,CAAC,cAAc,eAAe,OAAO,QAAQ,SAAS,GAAG;GAClE;GACA,MAAM,aAAa,WAAW;GAE9B,IAAI,OAAO,eAAe,UAGxB;GAGF,IAAI,CAAC,eAAe,IAAI,UAAU,GAChC,SAAS,KAAK;IAAE,QAAQ;IAAY,UAAU;IAAc,QAAQ;GAAW,CAAC;EAEpF;CACF;CAEA,IAAI,SAAS,SAAS,GAAG;EACvB,MAAM,OAAO,SACV,KAAK,MAAM,OAAO,EAAE,OAAO,GAAG,EAAE,SAAS,MAAM,EAAE,OAAO,oBAAoB,EAC5E,KAAK,IAAI;EACZ,MAAM,IAAI,MACR,8BAA8B,SAAS,OAAO,mCAAmC,KAAK,qFAExF;CACF;CAEA,OAAO;AACT"}
|