@warlock.js/cascade 4.0.162 → 4.0.164
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/cjs/context/database-data-source-context.d.ts +29 -0
- package/cjs/context/database-data-source-context.d.ts.map +1 -0
- package/cjs/context/database-data-source-context.js +28 -0
- package/cjs/context/database-data-source-context.js.map +1 -0
- package/cjs/context/database-transaction-context.d.ts +35 -0
- package/cjs/context/database-transaction-context.d.ts.map +1 -0
- package/cjs/context/database-transaction-context.js +40 -0
- package/cjs/context/database-transaction-context.js.map +1 -0
- package/cjs/contracts/database-driver.contract.d.ts +450 -0
- package/cjs/contracts/database-driver.contract.d.ts.map +1 -0
- package/cjs/contracts/database-id-generator.contract.d.ts +109 -0
- package/cjs/contracts/database-id-generator.contract.d.ts.map +1 -0
- package/cjs/contracts/database-remover.contract.d.ts +104 -0
- package/cjs/contracts/database-remover.contract.d.ts.map +1 -0
- package/cjs/contracts/database-restorer.contract.d.ts +143 -0
- package/cjs/contracts/database-restorer.contract.d.ts.map +1 -0
- package/cjs/contracts/database-writer.contract.d.ts +119 -0
- package/cjs/contracts/database-writer.contract.d.ts.map +1 -0
- package/cjs/contracts/driver-blueprint.contract.d.ts +49 -0
- package/cjs/contracts/driver-blueprint.contract.d.ts.map +1 -0
- package/cjs/contracts/index.d.ts +10 -0
- package/cjs/contracts/index.d.ts.map +1 -0
- package/cjs/contracts/migration-driver.contract.d.ts +522 -0
- package/cjs/contracts/migration-driver.contract.d.ts.map +1 -0
- package/cjs/contracts/query-builder.contract.d.ts +1609 -0
- package/cjs/contracts/query-builder.contract.d.ts.map +1 -0
- package/cjs/contracts/sync-adapter.contract.d.ts +58 -0
- package/cjs/contracts/sync-adapter.contract.d.ts.map +1 -0
- package/cjs/data-source/data-source-registry.d.ts +108 -0
- package/cjs/data-source/data-source-registry.d.ts.map +1 -0
- package/cjs/data-source/data-source-registry.js +145 -0
- package/cjs/data-source/data-source-registry.js.map +1 -0
- package/cjs/data-source/data-source.d.ts +147 -0
- package/cjs/data-source/data-source.d.ts.map +1 -0
- package/cjs/data-source/data-source.js +83 -0
- package/cjs/data-source/data-source.js.map +1 -0
- package/cjs/database-dirty-tracker.d.ts +252 -0
- package/cjs/database-dirty-tracker.d.ts.map +1 -0
- package/cjs/database-dirty-tracker.js +386 -0
- package/cjs/database-dirty-tracker.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-blueprint.d.ts +30 -0
- package/cjs/drivers/mongodb/mongodb-blueprint.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-blueprint.js +51 -0
- package/cjs/drivers/mongodb/mongodb-blueprint.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-driver.d.ts +325 -0
- package/cjs/drivers/mongodb/mongodb-driver.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-driver.js +838 -0
- package/cjs/drivers/mongodb/mongodb-driver.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-id-generator.d.ts +116 -0
- package/cjs/drivers/mongodb/mongodb-id-generator.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-id-generator.js +149 -0
- package/cjs/drivers/mongodb/mongodb-id-generator.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-migration-driver.d.ts +317 -0
- package/cjs/drivers/mongodb/mongodb-migration-driver.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-migration-driver.js +666 -0
- package/cjs/drivers/mongodb/mongodb-migration-driver.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-builder.d.ts +1122 -0
- package/cjs/drivers/mongodb/mongodb-query-builder.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-builder.js +1988 -0
- package/cjs/drivers/mongodb/mongodb-query-builder.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-operations.d.ts +226 -0
- package/cjs/drivers/mongodb/mongodb-query-operations.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-operations.js +270 -0
- package/cjs/drivers/mongodb/mongodb-query-operations.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-parser.d.ts +262 -0
- package/cjs/drivers/mongodb/mongodb-query-parser.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-query-parser.js +1351 -0
- package/cjs/drivers/mongodb/mongodb-query-parser.js.map +1 -0
- package/cjs/drivers/mongodb/mongodb-sync-adapter.d.ts +79 -0
- package/cjs/drivers/mongodb/mongodb-sync-adapter.d.ts.map +1 -0
- package/cjs/drivers/mongodb/mongodb-sync-adapter.js +146 -0
- package/cjs/drivers/mongodb/mongodb-sync-adapter.js.map +1 -0
- package/cjs/drivers/mongodb/types.d.ts +43 -0
- package/cjs/drivers/mongodb/types.d.ts.map +1 -0
- package/cjs/drivers/postgres/index.d.ts +16 -0
- package/cjs/drivers/postgres/index.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-blueprint.d.ts +64 -0
- package/cjs/drivers/postgres/postgres-blueprint.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-blueprint.js +121 -0
- package/cjs/drivers/postgres/postgres-blueprint.js.map +1 -0
- package/cjs/drivers/postgres/postgres-dialect.d.ts +136 -0
- package/cjs/drivers/postgres/postgres-dialect.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-dialect.js +268 -0
- package/cjs/drivers/postgres/postgres-dialect.js.map +1 -0
- package/cjs/drivers/postgres/postgres-driver.d.ts +432 -0
- package/cjs/drivers/postgres/postgres-driver.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-driver.js +1010 -0
- package/cjs/drivers/postgres/postgres-driver.js.map +1 -0
- package/cjs/drivers/postgres/postgres-migration-driver.d.ts +397 -0
- package/cjs/drivers/postgres/postgres-migration-driver.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-migration-driver.js +900 -0
- package/cjs/drivers/postgres/postgres-migration-driver.js.map +1 -0
- package/cjs/drivers/postgres/postgres-query-builder.d.ts +254 -0
- package/cjs/drivers/postgres/postgres-query-builder.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-query-builder.js +933 -0
- package/cjs/drivers/postgres/postgres-query-builder.js.map +1 -0
- package/cjs/drivers/postgres/postgres-query-parser.d.ts +328 -0
- package/cjs/drivers/postgres/postgres-query-parser.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-query-parser.js +868 -0
- package/cjs/drivers/postgres/postgres-query-parser.js.map +1 -0
- package/cjs/drivers/postgres/postgres-sql-serializer.d.ts +37 -0
- package/cjs/drivers/postgres/postgres-sql-serializer.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-sql-serializer.js +400 -0
- package/cjs/drivers/postgres/postgres-sql-serializer.js.map +1 -0
- package/cjs/drivers/postgres/postgres-sync-adapter.d.ts +83 -0
- package/cjs/drivers/postgres/postgres-sync-adapter.d.ts.map +1 -0
- package/cjs/drivers/postgres/postgres-sync-adapter.js +197 -0
- package/cjs/drivers/postgres/postgres-sync-adapter.js.map +1 -0
- package/cjs/drivers/postgres/types.d.ts +144 -0
- package/cjs/drivers/postgres/types.d.ts.map +1 -0
- package/cjs/drivers/sql/index.d.ts +10 -0
- package/cjs/drivers/sql/index.d.ts.map +1 -0
- package/cjs/drivers/sql/sql-dialect.contract.d.ts +204 -0
- package/cjs/drivers/sql/sql-dialect.contract.d.ts.map +1 -0
- package/cjs/drivers/sql/sql-types.d.ts +202 -0
- package/cjs/drivers/sql/sql-types.d.ts.map +1 -0
- package/cjs/errors/missing-data-source.error.d.ts +22 -0
- package/cjs/errors/missing-data-source.error.d.ts.map +1 -0
- package/cjs/errors/missing-data-source.error.js +29 -0
- package/cjs/errors/missing-data-source.error.js.map +1 -0
- package/cjs/errors/transaction-rollback.error.d.ts +20 -0
- package/cjs/errors/transaction-rollback.error.d.ts.map +1 -0
- package/cjs/errors/transaction-rollback.error.js +27 -0
- package/cjs/errors/transaction-rollback.error.js.map +1 -0
- package/cjs/events/model-events.d.ts +231 -0
- package/cjs/events/model-events.d.ts.map +1 -0
- package/cjs/events/model-events.js +259 -0
- package/cjs/events/model-events.js.map +1 -0
- package/cjs/expressions/aggregate-expressions.d.ts +215 -0
- package/cjs/expressions/aggregate-expressions.d.ts.map +1 -0
- package/cjs/expressions/aggregate-expressions.js +221 -0
- package/cjs/expressions/aggregate-expressions.js.map +1 -0
- package/cjs/expressions/index.d.ts +2 -0
- package/cjs/expressions/index.d.ts.map +1 -0
- package/cjs/index.d.ts +45 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +1 -0
- package/cjs/index.js.map +1 -0
- package/cjs/migration/column-builder.d.ts +417 -0
- package/cjs/migration/column-builder.d.ts.map +1 -0
- package/cjs/migration/column-builder.js +586 -0
- package/cjs/migration/column-builder.js.map +1 -0
- package/cjs/migration/column-helpers.d.ts +275 -0
- package/cjs/migration/column-helpers.d.ts.map +1 -0
- package/cjs/migration/column-helpers.js +389 -0
- package/cjs/migration/column-helpers.js.map +1 -0
- package/cjs/migration/foreign-key-builder.d.ts +103 -0
- package/cjs/migration/foreign-key-builder.d.ts.map +1 -0
- package/cjs/migration/foreign-key-builder.js +121 -0
- package/cjs/migration/foreign-key-builder.js.map +1 -0
- package/cjs/migration/index.d.ts +7 -0
- package/cjs/migration/index.d.ts.map +1 -0
- package/cjs/migration/migration-runner.d.ts +278 -0
- package/cjs/migration/migration-runner.d.ts.map +1 -0
- package/cjs/migration/migration-runner.js +815 -0
- package/cjs/migration/migration-runner.js.map +1 -0
- package/cjs/migration/migration.d.ts +1992 -0
- package/cjs/migration/migration.d.ts.map +1 -0
- package/cjs/migration/migration.js +2162 -0
- package/cjs/migration/migration.js.map +1 -0
- package/cjs/migration/sql-grammar.d.ts +61 -0
- package/cjs/migration/sql-grammar.d.ts.map +1 -0
- package/cjs/migration/sql-grammar.js +164 -0
- package/cjs/migration/sql-grammar.js.map +1 -0
- package/cjs/migration/sql-serializer.d.ts +22 -0
- package/cjs/migration/sql-serializer.d.ts.map +1 -0
- package/cjs/migration/sql-serializer.js +26 -0
- package/cjs/migration/sql-serializer.js.map +1 -0
- package/cjs/migration/types.d.ts +155 -0
- package/cjs/migration/types.d.ts.map +1 -0
- package/cjs/model/methods/accessor-methods.d.ts +13 -0
- package/cjs/model/methods/accessor-methods.d.ts.map +1 -0
- package/cjs/model/methods/accessor-methods.js +51 -0
- package/cjs/model/methods/accessor-methods.js.map +1 -0
- package/cjs/model/methods/delete-methods.d.ts +10 -0
- package/cjs/model/methods/delete-methods.d.ts.map +1 -0
- package/cjs/model/methods/delete-methods.js +10 -0
- package/cjs/model/methods/delete-methods.js.map +1 -0
- package/cjs/model/methods/dirty-methods.d.ts +10 -0
- package/cjs/model/methods/dirty-methods.d.ts.map +1 -0
- package/cjs/model/methods/dirty-methods.js +15 -0
- package/cjs/model/methods/dirty-methods.js.map +1 -0
- package/cjs/model/methods/hydration-methods.d.ts +10 -0
- package/cjs/model/methods/hydration-methods.d.ts.map +1 -0
- package/cjs/model/methods/hydration-methods.js +57 -0
- package/cjs/model/methods/hydration-methods.js.map +1 -0
- package/cjs/model/methods/instance-event-methods.d.ts +7 -0
- package/cjs/model/methods/instance-event-methods.d.ts.map +1 -0
- package/cjs/model/methods/instance-event-methods.js +15 -0
- package/cjs/model/methods/instance-event-methods.js.map +1 -0
- package/cjs/model/methods/meta-methods.d.ts +7 -0
- package/cjs/model/methods/meta-methods.d.ts.map +1 -0
- package/cjs/model/methods/meta-methods.js +78 -0
- package/cjs/model/methods/meta-methods.js.map +1 -0
- package/cjs/model/methods/query-methods.d.ts +24 -0
- package/cjs/model/methods/query-methods.d.ts.map +1 -0
- package/cjs/model/methods/query-methods.js +164 -0
- package/cjs/model/methods/query-methods.js.map +1 -0
- package/cjs/model/methods/restore-methods.d.ts +10 -0
- package/cjs/model/methods/restore-methods.d.ts.map +1 -0
- package/cjs/model/methods/restore-methods.js +13 -0
- package/cjs/model/methods/restore-methods.js.map +1 -0
- package/cjs/model/methods/scope-methods.d.ts +7 -0
- package/cjs/model/methods/scope-methods.d.ts.map +1 -0
- package/cjs/model/methods/scope-methods.js +15 -0
- package/cjs/model/methods/scope-methods.js.map +1 -0
- package/cjs/model/methods/serialization-methods.d.ts +3 -0
- package/cjs/model/methods/serialization-methods.d.ts.map +1 -0
- package/cjs/model/methods/serialization-methods.js +27 -0
- package/cjs/model/methods/serialization-methods.js.map +1 -0
- package/cjs/model/methods/static-event-methods.d.ts +9 -0
- package/cjs/model/methods/static-event-methods.d.ts.map +1 -0
- package/cjs/model/methods/static-event-methods.js +29 -0
- package/cjs/model/methods/static-event-methods.js.map +1 -0
- package/cjs/model/methods/write-methods.d.ts +10 -0
- package/cjs/model/methods/write-methods.d.ts.map +1 -0
- package/cjs/model/methods/write-methods.js +52 -0
- package/cjs/model/methods/write-methods.js.map +1 -0
- package/cjs/model/model.d.ts +1647 -0
- package/cjs/model/model.d.ts.map +1 -0
- package/cjs/model/model.js +1657 -0
- package/cjs/model/model.js.map +1 -0
- package/cjs/model/model.types.d.ts +44 -0
- package/cjs/model/model.types.d.ts.map +1 -0
- package/cjs/model/register-model.d.ts +81 -0
- package/cjs/model/register-model.d.ts.map +1 -0
- package/cjs/model/register-model.js +94 -0
- package/cjs/model/register-model.js.map +1 -0
- package/cjs/query-builder/query-builder.d.ts +556 -0
- package/cjs/query-builder/query-builder.d.ts.map +1 -0
- package/cjs/query-builder/query-builder.js +1070 -0
- package/cjs/query-builder/query-builder.js.map +1 -0
- package/cjs/relations/helpers.d.ts +156 -0
- package/cjs/relations/helpers.d.ts.map +1 -0
- package/cjs/relations/helpers.js +202 -0
- package/cjs/relations/helpers.js.map +1 -0
- package/cjs/relations/index.d.ts +35 -0
- package/cjs/relations/index.d.ts.map +1 -0
- package/cjs/relations/pivot-operations.d.ts +160 -0
- package/cjs/relations/pivot-operations.d.ts.map +1 -0
- package/cjs/relations/pivot-operations.js +293 -0
- package/cjs/relations/pivot-operations.js.map +1 -0
- package/cjs/relations/relation-hydrator.d.ts +68 -0
- package/cjs/relations/relation-hydrator.d.ts.map +1 -0
- package/cjs/relations/relation-hydrator.js +81 -0
- package/cjs/relations/relation-hydrator.js.map +1 -0
- package/cjs/relations/relation-loader.d.ts +194 -0
- package/cjs/relations/relation-loader.d.ts.map +1 -0
- package/cjs/relations/relation-loader.js +466 -0
- package/cjs/relations/relation-loader.js.map +1 -0
- package/cjs/relations/types.d.ts +306 -0
- package/cjs/relations/types.d.ts.map +1 -0
- package/cjs/remover/database-remover.d.ts +100 -0
- package/cjs/remover/database-remover.d.ts.map +1 -0
- package/cjs/remover/database-remover.js +214 -0
- package/cjs/remover/database-remover.js.map +1 -0
- package/cjs/restorer/database-restorer.d.ts +131 -0
- package/cjs/restorer/database-restorer.d.ts.map +1 -0
- package/cjs/restorer/database-restorer.js +434 -0
- package/cjs/restorer/database-restorer.js.map +1 -0
- package/cjs/sql-database-dirty-tracker.d.ts +13 -0
- package/cjs/sql-database-dirty-tracker.d.ts.map +1 -0
- package/cjs/sql-database-dirty-tracker.js +14 -0
- package/cjs/sql-database-dirty-tracker.js.map +1 -0
- package/cjs/sync/index.d.ts +12 -0
- package/cjs/sync/index.d.ts.map +1 -0
- package/cjs/sync/model-events.d.ts +62 -0
- package/cjs/sync/model-events.d.ts.map +1 -0
- package/cjs/sync/model-events.js +49 -0
- package/cjs/sync/model-events.js.map +1 -0
- package/cjs/sync/model-sync-operation.d.ts +163 -0
- package/cjs/sync/model-sync-operation.d.ts.map +1 -0
- package/cjs/sync/model-sync-operation.js +292 -0
- package/cjs/sync/model-sync-operation.js.map +1 -0
- package/cjs/sync/model-sync.d.ts +130 -0
- package/cjs/sync/model-sync.d.ts.map +1 -0
- package/cjs/sync/model-sync.js +178 -0
- package/cjs/sync/model-sync.js.map +1 -0
- package/cjs/sync/sync-context.d.ts +70 -0
- package/cjs/sync/sync-context.d.ts.map +1 -0
- package/cjs/sync/sync-context.js +101 -0
- package/cjs/sync/sync-context.js.map +1 -0
- package/cjs/sync/sync-manager.d.ts +213 -0
- package/cjs/sync/sync-manager.d.ts.map +1 -0
- package/cjs/sync/sync-manager.js +689 -0
- package/cjs/sync/sync-manager.js.map +1 -0
- package/cjs/sync/types.d.ts +289 -0
- package/cjs/sync/types.d.ts.map +1 -0
- package/cjs/test-migrations/test-enhanced-features.migration.d.ts +15 -0
- package/cjs/test-migrations/test-enhanced-features.migration.d.ts.map +1 -0
- package/cjs/types.d.ts +371 -0
- package/cjs/types.d.ts.map +1 -0
- package/cjs/utils/connect-to-database.d.ts +307 -0
- package/cjs/utils/connect-to-database.d.ts.map +1 -0
- package/cjs/utils/connect-to-database.js +130 -0
- package/cjs/utils/connect-to-database.js.map +1 -0
- package/cjs/utils/database-writer.utils.d.ts +15 -0
- package/cjs/utils/database-writer.utils.d.ts.map +1 -0
- package/cjs/utils/database-writer.utils.js +14 -0
- package/cjs/utils/database-writer.utils.js.map +1 -0
- package/cjs/utils/define-model.js +100 -0
- package/cjs/utils/define-model.js.map +1 -0
- package/cjs/utils/is-valid-date-value.d.ts +5 -0
- package/cjs/utils/is-valid-date-value.d.ts.map +1 -0
- package/cjs/utils/is-valid-date-value.js +25 -0
- package/cjs/utils/is-valid-date-value.js.map +1 -0
- package/cjs/utils/once-connected.d.ts +146 -0
- package/cjs/utils/once-connected.d.ts.map +1 -0
- package/cjs/utils/once-connected.js +251 -0
- package/cjs/utils/once-connected.js.map +1 -0
- package/cjs/validation/database-seal-plugins.d.ts +12 -0
- package/cjs/validation/database-seal-plugins.d.ts.map +1 -0
- package/cjs/validation/database-seal-plugins.js +1 -0
- package/cjs/validation/database-seal-plugins.js.map +1 -0
- package/cjs/validation/database-writer-validation-error.d.ts +97 -0
- package/cjs/validation/database-writer-validation-error.d.ts.map +1 -0
- package/cjs/validation/database-writer-validation-error.js +160 -0
- package/cjs/validation/database-writer-validation-error.js.map +1 -0
- package/cjs/validation/index.d.ts +3 -0
- package/cjs/validation/index.d.ts.map +1 -0
- package/cjs/validation/mutators/embed-mutator.d.ts +9 -0
- package/cjs/validation/mutators/embed-mutator.d.ts.map +1 -0
- package/cjs/validation/mutators/embed-mutator.js +33 -0
- package/cjs/validation/mutators/embed-mutator.js.map +1 -0
- package/cjs/validation/plugins/embed-validator-plugin.d.ts +24 -0
- package/cjs/validation/plugins/embed-validator-plugin.d.ts.map +1 -0
- package/cjs/validation/plugins/embed-validator-plugin.js +18 -0
- package/cjs/validation/plugins/embed-validator-plugin.js.map +1 -0
- package/cjs/validation/rules/database-model-rule.d.ts +7 -0
- package/cjs/validation/rules/database-model-rule.d.ts.map +1 -0
- package/cjs/validation/rules/database-model-rule.js +27 -0
- package/cjs/validation/rules/database-model-rule.js.map +1 -0
- package/cjs/validation/transformers/embed-model-transformer.d.ts +3 -0
- package/cjs/validation/transformers/embed-model-transformer.d.ts.map +1 -0
- package/cjs/validation/transformers/embed-model-transformer.js +18 -0
- package/cjs/validation/transformers/embed-model-transformer.js.map +1 -0
- package/cjs/validation/validators/embed-validator.d.ts +21 -0
- package/cjs/validation/validators/embed-validator.d.ts.map +1 -0
- package/cjs/validation/validators/embed-validator.js +43 -0
- package/cjs/validation/validators/embed-validator.js.map +1 -0
- package/cjs/writer/database-writer.d.ts +181 -0
- package/cjs/writer/database-writer.d.ts.map +1 -0
- package/cjs/writer/database-writer.js +407 -0
- package/cjs/writer/database-writer.js.map +1 -0
- package/esm/data-source/data-source-registry.d.ts +108 -0
- package/esm/data-source/data-source-registry.d.ts.map +1 -0
- package/esm/data-source/data-source-registry.js +145 -0
- package/esm/data-source/data-source-registry.js.map +1 -0
- package/esm/data-source/data-source.d.ts +147 -0
- package/esm/data-source/data-source.d.ts.map +1 -0
- package/esm/data-source/data-source.js +83 -0
- package/esm/data-source/data-source.js.map +1 -0
- package/esm/database-dirty-tracker.d.ts +252 -0
- package/esm/database-dirty-tracker.d.ts.map +1 -0
- package/esm/database-dirty-tracker.js +386 -0
- package/esm/database-dirty-tracker.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-blueprint.d.ts +30 -0
- package/esm/drivers/mongodb/mongodb-blueprint.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-blueprint.js +51 -0
- package/esm/drivers/mongodb/mongodb-blueprint.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-driver.d.ts +325 -0
- package/esm/drivers/mongodb/mongodb-driver.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-driver.js +838 -0
- package/esm/drivers/mongodb/mongodb-driver.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-id-generator.d.ts +116 -0
- package/esm/drivers/mongodb/mongodb-id-generator.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-id-generator.js +149 -0
- package/esm/drivers/mongodb/mongodb-id-generator.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.d.ts +317 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.js +666 -0
- package/esm/drivers/mongodb/mongodb-migration-driver.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-builder.d.ts +1122 -0
- package/esm/drivers/mongodb/mongodb-query-builder.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-builder.js +1988 -0
- package/esm/drivers/mongodb/mongodb-query-builder.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-operations.d.ts +226 -0
- package/esm/drivers/mongodb/mongodb-query-operations.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-operations.js +270 -0
- package/esm/drivers/mongodb/mongodb-query-operations.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-parser.d.ts +262 -0
- package/esm/drivers/mongodb/mongodb-query-parser.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-query-parser.js +1351 -0
- package/esm/drivers/mongodb/mongodb-query-parser.js.map +1 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.ts +79 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.d.ts.map +1 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.js +146 -0
- package/esm/drivers/mongodb/mongodb-sync-adapter.js.map +1 -0
- package/esm/drivers/mongodb/types.d.ts +43 -0
- package/esm/drivers/mongodb/types.d.ts.map +1 -0
- package/esm/drivers/postgres/index.d.ts +16 -0
- package/esm/drivers/postgres/index.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-blueprint.d.ts +64 -0
- package/esm/drivers/postgres/postgres-blueprint.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-blueprint.js +121 -0
- package/esm/drivers/postgres/postgres-blueprint.js.map +1 -0
- package/esm/drivers/postgres/postgres-dialect.d.ts +136 -0
- package/esm/drivers/postgres/postgres-dialect.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-dialect.js +268 -0
- package/esm/drivers/postgres/postgres-dialect.js.map +1 -0
- package/esm/drivers/postgres/postgres-driver.d.ts +432 -0
- package/esm/drivers/postgres/postgres-driver.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-driver.js +1010 -0
- package/esm/drivers/postgres/postgres-driver.js.map +1 -0
- package/esm/drivers/postgres/postgres-migration-driver.d.ts +397 -0
- package/esm/drivers/postgres/postgres-migration-driver.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-migration-driver.js +900 -0
- package/esm/drivers/postgres/postgres-migration-driver.js.map +1 -0
- package/esm/drivers/postgres/postgres-query-builder.d.ts +254 -0
- package/esm/drivers/postgres/postgres-query-builder.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-query-builder.js +933 -0
- package/esm/drivers/postgres/postgres-query-builder.js.map +1 -0
- package/esm/drivers/postgres/postgres-query-parser.d.ts +328 -0
- package/esm/drivers/postgres/postgres-query-parser.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-query-parser.js +868 -0
- package/esm/drivers/postgres/postgres-query-parser.js.map +1 -0
- package/esm/drivers/postgres/postgres-sql-serializer.d.ts +37 -0
- package/esm/drivers/postgres/postgres-sql-serializer.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-sql-serializer.js +400 -0
- package/esm/drivers/postgres/postgres-sql-serializer.js.map +1 -0
- package/esm/drivers/postgres/postgres-sync-adapter.d.ts +83 -0
- package/esm/drivers/postgres/postgres-sync-adapter.d.ts.map +1 -0
- package/esm/drivers/postgres/postgres-sync-adapter.js +197 -0
- package/esm/drivers/postgres/postgres-sync-adapter.js.map +1 -0
- package/esm/drivers/postgres/types.d.ts +144 -0
- package/esm/drivers/postgres/types.d.ts.map +1 -0
- package/esm/drivers/sql/index.d.ts +10 -0
- package/esm/drivers/sql/index.d.ts.map +1 -0
- package/esm/drivers/sql/sql-dialect.contract.d.ts +204 -0
- package/esm/drivers/sql/sql-dialect.contract.d.ts.map +1 -0
- package/esm/drivers/sql/sql-types.d.ts +202 -0
- package/esm/drivers/sql/sql-types.d.ts.map +1 -0
- package/esm/errors/missing-data-source.error.d.ts +22 -0
- package/esm/errors/missing-data-source.error.d.ts.map +1 -0
- package/esm/errors/missing-data-source.error.js +29 -0
- package/esm/errors/missing-data-source.error.js.map +1 -0
- package/esm/errors/transaction-rollback.error.d.ts +20 -0
- package/esm/errors/transaction-rollback.error.d.ts.map +1 -0
- package/esm/errors/transaction-rollback.error.js +27 -0
- package/esm/errors/transaction-rollback.error.js.map +1 -0
- package/esm/events/model-events.d.ts +231 -0
- package/esm/events/model-events.d.ts.map +1 -0
- package/esm/events/model-events.js +259 -0
- package/esm/events/model-events.js.map +1 -0
- package/esm/expressions/aggregate-expressions.d.ts +215 -0
- package/esm/expressions/aggregate-expressions.d.ts.map +1 -0
- package/esm/expressions/aggregate-expressions.js +221 -0
- package/esm/expressions/aggregate-expressions.js.map +1 -0
- package/esm/expressions/index.d.ts +2 -0
- package/esm/expressions/index.d.ts.map +1 -0
- package/esm/index.d.ts +45 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -0
- package/esm/migration/column-builder.d.ts +417 -0
- package/esm/migration/column-builder.d.ts.map +1 -0
- package/esm/migration/column-builder.js +586 -0
- package/esm/migration/column-builder.js.map +1 -0
- package/esm/migration/column-helpers.d.ts +275 -0
- package/esm/migration/column-helpers.d.ts.map +1 -0
- package/esm/migration/column-helpers.js +389 -0
- package/esm/migration/column-helpers.js.map +1 -0
- package/esm/migration/foreign-key-builder.d.ts +103 -0
- package/esm/migration/foreign-key-builder.d.ts.map +1 -0
- package/esm/migration/foreign-key-builder.js +121 -0
- package/esm/migration/foreign-key-builder.js.map +1 -0
- package/esm/migration/index.d.ts +7 -0
- package/esm/migration/index.d.ts.map +1 -0
- package/esm/migration/migration-runner.d.ts +278 -0
- package/esm/migration/migration-runner.d.ts.map +1 -0
- package/esm/migration/migration-runner.js +815 -0
- package/esm/migration/migration-runner.js.map +1 -0
- package/esm/migration/migration.d.ts +1992 -0
- package/esm/migration/migration.d.ts.map +1 -0
- package/esm/migration/migration.js +2162 -0
- package/esm/migration/migration.js.map +1 -0
- package/esm/migration/sql-grammar.d.ts +61 -0
- package/esm/migration/sql-grammar.d.ts.map +1 -0
- package/esm/migration/sql-grammar.js +164 -0
- package/esm/migration/sql-grammar.js.map +1 -0
- package/esm/migration/sql-serializer.d.ts +22 -0
- package/esm/migration/sql-serializer.d.ts.map +1 -0
- package/esm/migration/sql-serializer.js +26 -0
- package/esm/migration/sql-serializer.js.map +1 -0
- package/esm/migration/types.d.ts +155 -0
- package/esm/migration/types.d.ts.map +1 -0
- package/esm/model/methods/accessor-methods.d.ts +13 -0
- package/esm/model/methods/accessor-methods.d.ts.map +1 -0
- package/esm/model/methods/accessor-methods.js +51 -0
- package/esm/model/methods/accessor-methods.js.map +1 -0
- package/esm/model/methods/delete-methods.d.ts +10 -0
- package/esm/model/methods/delete-methods.d.ts.map +1 -0
- package/esm/model/methods/delete-methods.js +10 -0
- package/esm/model/methods/delete-methods.js.map +1 -0
- package/esm/model/methods/dirty-methods.d.ts +10 -0
- package/esm/model/methods/dirty-methods.d.ts.map +1 -0
- package/esm/model/methods/dirty-methods.js +15 -0
- package/esm/model/methods/dirty-methods.js.map +1 -0
- package/esm/model/methods/hydration-methods.d.ts +10 -0
- package/esm/model/methods/hydration-methods.d.ts.map +1 -0
- package/esm/model/methods/hydration-methods.js +57 -0
- package/esm/model/methods/hydration-methods.js.map +1 -0
- package/esm/model/methods/instance-event-methods.d.ts +7 -0
- package/esm/model/methods/instance-event-methods.d.ts.map +1 -0
- package/esm/model/methods/instance-event-methods.js +15 -0
- package/esm/model/methods/instance-event-methods.js.map +1 -0
- package/esm/model/methods/meta-methods.d.ts +7 -0
- package/esm/model/methods/meta-methods.d.ts.map +1 -0
- package/esm/model/methods/meta-methods.js +78 -0
- package/esm/model/methods/meta-methods.js.map +1 -0
- package/esm/model/methods/query-methods.d.ts +24 -0
- package/esm/model/methods/query-methods.d.ts.map +1 -0
- package/esm/model/methods/query-methods.js +164 -0
- package/esm/model/methods/query-methods.js.map +1 -0
- package/esm/model/methods/restore-methods.d.ts +10 -0
- package/esm/model/methods/restore-methods.d.ts.map +1 -0
- package/esm/model/methods/restore-methods.js +13 -0
- package/esm/model/methods/restore-methods.js.map +1 -0
- package/esm/model/methods/scope-methods.d.ts +7 -0
- package/esm/model/methods/scope-methods.d.ts.map +1 -0
- package/esm/model/methods/scope-methods.js +15 -0
- package/esm/model/methods/scope-methods.js.map +1 -0
- package/esm/model/methods/serialization-methods.d.ts +3 -0
- package/esm/model/methods/serialization-methods.d.ts.map +1 -0
- package/esm/model/methods/serialization-methods.js +27 -0
- package/esm/model/methods/serialization-methods.js.map +1 -0
- package/esm/model/methods/static-event-methods.d.ts +9 -0
- package/esm/model/methods/static-event-methods.d.ts.map +1 -0
- package/esm/model/methods/static-event-methods.js +29 -0
- package/esm/model/methods/static-event-methods.js.map +1 -0
- package/esm/model/methods/write-methods.d.ts +10 -0
- package/esm/model/methods/write-methods.d.ts.map +1 -0
- package/esm/model/methods/write-methods.js +52 -0
- package/esm/model/methods/write-methods.js.map +1 -0
- package/esm/model/model.d.ts +1647 -0
- package/esm/model/model.d.ts.map +1 -0
- package/esm/model/model.js +1657 -0
- package/esm/model/model.js.map +1 -0
- package/esm/model/model.types.d.ts +44 -0
- package/esm/model/model.types.d.ts.map +1 -0
- package/esm/model/register-model.d.ts +81 -0
- package/esm/model/register-model.d.ts.map +1 -0
- package/esm/model/register-model.js +94 -0
- package/esm/model/register-model.js.map +1 -0
- package/esm/query-builder/query-builder.d.ts +556 -0
- package/esm/query-builder/query-builder.d.ts.map +1 -0
- package/esm/query-builder/query-builder.js +1070 -0
- package/esm/query-builder/query-builder.js.map +1 -0
- package/esm/relations/helpers.d.ts +156 -0
- package/esm/relations/helpers.d.ts.map +1 -0
- package/esm/relations/helpers.js +202 -0
- package/esm/relations/helpers.js.map +1 -0
- package/esm/relations/index.d.ts +35 -0
- package/esm/relations/index.d.ts.map +1 -0
- package/esm/relations/pivot-operations.d.ts +160 -0
- package/esm/relations/pivot-operations.d.ts.map +1 -0
- package/esm/relations/pivot-operations.js +293 -0
- package/esm/relations/pivot-operations.js.map +1 -0
- package/esm/relations/relation-hydrator.d.ts +68 -0
- package/esm/relations/relation-hydrator.d.ts.map +1 -0
- package/esm/relations/relation-hydrator.js +81 -0
- package/esm/relations/relation-hydrator.js.map +1 -0
- package/esm/relations/relation-loader.d.ts +194 -0
- package/esm/relations/relation-loader.d.ts.map +1 -0
- package/esm/relations/relation-loader.js +466 -0
- package/esm/relations/relation-loader.js.map +1 -0
- package/esm/relations/types.d.ts +306 -0
- package/esm/relations/types.d.ts.map +1 -0
- package/esm/remover/database-remover.d.ts +100 -0
- package/esm/remover/database-remover.d.ts.map +1 -0
- package/esm/remover/database-remover.js +214 -0
- package/esm/remover/database-remover.js.map +1 -0
- package/esm/restorer/database-restorer.d.ts +131 -0
- package/esm/restorer/database-restorer.d.ts.map +1 -0
- package/esm/restorer/database-restorer.js +434 -0
- package/esm/restorer/database-restorer.js.map +1 -0
- package/esm/sql-database-dirty-tracker.d.ts +13 -0
- package/esm/sql-database-dirty-tracker.d.ts.map +1 -0
- package/esm/sql-database-dirty-tracker.js +14 -0
- package/esm/sql-database-dirty-tracker.js.map +1 -0
- package/esm/sync/index.d.ts +12 -0
- package/esm/sync/index.d.ts.map +1 -0
- package/esm/sync/model-events.d.ts +62 -0
- package/esm/sync/model-events.d.ts.map +1 -0
- package/esm/sync/model-events.js +49 -0
- package/esm/sync/model-events.js.map +1 -0
- package/esm/sync/model-sync-operation.d.ts +163 -0
- package/esm/sync/model-sync-operation.d.ts.map +1 -0
- package/esm/sync/model-sync-operation.js +292 -0
- package/esm/sync/model-sync-operation.js.map +1 -0
- package/esm/sync/model-sync.d.ts +130 -0
- package/esm/sync/model-sync.d.ts.map +1 -0
- package/esm/sync/model-sync.js +178 -0
- package/esm/sync/model-sync.js.map +1 -0
- package/esm/sync/sync-context.d.ts +70 -0
- package/esm/sync/sync-context.d.ts.map +1 -0
- package/esm/sync/sync-context.js +101 -0
- package/esm/sync/sync-context.js.map +1 -0
- package/esm/sync/sync-manager.d.ts +213 -0
- package/esm/sync/sync-manager.d.ts.map +1 -0
- package/esm/sync/sync-manager.js +689 -0
- package/esm/sync/sync-manager.js.map +1 -0
- package/esm/sync/types.d.ts +289 -0
- package/esm/sync/types.d.ts.map +1 -0
- package/esm/test-migrations/test-enhanced-features.migration.d.ts +15 -0
- package/esm/test-migrations/test-enhanced-features.migration.d.ts.map +1 -0
- package/esm/types.d.ts +371 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/utils/connect-to-database.d.ts +307 -0
- package/esm/utils/connect-to-database.d.ts.map +1 -0
- package/esm/utils/connect-to-database.js +130 -0
- package/esm/utils/connect-to-database.js.map +1 -0
- package/esm/utils/database-writer.utils.d.ts +15 -0
- package/esm/utils/database-writer.utils.d.ts.map +1 -0
- package/esm/utils/database-writer.utils.js +14 -0
- package/esm/utils/database-writer.utils.js.map +1 -0
- package/esm/utils/define-model.js +100 -0
- package/esm/utils/define-model.js.map +1 -0
- package/esm/utils/is-valid-date-value.d.ts +5 -0
- package/esm/utils/is-valid-date-value.d.ts.map +1 -0
- package/esm/utils/is-valid-date-value.js +25 -0
- package/esm/utils/is-valid-date-value.js.map +1 -0
- package/esm/utils/once-connected.d.ts +146 -0
- package/esm/utils/once-connected.d.ts.map +1 -0
- package/esm/utils/once-connected.js +251 -0
- package/esm/utils/once-connected.js.map +1 -0
- package/esm/validation/database-seal-plugins.d.ts +12 -0
- package/esm/validation/database-seal-plugins.d.ts.map +1 -0
- package/esm/validation/database-seal-plugins.js +1 -0
- package/esm/validation/database-seal-plugins.js.map +1 -0
- package/esm/validation/database-writer-validation-error.d.ts +97 -0
- package/esm/validation/database-writer-validation-error.d.ts.map +1 -0
- package/esm/validation/database-writer-validation-error.js +160 -0
- package/esm/validation/database-writer-validation-error.js.map +1 -0
- package/esm/validation/index.d.ts +3 -0
- package/esm/validation/index.d.ts.map +1 -0
- package/esm/validation/mutators/embed-mutator.d.ts +9 -0
- package/esm/validation/mutators/embed-mutator.d.ts.map +1 -0
- package/esm/validation/mutators/embed-mutator.js +33 -0
- package/esm/validation/mutators/embed-mutator.js.map +1 -0
- package/esm/validation/plugins/embed-validator-plugin.d.ts +24 -0
- package/esm/validation/plugins/embed-validator-plugin.d.ts.map +1 -0
- package/esm/validation/plugins/embed-validator-plugin.js +18 -0
- package/esm/validation/plugins/embed-validator-plugin.js.map +1 -0
- package/esm/validation/rules/database-model-rule.d.ts +7 -0
- package/esm/validation/rules/database-model-rule.d.ts.map +1 -0
- package/esm/validation/rules/database-model-rule.js +27 -0
- package/esm/validation/rules/database-model-rule.js.map +1 -0
- package/esm/validation/transformers/embed-model-transformer.d.ts +3 -0
- package/esm/validation/transformers/embed-model-transformer.d.ts.map +1 -0
- package/esm/validation/transformers/embed-model-transformer.js +18 -0
- package/esm/validation/transformers/embed-model-transformer.js.map +1 -0
- package/esm/validation/validators/embed-validator.d.ts +21 -0
- package/esm/validation/validators/embed-validator.d.ts.map +1 -0
- package/esm/validation/validators/embed-validator.js +43 -0
- package/esm/validation/validators/embed-validator.js.map +1 -0
- package/esm/writer/database-writer.d.ts +181 -0
- package/esm/writer/database-writer.d.ts.map +1 -0
- package/esm/writer/database-writer.js +407 -0
- package/esm/writer/database-writer.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,1657 @@
|
|
|
1
|
+
'use strict';var modelEvents=require('../events/model-events.js'),relationLoader=require('../relations/relation-loader.js'),modelSync=require('../sync/model-sync.js'),accessorMethods=require('./methods/accessor-methods.js'),deleteMethods=require('./methods/delete-methods.js'),dirtyMethods=require('./methods/dirty-methods.js'),hydrationMethods=require('./methods/hydration-methods.js'),instanceEventMethods=require('./methods/instance-event-methods.js'),metaMethods=require('./methods/meta-methods.js'),queryMethods=require('./methods/query-methods.js'),restoreMethods=require('./methods/restore-methods.js'),scopeMethods=require('./methods/scope-methods.js'),serializationMethods=require('./methods/serialization-methods.js'),staticEventMethods=require('./methods/static-event-methods.js'),writeMethods=require('./methods/write-methods.js'),registerModel=require('./register-model.js');/**
|
|
2
|
+
* Base class that powers all Cascade models.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Type-safe value accessors with dot-notation support (get, set, has, unset, merge)
|
|
6
|
+
* - Automatic dirty tracking for efficient partial updates
|
|
7
|
+
* - Lifecycle event hooks (saving, created, deleting, etc.)
|
|
8
|
+
* - Integration with the data-source registry for multi-database support
|
|
9
|
+
* - Support for both per-model and global event listeners
|
|
10
|
+
*
|
|
11
|
+
* @template TSchema - The shape of the model's underlying data
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* interface UserSchema {
|
|
16
|
+
* id: number;
|
|
17
|
+
* name: string;
|
|
18
|
+
* email: string;
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* class User extends Model<UserSchema> {
|
|
22
|
+
* public static table = "users";
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* const user = new User({ name: "Alice" });
|
|
26
|
+
* user.set("email", "alice@example.com");
|
|
27
|
+
* console.log(user.hasChanges()); // true
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class Model {
|
|
31
|
+
/**
|
|
32
|
+
* The database table or collection name associated with this model.
|
|
33
|
+
*
|
|
34
|
+
* Must be defined by each concrete model subclass.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* class User extends Model {
|
|
39
|
+
* public static table = "users";
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
static table;
|
|
44
|
+
/**
|
|
45
|
+
* Resource for this model.
|
|
46
|
+
* It is a class that holds a toJSON function
|
|
47
|
+
* Called when the model is being converted to JSON (by calling toJSON or JSON.stringify(model))
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* class User extends Model {
|
|
52
|
+
* public static resource = UserResource;
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
static resource;
|
|
57
|
+
/**
|
|
58
|
+
* Resource columns
|
|
59
|
+
* Define what columns should be sent to the resource (if any) when converting to JSON
|
|
60
|
+
*/
|
|
61
|
+
static resourceColumns;
|
|
62
|
+
/**
|
|
63
|
+
* JSON keys for this model.
|
|
64
|
+
* This could be used if resource is not passed
|
|
65
|
+
* It will select only these keys from the model
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* class User extends Model {
|
|
69
|
+
* public static toJsonColumns = ["id", "name"];
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
static toJsonColumns;
|
|
74
|
+
/**
|
|
75
|
+
* Data source reference for this model.
|
|
76
|
+
*
|
|
77
|
+
* Can be:
|
|
78
|
+
* - A string name registered in the data-source registry
|
|
79
|
+
* - A DataSource instance
|
|
80
|
+
* - Undefined (falls back to the default data source)
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* class User extends Model {
|
|
85
|
+
* public static dataSource = "primary";
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
static dataSource;
|
|
90
|
+
/**
|
|
91
|
+
* Query builder class
|
|
92
|
+
*/
|
|
93
|
+
static builder;
|
|
94
|
+
/**
|
|
95
|
+
* Primary key field name used to identify records.
|
|
96
|
+
*
|
|
97
|
+
* @default "id"
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* class User extends Model {
|
|
102
|
+
* public static primaryKey = "_id"; // MongoDB
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* class Product extends Model {
|
|
106
|
+
* public static primaryKey = "id"; // SQL
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
static primaryKey = "id";
|
|
111
|
+
/**
|
|
112
|
+
* Embeded fields when document is Being embeded
|
|
113
|
+
*/
|
|
114
|
+
static embed;
|
|
115
|
+
/**
|
|
116
|
+
* Validation and casting schema using @warlock.js/seal.
|
|
117
|
+
*
|
|
118
|
+
* Defines validation rules and data transformations for the model.
|
|
119
|
+
* Used automatically during save operations.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* import { v } from "@warlock.js/seal";
|
|
124
|
+
*
|
|
125
|
+
* class User extends Model {
|
|
126
|
+
* public static schema = v.object({
|
|
127
|
+
* name: v.string().required().trim(),
|
|
128
|
+
* age: v.number().min(0).max(120),
|
|
129
|
+
* email: v.string().email().required().toLowerCase(),
|
|
130
|
+
* createdAt: v.date().default(() => new Date()),
|
|
131
|
+
* });
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
static schema;
|
|
136
|
+
/**
|
|
137
|
+
* Strict mode behavior for unknown fields.
|
|
138
|
+
*
|
|
139
|
+
* - `"strip"`: Remove unknown fields silently (default, recommended for APIs)
|
|
140
|
+
* - `"fail"`: Throw validation error on unknown fields (strict validation)
|
|
141
|
+
* - `"allow"`: Allow unknown fields to pass through (permissive)
|
|
142
|
+
*
|
|
143
|
+
* @default "strip"
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* import { Model, type StrictMode } from "@warlock.js/cascade";
|
|
148
|
+
*
|
|
149
|
+
* class User extends Model {
|
|
150
|
+
* public static strictMode: StrictMode = "fail"; // Throw on unknown fields
|
|
151
|
+
* }
|
|
152
|
+
*
|
|
153
|
+
* const user = new User({ name: "Alice", unknownField: "value" });
|
|
154
|
+
* await user.save(); // DatabaseWriterValidationError: unknown field
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
static strictMode = "strip";
|
|
158
|
+
/**
|
|
159
|
+
* Auto-generate incremental `id` field on insert (NoSQL only).
|
|
160
|
+
*
|
|
161
|
+
* When enabled, the ID generator creates a sequential integer ID
|
|
162
|
+
* separate from the database's native ID (_id for MongoDB).
|
|
163
|
+
*
|
|
164
|
+
* **Note:** SQL databases use native AUTO_INCREMENT and don't need this.
|
|
165
|
+
*
|
|
166
|
+
* @default true
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* class User extends Model {
|
|
171
|
+
* public static autoGenerateId = true;
|
|
172
|
+
* }
|
|
173
|
+
*
|
|
174
|
+
* const user = new User({ name: "Alice" });
|
|
175
|
+
* await user.save();
|
|
176
|
+
* console.log(user.get("_id")); // ObjectId("...") - MongoDB
|
|
177
|
+
* console.log(user.get("id")); // 1 - Generated
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
static autoGenerateId = true;
|
|
181
|
+
/**
|
|
182
|
+
* Initial ID value for the first record.
|
|
183
|
+
*
|
|
184
|
+
* If not set, defaults to 1 or uses `randomInitialId`.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* class User extends Model {
|
|
189
|
+
* public static initialId = 1000; // Start from 1000
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
static initialId;
|
|
194
|
+
/**
|
|
195
|
+
* Randomly generate the initial ID.
|
|
196
|
+
*
|
|
197
|
+
* Can be:
|
|
198
|
+
* - `true`: Generate random ID between 10000-499999
|
|
199
|
+
* - Function: Custom random ID generator
|
|
200
|
+
* - `false`: Use `initialId` or default to 1
|
|
201
|
+
*
|
|
202
|
+
* @default false
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* class User extends Model {
|
|
207
|
+
* public static randomInitialId = true; // Random 10000-499999
|
|
208
|
+
* }
|
|
209
|
+
*
|
|
210
|
+
* class Product extends Model {
|
|
211
|
+
* public static randomInitialId = () => Math.floor(Math.random() * 1000000);
|
|
212
|
+
* }
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
static randomInitialId;
|
|
216
|
+
/**
|
|
217
|
+
* Amount to increment ID by for each new record.
|
|
218
|
+
*
|
|
219
|
+
* If not set, defaults to 1 or uses `randomIncrement`.
|
|
220
|
+
*
|
|
221
|
+
* @default 1
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* class User extends Model {
|
|
226
|
+
* public static incrementIdBy = 5; // Increment by 5
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
static incrementIdBy = 1;
|
|
231
|
+
/**
|
|
232
|
+
* Randomly generate the increment amount.
|
|
233
|
+
*
|
|
234
|
+
* Can be:
|
|
235
|
+
* - `true`: Generate random increment between 1-10
|
|
236
|
+
* - Function: Custom random increment generator
|
|
237
|
+
* - `false`: Use `incrementIdBy` or default to 1
|
|
238
|
+
*
|
|
239
|
+
* @default false
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* class User extends Model {
|
|
244
|
+
* public static randomIncrement = true; // Random 1-10
|
|
245
|
+
* }
|
|
246
|
+
*
|
|
247
|
+
* class Product extends Model {
|
|
248
|
+
* public static randomIncrement = () => Math.floor(Math.random() * 100);
|
|
249
|
+
* }
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
static randomIncrement;
|
|
253
|
+
/**
|
|
254
|
+
* Created at column name.
|
|
255
|
+
*/
|
|
256
|
+
static createdAtColumn;
|
|
257
|
+
/**
|
|
258
|
+
* Updated at column name.
|
|
259
|
+
*/
|
|
260
|
+
static updatedAtColumn;
|
|
261
|
+
/**
|
|
262
|
+
* Delete strategy for this model.
|
|
263
|
+
*
|
|
264
|
+
* Controls how models are deleted:
|
|
265
|
+
* - `"trash"` - Moves to trash collection, then deletes
|
|
266
|
+
* - `"permanent"` - Direct deletion (hard delete)
|
|
267
|
+
* - `"soft"` - Sets deletedAt timestamp (soft delete)
|
|
268
|
+
*
|
|
269
|
+
* Can be overridden by destroy() options.
|
|
270
|
+
* Falls back to data source default if not set.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* class User extends Model {
|
|
275
|
+
* public static deleteStrategy: DeleteStrategy = "soft";
|
|
276
|
+
* }
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
static deleteStrategy;
|
|
280
|
+
/**
|
|
281
|
+
* Column name for soft delete timestamp.
|
|
282
|
+
*
|
|
283
|
+
* Used when delete strategy is "soft".
|
|
284
|
+
*
|
|
285
|
+
* @default "deletedAt"
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* class User extends Model {
|
|
290
|
+
* public static deletedAtColumn = "archivedAt";
|
|
291
|
+
* }
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
static deletedAtColumn = "deletedAt";
|
|
295
|
+
/**
|
|
296
|
+
* Trash table/collection name override.
|
|
297
|
+
*
|
|
298
|
+
* If not set, defaults to `{table}Trash` or data source default.
|
|
299
|
+
* Used when delete strategy is "trash".
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* class User extends Model {
|
|
304
|
+
* public static trashTable = "userRecycleBin";
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
static trashTable;
|
|
309
|
+
/**
|
|
310
|
+
* Global scopes that are automatically applied to all queries.
|
|
311
|
+
* These scopes are inherited by child models.
|
|
312
|
+
*/
|
|
313
|
+
static globalScopes = new Map();
|
|
314
|
+
/**
|
|
315
|
+
* Local scopes that can be manually applied to queries.
|
|
316
|
+
* These are reusable query snippets that developers opt into.
|
|
317
|
+
*/
|
|
318
|
+
static localScopes = new Map();
|
|
319
|
+
/**
|
|
320
|
+
* Relation definitions for this model.
|
|
321
|
+
*
|
|
322
|
+
* Define relationships to other models using helper functions:
|
|
323
|
+
* - `hasMany()` - One-to-many (User has many Posts)
|
|
324
|
+
* - `hasOne()` - One-to-one (User has one Profile)
|
|
325
|
+
* - `belongsTo()` - Inverse of hasMany/hasOne (Post belongs to User)
|
|
326
|
+
* - `belongsToMany()` - Many-to-many with pivot table (User has many Roles)
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* import { hasMany, belongsTo, belongsToMany, hasOne } from "@warlock.js/cascade";
|
|
331
|
+
*
|
|
332
|
+
* class User extends Model {
|
|
333
|
+
* public posts?: Post[]; // Optional: for TypeScript autocomplete
|
|
334
|
+
*
|
|
335
|
+
* static relations = {
|
|
336
|
+
* posts: hasMany("Post"),
|
|
337
|
+
* profile: hasOne("Profile"),
|
|
338
|
+
* organization: belongsTo("Organization"),
|
|
339
|
+
* roles: belongsToMany("Role", { pivot: "user_roles" }),
|
|
340
|
+
* };
|
|
341
|
+
* }
|
|
342
|
+
*
|
|
343
|
+
* // Usage:
|
|
344
|
+
* const users = await User.query().with("posts").get();
|
|
345
|
+
* console.log(users[0].posts); // Post[]
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
static relations = {};
|
|
349
|
+
/**
|
|
350
|
+
* Flag indicating whether this model instance represents a new (unsaved) record.
|
|
351
|
+
*
|
|
352
|
+
* - `true`: The model has not been persisted to the database yet
|
|
353
|
+
* - `false`: The model represents an existing database record
|
|
354
|
+
*
|
|
355
|
+
* This flag is used by the writer to determine whether to perform an insert or update.
|
|
356
|
+
*/
|
|
357
|
+
isNew = true;
|
|
358
|
+
/**
|
|
359
|
+
* The raw mutable data backing this model instance.
|
|
360
|
+
*
|
|
361
|
+
* All field accessors (get, set, merge, etc.) operate on this object.
|
|
362
|
+
*/
|
|
363
|
+
data;
|
|
364
|
+
/**
|
|
365
|
+
* Dirty tracker that monitors changes to the model's data.
|
|
366
|
+
*
|
|
367
|
+
* Tracks:
|
|
368
|
+
* - Which fields have been modified (dirty columns)
|
|
369
|
+
* - Which fields have been removed
|
|
370
|
+
* - Original vs. current values for each dirty field
|
|
371
|
+
*
|
|
372
|
+
* Used by the writer to generate efficient partial update payloads.
|
|
373
|
+
*/
|
|
374
|
+
dirtyTracker;
|
|
375
|
+
/**
|
|
376
|
+
* Model instance events.
|
|
377
|
+
* Allows registering listeners for lifecycle events on this specific instance.
|
|
378
|
+
*/
|
|
379
|
+
events = new modelEvents.ModelEvents();
|
|
380
|
+
/**
|
|
381
|
+
* Map of loaded relations for this model instance.
|
|
382
|
+
*
|
|
383
|
+
* Populated automatically when using `with()` for eager loading,
|
|
384
|
+
* or when calling `load()` for lazy loading.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* ```typescript
|
|
388
|
+
* const user = await User.query().with("posts").first();
|
|
389
|
+
* console.log(user.loadedRelations.get("posts")); // Post[]
|
|
390
|
+
*
|
|
391
|
+
* // Also accessible as direct properties:
|
|
392
|
+
* console.log(user.posts); // Post[]\n * ```
|
|
393
|
+
*/
|
|
394
|
+
loadedRelations = new Map();
|
|
395
|
+
/**
|
|
396
|
+
* Column name for active status.
|
|
397
|
+
*/
|
|
398
|
+
isActiveColumn = "isActive";
|
|
399
|
+
/**
|
|
400
|
+
* Constructs a new model instance with optional initial data.
|
|
401
|
+
*
|
|
402
|
+
* Initializes the dirty tracker with a snapshot of the provided data.
|
|
403
|
+
*
|
|
404
|
+
* @param initialData - Partial data to populate the model
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```typescript
|
|
408
|
+
* const user = new User({ name: "Alice", email: "alice@example.com" });
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
constructor(initialData = {}) {
|
|
412
|
+
this.data = initialData;
|
|
413
|
+
this.dirtyTracker = this.self().getDriver().getDirtyTracker(this.data);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Lazily load one or more relations for this model instance.
|
|
417
|
+
*
|
|
418
|
+
* This method loads relations on-demand after the model has been fetched.
|
|
419
|
+
* The loaded relations are attached directly to the model instance and
|
|
420
|
+
* also stored in `loadedRelations` map.
|
|
421
|
+
*
|
|
422
|
+
* @param relations - Relation name(s) to load
|
|
423
|
+
* @returns This model instance for chaining
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* const user = await User.first();
|
|
428
|
+
*
|
|
429
|
+
* // Load single relation
|
|
430
|
+
* await user.load("posts");
|
|
431
|
+
* console.log(user.posts); // Post[]
|
|
432
|
+
*
|
|
433
|
+
* // Load multiple relations
|
|
434
|
+
* await user.load("posts", "organization");
|
|
435
|
+
*
|
|
436
|
+
* // Chain with other operations
|
|
437
|
+
* const posts = await user.load("posts").then(() => user.posts);
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
async load(...relations) {
|
|
441
|
+
const ModelClass = this.constructor;
|
|
442
|
+
const loader = new relationLoader.RelationLoader([this], ModelClass);
|
|
443
|
+
await loader.load(relations);
|
|
444
|
+
return this;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Check if a relation has been loaded.
|
|
448
|
+
*
|
|
449
|
+
* @param relationName - Name of the relation to check
|
|
450
|
+
* @returns True if the relation has been loaded
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```typescript
|
|
454
|
+
* const user = await User.first();
|
|
455
|
+
*
|
|
456
|
+
* console.log(user.isLoaded("posts")); // false
|
|
457
|
+
* await user.load("posts");
|
|
458
|
+
* console.log(user.isLoaded("posts")); // true
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
isLoaded(relationName) {
|
|
462
|
+
return this.loadedRelations.has(relationName);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get a loaded relation by name.
|
|
466
|
+
*
|
|
467
|
+
* Returns undefined if the relation has not been loaded.
|
|
468
|
+
*
|
|
469
|
+
* @param relationName - Name of the relation to get
|
|
470
|
+
* @returns The loaded relation data, or undefined
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```typescript
|
|
474
|
+
* const user = await User.query().with("posts").first();
|
|
475
|
+
*
|
|
476
|
+
* const posts = user.getRelation<Post[]>("posts");
|
|
477
|
+
* console.log(posts?.length);
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
getRelation(relationName) {
|
|
481
|
+
return this.loadedRelations.get(relationName);
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Get a model class by its name from the global registry.
|
|
485
|
+
*
|
|
486
|
+
* Models must be decorated with @RegisterModel() to be available in the registry.
|
|
487
|
+
*
|
|
488
|
+
* @param name - The model class name
|
|
489
|
+
* @returns The model class or undefined if not found
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* ```typescript
|
|
493
|
+
* const UserModel = Model.getModel("User");
|
|
494
|
+
* if (UserModel) {
|
|
495
|
+
* const user = await UserModel.find(1);
|
|
496
|
+
* }
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
static getModel(name) {
|
|
500
|
+
return registerModel.getModelFromRegistry(name);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get all registered models from the global registry.
|
|
504
|
+
*
|
|
505
|
+
* Only models decorated with @RegisterModel() will appear here.
|
|
506
|
+
*
|
|
507
|
+
* @returns A Map of all registered model classes by name
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* const allModels = Model.getAllModels();
|
|
512
|
+
* for (const [name, ModelClass] of allModels) {
|
|
513
|
+
* console.log(`Found model: ${name} with table: ${ModelClass.table}`);
|
|
514
|
+
* }
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
static getAllModels() {
|
|
518
|
+
return registerModel.getAllModelsFromRegistry();
|
|
519
|
+
}
|
|
520
|
+
// ============================================================================
|
|
521
|
+
// STATIC SYNC METHODS
|
|
522
|
+
// ============================================================================
|
|
523
|
+
/**
|
|
524
|
+
* Create a sync operation for a single embedded document.
|
|
525
|
+
*
|
|
526
|
+
* When this model is updated, the target model's field
|
|
527
|
+
* will be updated with the embedded data.
|
|
528
|
+
*
|
|
529
|
+
* @param TargetModel - Target model class that receives data
|
|
530
|
+
* @param targetField - Field path in target model
|
|
531
|
+
* @returns Sync operation for chaining configuration
|
|
532
|
+
*
|
|
533
|
+
* @example
|
|
534
|
+
* ```typescript
|
|
535
|
+
* // When Category updates, update Product.category
|
|
536
|
+
* Category.sync(Product, "category");
|
|
537
|
+
* ```
|
|
538
|
+
*/
|
|
539
|
+
static sync(TargetModel, targetField) {
|
|
540
|
+
return modelSync.modelSync.sync(this, TargetModel, targetField);
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Create a sync operation for an array of embedded documents.
|
|
544
|
+
*
|
|
545
|
+
* When this model is updated, the corresponding element
|
|
546
|
+
* in the target model's array field will be updated.
|
|
547
|
+
*
|
|
548
|
+
* @param TargetModel - Target model class that receives data
|
|
549
|
+
* @param targetField - Array field path in target model
|
|
550
|
+
* @returns Sync operation for chaining configuration
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* ```typescript
|
|
554
|
+
* // When Tag updates, update Post.tags[i] where tags[i].id matches
|
|
555
|
+
* Tag.syncMany(Post, "tags").identifyBy("id");
|
|
556
|
+
* ```
|
|
557
|
+
*/
|
|
558
|
+
static syncMany(TargetModel, targetField) {
|
|
559
|
+
return modelSync.modelSync.syncMany(this, TargetModel, targetField);
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Get model id
|
|
563
|
+
*/
|
|
564
|
+
get id() {
|
|
565
|
+
return this.get("id");
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Get uuid
|
|
569
|
+
*/
|
|
570
|
+
get uuid() {
|
|
571
|
+
return this.get("id");
|
|
572
|
+
}
|
|
573
|
+
get(field, defaultValue) {
|
|
574
|
+
return accessorMethods.getFieldValue(this, field, defaultValue);
|
|
575
|
+
}
|
|
576
|
+
only(fields) {
|
|
577
|
+
return accessorMethods.getOnlyFields(this, fields);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Get a string value
|
|
581
|
+
*/
|
|
582
|
+
string(key, defaultValue) {
|
|
583
|
+
return accessorMethods.getStringField(this, key, defaultValue);
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Get a number value
|
|
587
|
+
*/
|
|
588
|
+
number(key, defaultValue) {
|
|
589
|
+
return accessorMethods.getNumberField(this, key, defaultValue);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Get a boolean value
|
|
593
|
+
*/
|
|
594
|
+
boolean(key, defaultValue) {
|
|
595
|
+
return accessorMethods.getBooleanField(this, key, defaultValue);
|
|
596
|
+
}
|
|
597
|
+
set(field, value) {
|
|
598
|
+
return accessorMethods.setFieldValue(this, field, value);
|
|
599
|
+
}
|
|
600
|
+
has(field) {
|
|
601
|
+
return accessorMethods.hasField(this, field);
|
|
602
|
+
}
|
|
603
|
+
increment(field, amount) {
|
|
604
|
+
return accessorMethods.incrementField(this, field, amount);
|
|
605
|
+
}
|
|
606
|
+
decrement(field, amount) {
|
|
607
|
+
return accessorMethods.decrementField(this, field, amount);
|
|
608
|
+
}
|
|
609
|
+
unset(...fields) {
|
|
610
|
+
return accessorMethods.unsetFields(this, ...fields);
|
|
611
|
+
}
|
|
612
|
+
merge(values) {
|
|
613
|
+
return accessorMethods.mergeFields(this, values);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Perform atomoic update from current model instance
|
|
617
|
+
* Please note that it would require the id to be existing in the current
|
|
618
|
+
* model instance
|
|
619
|
+
* @returns number of affected records
|
|
620
|
+
*/
|
|
621
|
+
async atomicUpdate(operations) {
|
|
622
|
+
return metaMethods.performAtomicUpdate(this, operations);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Perform atomic increment
|
|
626
|
+
* This would issue a query update and update the given field without
|
|
627
|
+
* saving the model
|
|
628
|
+
*/
|
|
629
|
+
async atomicIncrement(field, amount = 1) {
|
|
630
|
+
return metaMethods.performAtomicIncrement(this, field, amount);
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Perform atomic decrement
|
|
634
|
+
* This would issue a query update and update the given field without
|
|
635
|
+
* saving the model
|
|
636
|
+
*/
|
|
637
|
+
async atomicDecrement(field, amount = 1) {
|
|
638
|
+
return metaMethods.performAtomicDecrement(this, field, amount);
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Determine if current model is active
|
|
642
|
+
*/
|
|
643
|
+
get isActive() {
|
|
644
|
+
return this.get(this.isActiveColumn);
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Get created at date
|
|
648
|
+
*/
|
|
649
|
+
get createdAt() {
|
|
650
|
+
const createdAtColumn = this.self().createdAtColumn;
|
|
651
|
+
if (!createdAtColumn)
|
|
652
|
+
return;
|
|
653
|
+
return this.get(createdAtColumn);
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Get updated at date
|
|
657
|
+
*/
|
|
658
|
+
get updatedAt() {
|
|
659
|
+
const updatedAtColumn = this.self().updatedAtColumn;
|
|
660
|
+
if (!updatedAtColumn)
|
|
661
|
+
return;
|
|
662
|
+
return this.get(updatedAtColumn);
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Check if current model record is created by the given user model
|
|
666
|
+
*/
|
|
667
|
+
isCreatedBy(user) {
|
|
668
|
+
return this.get(`createdBy.id`) === user.id;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Checks whether the model's data has changed since instantiation or last reset.
|
|
672
|
+
*
|
|
673
|
+
* @returns `true` if any fields have been modified or removed, `false` otherwise
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```typescript
|
|
677
|
+
* const user = new User({ name: "Alice" });
|
|
678
|
+
* user.hasChanges(); // false
|
|
679
|
+
* user.set("name", "Bob");
|
|
680
|
+
* user.hasChanges(); // true
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
hasChanges() {
|
|
684
|
+
return dirtyMethods.checkHasChanges(this);
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Check if the given column has been modified.
|
|
688
|
+
*
|
|
689
|
+
* @param column - The column name to check
|
|
690
|
+
* @returns `true` if the column has been modified, `false` otherwise
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```typescript
|
|
694
|
+
* user.set("name", "Bob");
|
|
695
|
+
* user.isDirty("name"); // true
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
isDirty(column) {
|
|
699
|
+
return dirtyMethods.checkIsDirty(this, column);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Retrieves all dirty columns with their old and new values.
|
|
703
|
+
*
|
|
704
|
+
* @returns A record mapping each dirty column to its previous and current value
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```typescript
|
|
708
|
+
* user.set("name", "Bob");
|
|
709
|
+
* user.getDirtyColumnsWithValues();
|
|
710
|
+
* // { name: { oldValue: "Alice", newValue: "Bob" } }
|
|
711
|
+
* ```
|
|
712
|
+
*/
|
|
713
|
+
getDirtyColumnsWithValues() {
|
|
714
|
+
return dirtyMethods.getDirtyColumnsWithValues(this);
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Lists all columns that have been removed from the model's data.
|
|
718
|
+
*
|
|
719
|
+
* @returns An array of field names that were present initially but have been unset
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```typescript
|
|
723
|
+
* user.unset("tempField");
|
|
724
|
+
* user.getRemovedColumns(); // ["tempField"]
|
|
725
|
+
* ```
|
|
726
|
+
*/
|
|
727
|
+
getRemovedColumns() {
|
|
728
|
+
return dirtyMethods.getRemovedColumns(this);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Lists all columns that have been modified since instantiation or last reset.
|
|
732
|
+
*
|
|
733
|
+
* @returns An array of field names that have changed
|
|
734
|
+
*
|
|
735
|
+
* @example
|
|
736
|
+
* ```typescript
|
|
737
|
+
* user.set("name", "Bob");
|
|
738
|
+
* user.getDirtyColumns(); // ["name"]
|
|
739
|
+
* ```
|
|
740
|
+
*/
|
|
741
|
+
getDirtyColumns() {
|
|
742
|
+
return dirtyMethods.getDirtyColumns(this);
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Emits a lifecycle event to both per-model and global listeners.
|
|
746
|
+
*
|
|
747
|
+
* This method is public so that external services (like the writer) can trigger
|
|
748
|
+
* lifecycle events when appropriate.
|
|
749
|
+
*
|
|
750
|
+
* @param event - The event name (e.g., "saving", "created", "deleting")
|
|
751
|
+
* @param context - Optional context data to pass to listeners
|
|
752
|
+
*
|
|
753
|
+
* @example
|
|
754
|
+
* ```typescript
|
|
755
|
+
* await user.emitEvent("saving");
|
|
756
|
+
* await user.emitEvent("validated", { errors: [] });
|
|
757
|
+
* ```
|
|
758
|
+
*/
|
|
759
|
+
async emitEvent(event, context) {
|
|
760
|
+
return instanceEventMethods.emitModelEvent(this, event, context);
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Register a listener for a model lifecycle event on this instance.
|
|
764
|
+
*
|
|
765
|
+
* @param event - Event name (e.g., "saving", "updated")
|
|
766
|
+
* @param listener - Callback function
|
|
767
|
+
* @returns Unsubscribe function
|
|
768
|
+
*/
|
|
769
|
+
on(event, listener) {
|
|
770
|
+
return instanceEventMethods.onModelEvent(this, event, listener);
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Register a one-time listener for a model lifecycle event on this instance.
|
|
774
|
+
*
|
|
775
|
+
* @param event - Event name
|
|
776
|
+
* @param listener - Callback function
|
|
777
|
+
* @returns Unsubscribe function
|
|
778
|
+
*/
|
|
779
|
+
once(event, listener) {
|
|
780
|
+
return instanceEventMethods.onceModelEvent(this, event, listener);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Remove a listener from this instance.
|
|
784
|
+
*
|
|
785
|
+
* @param event - Event name
|
|
786
|
+
* @param listener - Callback function to remove
|
|
787
|
+
*/
|
|
788
|
+
off(event, listener) {
|
|
789
|
+
instanceEventMethods.offModelEvent(this, event, listener);
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Resolves the data source associated with this model.
|
|
793
|
+
*
|
|
794
|
+
* Resolution order:
|
|
795
|
+
* 1. If `dataSource` is a string, looks it up in the data-source registry
|
|
796
|
+
* 2. If `dataSource` is a DataSource instance, returns it directly
|
|
797
|
+
* 3. Otherwise, returns the default data source from the registry
|
|
798
|
+
*
|
|
799
|
+
* @returns The resolved DataSource instance
|
|
800
|
+
* @throws Error if no data source is found
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```typescript
|
|
804
|
+
* class User extends Model {
|
|
805
|
+
* public static dataSource = "primary";
|
|
806
|
+
* }
|
|
807
|
+
*
|
|
808
|
+
* const ds = User.getDataSource();
|
|
809
|
+
* ```
|
|
810
|
+
*/
|
|
811
|
+
static getDataSource() {
|
|
812
|
+
return queryMethods.resolveDataSource(this);
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Get driver instance
|
|
816
|
+
*/
|
|
817
|
+
static getDriver() {
|
|
818
|
+
return this.getDataSource().driver;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Generate next id and set it to current model's id
|
|
822
|
+
*/
|
|
823
|
+
async generateNextId() {
|
|
824
|
+
return metaMethods.generateModelNextId(this);
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Apply model defaults from data source configuration.
|
|
828
|
+
*
|
|
829
|
+
* This is called automatically by getDataSource() the first time
|
|
830
|
+
* a model accesses its data source. Defaults are only applied if
|
|
831
|
+
* the model doesn't already have its own value set.
|
|
832
|
+
*
|
|
833
|
+
* The hierarchy is:
|
|
834
|
+
* 1. Model static property (highest priority - skipped here)
|
|
835
|
+
* 2. Database config modelDefaults (passed here)
|
|
836
|
+
* 3. Driver modelDefaults (merged before passing here)
|
|
837
|
+
* 4. Framework defaults (fallback values in the code)
|
|
838
|
+
*
|
|
839
|
+
* @param defaults - Model default configuration from data source
|
|
840
|
+
*/
|
|
841
|
+
static applyModelDefaults(defaults) {
|
|
842
|
+
metaMethods.applyDefaultsToModel(this, defaults);
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Add a global scope that is automatically applied to all queries.
|
|
846
|
+
*
|
|
847
|
+
* Global scopes are inherited by child models and applied before query execution.
|
|
848
|
+
* Use for security filters, multi-tenancy, soft deletes, etc.
|
|
849
|
+
*
|
|
850
|
+
* @param name - Unique name for the scope
|
|
851
|
+
* @param callback - Function that modifies the query
|
|
852
|
+
* @param options - Scope options (timing: 'before' | 'after')
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```typescript
|
|
856
|
+
* // Multi-tenancy scope
|
|
857
|
+
* Model.addGlobalScope('tenant', (query) => {
|
|
858
|
+
* query.where('tenantId', getCurrentTenant());
|
|
859
|
+
* }, { timing: 'before' });
|
|
860
|
+
*
|
|
861
|
+
* // Soft delete scope
|
|
862
|
+
* User.addGlobalScope('notDeleted', (query) => {
|
|
863
|
+
* query.whereNull('deletedAt');
|
|
864
|
+
* });
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
static addGlobalScope(name, callback, options = {}) {
|
|
868
|
+
scopeMethods.addGlobalModelScope(this, name, callback, options);
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Remove a global scope by name.
|
|
872
|
+
*
|
|
873
|
+
* @param name - Name of the scope to remove
|
|
874
|
+
*
|
|
875
|
+
* @example
|
|
876
|
+
* ```typescript
|
|
877
|
+
* Model.removeGlobalScope('tenant');
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
880
|
+
static removeGlobalScope(name) {
|
|
881
|
+
scopeMethods.removeGlobalModelScope(this, name);
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Add a local scope that can be manually applied to queries.
|
|
885
|
+
*
|
|
886
|
+
* Local scopes are reusable query snippets that developers opt into.
|
|
887
|
+
* They are not automatically applied.
|
|
888
|
+
*
|
|
889
|
+
* @param name - Unique name for the scope
|
|
890
|
+
* @param callback - Function that modifies the query
|
|
891
|
+
*
|
|
892
|
+
* @example
|
|
893
|
+
* ```typescript
|
|
894
|
+
* // Define reusable scopes
|
|
895
|
+
* User.addScope('active', (query) => {
|
|
896
|
+
* query.where('isActive', true);
|
|
897
|
+
* });
|
|
898
|
+
*
|
|
899
|
+
* User.addScope('admins', (query) => {
|
|
900
|
+
* query.where('role', 'admin');
|
|
901
|
+
* });
|
|
902
|
+
*
|
|
903
|
+
* // Use explicitly
|
|
904
|
+
* await User.query().scope('active').get();
|
|
905
|
+
* await User.query().scope('admins').get();
|
|
906
|
+
* ```
|
|
907
|
+
*/
|
|
908
|
+
static addScope(name, callback) {
|
|
909
|
+
scopeMethods.addLocalModelScope(this, name, callback);
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Remove a local scope by name.
|
|
913
|
+
*
|
|
914
|
+
* @param name - Name of the scope to remove
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```typescript
|
|
918
|
+
* User.removeScope('active');
|
|
919
|
+
* ```
|
|
920
|
+
*/
|
|
921
|
+
static removeScope(name) {
|
|
922
|
+
scopeMethods.removeLocalModelScope(this, name);
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Create a new query builder for this model
|
|
926
|
+
*/
|
|
927
|
+
static query() {
|
|
928
|
+
return queryMethods.buildQuery(this, Model);
|
|
929
|
+
}
|
|
930
|
+
static with(...args) {
|
|
931
|
+
return this.query().with(...args);
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Load relations using database JOINs in a single query.
|
|
935
|
+
*
|
|
936
|
+
* Unlike `with()` which uses separate queries, `joinWith()` uses
|
|
937
|
+
* LEFT JOIN (SQL) or $lookup (MongoDB) to fetch related data
|
|
938
|
+
* in a single query. The related data is hydrated into proper
|
|
939
|
+
* model instances and attached to the main model.
|
|
940
|
+
*
|
|
941
|
+
* Best for: belongsTo and hasOne relations where you need
|
|
942
|
+
* efficient single-query loading.
|
|
943
|
+
*
|
|
944
|
+
* @param relations - Relation names to load via JOIN
|
|
945
|
+
* @returns Query builder for chaining
|
|
946
|
+
*
|
|
947
|
+
* @example
|
|
948
|
+
* ```typescript
|
|
949
|
+
* // Single relation
|
|
950
|
+
* const post = await Post.joinWith("author").first();
|
|
951
|
+
* console.log(post.author); // User model instance
|
|
952
|
+
* console.log(post.data); // { id, title, authorId } - no author data
|
|
953
|
+
*
|
|
954
|
+
* // Multiple relations
|
|
955
|
+
* const post = await Post.joinWith("author", "category").first();
|
|
956
|
+
* ```
|
|
957
|
+
*/
|
|
958
|
+
static joinWith(...relations) {
|
|
959
|
+
return this.query().joinWith(...relations);
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Create new query builder.
|
|
963
|
+
*
|
|
964
|
+
* If the model has a static `builder` property set to a query builder class,
|
|
965
|
+
* it will be instantiated instead of the default driver query builder.
|
|
966
|
+
*
|
|
967
|
+
* @example
|
|
968
|
+
* ```typescript
|
|
969
|
+
* class UserQueryBuilder<T = User> extends MongoQueryBuilder<T> {
|
|
970
|
+
* active() { return this.where("isActive", true); }
|
|
971
|
+
* }
|
|
972
|
+
*
|
|
973
|
+
* class User extends Model {
|
|
974
|
+
* static builder = UserQueryBuilder; // That's it! ✨
|
|
975
|
+
* }
|
|
976
|
+
*
|
|
977
|
+
* // Now User.query() returns UserQueryBuilder<User> with autocomplete!
|
|
978
|
+
* ```
|
|
979
|
+
*/
|
|
980
|
+
static newQueryBuilder() {
|
|
981
|
+
return queryMethods.buildNewQueryBuilder(this);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Get First matched record for the given filter
|
|
985
|
+
*/
|
|
986
|
+
static async first(filter) {
|
|
987
|
+
return queryMethods.findFirst(this, filter);
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Get last matched record for the given filter
|
|
991
|
+
*/
|
|
992
|
+
static async last(filter) {
|
|
993
|
+
return queryMethods.findLast(this, filter);
|
|
994
|
+
}
|
|
995
|
+
static where(...args) {
|
|
996
|
+
return this.query().where(...args);
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Count the number of records in the table
|
|
1000
|
+
* @param filter - The filter to apply to the query
|
|
1001
|
+
*/
|
|
1002
|
+
static count(filter) {
|
|
1003
|
+
return queryMethods.countRecords(this, filter);
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Find record by id
|
|
1007
|
+
*/
|
|
1008
|
+
static async find(id) {
|
|
1009
|
+
return queryMethods.findById(this, id);
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Get all records from the table
|
|
1013
|
+
*
|
|
1014
|
+
* @param filter - The filter to apply to the query
|
|
1015
|
+
* @returns All records from the table
|
|
1016
|
+
*/
|
|
1017
|
+
static async all(filter) {
|
|
1018
|
+
return queryMethods.findAll(this, filter);
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Perform pagination
|
|
1022
|
+
*/
|
|
1023
|
+
static async paginate(options = {}) {
|
|
1024
|
+
return queryMethods.paginateRecords(this, options);
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Get latest records from the table
|
|
1028
|
+
*
|
|
1029
|
+
* @param filter - The filter to apply to the query
|
|
1030
|
+
*/
|
|
1031
|
+
static async latest(filter) {
|
|
1032
|
+
return queryMethods.findLatest(this, filter);
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Increment the given field by the given amount using atomic update
|
|
1036
|
+
*
|
|
1037
|
+
* @example ```typescript
|
|
1038
|
+
* // Increase age by 1 for user id 1
|
|
1039
|
+
* User.increment({id: 1}, "age", 1);
|
|
1040
|
+
* // Increase age by 1 and views by 2 for user id 1
|
|
1041
|
+
* User.increment({id: 1}, {age: 1, views: 2});
|
|
1042
|
+
* ```
|
|
1043
|
+
*/
|
|
1044
|
+
static increase(filter, field, amount) {
|
|
1045
|
+
return queryMethods.increaseField(this, filter, field, amount);
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Decrement the given field by the given amount using atomic update
|
|
1049
|
+
* @example ```typescript
|
|
1050
|
+
* // Decrease age by 1 for user id 1
|
|
1051
|
+
* User.decrement({id: 1}, "age", 1);
|
|
1052
|
+
* // Decrease age by 1 and views by 2 for user id 1
|
|
1053
|
+
* User.decrement({id: 1}, {age: 1, views: 2});
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
static decrease(filter, field, amount) {
|
|
1057
|
+
return queryMethods.decreaseField(this, filter, field, amount);
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Perform atomic operation
|
|
1061
|
+
* Example
|
|
1062
|
+
*
|
|
1063
|
+
* ```typescript
|
|
1064
|
+
* const user = await User.atomic({id: 1}, {$inc: {age: 1}})
|
|
1065
|
+
* Returns user model with updated age
|
|
1066
|
+
*/
|
|
1067
|
+
static async atomic(filter, operations) {
|
|
1068
|
+
return queryMethods.performAtomic(this, filter, operations);
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Perform a direct update $set for the given id
|
|
1072
|
+
*/
|
|
1073
|
+
static async update(id, data) {
|
|
1074
|
+
return queryMethods.updateById(this, id, data);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Find one and update multiple records that matches the provided filter and return the updated record
|
|
1078
|
+
* @param filter - Filter conditions
|
|
1079
|
+
* @param update - Update operations ($set, $unset, $inc)
|
|
1080
|
+
* @returns The updated records
|
|
1081
|
+
*/
|
|
1082
|
+
static async findAndUpdate(filter, update) {
|
|
1083
|
+
return queryMethods.findAndUpdateRecords(this, filter, update);
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Find one and update a single record that matches the provided filter and return the updated record
|
|
1087
|
+
* @param filter - Filter conditions
|
|
1088
|
+
* @param update - Update operations ($set, $unset, $inc)
|
|
1089
|
+
* @returns The updated record or null
|
|
1090
|
+
*/
|
|
1091
|
+
static async findOneAndUpdate(filter, update) {
|
|
1092
|
+
return queryMethods.findOneAndUpdateRecord(this, filter, update);
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Find and replace the entire document that matches the provided filter and return the replaced document
|
|
1096
|
+
*/
|
|
1097
|
+
static async findAndReplace(filter, document) {
|
|
1098
|
+
return queryMethods.findAndReplaceRecord(this, filter, document);
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Destroy (delete) the current model instance from the database.
|
|
1102
|
+
*
|
|
1103
|
+
* Emits lifecycle events:
|
|
1104
|
+
* - `deleting` - Before deletion
|
|
1105
|
+
* - `deleted` - After successful deletion
|
|
1106
|
+
*
|
|
1107
|
+
* @param options - Destroy options (strategy override, skipEvents)
|
|
1108
|
+
* @throws {Error} If the model is new (not saved) or if deletion fails
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```typescript
|
|
1112
|
+
* const user = await User.find(1);
|
|
1113
|
+
* await user.destroy(); // Uses default strategy
|
|
1114
|
+
* await user.destroy({ strategy: "permanent" }); // Override strategy
|
|
1115
|
+
* await user.destroy({ skipEvents: true }); // Silent delete
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
1118
|
+
async destroy(options) {
|
|
1119
|
+
return deleteMethods.destroyModel(this, options);
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Get the class constructor from an instance.
|
|
1123
|
+
*
|
|
1124
|
+
* This helper method allows instance methods to access static properties
|
|
1125
|
+
* and methods of the model class in a type-safe way.
|
|
1126
|
+
*
|
|
1127
|
+
* @returns The model class constructor
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* ```typescript
|
|
1131
|
+
* const constructor = this.self();
|
|
1132
|
+
* const table = constructor.table;
|
|
1133
|
+
* await constructor.deleteOne({ id: 1 });
|
|
1134
|
+
* ```
|
|
1135
|
+
*/
|
|
1136
|
+
self() {
|
|
1137
|
+
return this.constructor;
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Creates an immutable clone of the model with its current state.
|
|
1141
|
+
*
|
|
1142
|
+
* The cloned model:
|
|
1143
|
+
* - Contains a deep copy of all current data
|
|
1144
|
+
* - Has frozen (immutable) data that cannot be modified
|
|
1145
|
+
* - Preserves the `isNew` flag from the original
|
|
1146
|
+
* - Has no dirty changes (clean state)
|
|
1147
|
+
* - Cannot be saved or modified
|
|
1148
|
+
*
|
|
1149
|
+
* This is useful for:
|
|
1150
|
+
* - Creating snapshots of model state
|
|
1151
|
+
* - Passing read-only model data to other parts of the application
|
|
1152
|
+
* - Preventing accidental mutations
|
|
1153
|
+
* - Maintaining historical records
|
|
1154
|
+
*
|
|
1155
|
+
* @returns A new immutable model instance with the current state
|
|
1156
|
+
*
|
|
1157
|
+
* @example
|
|
1158
|
+
* ```typescript
|
|
1159
|
+
* const user = new User({ name: "Alice", email: "alice@example.com" });
|
|
1160
|
+
* await user.save();
|
|
1161
|
+
*
|
|
1162
|
+
* // Create an immutable snapshot
|
|
1163
|
+
* const snapshot = user.clone();
|
|
1164
|
+
*
|
|
1165
|
+
* // This will throw an error because the clone is immutable
|
|
1166
|
+
* snapshot.set("name", "Bob"); // TypeError: Cannot assign to read only property
|
|
1167
|
+
*
|
|
1168
|
+
* // Original can still be modified
|
|
1169
|
+
* user.set("name", "Bob");
|
|
1170
|
+
* await user.save();
|
|
1171
|
+
* ```
|
|
1172
|
+
*/
|
|
1173
|
+
clone() {
|
|
1174
|
+
return hydrationMethods.cloneModel(this);
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Recursively freezes an object and all its nested properties.
|
|
1178
|
+
*
|
|
1179
|
+
* @param obj - The object to freeze
|
|
1180
|
+
* @returns The frozen object
|
|
1181
|
+
*/
|
|
1182
|
+
deepFreeze(obj) {
|
|
1183
|
+
return hydrationMethods.deepFreezeObject(obj);
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Get table name
|
|
1187
|
+
*/
|
|
1188
|
+
getTableName() {
|
|
1189
|
+
return this.self().table;
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Get primary key name
|
|
1193
|
+
*/
|
|
1194
|
+
getPrimaryKey() {
|
|
1195
|
+
return this.self().primaryKey;
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Get model schema
|
|
1199
|
+
*/
|
|
1200
|
+
getSchema() {
|
|
1201
|
+
return this.self().schema;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Check if schema has the given key
|
|
1205
|
+
*/
|
|
1206
|
+
schemaHas(key) {
|
|
1207
|
+
return this.self().schema?.schema[key] !== undefined;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Get strict mode
|
|
1211
|
+
*/
|
|
1212
|
+
getStrictMode() {
|
|
1213
|
+
return this.self().strictMode;
|
|
1214
|
+
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Get data source (Connection)
|
|
1217
|
+
*/
|
|
1218
|
+
getConnection() {
|
|
1219
|
+
return this.self().getDataSource();
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Delete all matching documents from the table.
|
|
1223
|
+
*/
|
|
1224
|
+
static async delete(filter) {
|
|
1225
|
+
return deleteMethods.deleteRecords(this, filter);
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Delete a single matching document from the table.
|
|
1229
|
+
*/
|
|
1230
|
+
static async deleteOne(filter) {
|
|
1231
|
+
return deleteMethods.deleteOneRecord(this, filter);
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Restore a single deleted record by its ID.
|
|
1235
|
+
*
|
|
1236
|
+
* Automatically detects whether the record was deleted via "trash" or "soft" strategy.
|
|
1237
|
+
* Handles ID conflicts based on options.
|
|
1238
|
+
*
|
|
1239
|
+
* @param id - The primary key value of the record to restore
|
|
1240
|
+
* @param options - Restorer options (onIdConflict, skipEvents)
|
|
1241
|
+
* @returns The restored model instance
|
|
1242
|
+
*
|
|
1243
|
+
* @throws {Error} If record not found in trash or soft-deleted records
|
|
1244
|
+
* @throws {Error} If ID conflict and onIdConflict is "fail"
|
|
1245
|
+
*
|
|
1246
|
+
* @example
|
|
1247
|
+
* ```typescript
|
|
1248
|
+
* // Restore with default options (assign new ID if conflict)
|
|
1249
|
+
* const user = await User.restore(123);
|
|
1250
|
+
*
|
|
1251
|
+
* // Restore and fail if ID conflict
|
|
1252
|
+
* const user = await User.restore(123, { onIdConflict: "fail" });
|
|
1253
|
+
*
|
|
1254
|
+
* // Silent restore (skip events)
|
|
1255
|
+
* const user = await User.restore(123, { skipEvents: true });
|
|
1256
|
+
* ```
|
|
1257
|
+
*/
|
|
1258
|
+
static async restore(id, options) {
|
|
1259
|
+
return restoreMethods.restoreRecord(this, id, options);
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Restore all deleted records for the model's table.
|
|
1263
|
+
*
|
|
1264
|
+
* Restores all records from the trash table (if using trash strategy)
|
|
1265
|
+
* or all soft-deleted records (if using soft strategy).
|
|
1266
|
+
*
|
|
1267
|
+
* @param options - Restorer options (onIdConflict, skipEvents)
|
|
1268
|
+
* @returns Array of restored model instances
|
|
1269
|
+
*
|
|
1270
|
+
* @example
|
|
1271
|
+
* ```typescript
|
|
1272
|
+
* // Restore all with default options
|
|
1273
|
+
* const users = await User.restoreAll();
|
|
1274
|
+
*
|
|
1275
|
+
* // Restore all and fail on any ID conflict
|
|
1276
|
+
* const users = await User.restoreAll({ onIdConflict: "fail" });
|
|
1277
|
+
* ```
|
|
1278
|
+
*/
|
|
1279
|
+
static async restoreAll(options) {
|
|
1280
|
+
return restoreMethods.restoreAllRecords(this, options);
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Create a new record in database and return the model instance.
|
|
1284
|
+
*
|
|
1285
|
+
* The data type is automatically inferred from the model's schema type.
|
|
1286
|
+
*
|
|
1287
|
+
* @param data - Partial data matching the model's schema type
|
|
1288
|
+
* @returns The created model instance
|
|
1289
|
+
*
|
|
1290
|
+
* @example
|
|
1291
|
+
* ```typescript
|
|
1292
|
+
* // TypeScript automatically infers UserSchema from User model
|
|
1293
|
+
* const user = await User.create({
|
|
1294
|
+
* name: "Alice",
|
|
1295
|
+
* email: "alice@example.com",
|
|
1296
|
+
* age: 30
|
|
1297
|
+
* });
|
|
1298
|
+
* // Type: User (with UserSchema inferred)
|
|
1299
|
+
* ```
|
|
1300
|
+
*/
|
|
1301
|
+
static async create(data) {
|
|
1302
|
+
return writeMethods.createRecord(this, data);
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Create many documents and return an array of created models
|
|
1306
|
+
*/
|
|
1307
|
+
static async createMany(data) {
|
|
1308
|
+
return writeMethods.createManyRecords(this, data);
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Find a record or create it if not found.
|
|
1312
|
+
*
|
|
1313
|
+
* Does NOT update existing records - returns them as-is.
|
|
1314
|
+
* Useful when you want to ensure a record exists without modifying it.
|
|
1315
|
+
*
|
|
1316
|
+
* @param filter - Conditions to find by
|
|
1317
|
+
* @param data - Data to create if not found (merged with filter)
|
|
1318
|
+
* @returns Promise resolving to found or created model
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* ```typescript
|
|
1322
|
+
* // Ensure default admin exists (don't modify if exists)
|
|
1323
|
+
* const admin = await User.findOrCreate(
|
|
1324
|
+
* { email: "admin@example.com" },
|
|
1325
|
+
* { email: "admin@example.com", name: "Admin", role: "admin" }
|
|
1326
|
+
* );
|
|
1327
|
+
* // If admin exists, returns existing (password unchanged)
|
|
1328
|
+
* // If not found, creates new admin
|
|
1329
|
+
* ```
|
|
1330
|
+
*/
|
|
1331
|
+
static async findOrCreate(filter, data) {
|
|
1332
|
+
return writeMethods.findOrCreateRecord(this, filter, data);
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Upsert (insert or update) a record atomically.
|
|
1336
|
+
*
|
|
1337
|
+
* Uses the driver's native upsert operation for atomic insert-or-update.
|
|
1338
|
+
* More efficient than updateOrCreate as it's a single database operation.
|
|
1339
|
+
*
|
|
1340
|
+
* Includes full Model features:
|
|
1341
|
+
* - ID generation (if creating)
|
|
1342
|
+
* - createdAt timestamp (if creating)
|
|
1343
|
+
* - updatedAt timestamp (always)
|
|
1344
|
+
* - Validation & casting
|
|
1345
|
+
* - Lifecycle events
|
|
1346
|
+
*
|
|
1347
|
+
* @param filter - Conditions to find by (used for conflict detection)
|
|
1348
|
+
* @param data - Data to update or create (merged with filter)
|
|
1349
|
+
* @param options - Upsert options (conflictColumns for PostgreSQL, etc.)
|
|
1350
|
+
* @returns Promise resolving to upserted model
|
|
1351
|
+
*
|
|
1352
|
+
* @example
|
|
1353
|
+
* ```typescript
|
|
1354
|
+
* // PostgreSQL: upsert on unique email
|
|
1355
|
+
* const user = await User.upsert(
|
|
1356
|
+
* { email: "user@example.com" },
|
|
1357
|
+
* {
|
|
1358
|
+
* email: "user@example.com",
|
|
1359
|
+
* name: "John Updated",
|
|
1360
|
+
* lastSyncedAt: new Date()
|
|
1361
|
+
* },
|
|
1362
|
+
* { conflictColumns: ["email"] }
|
|
1363
|
+
* );
|
|
1364
|
+
*
|
|
1365
|
+
* // MongoDB: upsert by filter
|
|
1366
|
+
* const user = await User.upsert(
|
|
1367
|
+
* { externalId: "ext-123" },
|
|
1368
|
+
* {
|
|
1369
|
+
* externalId: "ext-123",
|
|
1370
|
+
* name: "John Updated",
|
|
1371
|
+
* email: "john.new@example.com"
|
|
1372
|
+
* }
|
|
1373
|
+
* );
|
|
1374
|
+
* ```
|
|
1375
|
+
*/
|
|
1376
|
+
static async upsert(filter, data, options) {
|
|
1377
|
+
return writeMethods.upsertRecord(this, filter, data, options);
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Update a record or create it if not found (upsert).
|
|
1381
|
+
*
|
|
1382
|
+
* @deprecated Use `upsert()` instead for better performance and atomicity.
|
|
1383
|
+
* This method is kept for backward compatibility but uses upsert internally.
|
|
1384
|
+
*
|
|
1385
|
+
* @param filter - Conditions to find by
|
|
1386
|
+
* @param data - Data to update or create (merged with filter)
|
|
1387
|
+
* @returns Promise resolving to updated or created model
|
|
1388
|
+
*/
|
|
1389
|
+
static async updateOrCreate(filter, data, options) {
|
|
1390
|
+
// Use upsert internally for better performance
|
|
1391
|
+
return await this.upsert(filter, data, options);
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Find one and delete a record that matches the filter and return the deleted record.
|
|
1395
|
+
*
|
|
1396
|
+
* @param filter - Filter conditions
|
|
1397
|
+
* @param options - Optional delete options
|
|
1398
|
+
* @returns The deleted model instance or null if not found
|
|
1399
|
+
*
|
|
1400
|
+
* @example
|
|
1401
|
+
* ```typescript
|
|
1402
|
+
* const deleted = await User.findOneAndDelete({ id: 1 });
|
|
1403
|
+
* if (deleted) {
|
|
1404
|
+
* console.log('Deleted user:', deleted.get('name'));
|
|
1405
|
+
* }
|
|
1406
|
+
* ```
|
|
1407
|
+
*/
|
|
1408
|
+
static async findOneAndDelete(filter, options) {
|
|
1409
|
+
return queryMethods.findOneAndDeleteRecord(this, filter, options);
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Returns embedded data for sync operations.
|
|
1413
|
+
* Excludes internal MongoDB fields and ensures proper date serialization.
|
|
1414
|
+
*
|
|
1415
|
+
* @returns Embedded data object suitable for syncing
|
|
1416
|
+
*
|
|
1417
|
+
* @example
|
|
1418
|
+
* ```typescript
|
|
1419
|
+
* const user = await User.find(1);
|
|
1420
|
+
* const embedData = user.embedData;
|
|
1421
|
+
* // Returns: { id: 1, name: "Alice", email: "alice@example.com", ... }
|
|
1422
|
+
* // Excludes: _id
|
|
1423
|
+
* ```
|
|
1424
|
+
*/
|
|
1425
|
+
get embedData() {
|
|
1426
|
+
return this.self().embed ? this.only(this.self().embed) : this.data;
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Cleanup model events
|
|
1430
|
+
*/
|
|
1431
|
+
static $cleanup() {
|
|
1432
|
+
staticEventMethods.cleanupModelEvents(this);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Accesses the event emitter dedicated to this model constructor.
|
|
1436
|
+
*
|
|
1437
|
+
* Each model subclass gets its own isolated event emitter, allowing you to
|
|
1438
|
+
* register lifecycle hooks that only apply to that specific model.
|
|
1439
|
+
*
|
|
1440
|
+
* @returns The ModelEvents instance for this model constructor
|
|
1441
|
+
*
|
|
1442
|
+
* @example
|
|
1443
|
+
* ```typescript
|
|
1444
|
+
* User.events().onSaving((user) => {
|
|
1445
|
+
* console.log("User is being saved:", user);
|
|
1446
|
+
* });
|
|
1447
|
+
* ```
|
|
1448
|
+
*/
|
|
1449
|
+
static events() {
|
|
1450
|
+
return staticEventMethods.getModelEvents(this);
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Registers an event listener for this model constructor.
|
|
1454
|
+
*
|
|
1455
|
+
* Convenience shorthand for `Model.events().on(...)`.
|
|
1456
|
+
*
|
|
1457
|
+
* @param event - The event name (e.g., "saving", "created")
|
|
1458
|
+
* @param listener - The callback to invoke when the event fires
|
|
1459
|
+
* @returns An unsubscribe function
|
|
1460
|
+
*
|
|
1461
|
+
* @example
|
|
1462
|
+
* ```typescript
|
|
1463
|
+
* const unsubscribe = User.on("saving", (user) => {
|
|
1464
|
+
* console.log("Saving user:", user);
|
|
1465
|
+
* });
|
|
1466
|
+
* ```
|
|
1467
|
+
*/
|
|
1468
|
+
static on(event, listener) {
|
|
1469
|
+
return staticEventMethods.onStaticEvent(this, event, listener);
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Registers a one-time event listener for this model constructor.
|
|
1473
|
+
*
|
|
1474
|
+
* The listener will automatically unsubscribe after its first invocation.
|
|
1475
|
+
* Convenience shorthand for `Model.events().once(...)`.
|
|
1476
|
+
*
|
|
1477
|
+
* @param event - The event name (e.g., "saving", "created")
|
|
1478
|
+
* @param listener - The callback to invoke when the event fires
|
|
1479
|
+
* @returns An unsubscribe function
|
|
1480
|
+
*
|
|
1481
|
+
* @example
|
|
1482
|
+
* ```typescript
|
|
1483
|
+
* User.once("created", (user) => {
|
|
1484
|
+
* console.log("First user created:", user);
|
|
1485
|
+
* });
|
|
1486
|
+
* ```
|
|
1487
|
+
*/
|
|
1488
|
+
static once(event, listener) {
|
|
1489
|
+
return staticEventMethods.onceStaticEvent(this, event, listener);
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Removes an event listener from this model constructor.
|
|
1493
|
+
*
|
|
1494
|
+
* Convenience shorthand for `Model.events().off(...)`.
|
|
1495
|
+
*
|
|
1496
|
+
* @param event - The event name
|
|
1497
|
+
* @param listener - The callback to remove
|
|
1498
|
+
*
|
|
1499
|
+
* @example
|
|
1500
|
+
* ```typescript
|
|
1501
|
+
* const listener = (user) => console.log(user);
|
|
1502
|
+
* User.on("saving", listener);
|
|
1503
|
+
* User.off("saving", listener);
|
|
1504
|
+
* ```
|
|
1505
|
+
*/
|
|
1506
|
+
static off(event, listener) {
|
|
1507
|
+
staticEventMethods.offStaticEvent(this, event, listener);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Accesses the global event emitter shared by all model instances.
|
|
1511
|
+
*
|
|
1512
|
+
* Use this for cross-cutting concerns like auditing, logging, or injecting
|
|
1513
|
+
* common fields (e.g., `createdBy`, `updatedBy`) across all models.
|
|
1514
|
+
*
|
|
1515
|
+
* @returns The global ModelEvents instance
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* ```typescript
|
|
1519
|
+
* Model.globalEvents().onSaving((model) => {
|
|
1520
|
+
* model.set("updatedAt", new Date());
|
|
1521
|
+
* });
|
|
1522
|
+
* ```
|
|
1523
|
+
*/
|
|
1524
|
+
static globalEvents() {
|
|
1525
|
+
return staticEventMethods.getGlobalEvents();
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Replace the model's data entirely.
|
|
1529
|
+
*
|
|
1530
|
+
* Used internally by the writer after validation to update the model
|
|
1531
|
+
* with validated/casted data.
|
|
1532
|
+
*
|
|
1533
|
+
* **Warning:** This replaces all data and updates the dirty tracker.
|
|
1534
|
+
* Use with caution in application code.
|
|
1535
|
+
*
|
|
1536
|
+
* @param data - New data to replace current data
|
|
1537
|
+
*
|
|
1538
|
+
* @example
|
|
1539
|
+
* ```typescript
|
|
1540
|
+
* // Internal usage by writer
|
|
1541
|
+
* model.replaceData(validatedData);
|
|
1542
|
+
* ```
|
|
1543
|
+
*/
|
|
1544
|
+
replaceData(data) {
|
|
1545
|
+
hydrationMethods.replaceModelData(this, data);
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Save the model to the database.
|
|
1549
|
+
*
|
|
1550
|
+
* Performs insert if `isNew === true`, otherwise performs update.
|
|
1551
|
+
* Automatically validates, casts, generates IDs, and emits lifecycle events.
|
|
1552
|
+
*
|
|
1553
|
+
* **Features:**
|
|
1554
|
+
* - Validation via @warlock.js/seal schema
|
|
1555
|
+
* - Data casting (string → number, etc.)
|
|
1556
|
+
* - ID generation (NoSQL only)
|
|
1557
|
+
* - Partial updates (only changed fields)
|
|
1558
|
+
* - Lifecycle events (validating, saving, created/updated, saved)
|
|
1559
|
+
*
|
|
1560
|
+
* @param data - Optional data to merge before saving
|
|
1561
|
+
* @param options - Save options
|
|
1562
|
+
* @returns The model instance for method chaining
|
|
1563
|
+
*
|
|
1564
|
+
* @throws {ValidationError} If validation fails
|
|
1565
|
+
* @throws {Error} If database operation fails
|
|
1566
|
+
*
|
|
1567
|
+
* @example
|
|
1568
|
+
* ```typescript
|
|
1569
|
+
* // Simple save
|
|
1570
|
+
* const user = new User({ name: "Alice" });
|
|
1571
|
+
* await user.save();
|
|
1572
|
+
*
|
|
1573
|
+
* // Merge data before saving
|
|
1574
|
+
* await user.save({ age: 31, email: "alice@example.com" });
|
|
1575
|
+
*
|
|
1576
|
+
* // Silent save (no events)
|
|
1577
|
+
* await user.save(null, { skipEvents: true });
|
|
1578
|
+
*
|
|
1579
|
+
* // Skip validation
|
|
1580
|
+
* await user.save(null, { skipValidation: true });
|
|
1581
|
+
*
|
|
1582
|
+
* // Method chaining
|
|
1583
|
+
* await user.set("name", "Bob").save();
|
|
1584
|
+
* ```
|
|
1585
|
+
*/
|
|
1586
|
+
async save(options) {
|
|
1587
|
+
return writeMethods.saveModel(this, options);
|
|
1588
|
+
}
|
|
1589
|
+
/**
|
|
1590
|
+
* Serialize the model data for storage in the database.
|
|
1591
|
+
*
|
|
1592
|
+
* Uses the driver's `serialize` to apply driver-specific type transformations
|
|
1593
|
+
* (e.g. Date → ISO string, BigInt → string for Postgres).
|
|
1594
|
+
*
|
|
1595
|
+
* **Not** the same as `toSnapshot` — this is a DB write concern, not a cache concern.
|
|
1596
|
+
*/
|
|
1597
|
+
serialize() {
|
|
1598
|
+
return hydrationMethods.serializeModel(this);
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* Produce a plain-object snapshot of this model suitable for cache storage.
|
|
1602
|
+
*
|
|
1603
|
+
* - `data`: The model's own fields, serialized via the driver (handles Dates, BigInt, ObjectId).
|
|
1604
|
+
* - `relations`: Each entry in `loadedRelations` recursively snapshotted via `toSnapshot`.
|
|
1605
|
+
* A relation that was loaded but resolved to `null` is stored as `null` (not omitted),
|
|
1606
|
+
* so that `fromSnapshot` can distinguish "loaded + null" from "never loaded".
|
|
1607
|
+
*
|
|
1608
|
+
* Use `Model.fromSnapshot(snapshot)` to reconstruct.
|
|
1609
|
+
*
|
|
1610
|
+
* @example
|
|
1611
|
+
* ```typescript
|
|
1612
|
+
* await cache.set(key, chat.toSnapshot());
|
|
1613
|
+
* ```
|
|
1614
|
+
*/
|
|
1615
|
+
toSnapshot() {
|
|
1616
|
+
return hydrationMethods.modelToSnapshot(this);
|
|
1617
|
+
}
|
|
1618
|
+
/**
|
|
1619
|
+
* Reconstruct a model instance (with relations) from a cache snapshot.
|
|
1620
|
+
*
|
|
1621
|
+
* Counterpart to `toSnapshot`. Applies driver deserialization (e.g. ISO string → Date)
|
|
1622
|
+
* and recursively hydrates any nested relation snapshots via `RelationHydrator`.
|
|
1623
|
+
*
|
|
1624
|
+
* @example
|
|
1625
|
+
* ```typescript
|
|
1626
|
+
* const snapshot = await cache.get(key);
|
|
1627
|
+
* const chat = Chat.fromSnapshot(snapshot);
|
|
1628
|
+
* chat.unit; // Unit model instance, fully hydrated
|
|
1629
|
+
* ```
|
|
1630
|
+
*/
|
|
1631
|
+
static fromSnapshot(snapshot) {
|
|
1632
|
+
return hydrationMethods.modelFromSnapshot(this, snapshot);
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Create a model instance from raw data (no relations).
|
|
1636
|
+
*
|
|
1637
|
+
* This is the data-only hydration path, used by the query builder when
|
|
1638
|
+
* converting a raw DB row into a model instance. Relations are NOT restored
|
|
1639
|
+
* here — use `fromSnapshot` when restoring from a cache snapshot that
|
|
1640
|
+
* includes relation data.
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* ```typescript
|
|
1644
|
+
* // Query builder internals:
|
|
1645
|
+
* const user = User.hydrate(rawRow);
|
|
1646
|
+
* ```
|
|
1647
|
+
*/
|
|
1648
|
+
static hydrate(data) {
|
|
1649
|
+
return hydrationMethods.hydrateModel(this, data);
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Convert the model into JSON
|
|
1653
|
+
*/
|
|
1654
|
+
toJSON() {
|
|
1655
|
+
return serializationMethods.modelToJSON(this);
|
|
1656
|
+
}
|
|
1657
|
+
}exports.Model=Model;//# sourceMappingURL=model.js.map
|