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.
Files changed (421) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +21 -0
  3. package/README.md +417 -0
  4. package/SECURITY.md +32 -0
  5. package/dist/arrow/aggregates.d.ts +12 -0
  6. package/dist/arrow/aggregates.d.ts.map +1 -0
  7. package/dist/arrow/aggregates.js +32 -0
  8. package/dist/arrow/aggregates.js.map +1 -0
  9. package/dist/arrow/constants.d.ts +15 -0
  10. package/dist/arrow/constants.d.ts.map +1 -0
  11. package/dist/arrow/constants.js +42 -0
  12. package/dist/arrow/constants.js.map +1 -0
  13. package/dist/arrow/index.d.ts +7 -0
  14. package/dist/arrow/index.d.ts.map +1 -0
  15. package/dist/arrow/index.js +7 -0
  16. package/dist/arrow/index.js.map +1 -0
  17. package/dist/config/index.d.ts +6 -0
  18. package/dist/config/index.d.ts.map +1 -0
  19. package/dist/config/index.js +4 -0
  20. package/dist/config/index.js.map +1 -0
  21. package/dist/config/load-config.d.ts +19 -0
  22. package/dist/config/load-config.d.ts.map +1 -0
  23. package/dist/config/load-config.js +84 -0
  24. package/dist/config/load-config.js.map +1 -0
  25. package/dist/config/load-env.d.ts +7 -0
  26. package/dist/config/load-env.d.ts.map +1 -0
  27. package/dist/config/load-env.js +62 -0
  28. package/dist/config/load-env.js.map +1 -0
  29. package/dist/config/types.d.ts +20 -0
  30. package/dist/config/types.d.ts.map +1 -0
  31. package/dist/config/types.js +10 -0
  32. package/dist/config/types.js.map +1 -0
  33. package/dist/dbs/base-migrator.d.ts +20 -0
  34. package/dist/dbs/base-migrator.d.ts.map +1 -0
  35. package/dist/dbs/base-migrator.js +112 -0
  36. package/dist/dbs/base-migrator.js.map +1 -0
  37. package/dist/dbs/index.d.ts +9 -0
  38. package/dist/dbs/index.d.ts.map +1 -0
  39. package/dist/dbs/index.js +17 -0
  40. package/dist/dbs/index.js.map +1 -0
  41. package/dist/dbs/postgres/dialect.d.ts +8 -0
  42. package/dist/dbs/postgres/dialect.d.ts.map +1 -0
  43. package/dist/dbs/postgres/dialect.js +17 -0
  44. package/dist/dbs/postgres/dialect.js.map +1 -0
  45. package/dist/dbs/postgres/driver.d.ts +42 -0
  46. package/dist/dbs/postgres/driver.d.ts.map +1 -0
  47. package/dist/dbs/postgres/driver.js +111 -0
  48. package/dist/dbs/postgres/driver.js.map +1 -0
  49. package/dist/dbs/postgres/index.d.ts +6 -0
  50. package/dist/dbs/postgres/index.d.ts.map +1 -0
  51. package/dist/dbs/postgres/index.js +5 -0
  52. package/dist/dbs/postgres/index.js.map +1 -0
  53. package/dist/dbs/postgres/migrator.d.ts +13 -0
  54. package/dist/dbs/postgres/migrator.d.ts.map +1 -0
  55. package/dist/dbs/postgres/migrator.js +22 -0
  56. package/dist/dbs/postgres/migrator.js.map +1 -0
  57. package/dist/dbs/postgres/query-compiler.d.ts +22 -0
  58. package/dist/dbs/postgres/query-compiler.d.ts.map +1 -0
  59. package/dist/dbs/postgres/query-compiler.js +140 -0
  60. package/dist/dbs/postgres/query-compiler.js.map +1 -0
  61. package/dist/dbs/postgres/trx.d.ts +16 -0
  62. package/dist/dbs/postgres/trx.d.ts.map +1 -0
  63. package/dist/dbs/postgres/trx.js +68 -0
  64. package/dist/dbs/postgres/trx.js.map +1 -0
  65. package/dist/dbs/query-compiler.d.ts +135 -0
  66. package/dist/dbs/query-compiler.d.ts.map +1 -0
  67. package/dist/dbs/query-compiler.js +775 -0
  68. package/dist/dbs/query-compiler.js.map +1 -0
  69. package/dist/dbs/sqlite/dialect.d.ts +8 -0
  70. package/dist/dbs/sqlite/dialect.d.ts.map +1 -0
  71. package/dist/dbs/sqlite/dialect.js +17 -0
  72. package/dist/dbs/sqlite/dialect.js.map +1 -0
  73. package/dist/dbs/sqlite/driver.d.ts +9 -0
  74. package/dist/dbs/sqlite/driver.d.ts.map +1 -0
  75. package/dist/dbs/sqlite/driver.js +66 -0
  76. package/dist/dbs/sqlite/driver.js.map +1 -0
  77. package/dist/dbs/sqlite/index.d.ts +6 -0
  78. package/dist/dbs/sqlite/index.d.ts.map +1 -0
  79. package/dist/dbs/sqlite/index.js +5 -0
  80. package/dist/dbs/sqlite/index.js.map +1 -0
  81. package/dist/dbs/sqlite/migrator.d.ts +13 -0
  82. package/dist/dbs/sqlite/migrator.d.ts.map +1 -0
  83. package/dist/dbs/sqlite/migrator.js +22 -0
  84. package/dist/dbs/sqlite/migrator.js.map +1 -0
  85. package/dist/dbs/sqlite/query-compiler.d.ts +26 -0
  86. package/dist/dbs/sqlite/query-compiler.d.ts.map +1 -0
  87. package/dist/dbs/sqlite/query-compiler.js +80 -0
  88. package/dist/dbs/sqlite/query-compiler.js.map +1 -0
  89. package/dist/dbs/sqlite/trx.d.ts +13 -0
  90. package/dist/dbs/sqlite/trx.d.ts.map +1 -0
  91. package/dist/dbs/sqlite/trx.js +69 -0
  92. package/dist/dbs/sqlite/trx.js.map +1 -0
  93. package/dist/dbs/types.d.ts +92 -0
  94. package/dist/dbs/types.d.ts.map +1 -0
  95. package/dist/dbs/types.js +26 -0
  96. package/dist/dbs/types.js.map +1 -0
  97. package/dist/dialect.d.ts +3 -0
  98. package/dist/dialect.d.ts.map +1 -0
  99. package/dist/dialect.js +2 -0
  100. package/dist/dialect.js.map +1 -0
  101. package/dist/driver/factory.d.ts +19 -0
  102. package/dist/driver/factory.d.ts.map +1 -0
  103. package/dist/driver/factory.js +24 -0
  104. package/dist/driver/factory.js.map +1 -0
  105. package/dist/driver/index.d.ts +6 -0
  106. package/dist/driver/index.d.ts.map +1 -0
  107. package/dist/driver/index.js +3 -0
  108. package/dist/driver/index.js.map +1 -0
  109. package/dist/driver/sqlite.d.ts +15 -0
  110. package/dist/driver/sqlite.d.ts.map +1 -0
  111. package/dist/driver/sqlite.js +74 -0
  112. package/dist/driver/sqlite.js.map +1 -0
  113. package/dist/driver/types.d.ts +75 -0
  114. package/dist/driver/types.d.ts.map +1 -0
  115. package/dist/driver/types.js +2 -0
  116. package/dist/driver/types.js.map +1 -0
  117. package/dist/entity/entity.d.ts +67 -0
  118. package/dist/entity/entity.d.ts.map +1 -0
  119. package/dist/entity/entity.js +139 -0
  120. package/dist/entity/entity.js.map +1 -0
  121. package/dist/entity/global-driver.d.ts +38 -0
  122. package/dist/entity/global-driver.d.ts.map +1 -0
  123. package/dist/entity/global-driver.js +109 -0
  124. package/dist/entity/global-driver.js.map +1 -0
  125. package/dist/entity/index.d.ts +8 -0
  126. package/dist/entity/index.d.ts.map +1 -0
  127. package/dist/entity/index.js +3 -0
  128. package/dist/entity/index.js.map +1 -0
  129. package/dist/entity/pk-columns.d.ts +5 -0
  130. package/dist/entity/pk-columns.d.ts.map +1 -0
  131. package/dist/entity/pk-columns.js +14 -0
  132. package/dist/entity/pk-columns.js.map +1 -0
  133. package/dist/entity/relations.d.ts +134 -0
  134. package/dist/entity/relations.d.ts.map +1 -0
  135. package/dist/entity/relations.js +23 -0
  136. package/dist/entity/relations.js.map +1 -0
  137. package/dist/entity/schema-inference.d.ts +77 -0
  138. package/dist/entity/schema-inference.d.ts.map +1 -0
  139. package/dist/entity/schema-inference.js +6 -0
  140. package/dist/entity/schema-inference.js.map +1 -0
  141. package/dist/entity/types.d.ts +30 -0
  142. package/dist/entity/types.d.ts.map +1 -0
  143. package/dist/entity/types.js +5 -0
  144. package/dist/entity/types.js.map +1 -0
  145. package/dist/index.d.ts +25 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +12 -0
  148. package/dist/index.js.map +1 -0
  149. package/dist/ir/index.d.ts +2 -0
  150. package/dist/ir/index.d.ts.map +1 -0
  151. package/dist/ir/index.js +2 -0
  152. package/dist/ir/index.js.map +1 -0
  153. package/dist/ir/types.d.ts +148 -0
  154. package/dist/ir/types.d.ts.map +1 -0
  155. package/dist/ir/types.js +97 -0
  156. package/dist/ir/types.js.map +1 -0
  157. package/dist/migration/cli.d.ts +18 -0
  158. package/dist/migration/cli.d.ts.map +1 -0
  159. package/dist/migration/cli.js +236 -0
  160. package/dist/migration/cli.js.map +1 -0
  161. package/dist/migration/diff.d.ts +10 -0
  162. package/dist/migration/diff.d.ts.map +1 -0
  163. package/dist/migration/diff.js +10 -0
  164. package/dist/migration/diff.js.map +1 -0
  165. package/dist/migration/generator.d.ts +12 -0
  166. package/dist/migration/generator.d.ts.map +1 -0
  167. package/dist/migration/generator.js +98 -0
  168. package/dist/migration/generator.js.map +1 -0
  169. package/dist/migration/index.d.ts +7 -0
  170. package/dist/migration/index.d.ts.map +1 -0
  171. package/dist/migration/index.js +5 -0
  172. package/dist/migration/index.js.map +1 -0
  173. package/dist/migration/runner.d.ts +32 -0
  174. package/dist/migration/runner.d.ts.map +1 -0
  175. package/dist/migration/runner.js +279 -0
  176. package/dist/migration/runner.js.map +1 -0
  177. package/dist/migration/topo-sort.d.ts +12 -0
  178. package/dist/migration/topo-sort.d.ts.map +1 -0
  179. package/dist/migration/topo-sort.js +42 -0
  180. package/dist/migration/topo-sort.js.map +1 -0
  181. package/dist/migration/types.d.ts +45 -0
  182. package/dist/migration/types.d.ts.map +1 -0
  183. package/dist/migration/types.js +2 -0
  184. package/dist/migration/types.js.map +1 -0
  185. package/dist/orm/aggregates.d.ts +19 -0
  186. package/dist/orm/aggregates.d.ts.map +1 -0
  187. package/dist/orm/aggregates.js +32 -0
  188. package/dist/orm/aggregates.js.map +1 -0
  189. package/dist/orm/db.d.ts +105 -0
  190. package/dist/orm/db.d.ts.map +1 -0
  191. package/dist/orm/db.js +172 -0
  192. package/dist/orm/db.js.map +1 -0
  193. package/dist/orm/expr.d.ts +125 -0
  194. package/dist/orm/expr.d.ts.map +1 -0
  195. package/dist/orm/expr.js +10 -0
  196. package/dist/orm/expr.js.map +1 -0
  197. package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.d.ts +9 -0
  198. package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.d.ts.map +1 -0
  199. package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.js +44 -0
  200. package/dist/orm/helpers/insert-graph/insert-graph-batch-executor.js.map +1 -0
  201. package/dist/orm/helpers/insert-graph/insert-graph-executor.d.ts +13 -0
  202. package/dist/orm/helpers/insert-graph/insert-graph-executor.d.ts.map +1 -0
  203. package/dist/orm/helpers/insert-graph/insert-graph-executor.js +42 -0
  204. package/dist/orm/helpers/insert-graph/insert-graph-executor.js.map +1 -0
  205. package/dist/orm/helpers/insert-graph/insert-graph-planner.d.ts +46 -0
  206. package/dist/orm/helpers/insert-graph/insert-graph-planner.d.ts.map +1 -0
  207. package/dist/orm/helpers/insert-graph/insert-graph-planner.js +258 -0
  208. package/dist/orm/helpers/insert-graph/insert-graph-planner.js.map +1 -0
  209. package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.d.ts +7 -0
  210. package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.d.ts.map +1 -0
  211. package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.js +8 -0
  212. package/dist/orm/helpers/insert-graph/insert-graph-sequential-executor.js.map +1 -0
  213. package/dist/orm/helpers/insert-graph/sequence-id-assigner.d.ts +15 -0
  214. package/dist/orm/helpers/insert-graph/sequence-id-assigner.d.ts.map +1 -0
  215. package/dist/orm/helpers/insert-graph/sequence-id-assigner.js +48 -0
  216. package/dist/orm/helpers/insert-graph/sequence-id-assigner.js.map +1 -0
  217. package/dist/orm/helpers/query-plan/expr-builder.d.ts +155 -0
  218. package/dist/orm/helpers/query-plan/expr-builder.d.ts.map +1 -0
  219. package/dist/orm/helpers/query-plan/expr-builder.js +297 -0
  220. package/dist/orm/helpers/query-plan/expr-builder.js.map +1 -0
  221. package/dist/orm/helpers/query-plan/query-ir-analyzer.d.ts +48 -0
  222. package/dist/orm/helpers/query-plan/query-ir-analyzer.d.ts.map +1 -0
  223. package/dist/orm/helpers/query-plan/query-ir-analyzer.js +262 -0
  224. package/dist/orm/helpers/query-plan/query-ir-analyzer.js.map +1 -0
  225. package/dist/orm/helpers/query-plan/query-plan.d.ts +164 -0
  226. package/dist/orm/helpers/query-plan/query-plan.d.ts.map +1 -0
  227. package/dist/orm/helpers/query-plan/query-plan.js +549 -0
  228. package/dist/orm/helpers/query-plan/query-plan.js.map +1 -0
  229. package/dist/orm/helpers/query-plan/select-classifier.d.ts +161 -0
  230. package/dist/orm/helpers/query-plan/select-classifier.d.ts.map +1 -0
  231. package/dist/orm/helpers/query-plan/select-classifier.js +359 -0
  232. package/dist/orm/helpers/query-plan/select-classifier.js.map +1 -0
  233. package/dist/orm/helpers/relations/relation-assembler.d.ts +21 -0
  234. package/dist/orm/helpers/relations/relation-assembler.d.ts.map +1 -0
  235. package/dist/orm/helpers/relations/relation-assembler.js +60 -0
  236. package/dist/orm/helpers/relations/relation-assembler.js.map +1 -0
  237. package/dist/orm/helpers/relations/relation-fetcher.d.ts +30 -0
  238. package/dist/orm/helpers/relations/relation-fetcher.d.ts.map +1 -0
  239. package/dist/orm/helpers/relations/relation-fetcher.js +128 -0
  240. package/dist/orm/helpers/relations/relation-fetcher.js.map +1 -0
  241. package/dist/orm/helpers/relations/relation-joins.d.ts +74 -0
  242. package/dist/orm/helpers/relations/relation-joins.d.ts.map +1 -0
  243. package/dist/orm/helpers/relations/relation-joins.js +138 -0
  244. package/dist/orm/helpers/relations/relation-joins.js.map +1 -0
  245. package/dist/orm/helpers/relations/relation-resolver.d.ts +14 -0
  246. package/dist/orm/helpers/relations/relation-resolver.d.ts.map +1 -0
  247. package/dist/orm/helpers/relations/relation-resolver.js +25 -0
  248. package/dist/orm/helpers/relations/relation-resolver.js.map +1 -0
  249. package/dist/orm/index.d.ts +7 -0
  250. package/dist/orm/index.d.ts.map +1 -0
  251. package/dist/orm/index.js +5 -0
  252. package/dist/orm/index.js.map +1 -0
  253. package/dist/orm/query-builder.d.ts +136 -0
  254. package/dist/orm/query-builder.d.ts.map +1 -0
  255. package/dist/orm/query-builder.js +433 -0
  256. package/dist/orm/query-builder.js.map +1 -0
  257. package/dist/orm/query-helpers.d.ts +35 -0
  258. package/dist/orm/query-helpers.d.ts.map +1 -0
  259. package/dist/orm/query-helpers.js +83 -0
  260. package/dist/orm/query-helpers.js.map +1 -0
  261. package/dist/orm/query-state.d.ts +56 -0
  262. package/dist/orm/query-state.d.ts.map +1 -0
  263. package/dist/orm/query-state.js +112 -0
  264. package/dist/orm/query-state.js.map +1 -0
  265. package/dist/orm/single-row-query-builder.d.ts +18 -0
  266. package/dist/orm/single-row-query-builder.d.ts.map +1 -0
  267. package/dist/orm/single-row-query-builder.js +90 -0
  268. package/dist/orm/single-row-query-builder.js.map +1 -0
  269. package/dist/orm/trx.d.ts +40 -0
  270. package/dist/orm/trx.d.ts.map +1 -0
  271. package/dist/orm/trx.js +118 -0
  272. package/dist/orm/trx.js.map +1 -0
  273. package/dist/parser/acorn-helpers.d.ts +43 -0
  274. package/dist/parser/acorn-helpers.d.ts.map +1 -0
  275. package/dist/parser/acorn-helpers.js +104 -0
  276. package/dist/parser/acorn-helpers.js.map +1 -0
  277. package/dist/parser/acorn-member.d.ts +16 -0
  278. package/dist/parser/acorn-member.d.ts.map +1 -0
  279. package/dist/parser/acorn-member.js +31 -0
  280. package/dist/parser/acorn-member.js.map +1 -0
  281. package/dist/parser/acorn-types.d.ts +14 -0
  282. package/dist/parser/acorn-types.d.ts.map +1 -0
  283. package/dist/parser/acorn-types.js +6 -0
  284. package/dist/parser/acorn-types.js.map +1 -0
  285. package/dist/parser/arrow-source.d.ts +23 -0
  286. package/dist/parser/arrow-source.d.ts.map +1 -0
  287. package/dist/parser/arrow-source.js +70 -0
  288. package/dist/parser/arrow-source.js.map +1 -0
  289. package/dist/parser/group-by.d.ts +17 -0
  290. package/dist/parser/group-by.d.ts.map +1 -0
  291. package/dist/parser/group-by.js +62 -0
  292. package/dist/parser/group-by.js.map +1 -0
  293. package/dist/parser/index.d.ts +5 -0
  294. package/dist/parser/index.d.ts.map +1 -0
  295. package/dist/parser/index.js +3 -0
  296. package/dist/parser/index.js.map +1 -0
  297. package/dist/parser/parse-arrow.d.ts +10 -0
  298. package/dist/parser/parse-arrow.d.ts.map +1 -0
  299. package/dist/parser/parse-arrow.js +9 -0
  300. package/dist/parser/parse-arrow.js.map +1 -0
  301. package/dist/parser/predicate-walk.d.ts +24 -0
  302. package/dist/parser/predicate-walk.d.ts.map +1 -0
  303. package/dist/parser/predicate-walk.js +247 -0
  304. package/dist/parser/predicate-walk.js.map +1 -0
  305. package/dist/parser/resolve.d.ts +25 -0
  306. package/dist/parser/resolve.d.ts.map +1 -0
  307. package/dist/parser/resolve.js +134 -0
  308. package/dist/parser/resolve.js.map +1 -0
  309. package/dist/parser/select.d.ts +7 -0
  310. package/dist/parser/select.d.ts.map +1 -0
  311. package/dist/parser/select.js +333 -0
  312. package/dist/parser/select.js.map +1 -0
  313. package/dist/parser/update.d.ts +7 -0
  314. package/dist/parser/update.d.ts.map +1 -0
  315. package/dist/parser/update.js +51 -0
  316. package/dist/parser/update.js.map +1 -0
  317. package/dist/postgres/aggregates.d.ts +12 -0
  318. package/dist/postgres/aggregates.d.ts.map +1 -0
  319. package/dist/postgres/aggregates.js +19 -0
  320. package/dist/postgres/aggregates.js.map +1 -0
  321. package/dist/postgres.d.ts +6 -0
  322. package/dist/postgres.d.ts.map +1 -0
  323. package/dist/postgres.js +6 -0
  324. package/dist/postgres.js.map +1 -0
  325. package/dist/schema/index.d.ts +2 -0
  326. package/dist/schema/index.d.ts.map +1 -0
  327. package/dist/schema/index.js +2 -0
  328. package/dist/schema/index.js.map +1 -0
  329. package/dist/schema/types.d.ts +16 -0
  330. package/dist/schema/types.d.ts.map +1 -0
  331. package/dist/schema/types.js +40 -0
  332. package/dist/schema/types.js.map +1 -0
  333. package/dist/sqlite/aggregates.d.ts +8 -0
  334. package/dist/sqlite/aggregates.d.ts.map +1 -0
  335. package/dist/sqlite/aggregates.js +11 -0
  336. package/dist/sqlite/aggregates.js.map +1 -0
  337. package/dist/sqlite.d.ts +6 -0
  338. package/dist/sqlite.d.ts.map +1 -0
  339. package/dist/sqlite.js +6 -0
  340. package/dist/sqlite.js.map +1 -0
  341. package/dist/transformer/bindings.d.ts +18 -0
  342. package/dist/transformer/bindings.d.ts.map +1 -0
  343. package/dist/transformer/bindings.js +52 -0
  344. package/dist/transformer/bindings.js.map +1 -0
  345. package/dist/transformer/index.d.ts +17 -0
  346. package/dist/transformer/index.d.ts.map +1 -0
  347. package/dist/transformer/index.js +75 -0
  348. package/dist/transformer/index.js.map +1 -0
  349. package/dist/transformer/ir-emit.d.ts +12 -0
  350. package/dist/transformer/ir-emit.d.ts.map +1 -0
  351. package/dist/transformer/ir-emit.js +144 -0
  352. package/dist/transformer/ir-emit.js.map +1 -0
  353. package/dist/transformer/join-transformer.d.ts +12 -0
  354. package/dist/transformer/join-transformer.d.ts.map +1 -0
  355. package/dist/transformer/join-transformer.js +102 -0
  356. package/dist/transformer/join-transformer.js.map +1 -0
  357. package/dist/transformer/orderby-transformer.d.ts +13 -0
  358. package/dist/transformer/orderby-transformer.d.ts.map +1 -0
  359. package/dist/transformer/orderby-transformer.js +84 -0
  360. package/dist/transformer/orderby-transformer.js.map +1 -0
  361. package/dist/transformer/select-transformer.d.ts +9 -0
  362. package/dist/transformer/select-transformer.d.ts.map +1 -0
  363. package/dist/transformer/select-transformer.js +222 -0
  364. package/dist/transformer/select-transformer.js.map +1 -0
  365. package/dist/transformer/shared.d.ts +12 -0
  366. package/dist/transformer/shared.d.ts.map +1 -0
  367. package/dist/transformer/shared.js +12 -0
  368. package/dist/transformer/shared.js.map +1 -0
  369. package/dist/transformer/subquery-transformer.d.ts +15 -0
  370. package/dist/transformer/subquery-transformer.d.ts.map +1 -0
  371. package/dist/transformer/subquery-transformer.js +43 -0
  372. package/dist/transformer/subquery-transformer.js.map +1 -0
  373. package/dist/transformer/ts-aggregates.d.ts +13 -0
  374. package/dist/transformer/ts-aggregates.d.ts.map +1 -0
  375. package/dist/transformer/ts-aggregates.js +83 -0
  376. package/dist/transformer/ts-aggregates.js.map +1 -0
  377. package/dist/transformer/ts-binary.d.ts +8 -0
  378. package/dist/transformer/ts-binary.d.ts.map +1 -0
  379. package/dist/transformer/ts-binary.js +32 -0
  380. package/dist/transformer/ts-binary.js.map +1 -0
  381. package/dist/transformer/ts-member.d.ts +12 -0
  382. package/dist/transformer/ts-member.d.ts.map +1 -0
  383. package/dist/transformer/ts-member.js +22 -0
  384. package/dist/transformer/ts-member.js.map +1 -0
  385. package/dist/transformer/ts-utils.d.ts +10 -0
  386. package/dist/transformer/ts-utils.d.ts.map +1 -0
  387. package/dist/transformer/ts-utils.js +38 -0
  388. package/dist/transformer/ts-utils.js.map +1 -0
  389. package/dist/transformer/typhex-type.d.ts +8 -0
  390. package/dist/transformer/typhex-type.d.ts.map +1 -0
  391. package/dist/transformer/typhex-type.js +52 -0
  392. package/dist/transformer/typhex-type.js.map +1 -0
  393. package/dist/transformer/where-transformer.d.ts +33 -0
  394. package/dist/transformer/where-transformer.d.ts.map +1 -0
  395. package/dist/transformer/where-transformer.js +400 -0
  396. package/dist/transformer/where-transformer.js.map +1 -0
  397. package/dist/utils.d.ts +5 -0
  398. package/dist/utils.d.ts.map +1 -0
  399. package/dist/utils.js +30 -0
  400. package/dist/utils.js.map +1 -0
  401. package/docs/drivers/postgres.md +54 -0
  402. package/docs/drivers/sqlite.md +33 -0
  403. package/docs/guide/aggregations.md +272 -0
  404. package/docs/guide/bulk-operations.md +204 -0
  405. package/docs/guide/cte-and-unions.md +270 -0
  406. package/docs/guide/entities-relations.md +208 -0
  407. package/docs/guide/expressions.md +98 -0
  408. package/docs/guide/filtering-by-relations.md +166 -0
  409. package/docs/guide/getting-started.md +277 -0
  410. package/docs/guide/querying-relations.md +133 -0
  411. package/docs/guide/subqueries.md +152 -0
  412. package/docs/guide/transactions.md +146 -0
  413. package/docs/guide/typescript-transformer.md +138 -0
  414. package/docs/index.md +33 -0
  415. package/docs/migrations/overview.md +143 -0
  416. package/docs/public-api.md +133 -0
  417. package/docs/reference/api.md +665 -0
  418. package/docs/reference/architecture.md +83 -0
  419. package/docs/release-checklist.md +55 -0
  420. package/etc/typhex.api.md +774 -0
  421. package/package.json +137 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Select-list classification.
