@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,1070 @@
|
|
|
1
|
+
'use strict';/**
|
|
2
|
+
* Pure Query Builder Base Class
|
|
3
|
+
*
|
|
4
|
+
* Driver-agnostic operation recorder. All fluent methods push typed entries into
|
|
5
|
+
* `operations[]`. No SQL, no driver references, no table property, no execution.
|
|
6
|
+
*
|
|
7
|
+
* ┌─────────────────────────────────────────────────┐
|
|
8
|
+
* │ Usage contexts │
|
|
9
|
+
* │ (a) Subclassed — PG / Mongo / MySQL / … │
|
|
10
|
+
* │ (b) Instantiated directly (new QueryBuilder()) │
|
|
11
|
+
* │ inside callbacks for: │
|
|
12
|
+
* │ • nested where groups │
|
|
13
|
+
* │ • joinWith constraints │
|
|
14
|
+
* │ • whereExists / whereHas subqueries │
|
|
15
|
+
* └─────────────────────────────────────────────────┘
|
|
16
|
+
*
|
|
17
|
+
* Design rules:
|
|
18
|
+
* - `table` / alias are NOT here — the parser gets them from the executor.
|
|
19
|
+
* - `opIndex` is protected so subclasses can rebuild after direct mutation.
|
|
20
|
+
* - Op type names are stable — parsers switch on them; no renaming without
|
|
21
|
+
* a parser update.
|
|
22
|
+
* - OR-variants keep distinct op types (orWhere, orWhereColumn, …) so existing
|
|
23
|
+
* parsers that switch on type need no changes.
|
|
24
|
+
* - `joinWith` eagerly resolves callbacks → subOps at record time so the
|
|
25
|
+
* driver executor receives a plain data structure, not a live function.
|
|
26
|
+
*
|
|
27
|
+
* @module cascade/query-builder
|
|
28
|
+
*/
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// QUERY BUILDER — CONCRETE, DIRECTLY INSTANTIABLE
|
|
31
|
+
// ============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Pure, driver-agnostic query builder.
|
|
34
|
+
*
|
|
35
|
+
* Records operations in `operations[]`. Subclasses own execution, parsing, and
|
|
36
|
+
* driver-specific clause generation. Safe to instantiate directly inside
|
|
37
|
+
* callbacks where only operation recording is needed.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* // Driver subclass usage:
|
|
42
|
+
* const users = await User.query()
|
|
43
|
+
* .select(["id", "name"])
|
|
44
|
+
* .where("status", "active")
|
|
45
|
+
* .where(q => q.where("role", "admin").orWhere("role", "mod"))
|
|
46
|
+
* .orderBy("createdAt", "desc")
|
|
47
|
+
* .limit(10)
|
|
48
|
+
* .get();
|
|
49
|
+
*
|
|
50
|
+
* // Direct instantiation (callback context — no driver needed):
|
|
51
|
+
* joinWith({ actions: q => q.where("status", "pending").limit(5) });
|
|
52
|
+
* // The sub-QB's operations[] are captured and stored in the joinWith op data.
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
class QueryBuilder {
|
|
56
|
+
// ════════════════════════════════════════════════════════
|
|
57
|
+
// OPERATION STORE
|
|
58
|
+
// ════════════════════════════════════════════════════════
|
|
59
|
+
/** Flat, ordered list of recorded operations. Public for parser access. */
|
|
60
|
+
operations = [];
|
|
61
|
+
/**
|
|
62
|
+
* type → ordered list of indices into `operations[]`.
|
|
63
|
+
*
|
|
64
|
+
* Protected (not private) so:
|
|
65
|
+
* - `rebuildIndex()` can reset it after direct `operations[]` mutation.
|
|
66
|
+
* - Subclasses can inspect it without unsafe casts.
|
|
67
|
+
*
|
|
68
|
+
* External consumers should use `getOps(type)` instead.
|
|
69
|
+
*/
|
|
70
|
+
opIndex = new Map();
|
|
71
|
+
// ════════════════════════════════════════════════════════
|
|
72
|
+
// SCOPE STATE (injected by Model.query(), consumed before execution)
|
|
73
|
+
// ════════════════════════════════════════════════════════
|
|
74
|
+
/** Global scope definitions injected by Model.query(). Keyed by scope name. */
|
|
75
|
+
pendingGlobalScopes;
|
|
76
|
+
/** Local scope callbacks injected by Model.query(). Applied on demand via scope(). */
|
|
77
|
+
availableLocalScopes;
|
|
78
|
+
/** Names of global scopes that have been intentionally disabled. */
|
|
79
|
+
disabledGlobalScopes = new Set();
|
|
80
|
+
/** True once the driver subclass has applied pending scopes. */
|
|
81
|
+
scopesApplied = false;
|
|
82
|
+
// ════════════════════════════════════════════════════════
|
|
83
|
+
// RELATION STATE (consumed by driver subclass at execute time)
|
|
84
|
+
// ════════════════════════════════════════════════════════
|
|
85
|
+
/** Relations to eager-load via separate queries. */
|
|
86
|
+
eagerLoadRelations = new Map();
|
|
87
|
+
/** Relation names to count alongside results. */
|
|
88
|
+
countRelations = [];
|
|
89
|
+
/** Relation definition map injected from the owning Model. */
|
|
90
|
+
relationDefinitions;
|
|
91
|
+
/** The Model class reference, required for relation resolution. */
|
|
92
|
+
modelClass;
|
|
93
|
+
// ════════════════════════════════════════════════════════
|
|
94
|
+
// CORE INTERNALS
|
|
95
|
+
// ════════════════════════════════════════════════════════
|
|
96
|
+
/**
|
|
97
|
+
* Append an operation to `operations[]` and update `opIndex`.
|
|
98
|
+
* Every fluent method calls this.
|
|
99
|
+
*/
|
|
100
|
+
addOperation(type, data) {
|
|
101
|
+
const idx = this.operations.length;
|
|
102
|
+
this.operations.push({ type, data });
|
|
103
|
+
const list = this.opIndex.get(type);
|
|
104
|
+
if (list) {
|
|
105
|
+
list.push(idx);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.opIndex.set(type, [idx]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return all recorded operations of the specified types in original
|
|
113
|
+
* insertion order.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* builder.getOps("where", "orWhere", "whereIn")
|
|
117
|
+
*/
|
|
118
|
+
getOps(...types) {
|
|
119
|
+
if (types.length === 1) {
|
|
120
|
+
return (this.opIndex.get(types[0]) ?? []).map((i) => this.operations[i]);
|
|
121
|
+
}
|
|
122
|
+
const result = [];
|
|
123
|
+
for (const type of types) {
|
|
124
|
+
for (const idx of this.opIndex.get(type) ?? []) {
|
|
125
|
+
result.push({ idx, op: this.operations[idx] });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result.sort((a, b) => a.idx - b.idx).map((r) => r.op);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Rebuild `opIndex` from scratch.
|
|
132
|
+
*
|
|
133
|
+
* Call this after any direct mutation of `this.operations[]` (e.g. scope
|
|
134
|
+
* injection, joinWith consumption in the executor, clone post-processing).
|
|
135
|
+
*/
|
|
136
|
+
rebuildIndex() {
|
|
137
|
+
this.opIndex = new Map();
|
|
138
|
+
for (let i = 0; i < this.operations.length; i++) {
|
|
139
|
+
const type = this.operations[i].type;
|
|
140
|
+
const list = this.opIndex.get(type);
|
|
141
|
+
if (list) {
|
|
142
|
+
list.push(i);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this.opIndex.set(type, [i]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Factory for sub-QueryBuilders used inside callbacks.
|
|
151
|
+
*
|
|
152
|
+
* Override in driver subclasses to return a driver-typed instance, so that
|
|
153
|
+
* driver-specific methods (e.g. `whereArrayContains`) are available inside
|
|
154
|
+
* nested `where(q => ...)` / `whereHas` / `joinWith` callbacks.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* // In PostgresQueryBuilder:
|
|
158
|
+
* protected override subQuery(): QueryBuilder {
|
|
159
|
+
* return new PostgresQueryBuilder("__sub__", this.dataSource);
|
|
160
|
+
* }
|
|
161
|
+
*/
|
|
162
|
+
subQuery() {
|
|
163
|
+
return new QueryBuilder();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Shallow-clone this builder — copies operations, opIndex, and all shared state.
|
|
167
|
+
*
|
|
168
|
+
* Subclasses MUST call `super.clone()` and then copy their own fields
|
|
169
|
+
* (dataSource, joinRelations, …).
|
|
170
|
+
*/
|
|
171
|
+
clone() {
|
|
172
|
+
const cloned = Object.create(Object.getPrototypeOf(this));
|
|
173
|
+
cloned.operations = [...this.operations];
|
|
174
|
+
cloned.opIndex = new Map(Array.from(this.opIndex.entries()).map(([k, v]) => [k, [...v]]));
|
|
175
|
+
cloned.pendingGlobalScopes = this.pendingGlobalScopes;
|
|
176
|
+
cloned.availableLocalScopes = this.availableLocalScopes;
|
|
177
|
+
cloned.disabledGlobalScopes = new Set(this.disabledGlobalScopes);
|
|
178
|
+
cloned.scopesApplied = this.scopesApplied;
|
|
179
|
+
cloned.eagerLoadRelations = new Map(this.eagerLoadRelations);
|
|
180
|
+
cloned.countRelations = [...this.countRelations];
|
|
181
|
+
cloned.relationDefinitions = this.relationDefinitions;
|
|
182
|
+
cloned.modelClass = this.modelClass;
|
|
183
|
+
return cloned;
|
|
184
|
+
}
|
|
185
|
+
// ════════════════════════════════════════════════════════
|
|
186
|
+
// SCOPES
|
|
187
|
+
// ════════════════════════════════════════════════════════
|
|
188
|
+
/** Disable one or more named global scopes for this query. */
|
|
189
|
+
withoutGlobalScope(...scopeNames) {
|
|
190
|
+
scopeNames.forEach((name) => this.disabledGlobalScopes.add(name));
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
/** Disable ALL pending global scopes for this query. */
|
|
194
|
+
withoutGlobalScopes() {
|
|
195
|
+
this.pendingGlobalScopes?.forEach((_, name) => this.disabledGlobalScopes.add(name));
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Apply a registered local scope by name.
|
|
200
|
+
* @throws if no local scopes are available or the named scope is not found
|
|
201
|
+
*/
|
|
202
|
+
scope(scopeName, ...args) {
|
|
203
|
+
if (!this.availableLocalScopes) {
|
|
204
|
+
throw new Error("No local scopes available on this query builder.");
|
|
205
|
+
}
|
|
206
|
+
const cb = this.availableLocalScopes.get(scopeName);
|
|
207
|
+
if (!cb)
|
|
208
|
+
throw new Error(`Local scope "${scopeName}" not found.`);
|
|
209
|
+
cb(this, ...args);
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
where(...args) {
|
|
213
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
214
|
+
const sub = this.subQuery();
|
|
215
|
+
args[0](sub);
|
|
216
|
+
this.addOperation("where", { nested: sub.operations });
|
|
217
|
+
}
|
|
218
|
+
else if (args.length === 1 && typeof args[0] === "object" && args[0] !== null) {
|
|
219
|
+
for (const [key, value] of Object.entries(args[0])) {
|
|
220
|
+
this.addOperation("where", { field: key, operator: "=", value });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (args.length === 2) {
|
|
224
|
+
this.addOperation("where", { field: args[0], operator: "=", value: args[1] });
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
this.addOperation("where", { field: args[0], operator: args[1], value: args[2] });
|
|
228
|
+
}
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
orWhere(...args) {
|
|
232
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
233
|
+
const sub = this.subQuery();
|
|
234
|
+
args[0](sub);
|
|
235
|
+
this.addOperation("orWhere", { nested: sub.operations });
|
|
236
|
+
}
|
|
237
|
+
else if (args.length === 1 && typeof args[0] === "object" && args[0] !== null) {
|
|
238
|
+
for (const [key, value] of Object.entries(args[0])) {
|
|
239
|
+
this.addOperation("orWhere", { field: key, operator: "=", value });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else if (args.length === 2) {
|
|
243
|
+
this.addOperation("orWhere", { field: args[0], operator: "=", value: args[1] });
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.addOperation("orWhere", { field: args[0], operator: args[1], value: args[2] });
|
|
247
|
+
}
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Raw WHERE expression in the target dialect (AND).
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* q.whereRaw("age > ? AND role = ?", [18, "admin"]) // SQL
|
|
255
|
+
* q.whereRaw({ $expr: { $gt: ["$stock", "$reserved"] } }) // MongoDB
|
|
256
|
+
*/
|
|
257
|
+
whereRaw(expression, bindings) {
|
|
258
|
+
this.addOperation("whereRaw", { expression, bindings: bindings ?? [] });
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
/** Raw OR WHERE expression. */
|
|
262
|
+
orWhereRaw(expression, bindings) {
|
|
263
|
+
this.addOperation("orWhereRaw", { expression, bindings: bindings ?? [] });
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
// ════════════════════════════════════════════════════════
|
|
267
|
+
// WHERE CLAUSES — COLUMN COMPARISONS
|
|
268
|
+
// ════════════════════════════════════════════════════════
|
|
269
|
+
/**
|
|
270
|
+
* Compare two columns directly (AND).
|
|
271
|
+
* @example q.whereColumn("stock", ">", "reserved")
|
|
272
|
+
*/
|
|
273
|
+
whereColumn(first, operator, second) {
|
|
274
|
+
this.addOperation("whereColumn", { first, operator, second });
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
/** Compare two columns directly (OR). */
|
|
278
|
+
orWhereColumn(first, operator, second) {
|
|
279
|
+
this.addOperation("orWhereColumn", { first, operator, second });
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
/** Compare multiple column pairs in one call. */
|
|
283
|
+
whereColumns(comparisons) {
|
|
284
|
+
for (const [left, operator, right] of comparisons) {
|
|
285
|
+
this.whereColumn(left, operator, right);
|
|
286
|
+
}
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Field value must fall between two other column values.
|
|
291
|
+
* Stored as a `whereBetween` op with `useColumns: true` so the SQL parser
|
|
292
|
+
* knows to quote the values as identifiers rather than bind them.
|
|
293
|
+
*/
|
|
294
|
+
whereBetweenColumns(field, lowerColumn, upperColumn) {
|
|
295
|
+
this.addOperation("whereBetween", { field, lowerColumn, upperColumn, useColumns: true });
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
// ════════════════════════════════════════════════════════
|
|
299
|
+
// WHERE CLAUSES — STANDARD COMPARISON OPERATORS
|
|
300
|
+
// ════════════════════════════════════════════════════════
|
|
301
|
+
/** WHERE field IN values. */
|
|
302
|
+
whereIn(field, values) {
|
|
303
|
+
this.addOperation("whereIn", { field, values });
|
|
304
|
+
return this;
|
|
305
|
+
}
|
|
306
|
+
/** WHERE field NOT IN values. */
|
|
307
|
+
whereNotIn(field, values) {
|
|
308
|
+
this.addOperation("whereNotIn", { field, values });
|
|
309
|
+
return this;
|
|
310
|
+
}
|
|
311
|
+
/** WHERE field IS NULL. */
|
|
312
|
+
whereNull(field) {
|
|
313
|
+
this.addOperation("whereNull", { field });
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
/** WHERE field IS NOT NULL. */
|
|
317
|
+
whereNotNull(field) {
|
|
318
|
+
this.addOperation("whereNotNull", { field });
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
/** WHERE field BETWEEN low AND high. */
|
|
322
|
+
whereBetween(field, range) {
|
|
323
|
+
this.addOperation("whereBetween", { field, range });
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
/** WHERE field NOT BETWEEN low AND high. */
|
|
327
|
+
whereNotBetween(field, range) {
|
|
328
|
+
this.addOperation("whereNotBetween", { field, range });
|
|
329
|
+
return this;
|
|
330
|
+
}
|
|
331
|
+
// ════════════════════════════════════════════════════════
|
|
332
|
+
// WHERE CLAUSES — PATTERN MATCHING
|
|
333
|
+
// ════════════════════════════════════════════════════════
|
|
334
|
+
/**
|
|
335
|
+
* LIKE pattern match (AND).
|
|
336
|
+
* @example q.whereLike("email", "%@gmail.com")
|
|
337
|
+
*/
|
|
338
|
+
whereLike(field, pattern) {
|
|
339
|
+
const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
|
|
340
|
+
this.addOperation("whereLike", { field, pattern: patternStr });
|
|
341
|
+
return this;
|
|
342
|
+
}
|
|
343
|
+
/** NOT LIKE pattern match. */
|
|
344
|
+
whereNotLike(field, pattern) {
|
|
345
|
+
const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
|
|
346
|
+
this.addOperation("whereNotLike", { field, pattern: patternStr });
|
|
347
|
+
return this;
|
|
348
|
+
}
|
|
349
|
+
/** Starts with a prefix. */
|
|
350
|
+
whereStartsWith(field, value) {
|
|
351
|
+
return this.whereLike(field, `${value}%`);
|
|
352
|
+
}
|
|
353
|
+
/** Does NOT start with a prefix. */
|
|
354
|
+
whereNotStartsWith(field, value) {
|
|
355
|
+
return this.whereNotLike(field, `${value}%`);
|
|
356
|
+
}
|
|
357
|
+
/** Ends with a suffix. */
|
|
358
|
+
whereEndsWith(field, value) {
|
|
359
|
+
return this.whereLike(field, `%${value}`);
|
|
360
|
+
}
|
|
361
|
+
/** Does NOT end with a suffix. */
|
|
362
|
+
whereNotEndsWith(field, value) {
|
|
363
|
+
return this.whereNotLike(field, `%${value}`);
|
|
364
|
+
}
|
|
365
|
+
// ════════════════════════════════════════════════════════
|
|
366
|
+
// WHERE CLAUSES — DATE/TIME PARTIALS
|
|
367
|
+
// ════════════════════════════════════════════════════════
|
|
368
|
+
/**
|
|
369
|
+
* Match on date portion only (time ignored).
|
|
370
|
+
* @example q.whereDate("createdAt", "2024-05-01")
|
|
371
|
+
*/
|
|
372
|
+
whereDate(field, value) {
|
|
373
|
+
this.addOperation("whereDate", { field, value });
|
|
374
|
+
return this;
|
|
375
|
+
}
|
|
376
|
+
/** Alias for whereDate. */
|
|
377
|
+
whereDateEquals(field, value) {
|
|
378
|
+
return this.whereDate(field, value);
|
|
379
|
+
}
|
|
380
|
+
/** Field date is before value. */
|
|
381
|
+
whereDateBefore(field, value) {
|
|
382
|
+
this.addOperation("whereDateBefore", { field, value });
|
|
383
|
+
return this;
|
|
384
|
+
}
|
|
385
|
+
/** Field date is after value. */
|
|
386
|
+
whereDateAfter(field, value) {
|
|
387
|
+
this.addOperation("whereDateAfter", { field, value });
|
|
388
|
+
return this;
|
|
389
|
+
}
|
|
390
|
+
/** Field date is within a range [from, to]. */
|
|
391
|
+
whereDateBetween(field, range) {
|
|
392
|
+
this.addOperation("whereDateBetween", { field, range });
|
|
393
|
+
return this;
|
|
394
|
+
}
|
|
395
|
+
/** Field date is NOT within a range. */
|
|
396
|
+
whereDateNotBetween(field, range) {
|
|
397
|
+
this.addOperation("whereNotBetween", { field, range });
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Match on the time portion of a datetime field.
|
|
402
|
+
* Emits a `whereRaw` op with a driver-agnostic marker; the driver parser
|
|
403
|
+
* rewrites it to the appropriate SQL (`TIME(field) = ?`) or Mongo expression.
|
|
404
|
+
*/
|
|
405
|
+
whereTime(field, value) {
|
|
406
|
+
this.addOperation("whereRaw", {
|
|
407
|
+
expression: `TIME(${field}) = ?`,
|
|
408
|
+
bindings: [value],
|
|
409
|
+
});
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Day-of-month from a date field (1–31).
|
|
414
|
+
* Uses a `whereRaw` op so SQL parsers get the `EXTRACT` expression directly.
|
|
415
|
+
* MongoDB drivers override to emit `$dayOfMonth`.
|
|
416
|
+
*/
|
|
417
|
+
whereDay(field, value) {
|
|
418
|
+
this.addOperation("whereRaw", {
|
|
419
|
+
expression: `EXTRACT(DAY FROM ${field}) = ?`,
|
|
420
|
+
bindings: [value],
|
|
421
|
+
});
|
|
422
|
+
return this;
|
|
423
|
+
}
|
|
424
|
+
/** Month extracted from a date field (1–12). */
|
|
425
|
+
whereMonth(field, value) {
|
|
426
|
+
this.addOperation("whereRaw", {
|
|
427
|
+
expression: `EXTRACT(MONTH FROM ${field}) = ?`,
|
|
428
|
+
bindings: [value],
|
|
429
|
+
});
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
432
|
+
/** Year extracted from a date field. */
|
|
433
|
+
whereYear(field, value) {
|
|
434
|
+
this.addOperation("whereRaw", {
|
|
435
|
+
expression: `EXTRACT(YEAR FROM ${field}) = ?`,
|
|
436
|
+
bindings: [value],
|
|
437
|
+
});
|
|
438
|
+
return this;
|
|
439
|
+
}
|
|
440
|
+
// ════════════════════════════════════════════════════════
|
|
441
|
+
// WHERE CLAUSES — JSON / STRUCTURED DATA
|
|
442
|
+
// ════════════════════════════════════════════════════════
|
|
443
|
+
/**
|
|
444
|
+
* JSON/array path contains the given value.
|
|
445
|
+
* @example q.whereJsonContains("tags", "typescript")
|
|
446
|
+
*/
|
|
447
|
+
whereJsonContains(path, value) {
|
|
448
|
+
this.addOperation("whereJsonContains", { path, value });
|
|
449
|
+
return this;
|
|
450
|
+
}
|
|
451
|
+
/** JSON/array path does NOT contain the value. */
|
|
452
|
+
whereJsonDoesntContain(path, value) {
|
|
453
|
+
this.addOperation("whereJsonDoesntContain", { path, value });
|
|
454
|
+
return this;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* JSON path key exists.
|
|
458
|
+
* Uses a `whereRaw` so existing SQL parsers get `IS NOT NULL` immediately.
|
|
459
|
+
*/
|
|
460
|
+
whereJsonContainsKey(path) {
|
|
461
|
+
this.addOperation("whereRaw", { expression: `${path} IS NOT NULL`, bindings: [] });
|
|
462
|
+
return this;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Constrain the length of a JSON array at a path.
|
|
466
|
+
* @example q.whereJsonLength("tags", ">", 3)
|
|
467
|
+
*/
|
|
468
|
+
whereJsonLength(path, operator, value) {
|
|
469
|
+
this.addOperation("whereRaw", {
|
|
470
|
+
expression: `jsonb_array_length(${path}) ${operator} ?`,
|
|
471
|
+
bindings: [value],
|
|
472
|
+
});
|
|
473
|
+
return this;
|
|
474
|
+
}
|
|
475
|
+
/** JSON path must resolve to an array. */
|
|
476
|
+
whereJsonIsArray(path) {
|
|
477
|
+
this.addOperation("whereRaw", {
|
|
478
|
+
expression: `jsonb_typeof(${path}) = 'array'`,
|
|
479
|
+
bindings: [],
|
|
480
|
+
});
|
|
481
|
+
return this;
|
|
482
|
+
}
|
|
483
|
+
/** JSON path must resolve to an object. */
|
|
484
|
+
whereJsonIsObject(path) {
|
|
485
|
+
this.addOperation("whereRaw", {
|
|
486
|
+
expression: `jsonb_typeof(${path}) = 'object'`,
|
|
487
|
+
bindings: [],
|
|
488
|
+
});
|
|
489
|
+
return this;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Constrain the number of elements in an array field.
|
|
493
|
+
* @example q.whereArrayLength("roles", ">=", 2)
|
|
494
|
+
*/
|
|
495
|
+
whereArrayLength(field, operator, value) {
|
|
496
|
+
this.addOperation("whereRaw", {
|
|
497
|
+
expression: `array_length(${field}, 1) ${operator} ?`,
|
|
498
|
+
bindings: [value],
|
|
499
|
+
});
|
|
500
|
+
return this;
|
|
501
|
+
}
|
|
502
|
+
// ════════════════════════════════════════════════════════
|
|
503
|
+
// WHERE CLAUSES — CONVENIENCE SHORTCUTS
|
|
504
|
+
// ════════════════════════════════════════════════════════
|
|
505
|
+
/** WHERE id = value. */
|
|
506
|
+
whereId(value) {
|
|
507
|
+
return this.where("id", value);
|
|
508
|
+
}
|
|
509
|
+
/** WHERE id IN values. */
|
|
510
|
+
whereIds(values) {
|
|
511
|
+
return this.whereIn("id", values);
|
|
512
|
+
}
|
|
513
|
+
/** WHERE uuid = value. */
|
|
514
|
+
whereUuid(value) {
|
|
515
|
+
return this.where("uuid", value);
|
|
516
|
+
}
|
|
517
|
+
/** WHERE ulid = value. */
|
|
518
|
+
whereUlid(value) {
|
|
519
|
+
return this.where("ulid", value);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Full-text search across one or more fields.
|
|
523
|
+
* @example q.whereFullText(["title", "body"], "typescript")
|
|
524
|
+
*/
|
|
525
|
+
whereFullText(fields, query) {
|
|
526
|
+
this.addOperation("whereFullText", {
|
|
527
|
+
fields: Array.isArray(fields) ? fields : [fields],
|
|
528
|
+
query,
|
|
529
|
+
});
|
|
530
|
+
return this;
|
|
531
|
+
}
|
|
532
|
+
/** Full-text search (OR). */
|
|
533
|
+
orWhereFullText(fields, query) {
|
|
534
|
+
return this.whereFullText(fields, query);
|
|
535
|
+
}
|
|
536
|
+
/** Alias for whereFullText with a single field. */
|
|
537
|
+
whereSearch(field, query) {
|
|
538
|
+
return this.whereFullText([field], query);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Text search with optional extra equality filters.
|
|
542
|
+
* MongoDB-style convenience shorthand.
|
|
543
|
+
*/
|
|
544
|
+
textSearch(query, filters) {
|
|
545
|
+
if (filters) {
|
|
546
|
+
for (const [key, value] of Object.entries(filters))
|
|
547
|
+
this.where(key, value);
|
|
548
|
+
}
|
|
549
|
+
return this;
|
|
550
|
+
}
|
|
551
|
+
whereExists(param) {
|
|
552
|
+
if (typeof param === "function") {
|
|
553
|
+
const sub = this.subQuery();
|
|
554
|
+
param(sub);
|
|
555
|
+
this.addOperation("whereExists", { subquery: sub.operations });
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
this.addOperation("whereNotNull", { field: param });
|
|
559
|
+
}
|
|
560
|
+
return this;
|
|
561
|
+
}
|
|
562
|
+
whereNotExists(param) {
|
|
563
|
+
if (typeof param === "function") {
|
|
564
|
+
const sub = this.subQuery();
|
|
565
|
+
param(sub);
|
|
566
|
+
this.addOperation("whereNotExists", { subquery: sub.operations });
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
this.addOperation("whereNull", { field: param });
|
|
570
|
+
}
|
|
571
|
+
return this;
|
|
572
|
+
}
|
|
573
|
+
whereSize(field, ...args) {
|
|
574
|
+
const operator = args.length === 2 ? args[0] : "=";
|
|
575
|
+
const size = (args.length === 2 ? args[1] : args[0]);
|
|
576
|
+
return this.whereArrayLength(field, operator, size);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* AND NOT wrapper — negate a nested group.
|
|
580
|
+
* @example q.whereNot(q => q.where("status", "banned").where("role", "user"))
|
|
581
|
+
*/
|
|
582
|
+
whereNot(callback) {
|
|
583
|
+
const sub = this.subQuery();
|
|
584
|
+
callback(sub);
|
|
585
|
+
this.addOperation("whereNot", { nested: sub.operations });
|
|
586
|
+
return this;
|
|
587
|
+
}
|
|
588
|
+
/** OR NOT wrapper. */
|
|
589
|
+
orWhereNot(callback) {
|
|
590
|
+
const sub = this.subQuery();
|
|
591
|
+
callback(sub);
|
|
592
|
+
this.addOperation("orWhereNot", { nested: sub.operations });
|
|
593
|
+
return this;
|
|
594
|
+
}
|
|
595
|
+
join(...args) {
|
|
596
|
+
if (args.length === 3) {
|
|
597
|
+
this.addOperation("join", { table: args[0], localField: args[1], foreignField: args[2] });
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
this.addOperation("join", args[0]);
|
|
601
|
+
}
|
|
602
|
+
return this;
|
|
603
|
+
}
|
|
604
|
+
leftJoin(...args) {
|
|
605
|
+
if (args.length === 3) {
|
|
606
|
+
this.addOperation("leftJoin", { table: args[0], localField: args[1], foreignField: args[2] });
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
this.addOperation("leftJoin", args[0]);
|
|
610
|
+
}
|
|
611
|
+
return this;
|
|
612
|
+
}
|
|
613
|
+
rightJoin(...args) {
|
|
614
|
+
if (args.length === 3) {
|
|
615
|
+
this.addOperation("rightJoin", {
|
|
616
|
+
table: args[0],
|
|
617
|
+
localField: args[1],
|
|
618
|
+
foreignField: args[2],
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
this.addOperation("rightJoin", args[0]);
|
|
623
|
+
}
|
|
624
|
+
return this;
|
|
625
|
+
}
|
|
626
|
+
innerJoin(...args) {
|
|
627
|
+
if (args.length === 3) {
|
|
628
|
+
this.addOperation("innerJoin", {
|
|
629
|
+
table: args[0],
|
|
630
|
+
localField: args[1],
|
|
631
|
+
foreignField: args[2],
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
this.addOperation("innerJoin", args[0]);
|
|
636
|
+
}
|
|
637
|
+
return this;
|
|
638
|
+
}
|
|
639
|
+
fullJoin(...args) {
|
|
640
|
+
if (args.length === 3) {
|
|
641
|
+
this.addOperation("fullJoin", { table: args[0], localField: args[1], foreignField: args[2] });
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
this.addOperation("fullJoin", args[0]);
|
|
645
|
+
}
|
|
646
|
+
return this;
|
|
647
|
+
}
|
|
648
|
+
/** CROSS JOIN. */
|
|
649
|
+
crossJoin(table) {
|
|
650
|
+
this.addOperation("crossJoin", { table });
|
|
651
|
+
return this;
|
|
652
|
+
}
|
|
653
|
+
/** Raw JOIN expression. Driver responsible for handling. */
|
|
654
|
+
joinRaw(expression, bindings) {
|
|
655
|
+
this.addOperation("joinRaw", { expression, bindings: bindings ?? [] });
|
|
656
|
+
return this;
|
|
657
|
+
}
|
|
658
|
+
// ════════════════════════════════════════════════════════
|
|
659
|
+
// RELATION EAGER LOADING — JOIN-BASED (joinWith)
|
|
660
|
+
// ════════════════════════════════════════════════════════
|
|
661
|
+
/**
|
|
662
|
+
* Eager-load named relations via a single JOIN / $lookup query.
|
|
663
|
+
*
|
|
664
|
+
* Constraints are eagerly resolved at call time:
|
|
665
|
+
* - Callbacks are invoked immediately → `subOps` stored in op data.
|
|
666
|
+
* - Column shorthands are parsed into a `columns[]` array.
|
|
667
|
+
*
|
|
668
|
+
* The driver executor reads the `joinWith` op and uses the resolved data
|
|
669
|
+
* alongside its own relation definition map to emit the appropriate SQL JOIN
|
|
670
|
+
* or MongoDB $lookup stage.
|
|
671
|
+
*
|
|
672
|
+
* Supported arg forms (may be mixed):
|
|
673
|
+
* - `"author"` / `["author", "category"]` — no constraint
|
|
674
|
+
* - `{ author: "id,name" }` — column shorthand
|
|
675
|
+
* - `{ actions: q => q.where("status","pending").limit(5) }` — callback
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* Post.joinWith("author", "category")
|
|
679
|
+
* ChatMessage.joinWith({ actions: q => q.where("status", "pending").limit(5) })
|
|
680
|
+
* ChatMessage.joinWith({ org: "id,name", actions: q => q.orderBy("sort_order") })
|
|
681
|
+
*/
|
|
682
|
+
joinWith(...args) {
|
|
683
|
+
const resolved = {};
|
|
684
|
+
for (const arg of args) {
|
|
685
|
+
if (typeof arg === "string") {
|
|
686
|
+
resolved[arg] = {};
|
|
687
|
+
}
|
|
688
|
+
else if (Array.isArray(arg)) {
|
|
689
|
+
for (const rel of arg)
|
|
690
|
+
resolved[rel] = {};
|
|
691
|
+
}
|
|
692
|
+
else if (typeof arg === "object" && arg !== null) {
|
|
693
|
+
for (const [rel, constraint] of Object.entries(arg)) {
|
|
694
|
+
if (typeof constraint === "function") {
|
|
695
|
+
const sub = this.subQuery();
|
|
696
|
+
constraint(sub);
|
|
697
|
+
resolved[rel] = { subOps: sub.operations };
|
|
698
|
+
}
|
|
699
|
+
else if (typeof constraint === "string" && constraint !== "") {
|
|
700
|
+
resolved[rel] = {
|
|
701
|
+
columns: constraint
|
|
702
|
+
.split(",")
|
|
703
|
+
.map((s) => s.trim())
|
|
704
|
+
.filter(Boolean),
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
resolved[rel] = {};
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
this.addOperation("joinWith", { resolved });
|
|
714
|
+
return this;
|
|
715
|
+
}
|
|
716
|
+
// ════════════════════════════════════════════════════════
|
|
717
|
+
// RELATION EAGER LOADING — SEPARATE QUERIES (with)
|
|
718
|
+
// ════════════════════════════════════════════════════════
|
|
719
|
+
/**
|
|
720
|
+
* Eager-load relations via separate queries (N+1 avoided by batching).
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* q.with("posts")
|
|
724
|
+
* q.with("posts", q => q.where("published", true))
|
|
725
|
+
* q.with({ posts: true, comments: q => q.limit(5) })
|
|
726
|
+
*/
|
|
727
|
+
with(...args) {
|
|
728
|
+
for (let i = 0; i < args.length; i++) {
|
|
729
|
+
const arg = args[i];
|
|
730
|
+
if (typeof arg === "string") {
|
|
731
|
+
const next = args[i + 1];
|
|
732
|
+
if (typeof next === "function") {
|
|
733
|
+
this.eagerLoadRelations.set(arg, next);
|
|
734
|
+
i++;
|
|
735
|
+
}
|
|
736
|
+
else {
|
|
737
|
+
this.eagerLoadRelations.set(arg, true);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
else if (typeof arg === "object" && arg !== null) {
|
|
741
|
+
for (const [key, value] of Object.entries(arg)) {
|
|
742
|
+
this.eagerLoadRelations.set(key, value);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return this;
|
|
747
|
+
}
|
|
748
|
+
/** Count related models alongside results. */
|
|
749
|
+
withCount(...relations) {
|
|
750
|
+
this.countRelations.push(...relations);
|
|
751
|
+
return this;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Filter to rows that have at least one related record.
|
|
755
|
+
* @example q.has("comments")
|
|
756
|
+
* @example q.has("comments", ">=", 3)
|
|
757
|
+
*/
|
|
758
|
+
has(relation, operator, count) {
|
|
759
|
+
this.addOperation("has", { relation, operator: operator ?? ">=", count: count ?? 1 });
|
|
760
|
+
return this;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Filter to rows with related records matching a sub-query (AND).
|
|
764
|
+
* @example q.whereHas("comments", q => q.where("approved", true))
|
|
765
|
+
*/
|
|
766
|
+
whereHas(relation, callback) {
|
|
767
|
+
const sub = this.subQuery();
|
|
768
|
+
callback(sub);
|
|
769
|
+
this.addOperation("whereHas", { relation, subquery: sub.operations });
|
|
770
|
+
return this;
|
|
771
|
+
}
|
|
772
|
+
/** Same as whereHas but OR-joined. */
|
|
773
|
+
orWhereHas(relation, callback) {
|
|
774
|
+
const sub = this.subQuery();
|
|
775
|
+
callback(sub);
|
|
776
|
+
this.addOperation("orWhereHas", { relation, subquery: sub.operations });
|
|
777
|
+
return this;
|
|
778
|
+
}
|
|
779
|
+
/** Filter to rows with NO related records. */
|
|
780
|
+
doesntHave(relation) {
|
|
781
|
+
this.addOperation("doesntHave", { relation });
|
|
782
|
+
return this;
|
|
783
|
+
}
|
|
784
|
+
/** Filter to rows with NO related records matching conditions. */
|
|
785
|
+
whereDoesntHave(relation, callback) {
|
|
786
|
+
const sub = this.subQuery();
|
|
787
|
+
callback(sub);
|
|
788
|
+
this.addOperation("whereDoesntHave", { relation, subquery: sub.operations });
|
|
789
|
+
return this;
|
|
790
|
+
}
|
|
791
|
+
select(...args) {
|
|
792
|
+
if (args.length === 1 && Array.isArray(args[0])) {
|
|
793
|
+
this.addOperation("select", { fields: args[0] });
|
|
794
|
+
}
|
|
795
|
+
else if (args.length === 1 && typeof args[0] === "object" && !Array.isArray(args[0])) {
|
|
796
|
+
this.addOperation("select", { fields: args[0] });
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
this.addOperation("select", { fields: args.flat() });
|
|
800
|
+
}
|
|
801
|
+
return this;
|
|
802
|
+
}
|
|
803
|
+
/** Select a field under an alias. @example q.selectAs("fullName", "name") */
|
|
804
|
+
selectAs(field, alias) {
|
|
805
|
+
this.addOperation("select", { fields: { [field]: alias } });
|
|
806
|
+
return this;
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Raw SELECT expression.
|
|
810
|
+
* @example q.selectRaw("COUNT(*) AS total")
|
|
811
|
+
*/
|
|
812
|
+
selectRaw(expression, bindings) {
|
|
813
|
+
this.addOperation("selectRaw", { expression, bindings: bindings ?? [] });
|
|
814
|
+
return this;
|
|
815
|
+
}
|
|
816
|
+
/** Multiple raw SELECT expressions in one call. */
|
|
817
|
+
selectRawMany(definitions) {
|
|
818
|
+
for (const def of definitions) {
|
|
819
|
+
this.selectRaw({ [def.alias]: def.expression }, def.bindings);
|
|
820
|
+
}
|
|
821
|
+
return this;
|
|
822
|
+
}
|
|
823
|
+
/** Subquery as a named projected field. */
|
|
824
|
+
selectSub(expression, alias) {
|
|
825
|
+
this.addOperation("selectRaw", { expression: { [alias]: expression } });
|
|
826
|
+
return this;
|
|
827
|
+
}
|
|
828
|
+
/** Alias for selectSub. */
|
|
829
|
+
addSelectSub(expression, alias) {
|
|
830
|
+
return this.selectSub(expression, alias);
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Aggregate function as a projected field.
|
|
834
|
+
* @example q.selectAggregate("price", "sum", "totalRevenue")
|
|
835
|
+
*/
|
|
836
|
+
selectAggregate(field, aggregate, alias) {
|
|
837
|
+
return this.selectRaw({ [alias]: `${aggregate.toUpperCase()}(${field})` });
|
|
838
|
+
}
|
|
839
|
+
/** Existence check as a projected boolean field. */
|
|
840
|
+
selectExists(field, alias) {
|
|
841
|
+
return this.selectRaw({ [alias]: `${field} IS NOT NULL` });
|
|
842
|
+
}
|
|
843
|
+
/** COUNT as a projected field. */
|
|
844
|
+
selectCount(field, alias) {
|
|
845
|
+
return this.selectAggregate(field, "count", alias);
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* CASE / switch expression.
|
|
849
|
+
* @example q.selectCase([{ when: "status = 1", then: "'active'" }], "'inactive'", "statusLabel")
|
|
850
|
+
*/
|
|
851
|
+
selectCase(cases, otherwise, alias) {
|
|
852
|
+
const caseExpr = cases.map((c) => `WHEN ${c.when} THEN ${c.then}`).join(" ");
|
|
853
|
+
return this.selectRaw({ [alias]: `CASE ${caseExpr} ELSE ${otherwise} END` });
|
|
854
|
+
}
|
|
855
|
+
/** IF/ELSE conditional field. */
|
|
856
|
+
selectWhen(condition, thenValue, elseValue, alias) {
|
|
857
|
+
return this.selectRaw({
|
|
858
|
+
[alias]: `CASE WHEN ${condition} THEN ${thenValue} ELSE ${elseValue} END`,
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Driver-native projection manipulation.
|
|
863
|
+
* No-op in base — override in driver subclasses.
|
|
864
|
+
*/
|
|
865
|
+
selectDriverProjection(_callback) {
|
|
866
|
+
return this;
|
|
867
|
+
}
|
|
868
|
+
/** JSON path extraction as a projected field. */
|
|
869
|
+
selectJson(path, alias) {
|
|
870
|
+
const parts = path.split("->");
|
|
871
|
+
const column = parts[0];
|
|
872
|
+
const jsonPath = parts.slice(1).join("->");
|
|
873
|
+
const expr = jsonPath ? `${column}->>'${jsonPath}'` : column;
|
|
874
|
+
return alias ? this.selectAs(expr, alias) : this.selectRaw(expr);
|
|
875
|
+
}
|
|
876
|
+
/** JSON extraction via raw expression. */
|
|
877
|
+
selectJsonRaw(_path, expression, alias) {
|
|
878
|
+
return this.selectRaw({ [alias]: expression });
|
|
879
|
+
}
|
|
880
|
+
/** Exclude a JSON path from projection. */
|
|
881
|
+
deselectJson(path) {
|
|
882
|
+
return this.deselect([path]);
|
|
883
|
+
}
|
|
884
|
+
/** String concatenation as a projected field. */
|
|
885
|
+
selectConcat(fields, alias) {
|
|
886
|
+
return this.selectRaw({ [alias]: fields.join(" || ") });
|
|
887
|
+
}
|
|
888
|
+
/** COALESCE (first non-null) as a projected field. */
|
|
889
|
+
selectCoalesce(fields, alias) {
|
|
890
|
+
return this.selectRaw({ [alias]: `COALESCE(${fields.join(", ")})` });
|
|
891
|
+
}
|
|
892
|
+
/** Window function expression. */
|
|
893
|
+
selectWindow(spec) {
|
|
894
|
+
this.addOperation("selectRaw", { expression: spec });
|
|
895
|
+
return this;
|
|
896
|
+
}
|
|
897
|
+
/** Exclude specific columns from results. */
|
|
898
|
+
deselect(fields) {
|
|
899
|
+
this.addOperation("deselect", { fields });
|
|
900
|
+
return this;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Remove all select operations (resets to wildcard).
|
|
904
|
+
* Uses `rebuildIndex()` — no unsafe casts.
|
|
905
|
+
*/
|
|
906
|
+
clearSelect() {
|
|
907
|
+
this.operations = this.operations.filter((op) => !op.type.startsWith("select") && op.type !== "deselect");
|
|
908
|
+
this.rebuildIndex();
|
|
909
|
+
return this;
|
|
910
|
+
}
|
|
911
|
+
/** Alias for clearSelect. */
|
|
912
|
+
selectAll() {
|
|
913
|
+
return this.clearSelect();
|
|
914
|
+
}
|
|
915
|
+
/** Alias for clearSelect. */
|
|
916
|
+
selectDefault() {
|
|
917
|
+
return this.clearSelect();
|
|
918
|
+
}
|
|
919
|
+
/** Append additional fields to existing selection. */
|
|
920
|
+
addSelect(fields) {
|
|
921
|
+
this.addOperation("select", { fields, add: true });
|
|
922
|
+
return this;
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Record a DISTINCT flag (fluent — does not execute).
|
|
926
|
+
* Subclasses expose a separate async `distinct(field)` execution method.
|
|
927
|
+
*/
|
|
928
|
+
distinctValues(fields) {
|
|
929
|
+
const fieldList = fields ? (Array.isArray(fields) ? fields : [fields]) : [];
|
|
930
|
+
this.addOperation("distinct", { fields: fieldList });
|
|
931
|
+
return this;
|
|
932
|
+
}
|
|
933
|
+
orderBy(...args) {
|
|
934
|
+
if (typeof args[0] === "string") {
|
|
935
|
+
this.addOperation("orderBy", {
|
|
936
|
+
field: args[0],
|
|
937
|
+
direction: args[1] ?? "asc",
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
for (const [field, direction] of Object.entries(args[0])) {
|
|
942
|
+
this.addOperation("orderBy", { field, direction });
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return this;
|
|
946
|
+
}
|
|
947
|
+
/** ORDER BY descending shorthand. */
|
|
948
|
+
orderByDesc(field) {
|
|
949
|
+
return this.orderBy(field, "desc");
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Raw ORDER BY expression.
|
|
953
|
+
* @example q.orderByRaw("RANDOM()")
|
|
954
|
+
* @example q.orderByRaw({ $meta: "textScore" })
|
|
955
|
+
*/
|
|
956
|
+
orderByRaw(expression, bindings) {
|
|
957
|
+
this.addOperation("orderByRaw", { expression, bindings: bindings ?? [] });
|
|
958
|
+
return this;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Random order. Maps to `RANDOM()` in SQL or `$sample` in MongoDB.
|
|
962
|
+
* @param limit - Optional limit (required for MongoDB $sample)
|
|
963
|
+
*/
|
|
964
|
+
orderByRandom(limit) {
|
|
965
|
+
this.addOperation("orderByRaw", { expression: "RANDOM()" });
|
|
966
|
+
if (limit !== undefined)
|
|
967
|
+
this.limit(limit);
|
|
968
|
+
return this;
|
|
969
|
+
}
|
|
970
|
+
/** Order ascending by a date column (oldest first). */
|
|
971
|
+
oldest(column = "createdAt") {
|
|
972
|
+
return this.orderBy(column, "asc");
|
|
973
|
+
}
|
|
974
|
+
// ════════════════════════════════════════════════════════
|
|
975
|
+
// LIMIT / OFFSET
|
|
976
|
+
// ════════════════════════════════════════════════════════
|
|
977
|
+
/** Limit number of results. */
|
|
978
|
+
limit(value) {
|
|
979
|
+
this.addOperation("limit", { value });
|
|
980
|
+
return this;
|
|
981
|
+
}
|
|
982
|
+
/** Skip N results (OFFSET). */
|
|
983
|
+
skip(value) {
|
|
984
|
+
this.addOperation("offset", { value });
|
|
985
|
+
return this;
|
|
986
|
+
}
|
|
987
|
+
/** Alias for skip. */
|
|
988
|
+
offset(value) {
|
|
989
|
+
return this.skip(value);
|
|
990
|
+
}
|
|
991
|
+
/** Alias for limit. */
|
|
992
|
+
take(value) {
|
|
993
|
+
return this.limit(value);
|
|
994
|
+
}
|
|
995
|
+
// ════════════════════════════════════════════════════════
|
|
996
|
+
// GROUPING / AGGREGATION
|
|
997
|
+
// ════════════════════════════════════════════════════════
|
|
998
|
+
/**
|
|
999
|
+
* GROUP BY clause.
|
|
1000
|
+
* @example q.groupBy("status")
|
|
1001
|
+
* @example q.groupBy(["year", "month"])
|
|
1002
|
+
*/
|
|
1003
|
+
groupBy(input) {
|
|
1004
|
+
const fields = Array.isArray(input) ? input : [input];
|
|
1005
|
+
this.addOperation("groupBy", { fields });
|
|
1006
|
+
return this;
|
|
1007
|
+
}
|
|
1008
|
+
/** Raw GROUP BY expression. */
|
|
1009
|
+
groupByRaw(expression, bindings) {
|
|
1010
|
+
this.addOperation("groupBy", { expression, bindings: bindings ?? [] });
|
|
1011
|
+
return this;
|
|
1012
|
+
}
|
|
1013
|
+
having(...args) {
|
|
1014
|
+
if (args.length === 1) {
|
|
1015
|
+
const input = args[0];
|
|
1016
|
+
if (Array.isArray(input)) {
|
|
1017
|
+
if (input.length === 2) {
|
|
1018
|
+
this.addOperation("having", { field: input[0], operator: "=", value: input[1] });
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
this.addOperation("having", { field: input[0], operator: input[1], value: input[2] });
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
else {
|
|
1025
|
+
for (const [key, value] of Object.entries(input)) {
|
|
1026
|
+
this.addOperation("having", { field: key, operator: "=", value });
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
else if (args.length === 2) {
|
|
1031
|
+
this.addOperation("having", { field: args[0], operator: "=", value: args[1] });
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
this.addOperation("having", { field: args[0], operator: args[1], value: args[2] });
|
|
1035
|
+
}
|
|
1036
|
+
return this;
|
|
1037
|
+
}
|
|
1038
|
+
/** Raw HAVING expression. */
|
|
1039
|
+
havingRaw(expression, bindings) {
|
|
1040
|
+
this.addOperation("havingRaw", { expression, bindings: bindings ?? [] });
|
|
1041
|
+
return this;
|
|
1042
|
+
}
|
|
1043
|
+
// ════════════════════════════════════════════════════════
|
|
1044
|
+
// UTILITY / CONTROL FLOW
|
|
1045
|
+
// ════════════════════════════════════════════════════════
|
|
1046
|
+
/**
|
|
1047
|
+
* Side-effect tap — executes callback synchronously and returns `this`.
|
|
1048
|
+
* @example q.where(...).tap(q => console.log(q.operations.length)).limit(10)
|
|
1049
|
+
*/
|
|
1050
|
+
tap(callback) {
|
|
1051
|
+
callback(this);
|
|
1052
|
+
return this;
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Conditionally apply query modifications.
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* q.when(userId, (q, id) => q.where("userId", id))
|
|
1059
|
+
* q.when(isAdmin, q => q.withoutGlobalScopes(), q => q.scope("active"))
|
|
1060
|
+
*/
|
|
1061
|
+
when(condition, callback, otherwise) {
|
|
1062
|
+
if (condition) {
|
|
1063
|
+
callback(this, condition);
|
|
1064
|
+
}
|
|
1065
|
+
else if (otherwise) {
|
|
1066
|
+
otherwise(this);
|
|
1067
|
+
}
|
|
1068
|
+
return this;
|
|
1069
|
+
}
|
|
1070
|
+
}exports.QueryBuilder=QueryBuilder;//# sourceMappingURL=query-builder.js.map
|