typhex 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +417 -0
- package/SECURITY.md +32 -0
- package/dist/arrow/aggregates.d.ts +12 -0
- package/dist/arrow/aggregates.d.ts.map +1 -0
- package/dist/arrow/aggregates.js +32 -0
- package/dist/arrow/aggregates.js.map +1 -0
- package/dist/arrow/constants.d.ts +15 -0
- package/dist/arrow/constants.d.ts.map +1 -0
- package/dist/arrow/constants.js +42 -0
- package/dist/arrow/constants.js.map +1 -0
- package/dist/arrow/index.d.ts +7 -0
- package/dist/arrow/index.d.ts.map +1 -0
- package/dist/arrow/index.js +7 -0
- package/dist/arrow/index.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/load-config.d.ts +19 -0
- package/dist/config/load-config.d.ts.map +1 -0
- package/dist/config/load-config.js +84 -0
- package/dist/config/load-config.js.map +1 -0
- package/dist/config/load-env.d.ts +7 -0
- package/dist/config/load-env.d.ts.map +1 -0
- package/dist/config/load-env.js +62 -0
- package/dist/config/load-env.js.map +1 -0
- package/dist/config/types.d.ts +20 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +10 -0
- package/dist/config/types.js.map +1 -0
- package/dist/dbs/base-migrator.d.ts +20 -0
- package/dist/dbs/base-migrator.d.ts.map +1 -0
- package/dist/dbs/base-migrator.js +112 -0
- package/dist/dbs/base-migrator.js.map +1 -0
- package/dist/dbs/index.d.ts +9 -0
- package/dist/dbs/index.d.ts.map +1 -0
- package/dist/dbs/index.js +17 -0
- package/dist/dbs/index.js.map +1 -0
- package/dist/dbs/postgres/dialect.d.ts +8 -0
- package/dist/dbs/postgres/dialect.d.ts.map +1 -0
- package/dist/dbs/postgres/dialect.js +17 -0
- package/dist/dbs/postgres/dialect.js.map +1 -0
- package/dist/dbs/postgres/driver.d.ts +42 -0
- package/dist/dbs/postgres/driver.d.ts.map +1 -0
- package/dist/dbs/postgres/driver.js +111 -0
- package/dist/dbs/postgres/driver.js.map +1 -0
- package/dist/dbs/postgres/index.d.ts +6 -0
- package/dist/dbs/postgres/index.d.ts.map +1 -0
- package/dist/dbs/postgres/index.js +5 -0
- package/dist/dbs/postgres/index.js.map +1 -0
- package/dist/dbs/postgres/migrator.d.ts +13 -0
- package/dist/dbs/postgres/migrator.d.ts.map +1 -0
- package/dist/dbs/postgres/migrator.js +22 -0
- package/dist/dbs/postgres/migrator.js.map +1 -0
- package/dist/dbs/postgres/query-compiler.d.ts +22 -0
- package/dist/dbs/postgres/query-compiler.d.ts.map +1 -0
- package/dist/dbs/postgres/query-compiler.js +140 -0
- package/dist/dbs/postgres/query-compiler.js.map +1 -0
- package/dist/dbs/postgres/trx.d.ts +16 -0
- package/dist/dbs/postgres/trx.d.ts.map +1 -0
- package/dist/dbs/postgres/trx.js +68 -0
- package/dist/dbs/postgres/trx.js.map +1 -0
- package/dist/dbs/query-compiler.d.ts +135 -0
- package/dist/dbs/query-compiler.d.ts.map +1 -0
- package/dist/dbs/query-compiler.js +775 -0
- package/dist/dbs/query-compiler.js.map +1 -0
- package/dist/dbs/sqlite/dialect.d.ts +8 -0
- package/dist/dbs/sqlite/dialect.d.ts.map +1 -0
- package/dist/dbs/sqlite/dialect.js +17 -0
- package/dist/dbs/sqlite/dialect.js.map +1 -0
- package/dist/dbs/sqlite/driver.d.ts +9 -0
- package/dist/dbs/sqlite/driver.d.ts.map +1 -0
- package/dist/dbs/sqlite/driver.js +66 -0
- package/dist/dbs/sqlite/driver.js.map +1 -0
- package/dist/dbs/sqlite/index.d.ts +6 -0
- package/dist/dbs/sqlite/index.d.ts.map +1 -0
- package/dist/dbs/sqlite/index.js +5 -0
- package/dist/dbs/sqlite/index.js.map +1 -0
- package/dist/dbs/sqlite/migrator.d.ts +13 -0
- package/dist/dbs/sqlite/migrator.d.ts.map +1 -0
- package/dist/dbs/sqlite/migrator.js +22 -0
- package/dist/dbs/sqlite/migrator.js.map +1 -0
- package/dist/dbs/sqlite/query-compiler.d.ts +26 -0
- package/dist/dbs/sqlite/query-compiler.d.ts.map +1 -0
- package/dist/dbs/sqlite/query-compiler.js +80 -0
- package/dist/dbs/sqlite/query-compiler.js.map +1 -0
- package/dist/dbs/sqlite/trx.d.ts +13 -0
- package/dist/dbs/sqlite/trx.d.ts.map +1 -0
- package/dist/dbs/sqlite/trx.js +69 -0
- package/dist/dbs/sqlite/trx.js.map +1 -0
- package/dist/dbs/types.d.ts +92 -0
- package/dist/dbs/types.d.ts.map +1 -0
- package/dist/dbs/types.js +26 -0
- package/dist/dbs/types.js.map +1 -0
- package/dist/dialect.d.ts +3 -0
- package/dist/dialect.d.ts.map +1 -0
- package/dist/dialect.js +2 -0
- package/dist/dialect.js.map +1 -0
- package/dist/driver/factory.d.ts +19 -0
- package/dist/driver/factory.d.ts.map +1 -0
- package/dist/driver/factory.js +24 -0
- package/dist/driver/factory.js.map +1 -0
- package/dist/driver/index.d.ts +6 -0
- package/dist/driver/index.d.ts.map +1 -0
- package/dist/driver/index.js +3 -0
- package/dist/driver/index.js.map +1 -0
- package/dist/driver/sqlite.d.ts +15 -0
- package/dist/driver/sqlite.d.ts.map +1 -0
- package/dist/driver/sqlite.js +74 -0
- package/dist/driver/sqlite.js.map +1 -0
- package/dist/driver/types.d.ts +75 -0
- package/dist/driver/types.d.ts.map +1 -0
- package/dist/driver/types.js +2 -0
- package/dist/driver/types.js.map +1 -0
- package/dist/entity/entity.d.ts +67 -0
- package/dist/entity/entity.d.ts.map +1 -0
- package/dist/entity/entity.js +139 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/global-driver.d.ts +38 -0
- package/dist/entity/global-driver.d.ts.map +1 -0
- package/dist/entity/global-driver.js +109 -0
- package/dist/entity/global-driver.js.map +1 -0
- package/dist/entity/index.d.ts +8 -0
- package/dist/entity/index.d.ts.map +1 -0
- package/dist/entity/index.js +3 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/pk-columns.d.ts +5 -0
- package/dist/entity/pk-columns.d.ts.map +1 -0
- package/dist/entity/pk-columns.js +14 -0
- package/dist/entity/pk-columns.js.map +1 -0
- package/dist/entity/relations.d.ts +134 -0
- package/dist/entity/relations.d.ts.map +1 -0
- package/dist/entity/relations.js +23 -0
- package/dist/entity/relations.js.map +1 -0
- package/dist/entity/schema-inference.d.ts +77 -0
- package/dist/entity/schema-inference.d.ts.map +1 -0
- package/dist/entity/schema-inference.js +6 -0
- package/dist/entity/schema-inference.js.map +1 -0
- package/dist/entity/types.d.ts +30 -0
- package/dist/entity/types.d.ts.map +1 -0
- package/dist/entity/types.js +5 -0
- package/dist/entity/types.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/index.d.ts +2 -0
- package/dist/ir/index.d.ts.map +1 -0
- package/dist/ir/index.js +2 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/types.d.ts +148 -0
- package/dist/ir/types.d.ts.map +1 -0
- package/dist/ir/types.js +97 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/migration/cli.d.ts +18 -0
- package/dist/migration/cli.d.ts.map +1 -0
- package/dist/migration/cli.js +236 -0
- package/dist/migration/cli.js.map +1 -0
- package/dist/migration/diff.d.ts +10 -0
- package/dist/migration/diff.d.ts.map +1 -0
- package/dist/migration/diff.js +10 -0
- package/dist/migration/diff.js.map +1 -0
- package/dist/migration/generator.d.ts +12 -0
- package/dist/migration/generator.d.ts.map +1 -0
- package/dist/migration/generator.js +98 -0
- package/dist/migration/generator.js.map +1 -0
- package/dist/migration/index.d.ts +7 -0
- package/dist/migration/index.d.ts.map +1 -0
- package/dist/migration/index.js +5 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/runner.d.ts +32 -0
- package/dist/migration/runner.d.ts.map +1 -0
- package/dist/migration/runner.js +279 -0
- package/dist/migration/runner.js.map +1 -0
- package/dist/migration/topo-sort.d.ts +12 -0
- package/dist/migration/topo-sort.d.ts.map +1 -0
- package/dist/migration/topo-sort.js +42 -0
- package/dist/migration/topo-sort.js.map +1 -0
- package/dist/migration/types.d.ts +45 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +2 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/orm/aggregates.d.ts +19 -0
- package/dist/orm/aggregates.d.ts.map +1 -0
- package/dist/orm/aggregates.js +32 -0
- package/dist/orm/aggregates.js.map +1 -0
- package/dist/orm/db.d.ts +105 -0
- package/dist/orm/db.d.ts.map +1 -0
- package/dist/orm/db.js +172 -0
- package/dist/orm/db.js.map +1 -0
- package/dist/orm/expr.d.ts +125 -0
- package/dist/orm/expr.d.ts.map +1 -0
- package/dist/orm/expr.js +10 -0
- package/dist/orm/expr.js.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.d.ts +9 -0
- package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.d.ts.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.js +44 -0
- package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.js.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-executor.d.ts +13 -0
- package/dist/orm/helpers/insert-graph/insert-graph-executor.d.ts.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-executor.js +42 -0
- package/dist/orm/helpers/insert-graph/insert-graph-executor.js.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-planner.d.ts +46 -0
- package/dist/orm/helpers/insert-graph/insert-graph-planner.d.ts.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-planner.js +258 -0
- package/dist/orm/helpers/insert-graph/insert-graph-planner.js.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.d.ts +7 -0
- package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.d.ts.map +1 -0
- package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.js +8 -0
- package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.js.map +1 -0
- package/dist/orm/helpers/insert-graph/sequence-id-assigner.d.ts +15 -0
- package/dist/orm/helpers/insert-graph/sequence-id-assigner.d.ts.map +1 -0
- package/dist/orm/helpers/insert-graph/sequence-id-assigner.js +48 -0
- package/dist/orm/helpers/insert-graph/sequence-id-assigner.js.map +1 -0
- package/dist/orm/helpers/query-plan/expr-builder.d.ts +155 -0
- package/dist/orm/helpers/query-plan/expr-builder.d.ts.map +1 -0
- package/dist/orm/helpers/query-plan/expr-builder.js +297 -0
- package/dist/orm/helpers/query-plan/expr-builder.js.map +1 -0
- package/dist/orm/helpers/query-plan/query-ir-analyzer.d.ts +48 -0
- package/dist/orm/helpers/query-plan/query-ir-analyzer.d.ts.map +1 -0
- package/dist/orm/helpers/query-plan/query-ir-analyzer.js +262 -0
- package/dist/orm/helpers/query-plan/query-ir-analyzer.js.map +1 -0
- package/dist/orm/helpers/query-plan/query-plan.d.ts +164 -0
- package/dist/orm/helpers/query-plan/query-plan.d.ts.map +1 -0
- package/dist/orm/helpers/query-plan/query-plan.js +549 -0
- package/dist/orm/helpers/query-plan/query-plan.js.map +1 -0
- package/dist/orm/helpers/query-plan/select-classifier.d.ts +161 -0
- package/dist/orm/helpers/query-plan/select-classifier.d.ts.map +1 -0
- package/dist/orm/helpers/query-plan/select-classifier.js +359 -0
- package/dist/orm/helpers/query-plan/select-classifier.js.map +1 -0
- package/dist/orm/helpers/relations/relation-assembler.d.ts +21 -0
- package/dist/orm/helpers/relations/relation-assembler.d.ts.map +1 -0
- package/dist/orm/helpers/relations/relation-assembler.js +60 -0
- package/dist/orm/helpers/relations/relation-assembler.js.map +1 -0
- package/dist/orm/helpers/relations/relation-fetcher.d.ts +30 -0
- package/dist/orm/helpers/relations/relation-fetcher.d.ts.map +1 -0
- package/dist/orm/helpers/relations/relation-fetcher.js +128 -0
- package/dist/orm/helpers/relations/relation-fetcher.js.map +1 -0
- package/dist/orm/helpers/relations/relation-joins.d.ts +74 -0
- package/dist/orm/helpers/relations/relation-joins.d.ts.map +1 -0
- package/dist/orm/helpers/relations/relation-joins.js +138 -0
- package/dist/orm/helpers/relations/relation-joins.js.map +1 -0
- package/dist/orm/helpers/relations/relation-resolver.d.ts +14 -0
- package/dist/orm/helpers/relations/relation-resolver.d.ts.map +1 -0
- package/dist/orm/helpers/relations/relation-resolver.js +25 -0
- package/dist/orm/helpers/relations/relation-resolver.js.map +1 -0
- package/dist/orm/index.d.ts +7 -0
- package/dist/orm/index.d.ts.map +1 -0
- package/dist/orm/index.js +5 -0
- package/dist/orm/index.js.map +1 -0
- package/dist/orm/query-builder.d.ts +136 -0
- package/dist/orm/query-builder.d.ts.map +1 -0
- package/dist/orm/query-builder.js +433 -0
- package/dist/orm/query-builder.js.map +1 -0
- package/dist/orm/query-helpers.d.ts +35 -0
- package/dist/orm/query-helpers.d.ts.map +1 -0
- package/dist/orm/query-helpers.js +83 -0
- package/dist/orm/query-helpers.js.map +1 -0
- package/dist/orm/query-state.d.ts +56 -0
- package/dist/orm/query-state.d.ts.map +1 -0
- package/dist/orm/query-state.js +112 -0
- package/dist/orm/query-state.js.map +1 -0
- package/dist/orm/single-row-query-builder.d.ts +18 -0
- package/dist/orm/single-row-query-builder.d.ts.map +1 -0
- package/dist/orm/single-row-query-builder.js +90 -0
- package/dist/orm/single-row-query-builder.js.map +1 -0
- package/dist/orm/trx.d.ts +40 -0
- package/dist/orm/trx.d.ts.map +1 -0
- package/dist/orm/trx.js +118 -0
- package/dist/orm/trx.js.map +1 -0
- package/dist/parser/acorn-helpers.d.ts +43 -0
- package/dist/parser/acorn-helpers.d.ts.map +1 -0
- package/dist/parser/acorn-helpers.js +104 -0
- package/dist/parser/acorn-helpers.js.map +1 -0
- package/dist/parser/acorn-member.d.ts +16 -0
- package/dist/parser/acorn-member.d.ts.map +1 -0
- package/dist/parser/acorn-member.js +31 -0
- package/dist/parser/acorn-member.js.map +1 -0
- package/dist/parser/acorn-types.d.ts +14 -0
- package/dist/parser/acorn-types.d.ts.map +1 -0
- package/dist/parser/acorn-types.js +6 -0
- package/dist/parser/acorn-types.js.map +1 -0
- package/dist/parser/arrow-source.d.ts +23 -0
- package/dist/parser/arrow-source.d.ts.map +1 -0
- package/dist/parser/arrow-source.js +70 -0
- package/dist/parser/arrow-source.js.map +1 -0
- package/dist/parser/group-by.d.ts +17 -0
- package/dist/parser/group-by.d.ts.map +1 -0
- package/dist/parser/group-by.js +62 -0
- package/dist/parser/group-by.js.map +1 -0
- package/dist/parser/index.d.ts +5 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parse-arrow.d.ts +10 -0
- package/dist/parser/parse-arrow.d.ts.map +1 -0
- package/dist/parser/parse-arrow.js +9 -0
- package/dist/parser/parse-arrow.js.map +1 -0
- package/dist/parser/predicate-walk.d.ts +24 -0
- package/dist/parser/predicate-walk.d.ts.map +1 -0
- package/dist/parser/predicate-walk.js +247 -0
- package/dist/parser/predicate-walk.js.map +1 -0
- package/dist/parser/resolve.d.ts +25 -0
- package/dist/parser/resolve.d.ts.map +1 -0
- package/dist/parser/resolve.js +134 -0
- package/dist/parser/resolve.js.map +1 -0
- package/dist/parser/select.d.ts +7 -0
- package/dist/parser/select.d.ts.map +1 -0
- package/dist/parser/select.js +333 -0
- package/dist/parser/select.js.map +1 -0
- package/dist/parser/update.d.ts +7 -0
- package/dist/parser/update.d.ts.map +1 -0
- package/dist/parser/update.js +51 -0
- package/dist/parser/update.js.map +1 -0
- package/dist/postgres/aggregates.d.ts +12 -0
- package/dist/postgres/aggregates.d.ts.map +1 -0
- package/dist/postgres/aggregates.js +19 -0
- package/dist/postgres/aggregates.js.map +1 -0
- package/dist/postgres.d.ts +6 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +6 -0
- package/dist/postgres.js.map +1 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/types.d.ts +16 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +40 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/sqlite/aggregates.d.ts +8 -0
- package/dist/sqlite/aggregates.d.ts.map +1 -0
- package/dist/sqlite/aggregates.js +11 -0
- package/dist/sqlite/aggregates.js.map +1 -0
- package/dist/sqlite.d.ts +6 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +6 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/transformer/bindings.d.ts +18 -0
- package/dist/transformer/bindings.d.ts.map +1 -0
- package/dist/transformer/bindings.js +52 -0
- package/dist/transformer/bindings.js.map +1 -0
- package/dist/transformer/index.d.ts +17 -0
- package/dist/transformer/index.d.ts.map +1 -0
- package/dist/transformer/index.js +75 -0
- package/dist/transformer/index.js.map +1 -0
- package/dist/transformer/ir-emit.d.ts +12 -0
- package/dist/transformer/ir-emit.d.ts.map +1 -0
- package/dist/transformer/ir-emit.js +144 -0
- package/dist/transformer/ir-emit.js.map +1 -0
- package/dist/transformer/join-transformer.d.ts +12 -0
- package/dist/transformer/join-transformer.d.ts.map +1 -0
- package/dist/transformer/join-transformer.js +102 -0
- package/dist/transformer/join-transformer.js.map +1 -0
- package/dist/transformer/orderby-transformer.d.ts +13 -0
- package/dist/transformer/orderby-transformer.d.ts.map +1 -0
- package/dist/transformer/orderby-transformer.js +84 -0
- package/dist/transformer/orderby-transformer.js.map +1 -0
- package/dist/transformer/select-transformer.d.ts +9 -0
- package/dist/transformer/select-transformer.d.ts.map +1 -0
- package/dist/transformer/select-transformer.js +222 -0
- package/dist/transformer/select-transformer.js.map +1 -0
- package/dist/transformer/shared.d.ts +12 -0
- package/dist/transformer/shared.d.ts.map +1 -0
- package/dist/transformer/shared.js +12 -0
- package/dist/transformer/shared.js.map +1 -0
- package/dist/transformer/subquery-transformer.d.ts +15 -0
- package/dist/transformer/subquery-transformer.d.ts.map +1 -0
- package/dist/transformer/subquery-transformer.js +43 -0
- package/dist/transformer/subquery-transformer.js.map +1 -0
- package/dist/transformer/ts-aggregates.d.ts +13 -0
- package/dist/transformer/ts-aggregates.d.ts.map +1 -0
- package/dist/transformer/ts-aggregates.js +83 -0
- package/dist/transformer/ts-aggregates.js.map +1 -0
- package/dist/transformer/ts-binary.d.ts +8 -0
- package/dist/transformer/ts-binary.d.ts.map +1 -0
- package/dist/transformer/ts-binary.js +32 -0
- package/dist/transformer/ts-binary.js.map +1 -0
- package/dist/transformer/ts-member.d.ts +12 -0
- package/dist/transformer/ts-member.d.ts.map +1 -0
- package/dist/transformer/ts-member.js +22 -0
- package/dist/transformer/ts-member.js.map +1 -0
- package/dist/transformer/ts-utils.d.ts +10 -0
- package/dist/transformer/ts-utils.d.ts.map +1 -0
- package/dist/transformer/ts-utils.js +38 -0
- package/dist/transformer/ts-utils.js.map +1 -0
- package/dist/transformer/typhex-type.d.ts +8 -0
- package/dist/transformer/typhex-type.d.ts.map +1 -0
- package/dist/transformer/typhex-type.js +52 -0
- package/dist/transformer/typhex-type.js.map +1 -0
- package/dist/transformer/where-transformer.d.ts +33 -0
- package/dist/transformer/where-transformer.d.ts.map +1 -0
- package/dist/transformer/where-transformer.js +400 -0
- package/dist/transformer/where-transformer.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +30 -0
- package/dist/utils.js.map +1 -0
- package/docs/drivers/postgres.md +54 -0
- package/docs/drivers/sqlite.md +33 -0
- package/docs/guide/aggregations.md +272 -0
- package/docs/guide/bulk-operations.md +204 -0
- package/docs/guide/cte-and-unions.md +270 -0
- package/docs/guide/entities-relations.md +208 -0
- package/docs/guide/expressions.md +98 -0
- package/docs/guide/filtering-by-relations.md +166 -0
- package/docs/guide/getting-started.md +277 -0
- package/docs/guide/querying-relations.md +133 -0
- package/docs/guide/subqueries.md +152 -0
- package/docs/guide/transactions.md +146 -0
- package/docs/guide/typescript-transformer.md +138 -0
- package/docs/index.md +33 -0
- package/docs/migrations/overview.md +143 -0
- package/docs/public-api.md +133 -0
- package/docs/reference/api.md +665 -0
- package/docs/reference/architecture.md +83 -0
- package/docs/release-checklist.md +55 -0
- package/etc/typhex.api.md +774 -0
- package/package.json +137 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## `Entity(tableName, schema, relations?)`
|
|
4
|
+
|
|
5
|
+
Creates a base class for a database table.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
const MyEntity = Entity(tableName: string, schema: Schema, relations?: Relations)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- **`tableName`** — SQL table name
|
|
12
|
+
- **`schema`** — Map of column names to SQL type strings (e.g., `"text not null"`, `"integer primary key autoincrement"`)
|
|
13
|
+
- **`relations`** — Optional map of relation names to relation definitions (see `rel` below)
|
|
14
|
+
|
|
15
|
+
Returns a class. Subclass it to add custom methods and lifecycle hooks. Call `.query()` on the class or an instance to get a query builder.
|
|
16
|
+
|
|
17
|
+
## `rel` Helpers
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { rel } from "typhex";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `rel.manyToOne(targetFn, options)`
|
|
24
|
+
|
|
25
|
+
Defines a many-to-one (N:1) relation. The current table holds the foreign key.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
rel.manyToOne(() => Company, { foreignKey: "companyId" });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Option | Type | Description |
|
|
32
|
+
| ------------ | -------- | ----------------------------------------------- |
|
|
33
|
+
| `foreignKey` | `string` | Column on this table that references the target |
|
|
34
|
+
|
|
35
|
+
### `rel.oneToMany(targetFn, options)`
|
|
36
|
+
|
|
37
|
+
Defines a one-to-many (1:N) relation. The target table holds the foreign key.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
rel.oneToMany(() => Employee, { foreignKey: "departmentId" });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Option | Type | Description |
|
|
44
|
+
| ------------ | -------- | ----------------------------------------------------- |
|
|
45
|
+
| `foreignKey` | `string` | Column on the target table that references this table |
|
|
46
|
+
|
|
47
|
+
### `rel.oneToOne(targetFn, options)`
|
|
48
|
+
|
|
49
|
+
Defines a one-to-one (1:1) relation. The FK lives on this table.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
rel.oneToOne(() => UserProfile, { foreignKey: "userId" });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Option | Type | Description |
|
|
56
|
+
| ------------ | -------------------- | ---------------------------------------------- |
|
|
57
|
+
| `foreignKey` | `string \| string[]` | Column(s) on this table pointing to the target |
|
|
58
|
+
|
|
59
|
+
### `rel.manyToMany(targetFn, options)`
|
|
60
|
+
|
|
61
|
+
Defines a many-to-many (M:N) relation via a junction table.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
rel.manyToMany(() => Tag, { junction: "post_tags", foreignKey: "postId", referenceKey: "tagId" });
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Option | Type | Description |
|
|
68
|
+
| -------------- | -------- | ------------------------------------ |
|
|
69
|
+
| `junction` | `string` | Junction table name |
|
|
70
|
+
| `foreignKey` | `string` | Column pointing to this entity |
|
|
71
|
+
| `referenceKey` | `string` | Column pointing to the target entity |
|
|
72
|
+
|
|
73
|
+
See [Composite Primary Keys](/guide/entities-relations#composite-primary-keys) for multi-column PK and FK syntax.
|
|
74
|
+
|
|
75
|
+
## `Db`
|
|
76
|
+
|
|
77
|
+
### Constructor
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
new Db(driver: Driver)
|
|
81
|
+
new Db({ driver: Driver, migrationsFolder?: string })
|
|
82
|
+
new Db({ dialect: "sqlite", database: string, migrationsFolder?: string })
|
|
83
|
+
new Db({ dialect: "postgres", url: string, migrationsFolder?: string })
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Sets the driver as the default for all entities registered in the current process.
|
|
87
|
+
|
|
88
|
+
### `Db.fromConfig(options?)`
|
|
89
|
+
|
|
90
|
+
Load `typhex.config.js` and create a database from it. This is the same config shape used by the CLI.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const db = await Db.fromConfig();
|
|
94
|
+
const db = await Db.fromConfig({ configPath: "./typhex.config.js" });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Config fields: `dialect`, `database` for SQLite, `url` for PostgreSQL, `migrationsFolder`, and `entities`.
|
|
98
|
+
|
|
99
|
+
### `db.migrate()`
|
|
100
|
+
|
|
101
|
+
Creates all registered tables that don't exist yet.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
await db.migrate();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `db.generateMigrations(dir)`
|
|
108
|
+
|
|
109
|
+
Diffs current entity definitions against existing migration files and writes new `.js` migration modules.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const files = await db.generateMigrations(dir: string)
|
|
113
|
+
// Returns: { name: string, upSql: string, downSql: string, content: string }[]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `db.runMigrations(dir)`
|
|
117
|
+
|
|
118
|
+
Applies all pending migration modules in `dir`.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const result = await db.runMigrations(dir: string)
|
|
122
|
+
// Returns: { applied: string[], skipped: string[] }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `db.migrationStatus(dir)`
|
|
126
|
+
|
|
127
|
+
Returns applied migration records and pending migration names.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const status = await db.migrationStatus(dir: string)
|
|
131
|
+
// Returns: { applied: MigrationRecord[], pending: string[] }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
See the [Migrations guide](/migrations/overview) for the generated module format.
|
|
135
|
+
|
|
136
|
+
### `db.transaction(fn, options?)`
|
|
137
|
+
|
|
138
|
+
Run a callback inside a transaction with implicit propagation via AsyncLocalStorage.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
await db.transaction(async (trx) => {
|
|
142
|
+
await User.query().insert({ name: "Alice" });
|
|
143
|
+
await Post.query().insert({ title: "Hello", authorId: 1 });
|
|
144
|
+
});
|
|
145
|
+
// rolls back automatically if fn throws
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Options: `{ isolationLevel?: "SERIALIZABLE" | ... }` and for SQLite: `{ sqliteMode?: "deferred" | "immediate" | "exclusive" }`.
|
|
149
|
+
|
|
150
|
+
### `db.beginTrx(options?)`
|
|
151
|
+
|
|
152
|
+
Begin a transaction and return a `Trx` handle for explicit management.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const trx = await db.beginTrx();
|
|
156
|
+
try {
|
|
157
|
+
await User.query(trx).insert({ name: "Alice" });
|
|
158
|
+
await trx.commit();
|
|
159
|
+
} catch {
|
|
160
|
+
await trx.rollback();
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `db.run(sql, params?)`
|
|
165
|
+
|
|
166
|
+
Execute raw SQL directly. Useful for DDL statements like creating junction tables.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
await db.run("CREATE TABLE post_tags (postId INTEGER NOT NULL, tagId INTEGER NOT NULL)");
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `db.query(sql, params?)`
|
|
173
|
+
|
|
174
|
+
Execute a raw SQL query and return rows.
|
|
175
|
+
|
|
176
|
+
### `db.close()`
|
|
177
|
+
|
|
178
|
+
Closes the database connection / releases the connection pool.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
await db.close();
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Query Builder
|
|
185
|
+
|
|
186
|
+
All methods below are available on `EntityClass.query()` and on instance `.query()`.
|
|
187
|
+
|
|
188
|
+
### `.where(predicate, closureVars?)`
|
|
189
|
+
|
|
190
|
+
Filter rows. `predicate` is an arrow function. With the transformer, closure variables are captured automatically; in runtime mode pass them as the second argument.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
.where((u) => u.age > 18)
|
|
194
|
+
.where((u) => u.country === country) // transformer
|
|
195
|
+
.where((u) => u.country === country, { country }) // runtime fallback
|
|
196
|
+
.where((u) => u.company.name === "Acme") // generates JOIN
|
|
197
|
+
.where((d) => d.employees.some((e) => e.name === "Alice")) // generates EXISTS
|
|
198
|
+
.where((d) => d.employees.every((e) => e.active === true)) // generates NOT EXISTS
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```sql
|
|
202
|
+
WHERE age > ?
|
|
203
|
+
WHERE country = ?
|
|
204
|
+
LEFT JOIN companies ON companies.id = users.companyId WHERE companies.name = ?
|
|
205
|
+
WHERE EXISTS (SELECT 1 FROM employees WHERE employees.departmentId = departments.id AND employees.name = ?)
|
|
206
|
+
WHERE NOT EXISTS (SELECT 1 FROM employees WHERE employees.departmentId = departments.id AND NOT (employees.active = ?))
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### `.select(columnsOrLambda, closureVars?)`
|
|
210
|
+
|
|
211
|
+
Limit or reshape the result columns.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
.select(["name", "country"]) // column list
|
|
215
|
+
.select((u) => ({ userId: u.id, name: u.name })) // projection with aliases
|
|
216
|
+
.select((o) => ({ revenue: o.price * o.qty })) // computed projection
|
|
217
|
+
.select((o) => ({ smalls: sum(o.qty < cutoff ? 1 : 0) }), { cutoff }) // runtime closure
|
|
218
|
+
.select((p) => ({ ...p, author: p.author })) // spread + relation
|
|
219
|
+
.select((u) => ({ posts: u.posts.query().select(…) })) // oneToMany sub-query
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```sql
|
|
223
|
+
SELECT name AS name, country AS country FROM users
|
|
224
|
+
SELECT id AS userId, name AS name FROM users
|
|
225
|
+
SELECT (price * qty) AS revenue FROM orders
|
|
226
|
+
-- spread + relation: main query selects all own cols, relation fetched separately
|
|
227
|
+
-- oneToMany sub-query: main + child fetch via WHERE foreignKey IN (...)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### `.orderBy(column, direction?)`
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
.orderBy((u) => u.name, "asc") // arrow form (preferred)
|
|
234
|
+
.orderBy((u) => u.age, "desc")
|
|
235
|
+
.orderBy((o) => o.price * o.qty, "desc") // expression
|
|
236
|
+
.orderBy((u) => u.company.name, "asc") // relation column — generates JOIN
|
|
237
|
+
.orderBy("name", "asc") // string form also accepted
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### `.limit(n)`
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
.limit(10)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### `.offset(n)`
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
.offset(20)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### `.withCte(name, query)`
|
|
253
|
+
|
|
254
|
+
Register a common table expression (`WITH name AS (…)`). The inner query is compiled when the outer query runs. Chain `.from(name)` on the outer query to read from the CTE.
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const adults = User.query().where((u) => u.age >= 18);
|
|
258
|
+
const rows = await User.query()
|
|
259
|
+
.withCte("adults", adults)
|
|
260
|
+
.from("adults")
|
|
261
|
+
.where((u) => u.age < 65)
|
|
262
|
+
.toArray();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
```sql
|
|
266
|
+
WITH "adults" AS (
|
|
267
|
+
SELECT "t0"."id", "t0"."name", "t0"."age"
|
|
268
|
+
FROM "users" AS "t0"
|
|
269
|
+
WHERE ("t0"."age" >= ?)
|
|
270
|
+
)
|
|
271
|
+
SELECT "t0"."id", "t0"."name", "t0"."age"
|
|
272
|
+
FROM "adults" AS "t0"
|
|
273
|
+
WHERE ("t0"."age" < ?)
|
|
274
|
+
-- params: [18, 65]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Later CTEs can reference earlier ones via `.from("earlier_name")`:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
const adults = User.query().where((u) => u.age >= 18);
|
|
281
|
+
const ukAdults = User.query()
|
|
282
|
+
.from("adults")
|
|
283
|
+
.where((u) => u.country === "UK");
|
|
284
|
+
await User.query()
|
|
285
|
+
.withCte("adults", adults)
|
|
286
|
+
.withCte("uk_adults", ukAdults)
|
|
287
|
+
.from("uk_adults")
|
|
288
|
+
.toArray();
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Callback form** — build the inner query from the base table and correlate to earlier CTEs in `WHERE` (not `.from("earlier")`). Requires the Typhex transformer so `ctes.<name>.<column>` in a single-arg `where` is compiled to IR:
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
await User.query()
|
|
295
|
+
.withCte("adults", adults)
|
|
296
|
+
.withCte("uk_adults", (ctes) =>
|
|
297
|
+
User.query().where((u) => u.country === "UK" && u.id === ctes.adults.id),
|
|
298
|
+
)
|
|
299
|
+
.from("uk_adults")
|
|
300
|
+
.toArray();
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```sql
|
|
304
|
+
-- uk_adults body: FROM "users" AS "t0", "adults" WHERE ... AND "t0"."id" = "adults"."id"
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### `.withRecursiveCte(name, query)`
|
|
308
|
+
|
|
309
|
+
Register a recursive CTE (`WITH RECURSIVE name AS (…)`). The body should combine an anchor `SELECT` with a recursive step via `.unionAll()`. Use `.from(name)` inside the recursive branch for self-reference.
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
const anchor = User.query().where((u) => u.age >= 65);
|
|
313
|
+
const recursive = User.query()
|
|
314
|
+
.from("seniors")
|
|
315
|
+
.where((u) => u.age >= 100);
|
|
316
|
+
const body = anchor.unionAll(recursive);
|
|
317
|
+
const seniors = await User.query().withRecursiveCte("seniors", body).from("seniors").toArray();
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
For hierarchies, join the base entity table in the recursive step:
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
await Category.query()
|
|
324
|
+
.withRecursiveCte(
|
|
325
|
+
"tree",
|
|
326
|
+
Category.query()
|
|
327
|
+
.where((c) => c.parentId === null)
|
|
328
|
+
.unionAll(
|
|
329
|
+
Category.query()
|
|
330
|
+
.from("tree")
|
|
331
|
+
.innerJoin(Category, (child, parent) => child.parentId === parent.id),
|
|
332
|
+
),
|
|
333
|
+
)
|
|
334
|
+
.from("tree")
|
|
335
|
+
.orderBy("name")
|
|
336
|
+
.toArray();
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### `.from(source?)`
|
|
340
|
+
|
|
341
|
+
Set the outer `FROM` source:
|
|
342
|
+
|
|
343
|
+
- omit — read from the entity's base table
|
|
344
|
+
- `string` — registered CTE name from `.withCte()` or `.withRecursiveCte()` on this builder
|
|
345
|
+
- `QueryBuilder` — inline subquery: `FROM (SELECT …) AS t0`
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
const inner = User.query().where((u) => u.age >= 18);
|
|
349
|
+
await User.query()
|
|
350
|
+
.from(inner)
|
|
351
|
+
.where((u) => u.country === "US")
|
|
352
|
+
.toArray();
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
```sql
|
|
356
|
+
SELECT ... FROM (
|
|
357
|
+
SELECT ... FROM "users" AS "t0" WHERE ("t0"."age" >= ?)
|
|
358
|
+
) AS "t0"
|
|
359
|
+
WHERE ("t0"."country" = ?)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### `.unionAll(other)`
|
|
363
|
+
|
|
364
|
+
Append a `UNION ALL` branch to the current `SELECT`. Used inside recursive CTE bodies together with `.withRecursiveCte()`, or to combine two filtered sets in a non-recursive CTE:
|
|
365
|
+
|
|
366
|
+
```ts
|
|
367
|
+
const young = User.query().where((u) => u.age < 25);
|
|
368
|
+
const senior = User.query().where((u) => u.age >= 65);
|
|
369
|
+
await User.query()
|
|
370
|
+
.withCte("ends", young.unionAll(senior))
|
|
371
|
+
.from("ends")
|
|
372
|
+
.orderBy("name", "asc")
|
|
373
|
+
.toArray();
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### `.toArray()`
|
|
377
|
+
|
|
378
|
+
Execute and return all matching rows.
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
const rows = await query.toArray();
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### `.first()`
|
|
385
|
+
|
|
386
|
+
Execute and return the first matching row, or `undefined`.
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
const row = await query.first();
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### `.count()`
|
|
393
|
+
|
|
394
|
+
Execute and return how many rows the query would produce without `limit`, `offset`, or `orderBy`. With `groupBy`, counts groups rather than base rows (Objection.js `resultSize()` semantics).
|
|
395
|
+
|
|
396
|
+
The query is compiled as a subquery and wrapped:
|
|
397
|
+
|
|
398
|
+
```sql
|
|
399
|
+
SELECT COUNT(*) AS c FROM (<inner SELECT …>) AS "_count"
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
`limit`, `offset`, and `orderBy` are stripped from the inner SELECT; `where`, joins, `groupBy`, `having`, and CTEs are kept.
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
const n = await query.count();
|
|
406
|
+
await User.query().withCte("us_users", usOnly).from("us_users").count();
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
```sql
|
|
410
|
+
-- simple filter
|
|
411
|
+
SELECT COUNT(*) AS c FROM (
|
|
412
|
+
SELECT "t0"."id", "t0"."name" FROM "users" AS "t0" WHERE ("t0"."country" = ?)
|
|
413
|
+
) AS "_count"
|
|
414
|
+
|
|
415
|
+
-- with CTE
|
|
416
|
+
SELECT COUNT(*) AS c FROM (
|
|
417
|
+
WITH "us_users" AS (
|
|
418
|
+
SELECT ... FROM "users" AS "t0" WHERE ("t0"."country" = ?)
|
|
419
|
+
)
|
|
420
|
+
SELECT ... FROM "us_users" AS "t0" WHERE 1=1
|
|
421
|
+
) AS "_count"
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### `.insert(data)`
|
|
425
|
+
|
|
426
|
+
Insert a row and return the inserted entity (with auto-generated `id`).
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
const row = await Entity.query().insert({ name: "Alice", age: 30 });
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### `.update(data)`
|
|
433
|
+
|
|
434
|
+
Update all rows matching the current `where()` predicate.
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
const updatedCount = await Entity.query().where(…).update({ age: 31 })
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
When `.withCte()` is registered on the same builder, correlate the base table to CTE rows via a second `where` argument or `ctes.<name>.<column>` in an update SET lambda. SQLite/Postgres emit `WITH … UPDATE … FROM <cte>` when the predicate references a registered CTE:
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
const adults = User.query().where((u) => u.age >= 18);
|
|
444
|
+
await User.query()
|
|
445
|
+
.withCte("adults", adults)
|
|
446
|
+
.where((u, ctes) => u.age === 35 && u.id === ctes.adults.id)
|
|
447
|
+
.update({ name: "Robert" });
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Returns the number of rows updated.
|
|
451
|
+
|
|
452
|
+
### `.delete()`
|
|
453
|
+
|
|
454
|
+
Delete all rows matching the current `where()` predicate.
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
const deletedCount = await Entity.query().where(…).delete()
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
With registered CTEs, correlation uses `WHERE EXISTS (SELECT 1 FROM <cte> WHERE …)`:
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
const ukAdults = User.query().where((u) => u.country === "UK" && u.age >= 18);
|
|
464
|
+
await User.query()
|
|
465
|
+
.withCte("uk_adults", ukAdults)
|
|
466
|
+
.where((u, ctes) => u.age >= 65 && u.id === ctes.uk_adults.id)
|
|
467
|
+
.delete();
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Returns the number of rows deleted.
|
|
471
|
+
|
|
472
|
+
### `.patch(data)`
|
|
473
|
+
|
|
474
|
+
Update matching rows and return the updated row (or `null` if no match).
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
const updated = await Entity.query()
|
|
478
|
+
.where((u) => u.name === "Bob")
|
|
479
|
+
.patch({ age: 26 });
|
|
480
|
+
// Returns: EntityInstance | null
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### `.findById(id)`
|
|
484
|
+
|
|
485
|
+
Find a single row by primary key.
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
const row = await Entity.query().findById(1);
|
|
489
|
+
// Returns the row or null
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### `.insertMany(rows)`
|
|
493
|
+
|
|
494
|
+
Insert multiple rows in one SQL statement. Returns the inserted rows on PostgreSQL; returns `[]` on SQLite.
|
|
495
|
+
|
|
496
|
+
```ts
|
|
497
|
+
await Product.query().insertMany([
|
|
498
|
+
{ sku: "W-001", name: "Widget", price: 999, stock: 100 },
|
|
499
|
+
{ sku: "G-001", name: "Gadget", price: 1499, stock: 50 },
|
|
500
|
+
]);
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Chain `.onConflict(columns).doNothing()` or `.onConflict(columns).doUpdate(updateCols?)` for upsert behaviour.
|
|
504
|
+
|
|
505
|
+
### `.insertGraph(graph)`
|
|
506
|
+
|
|
507
|
+
Insert a nested object graph — parents before children, children with wired foreign keys, junction rows for many-to-many.
|
|
508
|
+
|
|
509
|
+
```ts
|
|
510
|
+
await Post.query().insertGraph({
|
|
511
|
+
title: "Hello",
|
|
512
|
+
author: { name: "Alice" }, // manyToOne parent
|
|
513
|
+
tags: [{ name: "new-tag" }, { id: existingId }], // manyToMany: insert + link
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Accepts a single object or an array. Participates in an active transaction when one is passed via `Entity.query(trx)`.
|
|
518
|
+
|
|
519
|
+
### `.groupBy(columnsOrFnOrPositional)`
|
|
520
|
+
|
|
521
|
+
Group results. Accepts a lambda, column name(s), or positional index.
|
|
522
|
+
|
|
523
|
+
```ts
|
|
524
|
+
.groupBy((o) => o.category) // arrow form (preferred)
|
|
525
|
+
.groupBy((o) => o.category).groupBy((o) => o.status) // multiple columns
|
|
526
|
+
.groupBy("category", "status") // string form also accepted
|
|
527
|
+
.groupBy([1, 2]) // positional
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### `.having(predicate, closureVars?)`
|
|
531
|
+
|
|
532
|
+
Filter groups. Same arrow-function syntax as `.where()`.
|
|
533
|
+
|
|
534
|
+
```ts
|
|
535
|
+
.having((o) => count(o.id) > 1)
|
|
536
|
+
.having((o) => sum(o.price) >= minRevenue, { minRevenue }) // runtime mode
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### `.innerJoin(keysOrFn)` / `.leftJoin(…)` / `.rightJoin(…)` / `.fullJoin(…)` / `.crossJoin(…)`
|
|
540
|
+
|
|
541
|
+
Override the join type for a specific relation (Typhex defaults to `LEFT JOIN` for relations used in `where()`).
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
Contact.query()
|
|
545
|
+
.innerJoin((c) => c.company)
|
|
546
|
+
.where((c) => c.company.name === "Acme");
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Join an entity table directly with a custom `ON` predicate (for example when joining a recursive CTE to its base table, or self-joining for peer rows):
|
|
550
|
+
|
|
551
|
+
```ts
|
|
552
|
+
User.query()
|
|
553
|
+
.innerJoin(User, (peer, u) => peer.country === u.country && peer.id !== u.id)
|
|
554
|
+
.where((u) => u.name === "Alice");
|
|
555
|
+
|
|
556
|
+
Category.query()
|
|
557
|
+
.from("tree")
|
|
558
|
+
.innerJoin(Category, (child, parent) => child.parentId === parent.id);
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
```sql
|
|
562
|
+
SELECT ... FROM contacts
|
|
563
|
+
INNER JOIN companies ON companies.id = contacts.companyId
|
|
564
|
+
WHERE companies.name = ?
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
## Aggregate Functions
|
|
568
|
+
|
|
569
|
+
```ts
|
|
570
|
+
import { count, sum, avg, min, max, distinct } from "typhex";
|
|
571
|
+
import { groupConcat } from "typhex/sqlite"; // SQLite only
|
|
572
|
+
import { stringAgg, arrayAgg, jsonAgg } from "typhex/postgres"; // PostgreSQL only
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
| Function | SQL | Notes |
|
|
576
|
+
| ------------------------ | -------------- | ------------------------------ |
|
|
577
|
+
| `count(col?)` | `COUNT(col)` | Omit arg for `COUNT(*)` |
|
|
578
|
+
| `sum(expr)` | `SUM(expr)` | Accepts columns or expressions |
|
|
579
|
+
| `avg(expr)` | `AVG(expr)` | Accepts columns or expressions |
|
|
580
|
+
| `min(expr)` | `MIN(expr)` | Accepts columns or expressions |
|
|
581
|
+
| `max(expr)` | `MAX(expr)` | Accepts columns or expressions |
|
|
582
|
+
| `distinct(col)` | `DISTINCT col` | Wrap inside another aggregate |
|
|
583
|
+
| `groupConcat(col, sep?)` | `GROUP_CONCAT` | SQLite only |
|
|
584
|
+
| `stringAgg(col, sep)` | `STRING_AGG` | PostgreSQL only |
|
|
585
|
+
| `arrayAgg(col)` | `ARRAY_AGG` | PostgreSQL only |
|
|
586
|
+
| `jsonAgg(col)` | `JSON_AGG` | PostgreSQL only |
|
|
587
|
+
|
|
588
|
+
Used inside `.select()` and `.having()` lambdas. Aggregate arguments can include arithmetic and ternaries, for example `sum(o.price * o.qty)` or `sum(o.active ? 1 : 0)`.
|
|
589
|
+
|
|
590
|
+
## `createSqliteDriver(options)`
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
import { createSqliteDriver } from "typhex";
|
|
594
|
+
|
|
595
|
+
createSqliteDriver({ path: string });
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
| Option | Description |
|
|
599
|
+
| ------ | ----------------------------------- |
|
|
600
|
+
| `path` | Path to `.db` file, or `":memory:"` |
|
|
601
|
+
|
|
602
|
+
## `createPostgresDriver(options)`
|
|
603
|
+
|
|
604
|
+
```ts
|
|
605
|
+
import { createPostgresDriver } from "typhex";
|
|
606
|
+
|
|
607
|
+
createPostgresDriver({ connectionString: string });
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
| Option | Description |
|
|
611
|
+
| --------------------- | ------------------------------------------------------------- |
|
|
612
|
+
| `connectionString` | PostgreSQL connection URI |
|
|
613
|
+
| `url` | Alias for `connectionString`, useful in config files |
|
|
614
|
+
| `host` | Hostname when not using a connection string |
|
|
615
|
+
| `port` | Port, default `5432` |
|
|
616
|
+
| `database` | Database name, default `"postgres"` |
|
|
617
|
+
| `user` | Database user |
|
|
618
|
+
| `password` | Database password |
|
|
619
|
+
| `ssl` | SSL config forwarded to `pg` |
|
|
620
|
+
| `poolMin` | Minimum pool connections, default `2` |
|
|
621
|
+
| `poolMax` | Maximum pool connections, default `10` |
|
|
622
|
+
| `idleTimeoutMs` | Idle connection timeout in milliseconds, default `30000` |
|
|
623
|
+
| `connectionTimeoutMs` | Pool connection timeout in milliseconds, default `5000` |
|
|
624
|
+
| `statementTimeoutMs` | PostgreSQL `statement_timeout` in milliseconds |
|
|
625
|
+
| `logger` | Custom pool error logger with an `error(message, err)` method |
|
|
626
|
+
|
|
627
|
+
## `createDriver(options)`
|
|
628
|
+
|
|
629
|
+
Create a driver from a discriminated options object:
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
import { createDriver } from "typhex";
|
|
633
|
+
|
|
634
|
+
const sqlite = createDriver({ dialect: "sqlite", path: "./app.db" });
|
|
635
|
+
const postgres = createDriver({ dialect: "postgres", url: process.env.DATABASE_URL });
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
## Supported Predicate Syntax
|
|
639
|
+
|
|
640
|
+
| Expression | SQL equivalent | Notes |
|
|
641
|
+
| --------------------------- | ------------------------- | ---------------------------------------------- |
|
|
642
|
+
| `u.age > 18` | `age > ?` | `>`, `>=`, `<`, `<=`, `===`, `!==`, `==`, `!=` |
|
|
643
|
+
| `u.deletedAt === null` | `deletedAt IS NULL` | `!== null` emits `IS NOT NULL` |
|
|
644
|
+
| `u.active` | `active = 1` | boolean truthy |
|
|
645
|
+
| `!u.active` | `NOT active = 1` | unary negation |
|
|
646
|
+
| `u.a && u.b` | `a AND b` | |
|
|
647
|
+
| `u.a \|\| u.b` | `a OR b` | |
|
|
648
|
+
| `u.price * u.qty` | `price * qty` | arithmetic: `+`, `-`, `*`, `/`, `%` |
|
|
649
|
+
| `u.flags & 4` | `flags & ?` | bitwise: `&`, `\|`, `^`, `<<`, `>>`, `~` |
|
|
650
|
+
| `u.qty < 5 ? "s" : "l"` | `CASE WHEN … THEN … END` | works in predicates, projections, aggregates |
|
|
651
|
+
| `u.name.startsWith("A")` | `name LIKE 'A%'` | |
|
|
652
|
+
| `u.name.endsWith("z")` | `name LIKE '%z'` | |
|
|
653
|
+
| `u.name.includes("al")` | `name LIKE '%al%'` | |
|
|
654
|
+
| `u.id in [1, 2, 3]` | `id IN (?, ?, ?)` | literal array |
|
|
655
|
+
| `u.id in ids` | `id IN (?, …)` | variable array (pass as closure) |
|
|
656
|
+
| `!(u.id in [2])` | `id NOT IN (?)` | negated `in` |
|
|
657
|
+
| `u.company.name === "Acme"` | `JOIN … WHERE …` | manyToOne: generates JOIN |
|
|
658
|
+
| `d.employees.some(e => …)` | `EXISTS (SELECT 1 …)` | oneToMany: generates EXISTS |
|
|
659
|
+
| `d.employees.every(e => …)` | `NOT EXISTS (SELECT 1 …)` | oneToMany: no child may fail the predicate |
|
|
660
|
+
|
|
661
|
+
**Supported in runtime mode:** ternaries, arithmetic, bitwise operators, strict null checks, computed projections, aggregate expressions, expression `orderBy()`, and `IN` subqueries passed through the params object.
|
|
662
|
+
|
|
663
|
+
**Transformer-only:** scalar correlated subqueries in `.select()`, comparison `.where()` predicates, and `.orderBy()`; inline nested subqueries that rely on closure capture.
|
|
664
|
+
|
|
665
|
+
**Not supported:** unsigned right shift (`>>>`), optional chaining, nullish coalescing, arbitrary function calls, `await`, `new`, `instanceof`, assignments, and loops.
|