3
+ *
4
+ * A user-written `.select(...)` body can mix three kinds of references:
5
+ * plain columns (`u.name`), relation roots (`u.author`), and members of
6
+ * relations (`u.author.name`). How each is rendered depends on whether
7
+ * its relation is *joined* into the main SELECT (and therefore its
8
+ * columns can ride along) or *not joined* (and so the data has to be
9
+ * fetched separately by the relation pipeline).
10
+ *
11
+ * `SelectClassifier.classify()` walks the IR select once and produces a
12
+ * `ClassifiedSelect` that tells the rest of the planner how to handle
13
+ * each entry:
14
+ *
15
+ * - **`columnPaths` / `columnAliases`** — column references that should
16
+ * appear in the SQL SELECT list, as `<alias>.<col>` references. These
17
+ * include leaf columns, joined-relation members, and any join-key
18
+ * columns that need to be added so the row hydrator can pair fetched
19
+ * relation rows with their parents.
20
+ * - **`relationFetches`** — relations that need a separate eager-load
21
+ * query (one-to-many, many-to-many, or non-joined many-to-one). The
22
+ * relation-fetcher reads this list to produce the WHERE-IN secondary
23
+ * queries.
24
+ * - **`joinedProjections`** — relations whose data came in via the JOIN
25
+ * and needs to be re-shaped from flat result columns back into nested
26
+ * objects. Drives `RelationAssembler.assembleJoined`.
27
+ * - **`skipLoadFor`** — relation keys whose data is already in the
28
+ * SELECT-list via the JOIN; the eager-loader skips re-fetching these.
29
+ *
30
+ * The classifier is constructed once with the inputs that all five
31
+ * helper methods share, so the methods can be small and read directly
32
+ * from `this.*` rather than threading a context object.
33
+ */
34
+ import type { IrSelect } from "../../../ir/types.js";
35
+ import type { RelationsMap } from "../../../entity/relations.js";
36
+ import type { RelationFetchMetadata, JoinedProjection } from "./query-plan.js";
37
+ /**
38
+ * Result of classifying an IrSelect.
39
+ *
40
+ * `columnPaths` / `columnAliases` carry `null` when the original IR's
41
+ * paths/aliases should be used verbatim — that's the no-relations
42
+ * fast-path. Otherwise both are non-null and parallel: `columnPaths[i]`
43
+ * is the path, `columnAliases[i]` is its SELECT-list alias.
44
+ */
45
+ export interface ClassifiedSelect {
46
+ columnPaths: string[][] | null;
47
+ columnAliases: string[] | null;
48
+ relationFetches: RelationFetchMetadata[];
49
+ joinedProjections: JoinedProjection[];
50
+ skipLoadFor: Set<string>;
51
+ reusableJoinKeys: Set<string>;
52
+ }
53
+ /**
54
+ * Sentinel used by the planner when classification isn't needed (e.g.
55
+ * mutations like UPDATE/DELETE that have no SELECT list to classify).
56
+ * Identity-shared so equality checks stay cheap.
57
+ */
58
+ export declare const EMPTY_CLASSIFIED: ClassifiedSelect;
59
+ /**
60
+ * Classifies an `IrSelect` against the known relation map.
61
+ *
62
+ * Constructor inputs:
63
+ * - `select` — the IR select tree from `state.selectIr`.
64
+ * - `relations` — the relation map of the entity being queried; used to
65
+ * recognise relation keys in the IR and build fetch metadata.
66
+ * - `pkColumns` — primary-key columns of the parent entity. Used for
67
+ * `parentPkColumns` on to-many fetches and to ensure key columns are
68
+ * included for to-many parents.
69
+ * - `reusableJoinKeys` — relation keys that the planner has decided to
70
+ * join into the main SELECT because the where/orderBy already need
71
+ * that join. When non-empty, members of these relations stay in the
72
+ * SELECT list rather than triggering a separate fetch.
73
+ */
74
+ export declare class SelectClassifier {
75
+ private readonly select;
76
+ private readonly relations;
77
+ private readonly pkColumns;
78
+ private readonly reusableJoinKeys;
79
+ constructor(select: IrSelect, relations: RelationsMap, pkColumns: string[], reusableJoinKeys: Set<string>);
80
+ /**
81
+ * Run the classification pipeline:
82
+ *
83
+ * 1. Fast-path: if neither the select's paths nor its `relations` field
84
+ * references any known relation, return a no-op classification (the
85
+ * planner falls back to the IR's own paths/aliases).
86
+ * 2. Walk `select.paths` once, populating column lists, fetch metadata,
87
+ * joined-projection entries, and the skip-load set as we go.
88
+ * 3. Walk `select.relations` once, doing the same for nested-relation
89
+ * projections (e.g. `{ posts: p => ({ id: p.id, title: p.title }) }`).
90
+ * 4. Add any join-key columns that fetches need but the user didn't
91
+ * explicitly select — the row hydrator can't pair fetched rows with
92
+ * parents without them.
93
+ * 5. Stamp `parentPkColumns` onto to-many fetches.
94
+ *
95
+ * `joinedProjections` and `skipLoadFor` are populated incrementally
96
+ * inside the path/relation walks rather than via two extra passes
97
+ * because the matching condition (`reusableJoinKeys.has(...)` plus a
98
+ * length check) is exactly the same as the one that decides whether
99
+ * a member rides along the JOIN.
100
+ */
101
+ classify(): ClassifiedSelect;
102
+ /**
103
+ * Walk the IR `select.paths` array — every member-access in the user's
104
+ * select body lands here as a `string[]` path. Three cases:
105
+ *
106
+ * - **Leaf column** (`p.col`) — path doesn't start with a relation key,
107
+ * so it goes straight into the SELECT list as `<alias>.<col>`.
108
+ * - **Relation root** (`p.author`) — path is exactly `[relKey]`. Means
109
+ * "fetch the whole related entity"; produces a `relationFetch`.
110
+ * - **Relation member** (`p.author.name`) — depends on whether the
111
+ * relation is in `joinedRelationKeys`:
112
+ * - Joined → emit a column path on the JOIN's alias (rendered as
113
+ * e.g. `t1.name AS author_name`), record a projection entry on
114
+ * `joinedByKey` so the assembler can reshape the flat row, and
115
+ * add the relation key to `skipLoadFor` so the eager-loader
116
+ * doesn't redundantly fetch it.
117
+ * - Not joined → produce a `relationFetch` carrying just that
118
+ * sub-path so the eager-loader's secondary query selects only
119
+ * what was asked for.
120
+ *
121
+ * Side effects on `joinedByKey` and `skipLoadFor` mean we don't need a
122
+ * second pass over `select.paths` to compute those outputs.
123
+ */
124
+ private classifyPathEntries;
125
+ /**
126
+ * Walk the IR `select.relations` array — these come from explicit
127
+ * nested-relation projections (e.g. selecting `posts: p => ({ id, title })`
128
+ * means the IR carries a `{ name: "posts", outputKey: "posts",
129
+ * subPaths: [["id"], ["title"]] }` entry).
130
+ *
131
+ * `seenOutputKeys` is the set of `outputKey`s already produced by
132
+ * `classifyPathEntries` — duplicates here would cause the relation
133
+ * pipeline to fetch the same data twice or produce ambiguous result
134
+ * shapes, so we just skip them.
135
+ *
136
+ * Joined relation with non-empty subPaths → emit each subPath as a
137
+ * column-list entry (column names like `posts_title`), record a
138
+ * `joinedByKey` entry (overriding `outputKey` when the user aliased
139
+ * the relation), and add the relation to `skipLoadFor`. Non-joined or
140
+ * no subPaths → produce a relationFetch, the eager-loader handles it.
141
+ */
142
+ private classifyRelationEntries;
143
+ /**
144
+ * Make sure every join-key column a `relationFetch` needs is in the
145
+ * parent's SELECT list. Without this, the relation-fetcher would have
146
+ * the secondary query's rows but no way to pair them back to the
147
+ * correct parent row.
148
+ *
149
+ * The "key" columns differ by relation kind:
150
+ * - **to-many** (one-to-many, many-to-many): the parent's PK columns —
151
+ * the secondary query joins the child's FK against this.
152
+ * - **to-one** (many-to-one, one-to-one): the parent's FK columns
153
+ * stored on this row.
154
+ *
155
+ * Returns only the *missing* keys. Anything already in `existingPaths`
156
+ * is skipped to avoid duplicate SELECT entries (which would also break
157
+ * the row hydrator since aliases would clash).
158
+ */
159
+ private missingJoinKeyColumns;
160
+ }
161
+ //# sourceMappingURL=select-classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-classifier.d.ts","sourceRoot":"","sources":["../../../../src/orm/helpers/query-plan/select-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,8BAA8B,CAAC;AAItC,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAO9B,CAAC;AAcF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAHhB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,MAAM,EAAE,EACnB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC;IAGhD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,IAAI,gBAAgB;IAyD5B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,mBAAmB;IAoD3B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,uBAAuB;IAoD/B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,qBAAqB;CA0B9B"}
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Select-list classification.
3
+ *
4
+ * A user-written `.select(...)` body can mix three kinds of references:
5
+ * plain columns (`u.name`), relation roots (`u.author`), and members of
6
+ * relations (`u.author.name`). How each is rendered depends on whether
7
+ * its relation is *joined* into the main SELECT (and therefore its
8
+ * columns can ride along) or *not joined* (and so the data has to be
9
+ * fetched separately by the relation pipeline).
10
+ *
11
+ * `SelectClassifier.classify()` walks the IR select once and produces a
12
+ * `ClassifiedSelect` that tells the rest of the planner how to handle
13
+ * each entry:
14
+ *
15
+ * - **`columnPaths` / `columnAliases`** — column references that should
16
+ * appear in the SQL SELECT list, as `<alias>.<col>` references. These
17
+ * include leaf columns, joined-relation members, and any join-key
18
+ * columns that need to be added so the row hydrator can pair fetched
19
+ * relation rows with their parents.
20
+ * - **`relationFetches`** — relations that need a separate eager-load
21
+ * query (one-to-many, many-to-many, or non-joined many-to-one). The
22
+ * relation-fetcher reads this list to produce the WHERE-IN secondary
23
+ * queries.
24
+ * - **`joinedProjections`** — relations whose data came in via the JOIN
25
+ * and needs to be re-shaped from flat result columns back into nested
26
+ * objects. Drives `RelationAssembler.assembleJoined`.
27
+ * - **`skipLoadFor`** — relation keys whose data is already in the
28
+ * SELECT-list via the JOIN; the eager-loader skips re-fetching these.
29
+ *
30
+ * The classifier is constructed once with the inputs that all five
31
+ * helper methods share, so the methods can be small and read directly
32
+ * from `this.*` rather than threading a context object.
33
+ */
34
+ import { getPkColumnsFromSchema } from "../../../entity/pk-columns.js";
35
+ import { toArray } from "../../../utils.js";
36
+ /**
37
+ * Sentinel used by the planner when classification isn't needed (e.g.
38
+ * mutations like UPDATE/DELETE that have no SELECT list to classify).
39
+ * Identity-shared so equality checks stay cheap.
40
+ */
41
+ export const EMPTY_CLASSIFIED = {
42
+ columnPaths: null,
43
+ columnAliases: null,
44
+ relationFetches: [],
45
+ joinedProjections: [],
46
+ skipLoadFor: new Set(),
47
+ reusableJoinKeys: new Set(),
48
+ };
49
+ /**
50
+ * Classifies an `IrSelect` against the known relation map.
51
+ *
52
+ * Constructor inputs:
53
+ * - `select` — the IR select tree from `state.selectIr`.
54
+ * - `relations` — the relation map of the entity being queried; used to
55
+ * recognise relation keys in the IR and build fetch metadata.
56
+ * - `pkColumns` — primary-key columns of the parent entity. Used for
57
+ * `parentPkColumns` on to-many fetches and to ensure key columns are
58
+ * included for to-many parents.
59
+ * - `reusableJoinKeys` — relation keys that the planner has decided to
60
+ * join into the main SELECT because the where/orderBy already need
61
+ * that join. When non-empty, members of these relations stay in the
62
+ * SELECT list rather than triggering a separate fetch.
63
+ */
64
+ export class SelectClassifier {
65
+ select;
66
+ relations;
67
+ pkColumns;
68
+ reusableJoinKeys;
69
+ constructor(select, relations, pkColumns, reusableJoinKeys) {
70
+ this.select = select;
71
+ this.relations = relations;
72
+ this.pkColumns = pkColumns;
73
+ this.reusableJoinKeys = reusableJoinKeys;
74
+ }
75
+ /**
76
+ * Run the classification pipeline:
77
+ *
78
+ * 1. Fast-path: if neither the select's paths nor its `relations` field
79
+ * references any known relation, return a no-op classification (the
80
+ * planner falls back to the IR's own paths/aliases).
81
+ * 2. Walk `select.paths` once, populating column lists, fetch metadata,
82
+ * joined-projection entries, and the skip-load set as we go.
83
+ * 3. Walk `select.relations` once, doing the same for nested-relation
84
+ * projections (e.g. `{ posts: p => ({ id: p.id, title: p.title }) }`).
85
+ * 4. Add any join-key columns that fetches need but the user didn't
86
+ * explicitly select — the row hydrator can't pair fetched rows with
87
+ * parents without them.
88
+ * 5. Stamp `parentPkColumns` onto to-many fetches.
89
+ *
90
+ * `joinedProjections` and `skipLoadFor` are populated incrementally
91
+ * inside the path/relation walks rather than via two extra passes
92
+ * because the matching condition (`reusableJoinKeys.has(...)` plus a
93
+ * length check) is exactly the same as the one that decides whether
94
+ * a member rides along the JOIN.
95
+ */
96
+ classify() {
97
+ const { select, relations, reusableJoinKeys } = this;
98
+ const hasRelations = select.relations?.length || select.paths.some((p) => p.length >= 1 && relations[p[0]]);
99
+ if (!hasRelations) {
100
+ return {
101
+ columnPaths: null,
102
+ columnAliases: null,
103
+ relationFetches: [],
104
+ joinedProjections: [],
105
+ skipLoadFor: new Set(),
106
+ reusableJoinKeys,
107
+ };
108
+ }
109
+ const joinedKeys = reusableJoinKeys.size > 0 ? reusableJoinKeys : undefined;
110
+ const joinedByKey = new Map();
111
+ const skipLoadFor = new Set();
112
+ const fromPaths = this.classifyPathEntries(joinedKeys, joinedByKey, skipLoadFor);
113
+ const seenOutputKeys = new Set(fromPaths.relationFetches.map((m) => m.relation.outputKey));
114
+ const fromRelations = this.classifyRelationEntries(joinedKeys, seenOutputKeys, joinedByKey, skipLoadFor);
115
+ const columnPaths = [...fromPaths.columnPaths, ...fromRelations.columnPaths];
116
+ const columnAliases = [...fromPaths.columnAliases, ...fromRelations.columnAliases];
117
+ const relationFetches = [...fromPaths.relationFetches, ...fromRelations.relationFetches];
118
+ const { paths: keyPaths, aliases: keyAliases } = this.missingJoinKeyColumns(relationFetches, columnPaths);
119
+ columnPaths.push(...keyPaths);
120
+ columnAliases.push(...keyAliases);
121
+ for (const f of relationFetches) {
122
+ if (f.relationType === "one-to-many" || f.relationType === "many-to-many") {
123
+ f.parentPkColumns = this.pkColumns;
124
+ }
125
+ }
126
+ return {
127
+ columnPaths,
128
+ columnAliases,
129
+ relationFetches,
130
+ joinedProjections: [...joinedByKey.values()].filter((p) => p.members.length > 0),
131
+ skipLoadFor,
132
+ reusableJoinKeys,
133
+ };
134
+ }
135
+ /**
136
+ * Walk the IR `select.paths` array — every member-access in the user's
137
+ * select body lands here as a `string[]` path. Three cases:
138
+ *
139
+ * - **Leaf column** (`p.col`) — path doesn't start with a relation key,
140
+ * so it goes straight into the SELECT list as `<alias>.<col>`.
141
+ * - **Relation root** (`p.author`) — path is exactly `[relKey]`. Means
142
+ * "fetch the whole related entity"; produces a `relationFetch`.
143
+ * - **Relation member** (`p.author.name`) — depends on whether the
144
+ * relation is in `joinedRelationKeys`:
145
+ * - Joined → emit a column path on the JOIN's alias (rendered as
146
+ * e.g. `t1.name AS author_name`), record a projection entry on
147
+ * `joinedByKey` so the assembler can reshape the flat row, and
148
+ * add the relation key to `skipLoadFor` so the eager-loader
149
+ * doesn't redundantly fetch it.
150
+ * - Not joined → produce a `relationFetch` carrying just that
151
+ * sub-path so the eager-loader's secondary query selects only
152
+ * what was asked for.
153
+ *
154
+ * Side effects on `joinedByKey` and `skipLoadFor` mean we don't need a
155
+ * second pass over `select.paths` to compute those outputs.
156
+ */
157
+ classifyPathEntries(joinedRelationKeys, joinedByKey, skipLoadFor) {
158
+ const { select, relations } = this;
159
+ const relNames = new Set(Object.keys(relations));
160
+ const out = {
161
+ columnPaths: [],
162
+ columnAliases: [],
163
+ relationFetches: [],
164
+ };
165
+ for (let i = 0; i < select.paths.length; i++) {
166
+ const path = select.paths[i];
167
+ const alias = select.aliases?.[i] ?? path[path.length - 1];
168
+ if (path.length === 1 && relNames.has(path[0])) {
169
+ const meta = buildRelationFetchMeta({ name: path[0], outputKey: alias }, relations[path[0]]);
170
+ out.relationFetches.push(meta);
171
+ }
172
+ else if (path.length > 1 && relNames.has(path[0])) {
173
+ if (joinedRelationKeys?.has(path[0])) {
174
+ const colAlias = select.aliases?.[i] ?? `${path[0]}_${path[path.length - 1]}`;
175
+ out.columnPaths.push(path);
176
+ out.columnAliases.push(colAlias);
177
+ let proj = joinedByKey.get(path[0]);
178
+ if (!proj) {
179
+ proj = { relationKey: path[0], outputKey: path[0], members: [] };
180
+ joinedByKey.set(path[0], proj);
181
+ }
182
+ proj.members.push({ alias: colAlias, subPath: path[path.length - 1] });
183
+ skipLoadFor.add(path[0]);
184
+ }
185
+ else {
186
+ const meta = buildRelationFetchMeta({ name: path[0], outputKey: alias, subPaths: [path.slice(1)] }, relations[path[0]]);
187
+ out.relationFetches.push(meta);
188
+ }
189
+ }
190
+ else {
191
+ out.columnPaths.push(path);
192
+ out.columnAliases.push(alias);
193
+ }
194
+ }
195
+ return out;
196
+ }
197
+ /**
198
+ * Walk the IR `select.relations` array — these come from explicit
199
+ * nested-relation projections (e.g. selecting `posts: p => ({ id, title })`
200
+ * means the IR carries a `{ name: "posts", outputKey: "posts",
201
+ * subPaths: [["id"], ["title"]] }` entry).
202
+ *
203
+ * `seenOutputKeys` is the set of `outputKey`s already produced by
204
+ * `classifyPathEntries` — duplicates here would cause the relation
205
+ * pipeline to fetch the same data twice or produce ambiguous result
206
+ * shapes, so we just skip them.
207
+ *
208
+ * Joined relation with non-empty subPaths → emit each subPath as a
209
+ * column-list entry (column names like `posts_title`), record a
210
+ * `joinedByKey` entry (overriding `outputKey` when the user aliased
211
+ * the relation), and add the relation to `skipLoadFor`. Non-joined or
212
+ * no subPaths → produce a relationFetch, the eager-loader handles it.
213
+ */
214
+ classifyRelationEntries(joinedRelationKeys, seenOutputKeys, joinedByKey, skipLoadFor) {
215
+ const { select, relations } = this;
216
+ const out = {
217
+ columnPaths: [],
218
+ columnAliases: [],
219
+ relationFetches: [],
220
+ };
221
+ for (const r of select.relations ?? []) {
222
+ const relDef = relations[r.name];
223
+ if (!relDef) {
224
+ throw new Error(`[typhex] select relation "${r.name}" is not defined on this entity`);
225
+ }
226
+ if (seenOutputKeys.has(r.outputKey)) {
227
+ throw new Error(`[typhex] select relation output "${r.outputKey}" is duplicated`);
228
+ }
229
+ seenOutputKeys.add(r.outputKey);
230
+ if (joinedRelationKeys?.has(r.name) && r.subPaths?.length) {
231
+ let proj = joinedByKey.get(r.name);
232
+ if (!proj) {
233
+ proj = { relationKey: r.name, outputKey: r.outputKey, members: [] };
234
+ joinedByKey.set(r.name, proj);
235
+ }
236
+ else {
237
+ // A path-driven entry was created earlier with `outputKey: r.name`;
238
+ // an explicit relation entry takes precedence (user may have aliased it).
239
+ proj.outputKey = r.outputKey;
240
+ }
241
+ for (const sub of r.subPaths) {
242
+ if (sub.length > 0) {
243
+ const alias = `${r.outputKey}_${sub.join("_")}`;
244
+ out.columnPaths.push([r.name, ...sub]);
245
+ out.columnAliases.push(alias);
246
+ proj.members.push({ alias, subPath: sub[sub.length - 1] });
247
+ }
248
+ }
249
+ skipLoadFor.add(r.name);
250
+ }
251
+ else {
252
+ const meta = buildRelationFetchMeta(r, relDef);
253
+ out.relationFetches.push(meta);
254
+ }
255
+ }
256
+ return out;
257
+ }
258
+ /**
259
+ * Make sure every join-key column a `relationFetch` needs is in the
260
+ * parent's SELECT list. Without this, the relation-fetcher would have
261
+ * the secondary query's rows but no way to pair them back to the
262
+ * correct parent row.
263
+ *
264
+ * The "key" columns differ by relation kind:
265
+ * - **to-many** (one-to-many, many-to-many): the parent's PK columns —
266
+ * the secondary query joins the child's FK against this.
267
+ * - **to-one** (many-to-one, one-to-one): the parent's FK columns
268
+ * stored on this row.
269
+ *
270
+ * Returns only the *missing* keys. Anything already in `existingPaths`
271
+ * is skipped to avoid duplicate SELECT entries (which would also break
272
+ * the row hydrator since aliases would clash).
273
+ */
274
+ missingJoinKeyColumns(fetches, existingPaths) {
275
+ const paths = [];
276
+ const aliases = [];
277
+ const added = new Set(existingPaths.map((p) => p[0]));
278
+ for (const meta of fetches) {
279
+ const isMany = meta.relationType === "one-to-many" || meta.relationType === "many-to-many";
280
+ const cols = isMany ? this.pkColumns : meta.fkColumns;
281
+ if (isMany && cols.length === 0) {
282
+ throw new Error(`[typhex] select relation "${meta.relation.name}" requires a primary key on the parent entity`);
283
+ }
284
+ for (const col of cols) {
285
+ if (!added.has(col)) {
286
+ paths.push([col]);
287
+ aliases.push(col);
288
+ added.add(col);
289
+ }
290
+ }
291
+ }
292
+ return { paths, aliases };
293
+ }
294
+ }
295
+ /**
296
+ * Build the runtime metadata the relation-fetcher needs to execute a
297
+ * secondary load for one relation, given the IR description and the
298
+ * relation definition from the entity.
299
+ *
300
+ * Per relation-kind handling:
301
+ * - **many-to-one / one-to-one**: FK columns are on the parent; PK
302
+ * columns come from the target's schema unless overridden by the
303
+ * relation's `references` option.
304
+ * - **one-to-many**: FK columns are on the child (so we read them off
305
+ * the relation options); PK comes from the target schema.
306
+ * - **many-to-many**: both FK and PK live on the junction table; the
307
+ * junction itself is recorded so the fetcher can build the join.
308
+ */
309
+ function buildRelationFetchMeta(ir, relDef) {
310
+ const target = relDef._target();
311
+ const targetEntity = target && typeof target.query === "function"
312
+ ? target
313
+ : null;
314
+ if (!targetEntity) {
315
+ throw new Error(`[typhex] relation "${ir.name}" target is not a queryable entity`);
316
+ }
317
+ const targetPkColumnsFromSchema = getPkColumnsFromSchema(targetEntity.table._schema);
318
+ switch (relDef._relType) {
319
+ case "many-to-one":
320
+ case "one-to-one": {
321
+ const opts = relDef._options;
322
+ return {
323
+ relationType: relDef._relType,
324
+ relation: ir,
325
+ fkColumns: toArray(opts.foreignKey),
326
+ targetPkColumns: opts.references != null ? toArray(opts.references) : targetPkColumnsFromSchema,
327
+ targetEntity,
328
+ };
329
+ }
330
+ case "one-to-many": {
331
+ const opts = relDef._options;
332
+ return {
333
+ relationType: "one-to-many",
334
+ relation: ir,
335
+ fkColumns: toArray(opts.foreignKey),
336
+ targetPkColumns: targetPkColumnsFromSchema,
337
+ targetEntity,
338
+ };
339
+ }
340
+ case "many-to-many": {
341
+ const j = relDef._options;
342
+ return {
343
+ relationType: "many-to-many",
344
+ relation: ir,
345
+ fkColumns: toArray(j.referenceKey),
346
+ targetPkColumns: targetPkColumnsFromSchema,
347
+ targetEntity,
348
+ junction: {
349
+ table: j.junction,
350
+ foreignKey: toArray(j.foreignKey),
351
+ referenceKey: toArray(j.referenceKey),
352
+ },
353
+ };
354
+ }
355
+ default:
356
+ throw new Error(`[typhex] Unsupported relation type: ${relDef._relType}`);
357
+ }
358
+ }
359
+ //# sourceMappingURL=select-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-classifier.js","sourceRoot":"","sources":["../../../../src/orm/helpers/query-plan/select-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Relation assembler: attaches relation data onto rows.
3
+ * Handles both flat JOIN columns (assembleJoined) and pre-fetched maps (assembleFetched).
4
+ */
5
+ import type { JoinedProjection, RelationFetchMetadata } from "../query-plan/query-plan.js";
6
+ export type RelationFetchedData = Map<string, Map<string, unknown> | Map<string, unknown[]>>;
7
+ /** Attaches JOIN-projected and separately fetched relation data onto result rows. */
8
+ export declare class RelationAssembler {
9
+ private readonly rows;
10
+ constructor(rows: Record<string, unknown>[]);
11
+ /**
12
+ * Reconstruct nested objects from flat JOIN columns
13
+ * (e.g. author_name to row.author.name) using pre-extracted projections.
14
+ */
15
+ assembleJoined(projections: JoinedProjection[]): void;
16
+ /** Attach fetched relation maps onto rows. */
17
+ assembleFetched(fetches: RelationFetchMetadata[], fetched: RelationFetchedData, skip: Set<string>): void;
18
+ private attachToManyRelation;
19
+ private attachToOneRelation;
20
+ }
21
+ //# sourceMappingURL=relation-assembler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-assembler.d.ts","sourceRoot":"","sources":["../../../../src/orm/helpers/relations/relation-assembler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAG3F,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAE7F,qFAAqF;AACrF,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAE5D;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAYrD,8CAA8C;IAC9C,eAAe,CACb,OAAO,EAAE,qBAAqB,EAAE,EAChC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAChB,IAAI;IAaP,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,mBAAmB;CAM5B"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Relation assembler: attaches relation data onto rows.
3
+ * Handles both flat JOIN columns (assembleJoined) and pre-fetched maps (assembleFetched).
4
+ */
5
+ import { makeCompositeKey } from "../../query-helpers.js";
6
+ /** Attaches JOIN-projected and separately fetched relation data onto result rows. */
7
+ export class RelationAssembler {
8
+ rows;
9
+ constructor(rows) {
10
+ this.rows = rows;
11
+ }
12
+ /**
13
+ * Reconstruct nested objects from flat JOIN columns
14
+ * (e.g. author_name to row.author.name) using pre-extracted projections.
15
+ */
16
+ assembleJoined(projections) {
17
+ for (const proj of projections) {
18
+ if (proj.members.length === 0)
19
+ continue;
20
+ for (const row of this.rows) {
21
+ const obj = {};
22
+ for (const member of proj.members)
23
+ obj[member.subPath] = row[member.alias];
24
+ row[proj.outputKey] = obj;
25
+ for (const member of proj.members)
26
+ delete row[member.alias];
27
+ }
28
+ }
29
+ }
30
+ /** Attach fetched relation maps onto rows. */
31
+ assembleFetched(fetches, fetched, skip) {
32
+ for (const meta of fetches) {
33
+ if (skip.has(meta.relation.name))
34
+ continue;
35
+ const data = fetched.get(meta.relation.name);
36
+ if (!data)
37
+ continue;
38
+ if (meta.relationType === "one-to-many" || meta.relationType === "many-to-many") {
39
+ this.attachToManyRelation(meta, data);
40
+ }
41
+ else {
42
+ this.attachToOneRelation(meta, data);
43
+ }
44
+ }
45
+ }
46
+ attachToManyRelation(meta, data) {
47
+ const pkCols = meta.parentPkColumns;
48
+ for (const row of this.rows) {
49
+ const key = makeCompositeKey(row, pkCols);
50
+ row[meta.relation.outputKey] = data.get(key) ?? [];
51
+ }
52
+ }
53
+ attachToOneRelation(meta, data) {
54
+ for (const row of this.rows) {
55
+ const key = makeCompositeKey(row, meta.fkColumns);
56
+ row[meta.relation.outputKey] = data.get(key) ?? null;
57
+ }
58
+ }
59
+ }
60
+ //# sourceMappingURL=relation-assembler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-assembler.js","sourceRoot":"","sources":["../../../../src/orm/helpers/relations/relation-assembler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI1D,qFAAqF;AACrF,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,IAA+B;QAA/B,SAAI,GAAJ,IAAI,CAA2B;IAAG,CAAC;IAEhE;;;OAGG;IACH,cAAc,CAAC,WAA+B;QAC5C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACxC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAA4B,EAAE,CAAC;gBACxC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;oBAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3E,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;gBAC1B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;oBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,eAAe,CACb,OAAgC,EAChC,OAA4B,EAC5B,IAAiB;QAEjB,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,IAAI,IAAI,CAAC,YAAY,KAAK,aAAa,IAAI,IAAI,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;gBAChF,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAA8B,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,IAA4B,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,IAA2B,EAAE,IAA4B;QACpF,MAAM,MAAM,GAAG,IAAI,CAAC,eAAgB,CAAC;QACrC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,IAA2B,EAAE,IAA0B;QACjF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACvD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Relation fetcher: fetches related entities via WHERE IN queries.
3
+ * Does NOT mutate rows — returns fetched data as maps.
4
+ */
5
+ import type { QueryExecutor } from "../../db.js";
6
+ import type { RelationFetchMetadata } from "../query-plan/query-plan.js";
7
+ export type RelationFetchResult = Map<string, Map<string, unknown> | Map<string, unknown[]>>;
8
+ /** Runs one WHERE IN query per pending relation fetch and collects keyed result maps. */
9
+ export declare class RelationFetcher {
10
+ private readonly qe;
11
+ private readonly rows;
12
+ private readonly fetches;
13
+ private readonly skip;
14
+ constructor(qe: QueryExecutor, rows: Record<string, unknown>[], fetches: RelationFetchMetadata[], skip: Set<string>);
15
+ fetch(): Promise<RelationFetchResult>;
16
+ private fetchRelation;
17
+ /** Fetch a to-many relation: WHERE IN on FK columns, grouped by FK composite key. */
18
+ private fetchOneToMany;
19
+ /** Fetch a to-one relation: WHERE IN on FK to target-PK, indexed by target PK composite key. */
20
+ private fetchOneToOne;
21
+ /** Many-to-many: two fetchRows calls through the junction, grouped by parent composite key. */
22
+ private fetchManyToMany;
23
+ private buildTargetParentIndex;
24
+ /** Batch-fetch rows from `entity` by mapping source column values onto target columns. */
25
+ private fetchRows;
26
+ private remapCols;
27
+ private indexByCompositeKey;
28
+ private groupByCompositeKey;
29
+ }
30
+ //# sourceMappingURL=relation-fetcher.d.ts.map