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
package/dist/utils.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function toArray(value) {
|
|
2
|
+
if (value == null)
|
|
3
|
+
return [];
|
|
4
|
+
return Array.isArray(value) ? value : [value];
|
|
5
|
+
}
|
|
6
|
+
export function isRecord(value) {
|
|
7
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
export function groupBy(items, keyFn) {
|
|
10
|
+
const map = new Map();
|
|
11
|
+
for (const item of items) {
|
|
12
|
+
const key = keyFn(item);
|
|
13
|
+
const bucket = map.get(key);
|
|
14
|
+
if (bucket)
|
|
15
|
+
bucket.push(item);
|
|
16
|
+
else
|
|
17
|
+
map.set(key, [item]);
|
|
18
|
+
}
|
|
19
|
+
return map;
|
|
20
|
+
}
|
|
21
|
+
export function extractBaseType(def) {
|
|
22
|
+
const trimmed = def.trim().toLowerCase().replaceAll(/\s+/g, " ");
|
|
23
|
+
const withoutModifiers = trimmed.replace(/^(?:unsigned|signed)\s+/, "");
|
|
24
|
+
const multiWord = withoutModifiers.match(/^(?:double\s+precision|character\s+varying|timestamp\s+with\s+time\s+zone|timestamp\s+without\s+time\s+zone)(?:\([^)]*\))?/);
|
|
25
|
+
if (multiWord)
|
|
26
|
+
return multiWord[0];
|
|
27
|
+
const withParams = withoutModifiers.match(/^(\w+(?:\([^)]*\))?)/);
|
|
28
|
+
return withParams ? withParams[1] : (withoutModifiers.split(/\s/)[0] ?? trimmed);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAI,KAA0B;IACnD,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,OAAO,CAAO,KAAkB,EAAE,KAAqB;IACrE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YACzB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CACtC,4HAA4H,CAC7H,CAAC;IACF,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PostgreSQL Driver
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Db, createPostgresDriver } from "typhex";
|
|
7
|
+
|
|
8
|
+
const db = new Db(
|
|
9
|
+
createPostgresDriver({
|
|
10
|
+
connectionString: process.env.TYPHEX_POSTGRES_URL!,
|
|
11
|
+
}),
|
|
12
|
+
);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Options
|
|
16
|
+
|
|
17
|
+
| Option | Type | Description |
|
|
18
|
+
| --------------------- | ---------- | ------------------------------------------------------------------------ |
|
|
19
|
+
| `connectionString` | `string` | Standard PostgreSQL URI: `postgresql://user:password@host:port/database` |
|
|
20
|
+
| `url` | `string` | Alias for `connectionString`, useful in config files |
|
|
21
|
+
| `host` | `string` | Hostname when not using a connection string |
|
|
22
|
+
| `port` | `number` | Port, default `5432` |
|
|
23
|
+
| `database` | `string` | Database name, default `"postgres"` |
|
|
24
|
+
| `user` | `string` | Database user |
|
|
25
|
+
| `password` | `string` | Database password |
|
|
26
|
+
| `ssl` | `pg` value | SSL config forwarded to `pg` |
|
|
27
|
+
| `poolMin` | `number` | Minimum pool connections, default `2` |
|
|
28
|
+
| `poolMax` | `number` | Maximum pool connections, default `10` |
|
|
29
|
+
| `idleTimeoutMs` | `number` | Idle connection timeout in milliseconds, default `30000` |
|
|
30
|
+
| `connectionTimeoutMs` | `number` | Pool connection timeout in milliseconds, default `5000` |
|
|
31
|
+
| `statementTimeoutMs` | `number` | PostgreSQL `statement_timeout` in milliseconds |
|
|
32
|
+
| `logger` | `object` | Custom pool error logger with an `error(message, err)` method |
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install pg
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The driver uses `pg.Pool` internally; call `db.close()` on shutdown to release pool connections.
|
|
41
|
+
|
|
42
|
+
## Column Types
|
|
43
|
+
|
|
44
|
+
Use PostgreSQL-native types in your schema:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const User = Entity("users", {
|
|
48
|
+
id: "SERIAL PRIMARY KEY",
|
|
49
|
+
name: "VARCHAR(255) NOT NULL",
|
|
50
|
+
age: "INTEGER NOT NULL",
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The query API (`where`, `insert`, `select`, etc.) is identical to SQLite — only the driver and column types differ.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# SQLite Driver
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Db, createSqliteDriver } from "typhex";
|
|
7
|
+
|
|
8
|
+
const db = new Db(createSqliteDriver({ path: "./app.db" }));
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Use `":memory:"` for an in-memory database (created fresh, discarded on close — useful for tests):
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const db = new Db(createSqliteDriver({ path: ":memory:" }));
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Options
|
|
18
|
+
|
|
19
|
+
| Option | Type | Description |
|
|
20
|
+
| ------ | -------- | --------------------------------------- |
|
|
21
|
+
| `path` | `string` | Path to the `.db` file, or `":memory:"` |
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install better-sqlite3
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`better-sqlite3` includes a native C++ addon. If installation fails, install the appropriate build tools:
|
|
30
|
+
|
|
31
|
+
- **macOS:** `xcode-select --install`
|
|
32
|
+
- **Linux:** `apt install build-essential` (or distro equivalent)
|
|
33
|
+
- **Windows:** Visual Studio Build Tools
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Aggregations
|
|
2
|
+
|
|
3
|
+
Typhex supports `GROUP BY`, `HAVING`, and all standard aggregate functions. Import the aggregate helpers alongside your entities.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Db, Entity, createSqliteDriver, count, sum, avg, min, max, distinct } from "typhex";
|
|
7
|
+
import { groupConcat } from "typhex/sqlite"; // SQLite-specific
|
|
8
|
+
import { stringAgg, arrayAgg, jsonAgg } from "typhex/postgres"; // PostgreSQL-specific
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Aggregate Functions
|
|
12
|
+
|
|
13
|
+
Use aggregate functions inside a `.select()` lambda:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const Order = Entity("orders", {
|
|
17
|
+
id: "integer primary key autoincrement",
|
|
18
|
+
category: "text not null",
|
|
19
|
+
status: "text not null",
|
|
20
|
+
price: "integer not null",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Single aggregate — total count
|
|
24
|
+
const total = await Order.query()
|
|
25
|
+
.select((o) => count(o.id))
|
|
26
|
+
.toArray();
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```sql
|
|
30
|
+
SELECT COUNT(id) AS total FROM orders
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// Multiple aggregates
|
|
35
|
+
const stats = await Order.query()
|
|
36
|
+
.select((o) => ({
|
|
37
|
+
total: count(o.id),
|
|
38
|
+
minPrice: min(o.price),
|
|
39
|
+
maxPrice: max(o.price),
|
|
40
|
+
avgPrice: avg(o.price),
|
|
41
|
+
}))
|
|
42
|
+
.toArray();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```sql
|
|
46
|
+
SELECT COUNT(id) AS total, MIN(price) AS minPrice,
|
|
47
|
+
MAX(price) AS maxPrice, AVG(price) AS avgPrice
|
|
48
|
+
FROM orders
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Function | SQL | Notes |
|
|
52
|
+
| --------------- | -------------- | ----------------------------- |
|
|
53
|
+
| `count(col?)` | `COUNT(col)` | Omit arg for `COUNT(*)` |
|
|
54
|
+
| `sum(col)` | `SUM(col)` | |
|
|
55
|
+
| `avg(col)` | `AVG(col)` | |
|
|
56
|
+
| `min(col)` | `MIN(col)` | |
|
|
57
|
+
| `max(col)` | `MAX(col)` | |
|
|
58
|
+
| `distinct(col)` | `DISTINCT col` | Wrap inside another aggregate |
|
|
59
|
+
|
|
60
|
+
## GROUP BY
|
|
61
|
+
|
|
62
|
+
Pass an arrow function — the preferred form:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// Single column
|
|
66
|
+
const revenueByCategory = await Order.query()
|
|
67
|
+
.select((o) => ({ category: o.category, revenue: sum(o.price) }))
|
|
68
|
+
.groupBy((o) => o.category)
|
|
69
|
+
.toArray();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```sql
|
|
73
|
+
SELECT category AS category, SUM(price) AS revenue
|
|
74
|
+
FROM orders
|
|
75
|
+
GROUP BY category
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// Multiple columns — chain two groupBy calls
|
|
80
|
+
const byCategoryAndStatus = await Order.query()
|
|
81
|
+
.select((o) => ({ category: o.category, status: o.status, cnt: count(o.id) }))
|
|
82
|
+
.groupBy((o) => o.category)
|
|
83
|
+
.groupBy((o) => o.status)
|
|
84
|
+
.toArray();
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```sql
|
|
88
|
+
SELECT category AS category, status AS status, COUNT(id) AS cnt
|
|
89
|
+
FROM orders
|
|
90
|
+
GROUP BY category, status
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`.groupBy()` also accepts a column name string, an array of strings, or positional indices (`1`, `[1, 2]`) when chaining lambdas isn't convenient.
|
|
94
|
+
|
|
95
|
+
## HAVING
|
|
96
|
+
|
|
97
|
+
`.having()` accepts the same arrow-function syntax as `.where()`. Closure variables are auto-captured with the transformer:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// Only categories with more than 1 order
|
|
101
|
+
const busy = await Order.query()
|
|
102
|
+
.select((o) => ({ category: o.category, cnt: count(o.id) }))
|
|
103
|
+
.groupBy((o) => o.category)
|
|
104
|
+
.having((o) => count(o.id) > 1)
|
|
105
|
+
.toArray();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```sql
|
|
109
|
+
SELECT category AS category, COUNT(id) AS cnt
|
|
110
|
+
FROM orders
|
|
111
|
+
GROUP BY category
|
|
112
|
+
HAVING COUNT(id) > ?
|
|
113
|
+
-- params: [1]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
// Closure variable
|
|
118
|
+
const minRevenue = 200;
|
|
119
|
+
const highRevenue = await Order.query()
|
|
120
|
+
.select((o) => ({ category: o.category, revenue: sum(o.price) }))
|
|
121
|
+
.groupBy((o) => o.category)
|
|
122
|
+
.having((o) => sum(o.price) >= minRevenue)
|
|
123
|
+
.toArray();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```sql
|
|
127
|
+
SELECT category AS category, SUM(price) AS revenue
|
|
128
|
+
FROM orders
|
|
129
|
+
GROUP BY category
|
|
130
|
+
HAVING SUM(price) >= ?
|
|
131
|
+
-- params: [200]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
::: info Runtime mode
|
|
135
|
+
In runtime mode, pass closure variables explicitly: `.having((o) => sum(o.price) >= minRevenue, { minRevenue })`.
|
|
136
|
+
:::
|
|
137
|
+
|
|
138
|
+
## Expression Arguments
|
|
139
|
+
|
|
140
|
+
Aggregate arguments can be computed expressions. This is useful for totals derived from multiple columns and conditional counts:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const cutoff = 5;
|
|
144
|
+
const stats = await Order.query()
|
|
145
|
+
.select(
|
|
146
|
+
(o) => ({
|
|
147
|
+
category: o.category,
|
|
148
|
+
revenue: sum(o.price * o.qty),
|
|
149
|
+
smallOrders: sum(o.qty < cutoff ? 1 : 0),
|
|
150
|
+
}),
|
|
151
|
+
{ cutoff },
|
|
152
|
+
)
|
|
153
|
+
.groupBy((o) => o.category)
|
|
154
|
+
.toArray();
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```sql
|
|
158
|
+
SELECT category AS category,
|
|
159
|
+
SUM(price * qty) AS revenue,
|
|
160
|
+
SUM(CASE WHEN qty < ? THEN ? ELSE ? END) AS smallOrders
|
|
161
|
+
FROM orders
|
|
162
|
+
GROUP BY category
|
|
163
|
+
-- params: [5, 1, 0]
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
In runtime mode, pass closure variables used inside `.select()` as the second argument. With the transformer enabled, no second argument is needed.
|
|
167
|
+
|
|
168
|
+
## Combining WHERE + GROUP BY + HAVING
|
|
169
|
+
|
|
170
|
+
All three compose naturally:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const shippedStats = await Order.query()
|
|
174
|
+
.where((o) => o.status === "shipped")
|
|
175
|
+
.select((o) => ({ category: o.category, cnt: count(o.id), total: sum(o.price) }))
|
|
176
|
+
.groupBy((o) => o.category)
|
|
177
|
+
.having((o) => count(o.id) > 0)
|
|
178
|
+
.orderBy((o) => o.category, "asc")
|
|
179
|
+
.toArray();
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```sql
|
|
183
|
+
SELECT category AS category, COUNT(id) AS cnt, SUM(price) AS total
|
|
184
|
+
FROM orders
|
|
185
|
+
WHERE status = ?
|
|
186
|
+
GROUP BY category
|
|
187
|
+
HAVING COUNT(id) > ?
|
|
188
|
+
ORDER BY category ASC
|
|
189
|
+
-- params: ["shipped", 0]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## DISTINCT
|
|
193
|
+
|
|
194
|
+
Wrap a column with `distinct()` inside another aggregate to deduplicate before aggregating:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
// COUNT(DISTINCT category)
|
|
198
|
+
const uniqueCategories = await Order.query()
|
|
199
|
+
.select((o) => ({ uniqueCategories: count(distinct(o.category)) }))
|
|
200
|
+
.toArray();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```sql
|
|
204
|
+
SELECT COUNT(DISTINCT category) AS uniqueCategories FROM orders
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
// SUM(DISTINCT price)
|
|
209
|
+
const distinctRevenue = await Order.query()
|
|
210
|
+
.select((o) => ({ revenue: sum(distinct(o.price)) }))
|
|
211
|
+
.toArray();
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
```sql
|
|
215
|
+
SELECT SUM(DISTINCT price) AS revenue FROM orders
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Database-Specific Aggregates
|
|
219
|
+
|
|
220
|
+
### SQLite: `groupConcat`
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { groupConcat } from "typhex/sqlite";
|
|
224
|
+
|
|
225
|
+
// Per status
|
|
226
|
+
const byStatus = await Order.query()
|
|
227
|
+
.select((o) => ({ status: o.status, categories: groupConcat(o.category, ", ") }))
|
|
228
|
+
.groupBy((o) => o.status)
|
|
229
|
+
.toArray();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```sql
|
|
233
|
+
SELECT status AS status, GROUP_CONCAT(category, ?) AS categories
|
|
234
|
+
FROM orders
|
|
235
|
+
GROUP BY status
|
|
236
|
+
-- params: [", "]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### PostgreSQL: `stringAgg`, `arrayAgg`, `jsonAgg`
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import { stringAgg, arrayAgg, jsonAgg } from "typhex/postgres";
|
|
243
|
+
|
|
244
|
+
// STRING_AGG — concatenate with separator
|
|
245
|
+
const tagList = await Post.query()
|
|
246
|
+
.select((p) => ({ category: p.category, tags: stringAgg(p.tag, ", ") }))
|
|
247
|
+
.groupBy((p) => p.category)
|
|
248
|
+
.toArray();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```sql
|
|
252
|
+
SELECT "category" AS "category", STRING_AGG("tag", $1) AS "tags"
|
|
253
|
+
FROM "posts"
|
|
254
|
+
GROUP BY "category"
|
|
255
|
+
-- params: [", "]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
// ARRAY_AGG — collect values into a PostgreSQL array
|
|
260
|
+
const ids = await Post.query()
|
|
261
|
+
.select((p) => ({ category: p.category, ids: arrayAgg(p.id) }))
|
|
262
|
+
.groupBy((p) => p.category)
|
|
263
|
+
.toArray();
|
|
264
|
+
// SQL: ARRAY_AGG("id") AS "ids"
|
|
265
|
+
|
|
266
|
+
// JSON_AGG — collect values into a JSON array
|
|
267
|
+
const titles = await Post.query()
|
|
268
|
+
.select((p) => ({ category: p.category, titles: jsonAgg(p.title) }))
|
|
269
|
+
.groupBy((p) => p.category)
|
|
270
|
+
.toArray();
|
|
271
|
+
// SQL: JSON_AGG("title") AS "titles"
|
|
272
|
+
```
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Bulk Operations
|
|
2
|
+
|
|
3
|
+
## insertMany
|
|
4
|
+
|
|
5
|
+
Insert multiple rows in a single SQL statement:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
await Product.query().insertMany([
|
|
9
|
+
{ sku: "W-001", name: "Widget", price: 999, stock: 100 },
|
|
10
|
+
{ sku: "G-001", name: "Gadget", price: 1499, stock: 50 },
|
|
11
|
+
{ sku: "D-001", name: "Doohickey", price: 249, stock: 200 },
|
|
12
|
+
]);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```sql
|
|
16
|
+
INSERT INTO products (sku, name, price, stock)
|
|
17
|
+
VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?)
|
|
18
|
+
-- params: ["W-001", "Widget", 999, 100, "G-001", "Gadget", 1499, 50, "D-001", "Doohickey", 249, 200]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`insertMany` returns the inserted rows on PostgreSQL (where `RETURNING` is available). On SQLite, it returns an empty array — use a follow-up query if you need the inserted rows.
|
|
22
|
+
|
|
23
|
+
## onConflict
|
|
24
|
+
|
|
25
|
+
Both `insert()` and `insertMany()` support conflict resolution via `.onConflict(columns)`:
|
|
26
|
+
|
|
27
|
+
### doNothing
|
|
28
|
+
|
|
29
|
+
Skip rows that violate a unique constraint:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
await Product.query()
|
|
33
|
+
.insertMany([
|
|
34
|
+
{ sku: "W-001", name: "Updated", price: 888, stock: 999 }, // skipped (sku exists)
|
|
35
|
+
{ sku: "T-001", name: "Thingamajig", price: 599, stock: 75 }, // inserted
|
|
36
|
+
])
|
|
37
|
+
.onConflict(["sku"])
|
|
38
|
+
.doNothing();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```sql
|
|
42
|
+
INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?), (?, ?, ?, ?)
|
|
43
|
+
ON CONFLICT (sku) DO NOTHING
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### doUpdate (upsert)
|
|
47
|
+
|
|
48
|
+
Update all non-conflict columns when a clash is detected:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
await Product.query()
|
|
52
|
+
.insert({ sku: "W-001", name: "Widget v2", price: 1099, stock: 80 })
|
|
53
|
+
.onConflict(["sku"])
|
|
54
|
+
.doUpdate();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```sql
|
|
58
|
+
INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?)
|
|
59
|
+
ON CONFLICT (sku) DO UPDATE SET
|
|
60
|
+
name = excluded.name,
|
|
61
|
+
price = excluded.price,
|
|
62
|
+
stock = excluded.stock
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### doUpdate with specific columns
|
|
66
|
+
|
|
67
|
+
Update only specified columns, leaving the rest unchanged:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await Product.query()
|
|
71
|
+
.insert({ sku: "G-001", name: "Renamed (ignored)", price: 1799, stock: 0 })
|
|
72
|
+
.onConflict(["sku"])
|
|
73
|
+
.doUpdate(["price"]); // only price is updated; name stays as-is
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?)
|
|
78
|
+
ON CONFLICT (sku) DO UPDATE SET price = excluded.price
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Bulk upsert
|
|
82
|
+
|
|
83
|
+
Combine `insertMany` with `onConflict` for price-list style updates:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
await Product.query()
|
|
87
|
+
.insertMany([
|
|
88
|
+
{ sku: "W-001", name: "irrelevant", price: 500, stock: 0 },
|
|
89
|
+
{ sku: "Z-001", name: "Zapper", price: 3999, stock: 10 },
|
|
90
|
+
])
|
|
91
|
+
.onConflict(["sku"])
|
|
92
|
+
.doUpdate(["price"]);
|
|
93
|
+
// W-001's price is updated to 500; Z-001 is inserted as new
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```sql
|
|
97
|
+
INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?), (?, ?, ?, ?)
|
|
98
|
+
ON CONFLICT (sku) DO UPDATE SET price = excluded.price
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## insertGraph
|
|
102
|
+
|
|
103
|
+
`insertGraph` inserts an entire object graph — related entities and junction rows — in the correct dependency order. You pass a plain object shaped like your entity with its relations nested inside:
|
|
104
|
+
|
|
105
|
+
### manyToOne parent
|
|
106
|
+
|
|
107
|
+
Provide the parent as a nested object — Typhex inserts it first and wires the foreign key automatically:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const post = await Post.query().insertGraph({
|
|
111
|
+
title: "Hello",
|
|
112
|
+
author: { name: "Alice" },
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```sql
|
|
117
|
+
-- 1. Parent first
|
|
118
|
+
INSERT INTO users (name) VALUES (?) -- params: ["Alice"]
|
|
119
|
+
|
|
120
|
+
-- 2. Root with foreign key wired in
|
|
121
|
+
INSERT INTO posts (title, authorId) VALUES (?, ?) -- params: ["Hello", 1]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### oneToMany children
|
|
125
|
+
|
|
126
|
+
Provide children as an array — Typhex inserts the root first and back-fills the foreign key on each child:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const user = await User.query().insertGraph({
|
|
130
|
+
name: "Alice",
|
|
131
|
+
posts: [{ title: "First post" }, { title: "Second post" }],
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```sql
|
|
136
|
+
-- 1. Root first
|
|
137
|
+
INSERT INTO users (name) VALUES (?) -- params: ["Alice"]
|
|
138
|
+
|
|
139
|
+
-- 2. Children batched, with authorId auto-filled
|
|
140
|
+
INSERT INTO posts (title, authorId) VALUES (?, ?), (?, ?)
|
|
141
|
+
-- params: ["First post", 1, "Second post", 1]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### manyToMany
|
|
145
|
+
|
|
146
|
+
Mix new records with references to existing ones using `{ id: existingId }`:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
const existingTag = await Tag.query().findById(1);
|
|
150
|
+
|
|
151
|
+
const post = await Post.query().insertGraph({
|
|
152
|
+
title: "Hello",
|
|
153
|
+
author: { name: "Alice" },
|
|
154
|
+
tags: [
|
|
155
|
+
{ id: existingTag.id }, // link existing tag
|
|
156
|
+
{ name: "new-tag" }, // insert new tag
|
|
157
|
+
],
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```sql
|
|
162
|
+
INSERT INTO users (name) VALUES (?) -- author
|
|
163
|
+
INSERT INTO posts (title, authorId) VALUES (?, ?) -- root post
|
|
164
|
+
INSERT INTO tags (name) VALUES (?) -- only the new tag is inserted
|
|
165
|
+
|
|
166
|
+
-- Junction rows for both existing + new tag
|
|
167
|
+
INSERT INTO post_tags (postId, tagId) VALUES (?, ?), (?, ?)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Batch insert
|
|
171
|
+
|
|
172
|
+
Pass an array to insert multiple graphs at once:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const users = await User.query().insertGraph([
|
|
176
|
+
{ name: "Alice", posts: [{ title: "A-1" }, { title: "A-2" }] },
|
|
177
|
+
{ name: "Bob", posts: [{ title: "B-1" }] },
|
|
178
|
+
]);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```sql
|
|
182
|
+
-- Roots batched
|
|
183
|
+
INSERT INTO users (name) VALUES (?), (?) -- ["Alice", "Bob"]
|
|
184
|
+
|
|
185
|
+
-- All children batched, foreign keys back-filled
|
|
186
|
+
INSERT INTO posts (title, authorId) VALUES (?, ?), (?, ?), (?, ?)
|
|
187
|
+
-- ["A-1", 1, "A-2", 1, "B-1", 2]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### With a transaction
|
|
191
|
+
|
|
192
|
+
`insertGraph` participates in an existing transaction:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
await db.transaction(async (trx) => {
|
|
196
|
+
await Post.query(trx).insertGraph({
|
|
197
|
+
title: "Atomic post",
|
|
198
|
+
author: { name: "Dave" },
|
|
199
|
+
tags: [{ name: "typescript" }],
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
If any insert in the graph fails, the transaction rolls back the entire graph.
|