metal-orm 1.0.43 → 1.0.45

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 (85) hide show
  1. package/README.md +700 -557
  2. package/dist/index.cjs +896 -476
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1146 -275
  5. package/dist/index.d.ts +1146 -275
  6. package/dist/index.js +896 -474
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/core/ast/adapters.ts +8 -2
  10. package/src/core/ast/builders.ts +105 -81
  11. package/src/core/ast/expression-builders.ts +430 -390
  12. package/src/core/ast/expression-visitor.ts +47 -8
  13. package/src/core/ast/helpers.ts +23 -0
  14. package/src/core/ast/join-node.ts +17 -1
  15. package/src/core/ddl/dialects/base-schema-dialect.ts +7 -1
  16. package/src/core/ddl/dialects/index.ts +1 -0
  17. package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -0
  18. package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -0
  19. package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -0
  20. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -0
  21. package/src/core/ddl/introspect/catalogs/index.ts +1 -0
  22. package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
  23. package/src/core/ddl/introspect/context.ts +6 -0
  24. package/src/core/ddl/introspect/functions/postgres.ts +13 -0
  25. package/src/core/ddl/introspect/mssql.ts +11 -0
  26. package/src/core/ddl/introspect/mysql.ts +2 -0
  27. package/src/core/ddl/introspect/postgres.ts +14 -0
  28. package/src/core/ddl/introspect/registry.ts +14 -0
  29. package/src/core/ddl/introspect/run-select.ts +13 -0
  30. package/src/core/ddl/introspect/sqlite.ts +22 -0
  31. package/src/core/ddl/introspect/utils.ts +18 -0
  32. package/src/core/ddl/naming-strategy.ts +6 -0
  33. package/src/core/ddl/schema-dialect.ts +19 -6
  34. package/src/core/ddl/schema-diff.ts +22 -0
  35. package/src/core/ddl/schema-generator.ts +22 -0
  36. package/src/core/ddl/schema-plan-executor.ts +6 -0
  37. package/src/core/ddl/schema-types.ts +6 -0
  38. package/src/core/dialect/abstract.ts +2 -2
  39. package/src/core/execution/pooling/pool.ts +12 -7
  40. package/src/core/functions/datetime.ts +57 -33
  41. package/src/core/functions/numeric.ts +95 -30
  42. package/src/core/functions/standard-strategy.ts +35 -0
  43. package/src/core/functions/text.ts +83 -22
  44. package/src/core/functions/types.ts +23 -8
  45. package/src/decorators/bootstrap.ts +16 -4
  46. package/src/decorators/column.ts +17 -0
  47. package/src/decorators/decorator-metadata.ts +27 -0
  48. package/src/decorators/entity.ts +8 -0
  49. package/src/decorators/index.ts +3 -0
  50. package/src/decorators/relations.ts +32 -0
  51. package/src/orm/als.ts +34 -9
  52. package/src/orm/entity-context.ts +54 -0
  53. package/src/orm/entity-metadata.ts +122 -9
  54. package/src/orm/execute.ts +15 -0
  55. package/src/orm/lazy-batch.ts +158 -98
  56. package/src/orm/relations/has-many.ts +44 -0
  57. package/src/orm/save-graph.ts +45 -0
  58. package/src/query/index.ts +74 -0
  59. package/src/query/target.ts +46 -0
  60. package/src/query-builder/delete-query-state.ts +30 -0
  61. package/src/query-builder/delete.ts +64 -19
  62. package/src/query-builder/hydration-manager.ts +46 -0
  63. package/src/query-builder/insert-query-state.ts +30 -0
  64. package/src/query-builder/insert.ts +46 -2
  65. package/src/query-builder/query-ast-service.ts +5 -0
  66. package/src/query-builder/query-resolution.ts +78 -0
  67. package/src/query-builder/raw-column-parser.ts +5 -0
  68. package/src/query-builder/relation-alias.ts +7 -0
  69. package/src/query-builder/relation-conditions.ts +61 -48
  70. package/src/query-builder/relation-service.ts +68 -63
  71. package/src/query-builder/relation-utils.ts +3 -0
  72. package/src/query-builder/select/cte-facet.ts +40 -0
  73. package/src/query-builder/select/from-facet.ts +80 -0
  74. package/src/query-builder/select/join-facet.ts +62 -0
  75. package/src/query-builder/select/predicate-facet.ts +103 -0
  76. package/src/query-builder/select/projection-facet.ts +69 -0
  77. package/src/query-builder/select/relation-facet.ts +81 -0
  78. package/src/query-builder/select/setop-facet.ts +36 -0
  79. package/src/query-builder/select-helpers.ts +13 -0
  80. package/src/query-builder/select-query-builder-deps.ts +19 -1
  81. package/src/query-builder/select-query-state.ts +2 -1
  82. package/src/query-builder/select.ts +795 -1163
  83. package/src/query-builder/update-query-state.ts +52 -0
  84. package/src/query-builder/update.ts +69 -19
  85. package/src/schema/table-guards.ts +31 -0
package/dist/index.js CHANGED
@@ -325,39 +325,48 @@ var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "Windo
325
325
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
326
326
 
327
327
  // src/core/ast/expression-builders.ts
328
- var valueToOperand = (value) => {
329
- if (isOperandNode(value)) {
330
- return value;
331
- }
332
- return {
333
- type: "Literal",
334
- value
335
- };
336
- };
337
- var toNode = (col2) => {
338
- if (isOperandNode(col2)) return col2;
339
- const def = col2;
340
- return { type: "Column", table: def.table || "unknown", name: def.name };
341
- };
328
+ var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
342
329
  var toLiteralNode = (value) => ({
343
330
  type: "Literal",
344
331
  value
345
332
  });
346
- var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
347
- var isValueOperandInput = (value) => isOperandNode(value) || isLiteralValue(value);
348
- var toOperand = (val) => {
349
- if (isLiteralValue(val)) {
350
- return valueToOperand(val);
333
+ var columnRefToNode = (col2) => {
334
+ if (!col2.table) {
335
+ throw new Error(
336
+ `Column "${col2.name}" requires a table reference. Use columnOperand with a fully qualified ColumnRef or ColumnNode.`
337
+ );
351
338
  }
352
- return toNode(val);
339
+ return { type: "Column", table: col2.table, name: col2.name };
353
340
  };
341
+ var toOperandNode = (value) => {
342
+ if (isOperandNode(value)) {
343
+ return value;
344
+ }
345
+ if (isLiteralValue(value)) {
346
+ return toLiteralNode(value);
347
+ }
348
+ return columnRefToNode(value);
349
+ };
350
+ var valueToOperand = (value) => {
351
+ if (isOperandNode(value)) {
352
+ return value;
353
+ }
354
+ return toLiteralNode(value);
355
+ };
356
+ var toOperand = (val) => toOperandNode(val);
357
+ var isValueOperandInput = (value) => isOperandNode(value) || isLiteralValue(value);
354
358
  var hasQueryAst = (value) => typeof value.getAST === "function";
355
359
  var resolveSelectQueryNode = (query) => hasQueryAst(query) ? query.getAST() : query;
356
360
  var toScalarSubqueryNode = (query) => ({
357
361
  type: "ScalarSubquery",
358
362
  query: resolveSelectQueryNode(query)
359
363
  });
360
- var columnOperand = (col2) => toNode(col2);
364
+ var columnOperand = (col2) => {
365
+ if (isOperandNode(col2) && col2.type === "Column") {
366
+ return col2;
367
+ }
368
+ return columnRefToNode(col2);
369
+ };
361
370
  var outerRef = (col2) => ({
362
371
  ...columnOperand(col2),
363
372
  scope: "outer"
@@ -370,7 +379,7 @@ var correlateBy = (table, column) => outerRef({ name: column, table });
370
379
  var createBinaryExpression = (operator, left2, right2, escape) => {
371
380
  const node = {
372
381
  type: "BinaryExpression",
373
- left: toNode(left2),
382
+ left: toOperandNode(left2),
374
383
  operator,
375
384
  right: toOperand(right2)
376
385
  };
@@ -399,17 +408,17 @@ var or = (...operands) => ({
399
408
  });
400
409
  var isNull = (left2) => ({
401
410
  type: "NullExpression",
402
- left: toNode(left2),
411
+ left: toOperandNode(left2),
403
412
  operator: "IS NULL"
404
413
  });
405
414
  var isNotNull = (left2) => ({
406
415
  type: "NullExpression",
407
- left: toNode(left2),
416
+ left: toOperandNode(left2),
408
417
  operator: "IS NOT NULL"
409
418
  });
410
419
  var createInExpression = (operator, left2, right2) => ({
411
420
  type: "InExpression",
412
- left: toNode(left2),
421
+ left: toOperandNode(left2),
413
422
  operator,
414
423
  right: right2
415
424
  });
@@ -419,7 +428,7 @@ var inSubquery = (left2, subquery) => createInExpression("IN", left2, toScalarSu
419
428
  var notInSubquery = (left2, subquery) => createInExpression("NOT IN", left2, toScalarSubqueryNode(subquery));
420
429
  var createBetweenExpression = (operator, left2, lower2, upper2) => ({
421
430
  type: "BetweenExpression",
422
- left: toNode(left2),
431
+ left: toOperandNode(left2),
423
432
  operator,
424
433
  lower: toOperand(lower2),
425
434
  upper: toOperand(upper2)
@@ -601,16 +610,45 @@ var groupConcat = (col2, options) => ({
601
610
  });
602
611
 
603
612
  // src/core/ast/expression-visitor.ts
604
- var expressionDispatchers = /* @__PURE__ */ new Map();
605
- var operandDispatchers = /* @__PURE__ */ new Map();
613
+ var DispatcherRegistry = class _DispatcherRegistry {
614
+ constructor(dispatchers = /* @__PURE__ */ new Map()) {
615
+ this.dispatchers = dispatchers;
616
+ }
617
+ /**
618
+ * Registers a new dispatcher and returns a new registry instance
619
+ */
620
+ register(type, dispatcher) {
621
+ const newMap = new Map(this.dispatchers);
622
+ newMap.set(type, dispatcher);
623
+ return new _DispatcherRegistry(newMap);
624
+ }
625
+ /**
626
+ * Gets a dispatcher for the given type
627
+ */
628
+ get(type) {
629
+ return this.dispatchers.get(type);
630
+ }
631
+ /**
632
+ * Returns a new empty registry
633
+ */
634
+ clear() {
635
+ return new _DispatcherRegistry();
636
+ }
637
+ };
638
+ var expressionRegistry = new DispatcherRegistry();
639
+ var operandRegistry = new DispatcherRegistry();
606
640
  var registerExpressionDispatcher = (type, dispatcher) => {
607
- expressionDispatchers.set(type, dispatcher);
641
+ expressionRegistry = expressionRegistry.register(type, dispatcher);
608
642
  };
609
643
  var registerOperandDispatcher = (type, dispatcher) => {
610
- operandDispatchers.set(type, dispatcher);
644
+ operandRegistry = operandRegistry.register(type, dispatcher);
645
+ };
646
+ var clearExpressionDispatchers = () => {
647
+ expressionRegistry = expressionRegistry.clear();
648
+ };
649
+ var clearOperandDispatchers = () => {
650
+ operandRegistry = operandRegistry.clear();
611
651
  };
612
- var clearExpressionDispatchers = () => expressionDispatchers.clear();
613
- var clearOperandDispatchers = () => operandDispatchers.clear();
614
652
  var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
615
653
  var unsupportedExpression = (node) => {
616
654
  throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
@@ -619,7 +657,7 @@ var unsupportedOperand = (node) => {
619
657
  throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
620
658
  };
621
659
  var visitExpression = (node, visitor) => {
622
- const dynamic = expressionDispatchers.get(node.type);
660
+ const dynamic = expressionRegistry.get(node.type);
623
661
  if (dynamic) return dynamic(node, visitor);
624
662
  switch (node.type) {
625
663
  case "BinaryExpression":
@@ -650,7 +688,7 @@ var visitExpression = (node, visitor) => {
650
688
  return unsupportedExpression(node);
651
689
  };
652
690
  var visitOperand = (node, visitor) => {
653
- const dynamic = operandDispatchers.get(node.type);
691
+ const dynamic = operandRegistry.get(node.type);
654
692
  if (dynamic) return dynamic(node, visitor);
655
693
  switch (node.type) {
656
694
  case "Column":
@@ -685,24 +723,35 @@ var visitOperand = (node, visitor) => {
685
723
  };
686
724
 
687
725
  // src/core/ast/adapters.ts
726
+ var hasAlias = (obj) => typeof obj === "object" && obj !== null && "alias" in obj;
688
727
  var toColumnRef = (col2) => ({
689
728
  name: col2.name,
690
729
  table: col2.table,
691
- alias: col2.alias
730
+ alias: hasAlias(col2) ? col2.alias : void 0
692
731
  });
693
732
  var toTableRef = (table) => ({
694
733
  name: table.name,
695
734
  schema: table.schema,
696
- alias: table.alias
735
+ alias: hasAlias(table) ? table.alias : void 0
697
736
  });
698
737
 
699
738
  // src/core/ast/builders.ts
739
+ var isColumnNode = (col2) => "type" in col2 && col2.type === "Column";
740
+ var resolveTableName = (def, table) => {
741
+ if (!def.table) {
742
+ return table.alias || table.name;
743
+ }
744
+ if (table.alias && def.table === table.name) {
745
+ return table.alias;
746
+ }
747
+ return def.table;
748
+ };
700
749
  var buildColumnNode = (table, column) => {
701
- if (column.type === "Column") {
750
+ if (isColumnNode(column)) {
702
751
  return column;
703
752
  }
704
753
  const def = column;
705
- const baseTable = def.table ? table.alias && def.table === table.name ? table.alias : def.table : table.alias || table.name;
754
+ const baseTable = resolveTableName(def, table);
706
755
  return {
707
756
  type: "Column",
708
757
  table: baseTable,
@@ -716,7 +765,8 @@ var buildColumnNodes = (table, names) => names.map((name) => ({
716
765
  }));
717
766
  var createTableNode = (table) => ({
718
767
  type: "Table",
719
- name: table.name
768
+ name: table.name,
769
+ schema: table.schema
720
770
  });
721
771
  var fnTable = (name, args = [], alias, opts) => ({
722
772
  type: "FunctionTable",
@@ -737,6 +787,9 @@ var derivedTable = (query, alias, columnAliases) => ({
737
787
 
738
788
  // src/core/functions/standard-strategy.ts
739
789
  var StandardFunctionStrategy = class _StandardFunctionStrategy {
790
+ /**
791
+ * Creates a new StandardFunctionStrategy and registers standard functions.
792
+ */
740
793
  constructor() {
741
794
  this.renderers = /* @__PURE__ */ new Map();
742
795
  this.registerStandard();
@@ -775,12 +828,25 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
775
828
  this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
776
829
  this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
777
830
  }
831
+ /**
832
+ * Registers a renderer for a function name.
833
+ * @param name - The function name.
834
+ * @param renderer - The renderer function.
835
+ */
778
836
  add(name, renderer) {
779
837
  this.renderers.set(name, renderer);
780
838
  }
839
+ /**
840
+ * @inheritDoc
841
+ */
781
842
  getRenderer(name) {
782
843
  return this.renderers.get(name);
783
844
  }
845
+ /**
846
+ * Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
847
+ * @param ctx - The function render context.
848
+ * @returns The rendered SQL string.
849
+ */
784
850
  renderGroupConcat(ctx) {
785
851
  const arg = ctx.compiledArgs[0];
786
852
  const orderClause = this.buildOrderByExpression(ctx);
@@ -788,6 +854,11 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
788
854
  const separatorClause = this.formatGroupConcatSeparator(ctx);
789
855
  return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
790
856
  }
857
+ /**
858
+ * Builds the ORDER BY clause for functions like GROUP_CONCAT.
859
+ * @param ctx - The function render context.
860
+ * @returns The ORDER BY SQL clause or empty string.
861
+ */
791
862
  buildOrderByExpression(ctx) {
792
863
  const orderBy = ctx.node.orderBy;
793
864
  if (!orderBy || orderBy.length === 0) {
@@ -803,16 +874,27 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
803
874
  });
804
875
  return `ORDER BY ${parts.join(", ")}`;
805
876
  }
877
+ /**
878
+ * Formats the SEPARATOR clause for GROUP_CONCAT.
879
+ * @param ctx - The function render context.
880
+ * @returns The SEPARATOR SQL clause or empty string.
881
+ */
806
882
  formatGroupConcatSeparator(ctx) {
807
883
  if (!ctx.node.separator) {
808
884
  return "";
809
885
  }
810
886
  return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
811
887
  }
888
+ /**
889
+ * Gets the separator operand for GROUP_CONCAT, defaulting to comma.
890
+ * @param ctx - The function render context.
891
+ * @returns The separator operand.
892
+ */
812
893
  getGroupConcatSeparatorOperand(ctx) {
813
894
  return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
814
895
  }
815
896
  static {
897
+ /** Default separator for GROUP_CONCAT, a comma. */
816
898
  this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
817
899
  type: "Literal",
818
900
  value: ","
@@ -2333,7 +2415,7 @@ var SelectQueryState = class _SelectQueryState {
2333
2415
  this.table = table;
2334
2416
  this.ast = ast ?? {
2335
2417
  type: "SelectQuery",
2336
- from: { type: "Table", name: table.name },
2418
+ from: createTableNode(table),
2337
2419
  columns: [],
2338
2420
  joins: []
2339
2421
  };
@@ -2484,10 +2566,18 @@ var SelectQueryState = class _SelectQueryState {
2484
2566
  var createJoinNode = (kind, tableName, condition, relationName) => ({
2485
2567
  type: "Join",
2486
2568
  kind,
2487
- table: typeof tableName === "string" ? { type: "Table", name: tableName } : tableName,
2569
+ table: typeof tableName === "string" ? parseQualifiedTableRef(tableName) : tableName,
2488
2570
  condition,
2489
2571
  meta: relationName ? { relationName } : void 0
2490
2572
  });
2573
+ var parseQualifiedTableRef = (ref) => {
2574
+ const parts = ref.split(".");
2575
+ if (parts.length === 2) {
2576
+ const [schema, name] = parts;
2577
+ return { type: "Table", schema, name };
2578
+ }
2579
+ return { type: "Table", name: ref };
2580
+ };
2491
2581
 
2492
2582
  // src/query-builder/hydration-manager.ts
2493
2583
  var HydrationManager = class _HydrationManager {
@@ -2574,6 +2664,11 @@ var HydrationManager = class _HydrationManager {
2574
2664
  const hasPagination = ast.limit !== void 0 || ast.offset !== void 0;
2575
2665
  return hasPagination && this.hasMultiplyingRelations(plan);
2576
2666
  }
2667
+ /**
2668
+ * Checks if the hydration plan contains relations that multiply rows
2669
+ * @param plan - Hydration plan to check
2670
+ * @returns True if plan has HasMany or BelongsToMany relations
2671
+ */
2577
2672
  hasMultiplyingRelations(plan) {
2578
2673
  return plan.relations.some(
2579
2674
  (rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany
@@ -2651,6 +2746,12 @@ var HydrationManager = class _HydrationManager {
2651
2746
  ctes: [...ast.ctes ?? [], baseCte, pageCte]
2652
2747
  };
2653
2748
  }
2749
+ /**
2750
+ * Generates a unique CTE name by appending a suffix if needed
2751
+ * @param existing - Existing CTE nodes
2752
+ * @param baseName - Base name for the CTE
2753
+ * @returns Unique CTE name
2754
+ */
2654
2755
  nextCteName(existing, baseName) {
2655
2756
  const names = new Set((existing ?? []).map((cte) => cte.name));
2656
2757
  let candidate = baseName;
@@ -2661,6 +2762,11 @@ var HydrationManager = class _HydrationManager {
2661
2762
  }
2662
2763
  return candidate;
2663
2764
  }
2765
+ /**
2766
+ * Extracts projection names from column nodes
2767
+ * @param columns - Projection nodes
2768
+ * @returns Array of names or undefined if any column lacks name/alias
2769
+ */
2664
2770
  getProjectionNames(columns) {
2665
2771
  const names = [];
2666
2772
  for (const col2 of columns) {
@@ -2671,6 +2777,11 @@ var HydrationManager = class _HydrationManager {
2671
2777
  }
2672
2778
  return names;
2673
2779
  }
2780
+ /**
2781
+ * Builds a map of column keys to their aliases from projection nodes
2782
+ * @param columns - Projection nodes
2783
+ * @returns Map of 'table.name' to alias
2784
+ */
2674
2785
  buildProjectionAliasMap(columns) {
2675
2786
  const map = /* @__PURE__ */ new Map();
2676
2787
  for (const col2 of columns) {
@@ -2681,6 +2792,15 @@ var HydrationManager = class _HydrationManager {
2681
2792
  }
2682
2793
  return map;
2683
2794
  }
2795
+ /**
2796
+ * Maps order by nodes to use base CTE alias
2797
+ * @param orderBy - Original order by nodes
2798
+ * @param plan - Hydration plan
2799
+ * @param projectionAliases - Map of column aliases
2800
+ * @param baseAlias - Base CTE alias
2801
+ * @param availableColumns - Set of available column names
2802
+ * @returns Mapped order by nodes, null if cannot map
2803
+ */
2684
2804
  mapOrderBy(orderBy, plan, projectionAliases, baseAlias, availableColumns) {
2685
2805
  if (!orderBy || orderBy.length === 0) {
2686
2806
  return void 0;
@@ -2693,6 +2813,15 @@ var HydrationManager = class _HydrationManager {
2693
2813
  }
2694
2814
  return mapped;
2695
2815
  }
2816
+ /**
2817
+ * Maps a single ordering term to use base CTE alias
2818
+ * @param term - Ordering term to map
2819
+ * @param plan - Hydration plan
2820
+ * @param projectionAliases - Map of column aliases
2821
+ * @param baseAlias - Base CTE alias
2822
+ * @param availableColumns - Set of available column names
2823
+ * @returns Mapped term or null if cannot map
2824
+ */
2696
2825
  mapOrderingTerm(term, plan, projectionAliases, baseAlias, availableColumns) {
2697
2826
  if (term.type === "Column") {
2698
2827
  const col2 = term;
@@ -2708,6 +2837,13 @@ var HydrationManager = class _HydrationManager {
2708
2837
  }
2709
2838
  return null;
2710
2839
  }
2840
+ /**
2841
+ * Builds column nodes for paging CTE
2842
+ * @param primaryKey - Primary key name
2843
+ * @param orderBy - Order by nodes
2844
+ * @param tableAlias - Table alias for columns
2845
+ * @returns Array of column nodes for paging
2846
+ */
2711
2847
  buildPagingColumns(primaryKey, orderBy, tableAlias) {
2712
2848
  const columns = [{ type: "Column", table: tableAlias, name: primaryKey, alias: primaryKey }];
2713
2849
  if (!orderBy) return columns;
@@ -3080,6 +3216,11 @@ var QueryAstService = class {
3080
3216
  combineExpressions(existing, next) {
3081
3217
  return existing ? and(existing, next) : next;
3082
3218
  }
3219
+ /**
3220
+ * Normalizes an ordering term to a standard OrderingTerm
3221
+ * @param term - Column definition or ordering term to normalize
3222
+ * @returns Normalized ordering term
3223
+ */
3083
3224
  normalizeOrderingTerm(term) {
3084
3225
  const from = this.state.ast.from;
3085
3226
  const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
@@ -3196,7 +3337,11 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
3196
3337
  { type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToRoot },
3197
3338
  { type: "Column", table: rootTable, name: rootKey }
3198
3339
  );
3199
- const pivotJoin = createJoinNode(joinKind, relation.pivotTable.name, pivotCondition);
3340
+ const pivotJoin = createJoinNode(
3341
+ joinKind,
3342
+ { type: "Table", name: relation.pivotTable.name, schema: relation.pivotTable.schema },
3343
+ pivotCondition
3344
+ );
3200
3345
  let targetCondition = eq(
3201
3346
  { type: "Column", table: relation.target.name, name: targetKey },
3202
3347
  { type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToTarget }
@@ -3206,7 +3351,7 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
3206
3351
  }
3207
3352
  const targetJoin = createJoinNode(
3208
3353
  joinKind,
3209
- relation.target.name,
3354
+ { type: "Table", name: relation.target.name, schema: relation.target.schema },
3210
3355
  targetCondition,
3211
3356
  relationName
3212
3357
  );
@@ -3384,7 +3529,12 @@ var RelationService = class {
3384
3529
  return joins.reduce((current, join) => this.astService(current).withJoin(join), state);
3385
3530
  }
3386
3531
  const condition = buildRelationJoinCondition(this.table, relation, extraCondition, rootAlias);
3387
- const joinNode = createJoinNode(joinKind, relation.target.name, condition, relationName);
3532
+ const joinNode = createJoinNode(
3533
+ joinKind,
3534
+ { type: "Table", name: relation.target.name, schema: relation.target.schema },
3535
+ condition,
3536
+ relationName
3537
+ );
3388
3538
  return this.astService(state).withJoin(joinNode);
3389
3539
  }
3390
3540
  /**
@@ -3429,25 +3579,6 @@ var RelationService = class {
3429
3579
  }
3430
3580
  };
3431
3581
 
3432
- // src/query-builder/select-query-builder-deps.ts
3433
- var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
3434
- var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
3435
- var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
3436
- var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
3437
- const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
3438
- const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
3439
- const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
3440
- const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
3441
- return {
3442
- createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
3443
- createHydration,
3444
- createHydrationPlanner,
3445
- createQueryAstService,
3446
- createRelationService
3447
- };
3448
- };
3449
- var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
3450
-
3451
3582
  // src/query-builder/column-selector.ts
3452
3583
  var ColumnSelector = class {
3453
3584
  /**
@@ -3573,6 +3704,29 @@ var RelationManager = class {
3573
3704
  }
3574
3705
  };
3575
3706
 
3707
+ // src/query-builder/select-query-builder-deps.ts
3708
+ var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
3709
+ var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
3710
+ var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
3711
+ var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
3712
+ const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
3713
+ const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
3714
+ const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
3715
+ const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
3716
+ const createColumnSelector = overrides.createColumnSelector ?? ((env) => new ColumnSelector(env));
3717
+ const createRelationManager = overrides.createRelationManager ?? ((env) => new RelationManager(env));
3718
+ return {
3719
+ createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
3720
+ createHydration,
3721
+ createHydrationPlanner,
3722
+ createQueryAstService,
3723
+ createRelationService,
3724
+ createColumnSelector,
3725
+ createRelationManager
3726
+ };
3727
+ };
3728
+ var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
3729
+
3576
3730
  // src/orm/hydration.ts
3577
3731
  var hydrateRows = (rows, plan) => {
3578
3732
  if (!plan || !rows.length) return rows;
@@ -3698,6 +3852,18 @@ var hideInternal = (obj, keys) => {
3698
3852
  }
3699
3853
  };
3700
3854
  var DefaultHasManyCollection = class {
3855
+ /**
3856
+ * Creates a new DefaultHasManyCollection instance.
3857
+ * @param ctx - The entity context
3858
+ * @param meta - The entity metadata
3859
+ * @param root - The root entity
3860
+ * @param relationName - The relation name
3861
+ * @param relation - The relation definition
3862
+ * @param rootTable - The root table definition
3863
+ * @param loader - The loader function for lazy loading
3864
+ * @param createEntity - Function to create entities from rows
3865
+ * @param localKey - The local key for the relation
3866
+ */
3701
3867
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
3702
3868
  this.ctx = ctx;
3703
3869
  this.meta = meta;
@@ -3715,6 +3881,10 @@ var DefaultHasManyCollection = class {
3715
3881
  hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
3716
3882
  this.hydrateFromCache();
3717
3883
  }
3884
+ /**
3885
+ * Loads the related entities if not already loaded.
3886
+ * @returns Promise resolving to the array of child entities
3887
+ */
3718
3888
  async load() {
3719
3889
  if (this.loaded) return this.items;
3720
3890
  const map = await this.loader();
@@ -3724,9 +3894,18 @@ var DefaultHasManyCollection = class {
3724
3894
  this.loaded = true;
3725
3895
  return this.items;
3726
3896
  }
3897
+ /**
3898
+ * Gets the current items in the collection.
3899
+ * @returns Array of child entities
3900
+ */
3727
3901
  getItems() {
3728
3902
  return this.items;
3729
3903
  }
3904
+ /**
3905
+ * Adds a new child entity to the collection.
3906
+ * @param data - Partial data for the new entity
3907
+ * @returns The created entity
3908
+ */
3730
3909
  add(data) {
3731
3910
  const keyValue = this.root[this.localKey];
3732
3911
  const childRow = {
@@ -3746,6 +3925,10 @@ var DefaultHasManyCollection = class {
3746
3925
  );
3747
3926
  return entity;
3748
3927
  }
3928
+ /**
3929
+ * Attaches an existing entity to the collection.
3930
+ * @param entity - The entity to attach
3931
+ */
3749
3932
  attach(entity) {
3750
3933
  const keyValue = this.root[this.localKey];
3751
3934
  entity[this.relation.foreignKey] = keyValue;
@@ -3760,6 +3943,10 @@ var DefaultHasManyCollection = class {
3760
3943
  { kind: "attach", entity }
3761
3944
  );
3762
3945
  }
3946
+ /**
3947
+ * Removes an entity from the collection.
3948
+ * @param entity - The entity to remove
3949
+ */
3763
3950
  remove(entity) {
3764
3951
  this.items = this.items.filter((item) => item !== entity);
3765
3952
  this.removed.add(entity);
@@ -3772,6 +3959,9 @@ var DefaultHasManyCollection = class {
3772
3959
  { kind: "remove", entity }
3773
3960
  );
3774
3961
  }
3962
+ /**
3963
+ * Clears all entities from the collection.
3964
+ */
3775
3965
  clear() {
3776
3966
  for (const entity of [...this.items]) {
3777
3967
  this.remove(entity);
@@ -3788,6 +3978,10 @@ var DefaultHasManyCollection = class {
3788
3978
  this.items = rows.map((row) => this.createEntity(row));
3789
3979
  this.loaded = true;
3790
3980
  }
3981
+ /**
3982
+ * Returns the items for JSON serialization.
3983
+ * @returns Array of child entities
3984
+ */
3791
3985
  toJSON() {
3792
3986
  return this.items;
3793
3987
  }
@@ -4163,112 +4357,92 @@ var executeQuery = async (ctx, qb) => {
4163
4357
  return rowsFromResults(results);
4164
4358
  };
4165
4359
  var toKey6 = (value) => value === null || value === void 0 ? "" : String(value);
4166
- var loadHasManyRelation = async (ctx, rootTable, _relationName, relation) => {
4167
- const localKey = relation.localKey || findPrimaryKey(rootTable);
4168
- const roots = ctx.getEntitiesForTable(rootTable);
4169
- const keys = /* @__PURE__ */ new Set();
4360
+ var collectKeysFromRoots = (roots, key) => {
4361
+ const collected = /* @__PURE__ */ new Set();
4170
4362
  for (const tracked of roots) {
4171
- const value = tracked.entity[localKey];
4363
+ const value = tracked.entity[key];
4172
4364
  if (value !== null && value !== void 0) {
4173
- keys.add(value);
4365
+ collected.add(value);
4174
4366
  }
4175
4367
  }
4176
- if (!keys.size) {
4177
- return /* @__PURE__ */ new Map();
4178
- }
4179
- const selectMap = selectAllColumns(relation.target);
4180
- const fb = new SelectQueryBuilder(relation.target).select(selectMap);
4181
- const fkColumn = relation.target.columns[relation.foreignKey];
4182
- if (!fkColumn) return /* @__PURE__ */ new Map();
4183
- fb.where(inList(fkColumn, Array.from(keys)));
4184
- const rows = await executeQuery(ctx, fb);
4368
+ return collected;
4369
+ };
4370
+ var buildInListValues = (keys) => Array.from(keys);
4371
+ var fetchRowsForKeys = async (ctx, table, column, keys) => {
4372
+ const qb = new SelectQueryBuilder(table).select(selectAllColumns(table));
4373
+ qb.where(inList(column, buildInListValues(keys)));
4374
+ return executeQuery(ctx, qb);
4375
+ };
4376
+ var groupRowsByMany = (rows, keyColumn) => {
4185
4377
  const grouped = /* @__PURE__ */ new Map();
4186
4378
  for (const row of rows) {
4187
- const fkValue = row[relation.foreignKey];
4188
- if (fkValue === null || fkValue === void 0) continue;
4189
- const key = toKey6(fkValue);
4379
+ const value = row[keyColumn];
4380
+ if (value === null || value === void 0) continue;
4381
+ const key = toKey6(value);
4190
4382
  const bucket = grouped.get(key) ?? [];
4191
4383
  bucket.push(row);
4192
4384
  grouped.set(key, bucket);
4193
4385
  }
4194
4386
  return grouped;
4195
4387
  };
4196
- var loadHasOneRelation = async (ctx, rootTable, _relationName, relation) => {
4197
- const localKey = relation.localKey || findPrimaryKey(rootTable);
4198
- const roots = ctx.getEntitiesForTable(rootTable);
4199
- const keys = /* @__PURE__ */ new Set();
4200
- for (const tracked of roots) {
4201
- const value = tracked.entity[localKey];
4202
- if (value !== null && value !== void 0) {
4203
- keys.add(value);
4388
+ var groupRowsByUnique = (rows, keyColumn) => {
4389
+ const lookup = /* @__PURE__ */ new Map();
4390
+ for (const row of rows) {
4391
+ const value = row[keyColumn];
4392
+ if (value === null || value === void 0) continue;
4393
+ const key = toKey6(value);
4394
+ if (!lookup.has(key)) {
4395
+ lookup.set(key, row);
4204
4396
  }
4205
4397
  }
4398
+ return lookup;
4399
+ };
4400
+ var loadHasManyRelation = async (ctx, rootTable, _relationName, relation) => {
4401
+ const localKey = relation.localKey || findPrimaryKey(rootTable);
4402
+ const roots = ctx.getEntitiesForTable(rootTable);
4403
+ const keys = collectKeysFromRoots(roots, localKey);
4206
4404
  if (!keys.size) {
4207
4405
  return /* @__PURE__ */ new Map();
4208
4406
  }
4209
- const selectMap = selectAllColumns(relation.target);
4210
- const qb = new SelectQueryBuilder(relation.target).select(selectMap);
4211
4407
  const fkColumn = relation.target.columns[relation.foreignKey];
4212
4408
  if (!fkColumn) return /* @__PURE__ */ new Map();
4213
- qb.where(inList(fkColumn, Array.from(keys)));
4214
- const rows = await executeQuery(ctx, qb);
4215
- const lookup = /* @__PURE__ */ new Map();
4216
- for (const row of rows) {
4217
- const fkValue = row[relation.foreignKey];
4218
- if (fkValue === null || fkValue === void 0) continue;
4219
- const key = toKey6(fkValue);
4220
- if (!lookup.has(key)) {
4221
- lookup.set(key, row);
4222
- }
4409
+ const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
4410
+ return groupRowsByMany(rows, relation.foreignKey);
4411
+ };
4412
+ var loadHasOneRelation = async (ctx, rootTable, _relationName, relation) => {
4413
+ const localKey = relation.localKey || findPrimaryKey(rootTable);
4414
+ const roots = ctx.getEntitiesForTable(rootTable);
4415
+ const keys = collectKeysFromRoots(roots, localKey);
4416
+ if (!keys.size) {
4417
+ return /* @__PURE__ */ new Map();
4223
4418
  }
4224
- return lookup;
4419
+ const fkColumn = relation.target.columns[relation.foreignKey];
4420
+ if (!fkColumn) return /* @__PURE__ */ new Map();
4421
+ const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
4422
+ return groupRowsByUnique(rows, relation.foreignKey);
4225
4423
  };
4226
4424
  var loadBelongsToRelation = async (ctx, rootTable, _relationName, relation) => {
4227
4425
  const roots = ctx.getEntitiesForTable(rootTable);
4228
- const foreignKeys = /* @__PURE__ */ new Set();
4229
- for (const tracked of roots) {
4230
- const value = tracked.entity[relation.foreignKey];
4231
- if (value !== null && value !== void 0) {
4232
- foreignKeys.add(value);
4233
- }
4234
- }
4426
+ const foreignKeys = collectKeysFromRoots(roots, relation.foreignKey);
4235
4427
  if (!foreignKeys.size) {
4236
4428
  return /* @__PURE__ */ new Map();
4237
4429
  }
4238
- const selectMap = selectAllColumns(relation.target);
4239
- const qb = new SelectQueryBuilder(relation.target).select(selectMap);
4240
4430
  const targetKey = relation.localKey || findPrimaryKey(relation.target);
4241
4431
  const pkColumn = relation.target.columns[targetKey];
4242
4432
  if (!pkColumn) return /* @__PURE__ */ new Map();
4243
- qb.where(inList(pkColumn, Array.from(foreignKeys)));
4244
- const rows = await executeQuery(ctx, qb);
4245
- const map = /* @__PURE__ */ new Map();
4246
- for (const row of rows) {
4247
- const keyValue = row[targetKey];
4248
- if (keyValue === null || keyValue === void 0) continue;
4249
- map.set(toKey6(keyValue), row);
4250
- }
4251
- return map;
4433
+ const rows = await fetchRowsForKeys(ctx, relation.target, pkColumn, foreignKeys);
4434
+ return groupRowsByUnique(rows, targetKey);
4252
4435
  };
4253
4436
  var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation) => {
4254
4437
  const rootKey = relation.localKey || findPrimaryKey(rootTable);
4255
4438
  const roots = ctx.getEntitiesForTable(rootTable);
4256
- const rootIds = /* @__PURE__ */ new Set();
4257
- for (const tracked of roots) {
4258
- const value = tracked.entity[rootKey];
4259
- if (value !== null && value !== void 0) {
4260
- rootIds.add(value);
4261
- }
4262
- }
4439
+ const rootIds = collectKeysFromRoots(roots, rootKey);
4263
4440
  if (!rootIds.size) {
4264
4441
  return /* @__PURE__ */ new Map();
4265
4442
  }
4266
- const pivotSelect = selectAllColumns(relation.pivotTable);
4267
- const pivotQb = new SelectQueryBuilder(relation.pivotTable).select(pivotSelect);
4268
- const pivotFkCol = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
4269
- if (!pivotFkCol) return /* @__PURE__ */ new Map();
4270
- pivotQb.where(inList(pivotFkCol, Array.from(rootIds)));
4271
- const pivotRows = await executeQuery(ctx, pivotQb);
4443
+ const pivotColumn = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
4444
+ if (!pivotColumn) return /* @__PURE__ */ new Map();
4445
+ const pivotRows = await fetchRowsForKeys(ctx, relation.pivotTable, pivotColumn, rootIds);
4272
4446
  const rootLookup = /* @__PURE__ */ new Map();
4273
4447
  const targetIds = /* @__PURE__ */ new Set();
4274
4448
  for (const pivot of pivotRows) {
@@ -4288,19 +4462,11 @@ var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation)
4288
4462
  if (!targetIds.size) {
4289
4463
  return /* @__PURE__ */ new Map();
4290
4464
  }
4291
- const targetSelect = selectAllColumns(relation.target);
4292
4465
  const targetKey = relation.targetKey || findPrimaryKey(relation.target);
4293
4466
  const targetPkColumn = relation.target.columns[targetKey];
4294
4467
  if (!targetPkColumn) return /* @__PURE__ */ new Map();
4295
- const targetQb = new SelectQueryBuilder(relation.target).select(targetSelect);
4296
- targetQb.where(inList(targetPkColumn, Array.from(targetIds)));
4297
- const targetRows = await executeQuery(ctx, targetQb);
4298
- const targetMap = /* @__PURE__ */ new Map();
4299
- for (const row of targetRows) {
4300
- const pkValue = row[targetKey];
4301
- if (pkValue === null || pkValue === void 0) continue;
4302
- targetMap.set(toKey6(pkValue), row);
4303
- }
4468
+ const targetRows = await fetchRowsForKeys(ctx, relation.target, targetPkColumn, targetIds);
4469
+ const targetMap = groupRowsByUnique(targetRows, targetKey);
4304
4470
  const result = /* @__PURE__ */ new Map();
4305
4471
  for (const [rootId, entries] of rootLookup.entries()) {
4306
4472
  const bucket = [];
@@ -4577,21 +4743,21 @@ async function executeHydratedWithContexts(_execCtx, hydCtx, qb) {
4577
4743
  return executeWithEntityContext(entityCtx, qb);
4578
4744
  }
4579
4745
 
4746
+ // src/query-builder/query-resolution.ts
4747
+ function resolveSelectQuery(query) {
4748
+ const candidate = query;
4749
+ return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
4750
+ }
4751
+
4580
4752
  // src/query-builder/select.ts
4581
4753
  var SelectQueryBuilder = class _SelectQueryBuilder {
4582
4754
  /**
4583
-
4584
- * Creates a new SelectQueryBuilder instance
4585
-
4586
- * @param table - Table definition to query
4587
-
4588
- * @param state - Optional initial query state
4589
-
4590
- * @param hydration - Optional hydration manager
4591
-
4592
- * @param dependencies - Optional query builder dependencies
4593
-
4594
- */
4755
+ * Creates a new SelectQueryBuilder instance
4756
+ * @param table - Table definition to query
4757
+ * @param state - Optional initial query state
4758
+ * @param hydration - Optional hydration manager
4759
+ * @param dependencies - Optional query builder dependencies
4760
+ */
4595
4761
  constructor(table, state, hydration, dependencies, lazyRelations) {
4596
4762
  const deps = resolveSelectQueryBuilderDependencies(dependencies);
4597
4763
  this.env = { table, deps };
@@ -4602,9 +4768,15 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4602
4768
  hydration: initialHydration
4603
4769
  };
4604
4770
  this.lazyRelations = new Set(lazyRelations ?? []);
4605
- this.columnSelector = new ColumnSelector(this.env);
4606
- this.relationManager = new RelationManager(this.env);
4771
+ this.columnSelector = deps.createColumnSelector(this.env);
4772
+ this.relationManager = deps.createRelationManager(this.env);
4607
4773
  }
4774
+ /**
4775
+ * Creates a new SelectQueryBuilder instance with updated context and lazy relations
4776
+ * @param context - Updated query context
4777
+ * @param lazyRelations - Updated lazy relations set
4778
+ * @returns New SelectQueryBuilder instance
4779
+ */
4608
4780
  clone(context = this.context, lazyRelations = new Set(this.lazyRelations)) {
4609
4781
  return new _SelectQueryBuilder(this.env.table, context.state, context.hydration, this.env.deps, lazyRelations);
4610
4782
  }
@@ -4621,10 +4793,12 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4621
4793
  const nextContext = this.applyAst(this.context, (service) => service.withFrom(nextFrom));
4622
4794
  return this.clone(nextContext);
4623
4795
  }
4624
- resolveQueryNode(query) {
4625
- const candidate = query;
4626
- return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
4627
- }
4796
+ /**
4797
+ * Applies correlation expression to the query AST
4798
+ * @param ast - Query AST to modify
4799
+ * @param correlation - Correlation expression
4800
+ * @returns Modified AST with correlation applied
4801
+ */
4628
4802
  applyCorrelation(ast, correlation) {
4629
4803
  if (!correlation) return ast;
4630
4804
  const combinedWhere = ast.where ? and(correlation, ast.where) : correlation;
@@ -4633,39 +4807,53 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4633
4807
  where: combinedWhere
4634
4808
  };
4635
4809
  }
4810
+ /**
4811
+ * Creates a new child query builder for a related table
4812
+ * @param table - Table definition for the child builder
4813
+ * @returns New SelectQueryBuilder instance for the child table
4814
+ */
4636
4815
  createChildBuilder(table) {
4637
4816
  return new _SelectQueryBuilder(table, void 0, void 0, this.env.deps);
4638
4817
  }
4818
+ /**
4819
+ * Applies an AST mutation using the query AST service
4820
+ * @param context - Current query context
4821
+ * @param mutator - Function that mutates the AST
4822
+ * @returns Updated query context
4823
+ */
4639
4824
  applyAst(context, mutator) {
4640
4825
  const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
4641
4826
  const nextState = mutator(astService);
4642
4827
  return { state: nextState, hydration: context.hydration };
4643
4828
  }
4829
+ /**
4830
+ * Applies a join to the query context
4831
+ * @param context - Current query context
4832
+ * @param table - Table to join
4833
+ * @param condition - Join condition
4834
+ * @param kind - Join kind
4835
+ * @returns Updated query context with join applied
4836
+ */
4644
4837
  applyJoin(context, table, condition, kind) {
4645
- const joinNode = createJoinNode(kind, table.name, condition);
4838
+ const joinNode = createJoinNode(kind, { type: "Table", name: table.name, schema: table.schema }, condition);
4646
4839
  return this.applyAst(context, (service) => service.withJoin(joinNode));
4647
4840
  }
4841
+ /**
4842
+ * Applies a set operation to the query
4843
+ * @param operator - Set operation kind
4844
+ * @param query - Query to combine with
4845
+ * @returns Updated query context with set operation
4846
+ */
4648
4847
  applySetOperation(operator, query) {
4649
- const subAst = this.resolveQueryNode(query);
4848
+ const subAst = resolveSelectQuery(query);
4650
4849
  return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
4651
4850
  }
4652
- /**
4653
-
4654
- * Selects specific columns for the query
4655
-
4656
- * @param columns - Record of column definitions, function nodes, case expressions, or window functions
4657
-
4658
- * @returns New query builder instance with selected columns
4659
-
4660
- */
4661
- select(columns) {
4662
- return this.clone(this.columnSelector.select(this.context, columns));
4663
- }
4664
- /**
4665
- * Selects columns from the root table by name (typed).
4666
- * @param cols - Column names on the root table
4667
- */
4668
- selectColumns(...cols) {
4851
+ select(...args) {
4852
+ if (args.length === 1 && typeof args[0] === "object" && args[0] !== null && typeof args[0] !== "string") {
4853
+ const columns = args[0];
4854
+ return this.clone(this.columnSelector.select(this.context, columns));
4855
+ }
4856
+ const cols = args;
4669
4857
  const selection = {};
4670
4858
  for (const key of cols) {
4671
4859
  const col2 = this.env.table.columns[key];
@@ -4674,53 +4862,37 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4674
4862
  }
4675
4863
  selection[key] = col2;
4676
4864
  }
4677
- return this.select(selection);
4865
+ return this.clone(this.columnSelector.select(this.context, selection));
4678
4866
  }
4679
4867
  /**
4680
-
4681
- * Selects raw column expressions
4682
-
4683
- * @param cols - Column expressions as strings
4684
-
4685
- * @returns New query builder instance with raw column selections
4686
-
4687
- */
4868
+ * Selects raw column expressions
4869
+ * @param cols - Column expressions as strings
4870
+ * @returns New query builder instance with raw column selections
4871
+ */
4688
4872
  selectRaw(...cols) {
4689
4873
  return this.clone(this.columnSelector.selectRaw(this.context, cols));
4690
4874
  }
4691
4875
  /**
4692
-
4693
- * Adds a Common Table Expression (CTE) to the query
4694
-
4695
- * @param name - Name of the CTE
4696
-
4697
- * @param query - Query builder or query node for the CTE
4698
-
4699
- * @param columns - Optional column names for the CTE
4700
-
4701
- * @returns New query builder instance with the CTE
4702
-
4703
- */
4876
+ * Adds a Common Table Expression (CTE) to the query
4877
+ * @param name - Name of the CTE
4878
+ * @param query - Query builder or query node for the CTE
4879
+ * @param columns - Optional column names for the CTE
4880
+ * @returns New query builder instance with the CTE
4881
+ */
4704
4882
  with(name, query, columns) {
4705
- const subAst = this.resolveQueryNode(query);
4883
+ const subAst = resolveSelectQuery(query);
4706
4884
  const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, false));
4707
4885
  return this.clone(nextContext);
4708
4886
  }
4709
4887
  /**
4710
-
4711
- * Adds a recursive Common Table Expression (CTE) to the query
4712
-
4713
- * @param name - Name of the CTE
4714
-
4715
- * @param query - Query builder or query node for the CTE
4716
-
4717
- * @param columns - Optional column names for the CTE
4718
-
4719
- * @returns New query builder instance with the recursive CTE
4720
-
4721
- */
4888
+ * Adds a recursive Common Table Expression (CTE) to the query
4889
+ * @param name - Name of the CTE
4890
+ * @param query - Query builder or query node for the CTE
4891
+ * @param columns - Optional column names for the CTE
4892
+ * @returns New query builder instance with the recursive CTE
4893
+ */
4722
4894
  withRecursive(name, query, columns) {
4723
- const subAst = this.resolveQueryNode(query);
4895
+ const subAst = resolveSelectQuery(query);
4724
4896
  const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
4725
4897
  return this.clone(nextContext);
4726
4898
  }
@@ -4732,24 +4904,31 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4732
4904
  * @returns New query builder instance with updated FROM
4733
4905
  */
4734
4906
  fromSubquery(subquery, alias, columnAliases) {
4735
- const subAst = this.resolveQueryNode(subquery);
4907
+ const subAst = resolveSelectQuery(subquery);
4736
4908
  const fromNode = derivedTable(subAst, alias, columnAliases);
4737
4909
  const nextContext = this.applyAst(this.context, (service) => service.withFrom(fromNode));
4738
4910
  return this.clone(nextContext);
4739
4911
  }
4740
4912
  /**
4741
-
4742
- * Selects a subquery as a column
4743
-
4744
- * @param alias - Alias for the subquery column
4745
-
4746
- * @param sub - Query builder or query node for the subquery
4747
-
4748
- * @returns New query builder instance with the subquery selection
4749
-
4750
- */
4913
+ * Replaces the FROM clause with a function table expression.
4914
+ * @param name - Function name
4915
+ * @param args - Optional function arguments
4916
+ * @param alias - Optional alias for the function table
4917
+ * @param options - Optional function-table metadata (lateral, ordinality, column aliases, schema)
4918
+ */
4919
+ fromFunctionTable(name, args = [], alias, options) {
4920
+ const functionTable = fnTable(name, args, alias, options);
4921
+ const nextContext = this.applyAst(this.context, (service) => service.withFrom(functionTable));
4922
+ return this.clone(nextContext);
4923
+ }
4924
+ /**
4925
+ * Selects a subquery as a column
4926
+ * @param alias - Alias for the subquery column
4927
+ * @param sub - Query builder or query node for the subquery
4928
+ * @returns New query builder instance with the subquery selection
4929
+ */
4751
4930
  selectSubquery(alias, sub2) {
4752
- const query = this.resolveQueryNode(sub2);
4931
+ const query = resolveSelectQuery(sub2);
4753
4932
  return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
4754
4933
  }
4755
4934
  /**
@@ -4762,103 +4941,92 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4762
4941
  * @returns New query builder instance with the derived-table join
4763
4942
  */
4764
4943
  joinSubquery(subquery, alias, condition, joinKind = JOIN_KINDS.INNER, columnAliases) {
4765
- const subAst = this.resolveQueryNode(subquery);
4944
+ const subAst = resolveSelectQuery(subquery);
4766
4945
  const joinNode = createJoinNode(joinKind, derivedTable(subAst, alias, columnAliases), condition);
4767
4946
  const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
4768
4947
  return this.clone(nextContext);
4769
4948
  }
4770
4949
  /**
4771
-
4772
- * Adds an INNER JOIN to the query
4773
-
4774
- * @param table - Table to join
4775
-
4776
- * @param condition - Join condition expression
4777
-
4778
- * @returns New query builder instance with the INNER JOIN
4779
-
4780
- */
4950
+ * Adds a join against a function table (e.g., `generate_series`) using `fnTable` internally.
4951
+ * @param name - Function name
4952
+ * @param args - Optional arguments passed to the function
4953
+ * @param alias - Alias for the function table so columns can be referenced
4954
+ * @param condition - Join condition expression
4955
+ * @param joinKind - Kind of join (defaults to INNER)
4956
+ * @param options - Optional metadata (lateral, ordinality, column aliases, schema)
4957
+ */
4958
+ joinFunctionTable(name, args = [], alias, condition, joinKind = JOIN_KINDS.INNER, options) {
4959
+ const functionTable = fnTable(name, args, alias, options);
4960
+ const joinNode = createJoinNode(joinKind, functionTable, condition);
4961
+ const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
4962
+ return this.clone(nextContext);
4963
+ }
4964
+ /**
4965
+ * Adds an INNER JOIN to the query
4966
+ * @param table - Table to join
4967
+ * @param condition - Join condition expression
4968
+ * @returns New query builder instance with the INNER JOIN
4969
+ */
4781
4970
  innerJoin(table, condition) {
4782
4971
  const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
4783
4972
  return this.clone(nextContext);
4784
4973
  }
4785
4974
  /**
4786
-
4787
- * Adds a LEFT JOIN to the query
4788
-
4789
- * @param table - Table to join
4790
-
4791
- * @param condition - Join condition expression
4792
-
4793
- * @returns New query builder instance with the LEFT JOIN
4794
-
4795
- */
4975
+ * Adds a LEFT JOIN to the query
4976
+ * @param table - Table to join
4977
+ * @param condition - Join condition expression
4978
+ * @returns New query builder instance with the LEFT JOIN
4979
+ */
4796
4980
  leftJoin(table, condition) {
4797
4981
  const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
4798
4982
  return this.clone(nextContext);
4799
4983
  }
4800
4984
  /**
4801
-
4802
- * Adds a RIGHT JOIN to the query
4803
-
4804
- * @param table - Table to join
4805
-
4806
- * @param condition - Join condition expression
4807
-
4808
- * @returns New query builder instance with the RIGHT JOIN
4809
-
4810
- */
4985
+ * Adds a RIGHT JOIN to the query
4986
+ * @param table - Table to join
4987
+ * @param condition - Join condition expression
4988
+ * @returns New query builder instance with the RIGHT JOIN
4989
+ */
4811
4990
  rightJoin(table, condition) {
4812
4991
  const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
4813
4992
  return this.clone(nextContext);
4814
4993
  }
4815
4994
  /**
4816
-
4817
- * Matches records based on a relationship
4818
-
4819
- * @param relationName - Name of the relationship to match
4820
-
4821
- * @param predicate - Optional predicate expression
4822
-
4823
- * @returns New query builder instance with the relationship match
4824
-
4825
- */
4995
+ * Matches records based on a relationship
4996
+ * @param relationName - Name of the relationship to match
4997
+ * @param predicate - Optional predicate expression
4998
+ * @returns New query builder instance with the relationship match
4999
+ */
4826
5000
  match(relationName, predicate) {
4827
5001
  const nextContext = this.relationManager.match(this.context, relationName, predicate);
4828
5002
  return this.clone(nextContext);
4829
5003
  }
4830
5004
  /**
4831
-
4832
- * Joins a related table
4833
-
4834
- * @param relationName - Name of the relationship to join
4835
-
4836
- * @param joinKind - Type of join (defaults to INNER)
4837
-
4838
- * @param extraCondition - Optional additional join condition
4839
-
4840
- * @returns New query builder instance with the relationship join
4841
-
4842
- */
5005
+ * Joins a related table
5006
+ * @param relationName - Name of the relationship to join
5007
+ * @param joinKind - Type of join (defaults to INNER)
5008
+ * @param extraCondition - Optional additional join condition
5009
+ * @returns New query builder instance with the relationship join
5010
+ */
4843
5011
  joinRelation(relationName, joinKind = JOIN_KINDS.INNER, extraCondition) {
4844
5012
  const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
4845
5013
  return this.clone(nextContext);
4846
5014
  }
4847
5015
  /**
4848
-
4849
- * Includes related data in the query results
4850
-
4851
- * @param relationName - Name of the relationship to include
4852
-
4853
- * @param options - Optional include options
4854
-
4855
- * @returns New query builder instance with the relationship inclusion
4856
-
4857
- */
5016
+ * Includes related data in the query results
5017
+ * @param relationName - Name of the relationship to include
5018
+ * @param options - Optional include options
5019
+ * @returns New query builder instance with the relationship inclusion
5020
+ */
4858
5021
  include(relationName, options) {
4859
5022
  const nextContext = this.relationManager.include(this.context, relationName, options);
4860
5023
  return this.clone(nextContext);
4861
5024
  }
5025
+ /**
5026
+ * Includes a relation lazily in the query results
5027
+ * @param relationName - Name of the relation to include lazily
5028
+ * @returns New query builder instance with lazy relation inclusion
5029
+ */
4862
5030
  includeLazy(relationName) {
4863
5031
  const nextLazy = new Set(this.lazyRelations);
4864
5032
  nextLazy.add(relationName);
@@ -4889,43 +5057,57 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4889
5057
  return this.selectRelationColumns(relationName, ...cols);
4890
5058
  }
4891
5059
  /**
4892
- * Selects columns for the root table and relations from a single config object.
5060
+ * Selects columns for the root table and relations from an array of entries
5061
+ * @param config - Configuration array for deep column selection
5062
+ * @returns New query builder instance with deep column selections
4893
5063
  */
4894
5064
  selectColumnsDeep(config) {
4895
5065
  let currBuilder = this;
4896
- if (config.root?.length) {
4897
- currBuilder = currBuilder.selectColumns(...config.root);
4898
- }
4899
- for (const key of Object.keys(config)) {
4900
- if (key === "root") continue;
4901
- const relName = key;
4902
- const cols = config[relName];
4903
- if (!cols || !cols.length) continue;
4904
- currBuilder = currBuilder.selectRelationColumns(relName, ...cols);
5066
+ for (const entry of config) {
5067
+ if (entry.type === "root") {
5068
+ currBuilder = currBuilder.select(...entry.columns);
5069
+ } else {
5070
+ currBuilder = currBuilder.selectRelationColumns(entry.relationName, ...entry.columns);
5071
+ }
4905
5072
  }
4906
5073
  return currBuilder;
4907
5074
  }
5075
+ /**
5076
+ * Gets the list of lazy relations
5077
+ * @returns Array of lazy relation names
5078
+ */
4908
5079
  getLazyRelations() {
4909
5080
  return Array.from(this.lazyRelations);
4910
5081
  }
5082
+ /**
5083
+ * Gets the table definition for this query builder
5084
+ * @returns Table definition
5085
+ */
4911
5086
  getTable() {
4912
5087
  return this.env.table;
4913
5088
  }
5089
+ /**
5090
+ * Executes the query and returns hydrated results
5091
+ * @param ctx - ORM session context
5092
+ * @returns Promise of entity instances
5093
+ */
4914
5094
  async execute(ctx) {
4915
5095
  return executeHydrated(ctx, this);
4916
5096
  }
5097
+ /**
5098
+ * Executes the query with provided execution and hydration contexts
5099
+ * @param execCtx - Execution context
5100
+ * @param hydCtx - Hydration context
5101
+ * @returns Promise of entity instances
5102
+ */
4917
5103
  async executeWithContexts(execCtx, hydCtx) {
4918
5104
  return executeHydratedWithContexts(execCtx, hydCtx, this);
4919
5105
  }
4920
5106
  /**
4921
-
4922
- * Adds a WHERE condition to the query
4923
-
4924
- * @param expr - Expression for the WHERE clause
4925
-
4926
- * @returns New query builder instance with the WHERE condition
4927
-
4928
- */
5107
+ * Adds a WHERE condition to the query
5108
+ * @param expr - Expression for the WHERE clause
5109
+ * @returns New query builder instance with the WHERE condition
5110
+ */
4929
5111
  where(expr) {
4930
5112
  const nextContext = this.applyAst(this.context, (service) => service.withWhere(expr));
4931
5113
  return this.clone(nextContext);
@@ -4940,14 +5122,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4940
5122
  return this.clone(nextContext);
4941
5123
  }
4942
5124
  /**
4943
-
4944
- * Adds a HAVING condition to the query
4945
-
4946
- * @param expr - Expression for the HAVING clause
4947
-
4948
- * @returns New query builder instance with the HAVING condition
4949
-
4950
- */
5125
+ * Adds a HAVING condition to the query
5126
+ * @param expr - Expression for the HAVING clause
5127
+ * @returns New query builder instance with the HAVING condition
5128
+ */
4951
5129
  having(expr) {
4952
5130
  const nextContext = this.applyAst(this.context, (service) => service.withHaving(expr));
4953
5131
  return this.clone(nextContext);
@@ -4968,130 +5146,89 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4968
5146
  return this.clone(nextContext);
4969
5147
  }
4970
5148
  /**
4971
-
4972
- * Adds a DISTINCT clause to the query
4973
-
4974
- * @param cols - Columns to make distinct
4975
-
4976
- * @returns New query builder instance with the DISTINCT clause
4977
-
4978
- */
5149
+ * Adds a DISTINCT clause to the query
5150
+ * @param cols - Columns to make distinct
5151
+ * @returns New query builder instance with the DISTINCT clause
5152
+ */
4979
5153
  distinct(...cols) {
4980
5154
  return this.clone(this.columnSelector.distinct(this.context, cols));
4981
5155
  }
4982
5156
  /**
4983
-
4984
- * Adds a LIMIT clause to the query
4985
-
4986
- * @param n - Maximum number of rows to return
4987
-
4988
- * @returns New query builder instance with the LIMIT clause
4989
-
4990
- */
5157
+ * Adds a LIMIT clause to the query
5158
+ * @param n - Maximum number of rows to return
5159
+ * @returns New query builder instance with the LIMIT clause
5160
+ */
4991
5161
  limit(n) {
4992
5162
  const nextContext = this.applyAst(this.context, (service) => service.withLimit(n));
4993
5163
  return this.clone(nextContext);
4994
5164
  }
4995
5165
  /**
4996
-
4997
- * Adds an OFFSET clause to the query
4998
-
4999
- * @param n - Number of rows to skip
5000
-
5001
- * @returns New query builder instance with the OFFSET clause
5002
-
5003
- */
5166
+ * Adds an OFFSET clause to the query
5167
+ * @param n - Number of rows to skip
5168
+ * @returns New query builder instance with the OFFSET clause
5169
+ */
5004
5170
  offset(n) {
5005
5171
  const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
5006
5172
  return this.clone(nextContext);
5007
5173
  }
5008
5174
  /**
5009
-
5010
- * Combines this query with another using UNION
5011
-
5012
- * @param query - Query to union with
5013
-
5014
- * @returns New query builder instance with the set operation
5015
-
5016
- */
5175
+ * Combines this query with another using UNION
5176
+ * @param query - Query to union with
5177
+ * @returns New query builder instance with the set operation
5178
+ */
5017
5179
  union(query) {
5018
5180
  return this.clone(this.applySetOperation("UNION", query));
5019
5181
  }
5020
5182
  /**
5021
-
5022
- * Combines this query with another using UNION ALL
5023
-
5024
- * @param query - Query to union with
5025
-
5026
- * @returns New query builder instance with the set operation
5027
-
5028
- */
5183
+ * Combines this query with another using UNION ALL
5184
+ * @param query - Query to union with
5185
+ * @returns New query builder instance with the set operation
5186
+ */
5029
5187
  unionAll(query) {
5030
5188
  return this.clone(this.applySetOperation("UNION ALL", query));
5031
5189
  }
5032
5190
  /**
5033
-
5034
- * Combines this query with another using INTERSECT
5035
-
5036
- * @param query - Query to intersect with
5037
-
5038
- * @returns New query builder instance with the set operation
5039
-
5040
- */
5191
+ * Combines this query with another using INTERSECT
5192
+ * @param query - Query to intersect with
5193
+ * @returns New query builder instance with the set operation
5194
+ */
5041
5195
  intersect(query) {
5042
5196
  return this.clone(this.applySetOperation("INTERSECT", query));
5043
5197
  }
5044
5198
  /**
5045
-
5046
- * Combines this query with another using EXCEPT
5047
-
5048
- * @param query - Query to subtract
5049
-
5050
- * @returns New query builder instance with the set operation
5051
-
5052
- */
5199
+ * Combines this query with another using EXCEPT
5200
+ * @param query - Query to subtract
5201
+ * @returns New query builder instance with the set operation
5202
+ */
5053
5203
  except(query) {
5054
5204
  return this.clone(this.applySetOperation("EXCEPT", query));
5055
5205
  }
5056
5206
  /**
5057
-
5058
- * Adds a WHERE EXISTS condition to the query
5059
-
5060
- * @param subquery - Subquery to check for existence
5061
-
5062
- * @returns New query builder instance with the WHERE EXISTS condition
5063
-
5064
- */
5207
+ * Adds a WHERE EXISTS condition to the query
5208
+ * @param subquery - Subquery to check for existence
5209
+ * @returns New query builder instance with the WHERE EXISTS condition
5210
+ */
5065
5211
  whereExists(subquery, correlate) {
5066
- const subAst = this.resolveQueryNode(subquery);
5212
+ const subAst = resolveSelectQuery(subquery);
5067
5213
  const correlated = this.applyCorrelation(subAst, correlate);
5068
5214
  return this.where(exists(correlated));
5069
5215
  }
5070
5216
  /**
5071
-
5072
- * Adds a WHERE NOT EXISTS condition to the query
5073
-
5074
- * @param subquery - Subquery to check for non-existence
5075
-
5076
- * @returns New query builder instance with the WHERE NOT EXISTS condition
5077
-
5078
- */
5217
+ * Adds a WHERE NOT EXISTS condition to the query
5218
+ * @param subquery - Subquery to check for non-existence
5219
+ * @returns New query builder instance with the WHERE NOT EXISTS condition
5220
+ */
5079
5221
  whereNotExists(subquery, correlate) {
5080
- const subAst = this.resolveQueryNode(subquery);
5222
+ const subAst = resolveSelectQuery(subquery);
5081
5223
  const correlated = this.applyCorrelation(subAst, correlate);
5082
5224
  return this.where(notExists(correlated));
5083
5225
  }
5084
5226
  /**
5085
-
5086
- * Adds a WHERE EXISTS condition based on a relationship
5087
-
5088
- * @param relationName - Name of the relationship to check
5089
-
5090
- * @param callback - Optional callback to modify the relationship query
5091
-
5092
- * @returns New query builder instance with the relationship existence check
5093
-
5094
- */
5227
+ * Adds a WHERE EXISTS condition based on a relationship
5228
+ * @param relationName - Name of the relationship to check
5229
+ * @param callback - Optional callback to modify the relationship query
5230
+ * @returns New query builder instance with the relationship existence check
5231
+ */
5095
5232
  whereHas(relationName, callbackOrOptions, maybeOptions) {
5096
5233
  const relation = this.env.table.relations[relationName];
5097
5234
  if (!relation) {
@@ -5108,16 +5245,11 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
5108
5245
  return this.where(exists(finalSubAst));
5109
5246
  }
5110
5247
  /**
5111
-
5112
- * Adds a WHERE NOT EXISTS condition based on a relationship
5113
-
5114
- * @param relationName - Name of the relationship to check
5115
-
5116
- * @param callback - Optional callback to modify the relationship query
5117
-
5118
- * @returns New query builder instance with the relationship non-existence check
5119
-
5120
- */
5248
+ * Adds a WHERE NOT EXISTS condition based on a relationship
5249
+ * @param relationName - Name of the relationship to check
5250
+ * @param callback - Optional callback to modify the relationship query
5251
+ * @returns New query builder instance with the relationship non-existence check
5252
+ */
5121
5253
  whereHasNot(relationName, callbackOrOptions, maybeOptions) {
5122
5254
  const relation = this.env.table.relations[relationName];
5123
5255
  if (!relation) {
@@ -5134,53 +5266,61 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
5134
5266
  return this.where(notExists(finalSubAst));
5135
5267
  }
5136
5268
  /**
5137
-
5138
- * Compiles the query to SQL for a specific dialect
5139
-
5140
- * @param dialect - Database dialect to compile for
5141
-
5142
- * @returns Compiled query with SQL and parameters
5143
-
5144
- */
5269
+ * Compiles the query to SQL for a specific dialect
5270
+ * @param dialect - Database dialect to compile for
5271
+ * @returns Compiled query with SQL and parameters
5272
+ */
5145
5273
  compile(dialect) {
5146
5274
  const resolved = resolveDialectInput(dialect);
5147
- return resolved.compileSelect(this.context.state.ast);
5275
+ return resolved.compileSelect(this.getAST());
5148
5276
  }
5149
5277
  /**
5150
-
5151
- * Converts the query to SQL string for a specific dialect
5152
-
5153
- * @param dialect - Database dialect to generate SQL for
5154
-
5155
- * @returns SQL string representation of the query
5156
-
5157
- */
5278
+ * Converts the query to SQL string for a specific dialect
5279
+ * @param dialect - Database dialect to generate SQL for
5280
+ * @returns SQL string representation of the query
5281
+ */
5158
5282
  toSql(dialect) {
5159
5283
  return this.compile(dialect).sql;
5160
5284
  }
5161
5285
  /**
5162
-
5163
- * Gets the hydration plan for the query
5164
-
5165
- * @returns Hydration plan or undefined if none exists
5166
-
5167
- */
5286
+ * Gets the hydration plan for the query
5287
+ * @returns Hydration plan or undefined if none exists
5288
+ */
5168
5289
  getHydrationPlan() {
5169
5290
  return this.context.hydration.getPlan();
5170
5291
  }
5171
5292
  /**
5172
-
5173
- * Gets the Abstract Syntax Tree (AST) representation of the query
5174
-
5175
- * @returns Query AST with hydration applied
5176
-
5177
- */
5293
+ * Gets the Abstract Syntax Tree (AST) representation of the query
5294
+ * @returns Query AST with hydration applied
5295
+ */
5178
5296
  getAST() {
5179
5297
  return this.context.hydration.applyToAst(this.context.state.ast);
5180
5298
  }
5181
5299
  };
5182
- var createColumn = (table, name) => ({ type: "Column", table, name });
5183
- var createLiteral = (val) => ({ type: "Literal", value: val });
5300
+
5301
+ // src/schema/table-guards.ts
5302
+ var isColumnsRecord = (columns) => {
5303
+ return typeof columns === "object" && columns !== null;
5304
+ };
5305
+ var isRelationsRecord = (relations) => {
5306
+ return typeof relations === "object" && relations !== null;
5307
+ };
5308
+ var isTableDef = (value) => {
5309
+ if (typeof value !== "object" || value === null) {
5310
+ return false;
5311
+ }
5312
+ const candidate = value;
5313
+ if (typeof candidate.name !== "string") {
5314
+ return false;
5315
+ }
5316
+ if (!isColumnsRecord(candidate.columns)) {
5317
+ return false;
5318
+ }
5319
+ if (!isRelationsRecord(candidate.relations)) {
5320
+ return false;
5321
+ }
5322
+ return true;
5323
+ };
5184
5324
 
5185
5325
  // src/orm/entity-metadata.ts
5186
5326
  var metadataMap = /* @__PURE__ */ new Map();
@@ -5224,23 +5364,20 @@ var buildTableDef = (meta) => {
5224
5364
  if (meta.table) {
5225
5365
  return meta.table;
5226
5366
  }
5227
- const columns = Object.entries(meta.columns).reduce((acc, [key, def]) => {
5228
- acc[key] = {
5367
+ const columns = {};
5368
+ for (const [key, def] of Object.entries(meta.columns)) {
5369
+ columns[key] = {
5229
5370
  ...def,
5230
5371
  name: key,
5231
5372
  table: meta.tableName
5232
5373
  };
5233
- return acc;
5234
- }, {});
5374
+ }
5235
5375
  const table = defineTable(meta.tableName, columns, {}, meta.hooks);
5236
5376
  meta.table = table;
5237
5377
  return table;
5238
5378
  };
5239
5379
 
5240
5380
  // src/decorators/bootstrap.ts
5241
- var isTableDef = (value) => {
5242
- return typeof value === "object" && value !== null && "columns" in value;
5243
- };
5244
5381
  var unwrapTarget = (target) => {
5245
5382
  if (typeof target === "function" && target.prototype === void 0) {
5246
5383
  return target();
@@ -5376,6 +5513,11 @@ function esel(entity, ...props) {
5376
5513
 
5377
5514
  // src/query-builder/insert-query-state.ts
5378
5515
  var InsertQueryState = class _InsertQueryState {
5516
+ /**
5517
+ * Creates a new InsertQueryState instance
5518
+ * @param table - The table definition for the INSERT query
5519
+ * @param ast - Optional initial AST node, defaults to a basic INSERT query
5520
+ */
5379
5521
  constructor(table, ast) {
5380
5522
  this.table = table;
5381
5523
  this.ast = ast ?? {
@@ -5406,6 +5548,13 @@ var InsertQueryState = class _InsertQueryState {
5406
5548
  if (!names.length) return [];
5407
5549
  return buildColumnNodes(this.table, names);
5408
5550
  }
5551
+ /**
5552
+ * Adds VALUES clause to the INSERT query
5553
+ * @param rows - Array of row objects to insert
5554
+ * @returns A new InsertQueryState with the VALUES clause added
5555
+ * @throws Error if mixing VALUES with SELECT source
5556
+ * @throws Error if invalid values are provided
5557
+ */
5409
5558
  withValues(rows) {
5410
5559
  if (!rows.length) return this;
5411
5560
  if (this.ast.source.type === "InsertSelect") {
@@ -5432,6 +5581,11 @@ var InsertQueryState = class _InsertQueryState {
5432
5581
  }
5433
5582
  });
5434
5583
  }
5584
+ /**
5585
+ * Sets the columns for the INSERT query
5586
+ * @param columns - Column nodes to insert into
5587
+ * @returns A new InsertQueryState with the specified columns
5588
+ */
5435
5589
  withColumns(columns) {
5436
5590
  if (!columns.length) return this;
5437
5591
  return this.clone({
@@ -5439,6 +5593,14 @@ var InsertQueryState = class _InsertQueryState {
5439
5593
  columns: [...columns]
5440
5594
  });
5441
5595
  }
5596
+ /**
5597
+ * Adds SELECT source to the INSERT query
5598
+ * @param query - The SELECT query to use as source
5599
+ * @param columns - Target columns for the INSERT
5600
+ * @returns A new InsertQueryState with the SELECT source
5601
+ * @throws Error if mixing SELECT with VALUES source
5602
+ * @throws Error if no destination columns specified
5603
+ */
5442
5604
  withSelect(query, columns) {
5443
5605
  const targetColumns = columns.length ? columns : this.ast.columns.length ? this.ast.columns : this.getTableColumns();
5444
5606
  if (!targetColumns.length) {
@@ -5456,6 +5618,11 @@ var InsertQueryState = class _InsertQueryState {
5456
5618
  }
5457
5619
  });
5458
5620
  }
5621
+ /**
5622
+ * Adds a RETURNING clause to the INSERT query
5623
+ * @param columns - Columns to return after insertion
5624
+ * @returns A new InsertQueryState with the RETURNING clause added
5625
+ */
5459
5626
  withReturning(columns) {
5460
5627
  return this.clone({
5461
5628
  ...this.ast,
@@ -5466,6 +5633,11 @@ var InsertQueryState = class _InsertQueryState {
5466
5633
 
5467
5634
  // src/query-builder/insert.ts
5468
5635
  var InsertQueryBuilder = class _InsertQueryBuilder {
5636
+ /**
5637
+ * Creates a new InsertQueryBuilder instance
5638
+ * @param table - The table definition for the INSERT query
5639
+ * @param state - Optional initial query state, defaults to a new InsertQueryState
5640
+ */
5469
5641
  constructor(table, state) {
5470
5642
  this.table = table;
5471
5643
  this.state = state ?? new InsertQueryState(table);
@@ -5473,20 +5645,42 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
5473
5645
  clone(state) {
5474
5646
  return new _InsertQueryBuilder(this.table, state);
5475
5647
  }
5648
+ /**
5649
+ * Adds VALUES to the INSERT query
5650
+ * @param rowOrRows - Single row object or array of row objects to insert
5651
+ * @returns A new InsertQueryBuilder with the VALUES clause added
5652
+ */
5476
5653
  values(rowOrRows) {
5477
5654
  const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
5478
5655
  if (!rows.length) return this;
5479
5656
  return this.clone(this.state.withValues(rows));
5480
5657
  }
5658
+ /**
5659
+ * Specifies the columns for the INSERT query
5660
+ * @param columns - Column definitions or nodes to insert into
5661
+ * @returns A new InsertQueryBuilder with the specified columns
5662
+ */
5481
5663
  columns(...columns) {
5482
5664
  if (!columns.length) return this;
5483
5665
  return this.clone(this.state.withColumns(this.resolveColumnNodes(columns)));
5484
5666
  }
5667
+ /**
5668
+ * Sets the source of the INSERT query to a SELECT query
5669
+ * @template TSource - The source table type
5670
+ * @param query - The SELECT query or query builder to use as source
5671
+ * @param columns - Optional target columns for the INSERT
5672
+ * @returns A new InsertQueryBuilder with the SELECT source
5673
+ */
5485
5674
  fromSelect(query, columns = []) {
5486
5675
  const ast = this.resolveSelectQuery(query);
5487
5676
  const nodes = columns.length ? this.resolveColumnNodes(columns) : [];
5488
5677
  return this.clone(this.state.withSelect(ast, nodes));
5489
5678
  }
5679
+ /**
5680
+ * Adds a RETURNING clause to the INSERT query
5681
+ * @param columns - Columns to return after insertion
5682
+ * @returns A new InsertQueryBuilder with the RETURNING clause added
5683
+ */
5490
5684
  returning(...columns) {
5491
5685
  if (!columns.length) return this;
5492
5686
  const nodes = columns.map((column) => buildColumnNode(this.table, column));
@@ -5508,9 +5702,18 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
5508
5702
  const dialect = resolveDialectInput(arg);
5509
5703
  return dialect.compileInsert(this.state.ast);
5510
5704
  }
5705
+ /**
5706
+ * Returns the SQL string for the INSERT query
5707
+ * @param arg - The compiler or dialect to generate SQL for
5708
+ * @returns The SQL string representation of the query
5709
+ */
5511
5710
  toSql(arg) {
5512
5711
  return this.compile(arg).sql;
5513
5712
  }
5713
+ /**
5714
+ * Returns the Abstract Syntax Tree (AST) representation of the query
5715
+ * @returns The AST node for the INSERT query
5716
+ */
5514
5717
  getAST() {
5515
5718
  return this.state.ast;
5516
5719
  }
@@ -5529,6 +5732,11 @@ var isUpdateValue = (value) => {
5529
5732
  }
5530
5733
  };
5531
5734
  var UpdateQueryState = class _UpdateQueryState {
5735
+ /**
5736
+ * Creates a new UpdateQueryState instance
5737
+ * @param table - Table definition for the update
5738
+ * @param ast - Optional existing AST
5739
+ */
5532
5740
  constructor(table, ast) {
5533
5741
  this.table = table;
5534
5742
  this.ast = ast ?? {
@@ -5538,9 +5746,19 @@ var UpdateQueryState = class _UpdateQueryState {
5538
5746
  joins: []
5539
5747
  };
5540
5748
  }
5749
+ /**
5750
+ * Creates a new UpdateQueryState with updated AST
5751
+ * @param nextAst - Updated AST
5752
+ * @returns New UpdateQueryState instance
5753
+ */
5541
5754
  clone(nextAst) {
5542
5755
  return new _UpdateQueryState(this.table, nextAst);
5543
5756
  }
5757
+ /**
5758
+ * Sets the columns to update with their new values
5759
+ * @param values - Record of column names to values
5760
+ * @returns New UpdateQueryState with SET clause
5761
+ */
5544
5762
  withSet(values) {
5545
5763
  const assignments = Object.entries(values).map(([column, rawValue]) => {
5546
5764
  if (!isUpdateValue(rawValue)) {
@@ -5562,30 +5780,55 @@ var UpdateQueryState = class _UpdateQueryState {
5562
5780
  set: assignments
5563
5781
  });
5564
5782
  }
5783
+ /**
5784
+ * Adds a WHERE condition to the update query
5785
+ * @param expr - WHERE expression
5786
+ * @returns New UpdateQueryState with WHERE clause
5787
+ */
5565
5788
  withWhere(expr) {
5566
5789
  return this.clone({
5567
5790
  ...this.ast,
5568
5791
  where: expr
5569
5792
  });
5570
5793
  }
5794
+ /**
5795
+ * Adds a RETURNING clause to the update query
5796
+ * @param columns - Columns to return
5797
+ * @returns New UpdateQueryState with RETURNING clause
5798
+ */
5571
5799
  withReturning(columns) {
5572
5800
  return this.clone({
5573
5801
  ...this.ast,
5574
5802
  returning: [...columns]
5575
5803
  });
5576
5804
  }
5805
+ /**
5806
+ * Sets the FROM clause for the update query
5807
+ * @param from - Table source for FROM
5808
+ * @returns New UpdateQueryState with FROM clause
5809
+ */
5577
5810
  withFrom(from) {
5578
5811
  return this.clone({
5579
5812
  ...this.ast,
5580
5813
  from
5581
5814
  });
5582
5815
  }
5816
+ /**
5817
+ * Adds a JOIN to the update query
5818
+ * @param join - Join node to add
5819
+ * @returns New UpdateQueryState with JOIN
5820
+ */
5583
5821
  withJoin(join) {
5584
5822
  return this.clone({
5585
5823
  ...this.ast,
5586
5824
  joins: [...this.ast.joins ?? [], join]
5587
5825
  });
5588
5826
  }
5827
+ /**
5828
+ * Applies an alias to the table being updated
5829
+ * @param alias - Alias for the table
5830
+ * @returns New UpdateQueryState with table alias
5831
+ */
5589
5832
  withTableAlias(alias) {
5590
5833
  return this.clone({
5591
5834
  ...this.ast,
@@ -5599,6 +5842,11 @@ var UpdateQueryState = class _UpdateQueryState {
5599
5842
 
5600
5843
  // src/query-builder/update.ts
5601
5844
  var UpdateQueryBuilder = class _UpdateQueryBuilder {
5845
+ /**
5846
+ * Creates a new UpdateQueryBuilder instance
5847
+ * @param table - The table definition for the UPDATE query
5848
+ * @param state - Optional initial query state, defaults to a new UpdateQueryState
5849
+ */
5602
5850
  constructor(table, state) {
5603
5851
  this.table = table;
5604
5852
  this.state = state ?? new UpdateQueryState(table);
@@ -5606,24 +5854,57 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
5606
5854
  clone(state) {
5607
5855
  return new _UpdateQueryBuilder(this.table, state);
5608
5856
  }
5857
+ /**
5858
+ * Sets an alias for the table in the UPDATE query
5859
+ * @param alias - The alias to assign to the table
5860
+ * @returns A new UpdateQueryBuilder with the table alias set
5861
+ */
5609
5862
  as(alias) {
5610
5863
  return this.clone(this.state.withTableAlias(alias));
5611
5864
  }
5865
+ /**
5866
+ * Adds a FROM clause to the UPDATE query
5867
+ * @param source - The table source to use in the FROM clause
5868
+ * @returns A new UpdateQueryBuilder with the FROM clause added
5869
+ */
5612
5870
  from(source) {
5613
5871
  const tableSource = this.resolveTableSource(source);
5614
5872
  return this.clone(this.state.withFrom(tableSource));
5615
5873
  }
5874
+ /**
5875
+ * Adds a JOIN clause to the UPDATE query
5876
+ * @param table - The table to join with
5877
+ * @param condition - The join condition expression
5878
+ * @param kind - The type of join (defaults to INNER)
5879
+ * @param relationName - Optional name for the relation
5880
+ * @returns A new UpdateQueryBuilder with the JOIN clause added
5881
+ */
5616
5882
  join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
5617
5883
  const joinTarget = this.resolveJoinTarget(table);
5618
5884
  const joinNode = createJoinNode(kind, joinTarget, condition, relationName);
5619
5885
  return this.clone(this.state.withJoin(joinNode));
5620
5886
  }
5887
+ /**
5888
+ * Adds a SET clause to the UPDATE query
5889
+ * @param values - The column-value pairs to update
5890
+ * @returns A new UpdateQueryBuilder with the SET clause added
5891
+ */
5621
5892
  set(values) {
5622
5893
  return this.clone(this.state.withSet(values));
5623
5894
  }
5895
+ /**
5896
+ * Adds a WHERE clause to the UPDATE query
5897
+ * @param expr - The expression to use as the WHERE condition
5898
+ * @returns A new UpdateQueryBuilder with the WHERE clause added
5899
+ */
5624
5900
  where(expr) {
5625
5901
  return this.clone(this.state.withWhere(expr));
5626
5902
  }
5903
+ /**
5904
+ * Adds a RETURNING clause to the UPDATE query
5905
+ * @param columns - Columns to return after update
5906
+ * @returns A new UpdateQueryBuilder with the RETURNING clause added
5907
+ */
5627
5908
  returning(...columns) {
5628
5909
  if (!columns.length) return this;
5629
5910
  const nodes = columns.map((column) => buildColumnNode(this.table, column));
@@ -5639,17 +5920,36 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
5639
5920
  if (typeof table === "string") return table;
5640
5921
  return this.resolveTableSource(table);
5641
5922
  }
5642
- compile(arg) {
5643
- const candidate = arg;
5644
- if (typeof candidate.compileUpdate === "function") {
5645
- return candidate.compileUpdate(this.state.ast);
5646
- }
5647
- const dialect = resolveDialectInput(arg);
5648
- return dialect.compileUpdate(this.state.ast);
5923
+ /**
5924
+ * Compiles the UPDATE query for the specified dialect
5925
+ * @param dialect - The SQL dialect to compile for
5926
+ * @returns The compiled query with SQL and parameters
5927
+ */
5928
+ compile(dialect) {
5929
+ const resolved = resolveDialectInput(dialect);
5930
+ return resolved.compileUpdate(this.state.ast);
5649
5931
  }
5650
- toSql(arg) {
5651
- return this.compile(arg).sql;
5932
+ /**
5933
+ * Returns the SQL string for the UPDATE query
5934
+ * @param dialect - The SQL dialect to generate SQL for
5935
+ * @returns The SQL string representation of the query
5936
+ */
5937
+ toSql(dialect) {
5938
+ return this.compile(dialect).sql;
5652
5939
  }
5940
+ /**
5941
+ * Executes the UPDATE query using the provided session
5942
+ * @param session - The ORM session to execute the query with
5943
+ * @returns A promise that resolves to the query results
5944
+ */
5945
+ async execute(session) {
5946
+ const compiled = this.compile(session.dialect);
5947
+ return session.executor.executeSql(compiled.sql, compiled.params);
5948
+ }
5949
+ /**
5950
+ * Returns the Abstract Syntax Tree (AST) representation of the query
5951
+ * @returns The AST node for the UPDATE query
5952
+ */
5653
5953
  getAST() {
5654
5954
  return this.state.ast;
5655
5955
  }
@@ -5658,6 +5958,11 @@ var isTableSourceNode = (source) => typeof source.type === "string";
5658
5958
 
5659
5959
  // src/query-builder/delete-query-state.ts
5660
5960
  var DeleteQueryState = class _DeleteQueryState {
5961
+ /**
5962
+ * Creates a new DeleteQueryState instance
5963
+ * @param table - The table definition for the DELETE query
5964
+ * @param ast - Optional initial AST node, defaults to a basic DELETE query
5965
+ */
5661
5966
  constructor(table, ast) {
5662
5967
  this.table = table;
5663
5968
  this.ast = ast ?? {
@@ -5669,30 +5974,55 @@ var DeleteQueryState = class _DeleteQueryState {
5669
5974
  clone(nextAst) {
5670
5975
  return new _DeleteQueryState(this.table, nextAst);
5671
5976
  }
5977
+ /**
5978
+ * Adds a WHERE clause to the DELETE query
5979
+ * @param expr - The expression to use as the WHERE condition
5980
+ * @returns A new DeleteQueryState with the WHERE clause added
5981
+ */
5672
5982
  withWhere(expr) {
5673
5983
  return this.clone({
5674
5984
  ...this.ast,
5675
5985
  where: expr
5676
5986
  });
5677
5987
  }
5988
+ /**
5989
+ * Adds a RETURNING clause to the DELETE query
5990
+ * @param columns - The columns to return after deletion
5991
+ * @returns A new DeleteQueryState with the RETURNING clause added
5992
+ */
5678
5993
  withReturning(columns) {
5679
5994
  return this.clone({
5680
5995
  ...this.ast,
5681
5996
  returning: [...columns]
5682
5997
  });
5683
5998
  }
5999
+ /**
6000
+ * Adds a USING clause to the DELETE query
6001
+ * @param source - The table source to use in the USING clause
6002
+ * @returns A new DeleteQueryState with the USING clause added
6003
+ */
5684
6004
  withUsing(source) {
5685
6005
  return this.clone({
5686
6006
  ...this.ast,
5687
6007
  using: source
5688
6008
  });
5689
6009
  }
6010
+ /**
6011
+ * Adds a JOIN clause to the DELETE query
6012
+ * @param join - The join node to add
6013
+ * @returns A new DeleteQueryState with the JOIN clause added
6014
+ */
5690
6015
  withJoin(join) {
5691
6016
  return this.clone({
5692
6017
  ...this.ast,
5693
6018
  joins: [...this.ast.joins ?? [], join]
5694
6019
  });
5695
6020
  }
6021
+ /**
6022
+ * Sets an alias for the table in the DELETE query
6023
+ * @param alias - The alias to assign to the table
6024
+ * @returns A new DeleteQueryState with the table alias set
6025
+ */
5696
6026
  withTableAlias(alias) {
5697
6027
  return this.clone({
5698
6028
  ...this.ast,
@@ -5706,6 +6036,11 @@ var DeleteQueryState = class _DeleteQueryState {
5706
6036
 
5707
6037
  // src/query-builder/delete.ts
5708
6038
  var DeleteQueryBuilder = class _DeleteQueryBuilder {
6039
+ /**
6040
+ * Creates a new DeleteQueryBuilder instance
6041
+ * @param table - The table definition for the DELETE query
6042
+ * @param state - Optional initial query state, defaults to a new DeleteQueryState
6043
+ */
5709
6044
  constructor(table, state) {
5710
6045
  this.table = table;
5711
6046
  this.state = state ?? new DeleteQueryState(table);
@@ -5713,20 +6048,48 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
5713
6048
  clone(state) {
5714
6049
  return new _DeleteQueryBuilder(this.table, state);
5715
6050
  }
6051
+ /**
6052
+ * Adds a WHERE clause to the DELETE query
6053
+ * @param expr - The expression to use as the WHERE condition
6054
+ * @returns A new DeleteQueryBuilder with the WHERE clause added
6055
+ */
5716
6056
  where(expr) {
5717
6057
  return this.clone(this.state.withWhere(expr));
5718
6058
  }
6059
+ /**
6060
+ * Sets an alias for the table in the DELETE query
6061
+ * @param alias - The alias to assign to the table
6062
+ * @returns A new DeleteQueryBuilder with the table alias set
6063
+ */
5719
6064
  as(alias) {
5720
6065
  return this.clone(this.state.withTableAlias(alias));
5721
6066
  }
6067
+ /**
6068
+ * Adds a USING clause to the DELETE query
6069
+ * @param source - The table source to use in the USING clause
6070
+ * @returns A new DeleteQueryBuilder with the USING clause added
6071
+ */
5722
6072
  using(source) {
5723
6073
  return this.clone(this.state.withUsing(this.resolveTableSource(source)));
5724
6074
  }
6075
+ /**
6076
+ * Adds a JOIN clause to the DELETE query
6077
+ * @param table - The table to join with
6078
+ * @param condition - The join condition expression
6079
+ * @param kind - The type of join (defaults to INNER)
6080
+ * @param relationName - Optional name for the relation
6081
+ * @returns A new DeleteQueryBuilder with the JOIN clause added
6082
+ */
5725
6083
  join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
5726
6084
  const target = this.resolveJoinTarget(table);
5727
6085
  const joinNode = createJoinNode(kind, target, condition, relationName);
5728
6086
  return this.clone(this.state.withJoin(joinNode));
5729
6087
  }
6088
+ /**
6089
+ * Adds a RETURNING clause to the DELETE query
6090
+ * @param columns - The columns to return after deletion
6091
+ * @returns A new DeleteQueryBuilder with the RETURNING clause added
6092
+ */
5730
6093
  returning(...columns) {
5731
6094
  if (!columns.length) return this;
5732
6095
  const nodes = columns.map((column) => buildColumnNode(this.table, column));
@@ -5742,17 +6105,36 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
5742
6105
  if (typeof table === "string") return table;
5743
6106
  return this.resolveTableSource(table);
5744
6107
  }
5745
- compile(arg) {
5746
- const candidate = arg;
5747
- if (typeof candidate.compileDelete === "function") {
5748
- return candidate.compileDelete(this.state.ast);
5749
- }
5750
- const dialect = resolveDialectInput(arg);
5751
- return dialect.compileDelete(this.state.ast);
6108
+ /**
6109
+ * Compiles the DELETE query for the specified dialect
6110
+ * @param dialect - The SQL dialect to compile for
6111
+ * @returns The compiled query with SQL and parameters
6112
+ */
6113
+ compile(dialect) {
6114
+ const resolved = resolveDialectInput(dialect);
6115
+ return resolved.compileDelete(this.state.ast);
5752
6116
  }
5753
- toSql(arg) {
5754
- return this.compile(arg).sql;
6117
+ /**
6118
+ * Returns the SQL string for the DELETE query
6119
+ * @param dialect - The SQL dialect to generate SQL for
6120
+ * @returns The SQL string representation of the query
6121
+ */
6122
+ toSql(dialect) {
6123
+ return this.compile(dialect).sql;
5755
6124
  }
6125
+ /**
6126
+ * Executes the DELETE query using the provided session
6127
+ * @param session - The ORM session to execute the query with
6128
+ * @returns A promise that resolves to the query results
6129
+ */
6130
+ async execute(session) {
6131
+ const compiled = this.compile(session.dialect);
6132
+ return session.executor.executeSql(compiled.sql, compiled.params);
6133
+ }
6134
+ /**
6135
+ * Returns the Abstract Syntax Tree (AST) representation of the query
6136
+ * @returns The AST node for the DELETE query
6137
+ */
5756
6138
  getAST() {
5757
6139
  return this.state.ast;
5758
6140
  }
@@ -6187,6 +6569,13 @@ async function runSelectNode(ast, ctx) {
6187
6569
 
6188
6570
  // src/core/ddl/introspect/postgres.ts
6189
6571
  var postgresIntrospector = {
6572
+ /**
6573
+ * Introspects the PostgreSQL database schema by querying information_schema and pg_catalog.
6574
+ * Builds tables with columns, primary keys, foreign keys, and indexes.
6575
+ * @param ctx - The introspection context with database executor.
6576
+ * @param options - Options for schema selection and table filtering.
6577
+ * @returns A promise resolving to the complete database schema.
6578
+ */
6190
6579
  async introspect(ctx, options) {
6191
6580
  const schema = options.schema || "public";
6192
6581
  const tables = [];
@@ -6474,6 +6863,12 @@ var toReferentialAction = (value) => {
6474
6863
  };
6475
6864
  var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
6476
6865
  var sqliteIntrospector = {
6866
+ /**
6867
+ * Introspects the SQLite database schema by querying sqlite_master and various PRAGMAs.
6868
+ * @param ctx - The database execution context containing the DbExecutor.
6869
+ * @param options - Options controlling which tables and schemas to include.
6870
+ * @returns A promise that resolves to the introspected DatabaseSchema.
6871
+ */
6477
6872
  async introspect(ctx, options) {
6478
6873
  const tables = [];
6479
6874
  const tableRows = await queryRows(
@@ -6529,6 +6924,12 @@ var sqliteIntrospector = {
6529
6924
 
6530
6925
  // src/core/ddl/introspect/mssql.ts
6531
6926
  var mssqlIntrospector = {
6927
+ /**
6928
+ * Introspects the MSSQL database schema.
6929
+ * @param ctx - The introspection context containing the database executor.
6930
+ * @param options - Options for introspection, such as schema filter.
6931
+ * @returns A promise that resolves to the introspected database schema.
6932
+ */
6532
6933
  async introspect(ctx, options) {
6533
6934
  const schema = options.schema;
6534
6935
  const filterSchema = schema ? "sch.name = @p1" : "1=1";
@@ -6811,10 +7212,21 @@ var dateTrunc = (part, date) => fn3("DATE_TRUNC", [part, date]);
6811
7212
  // src/orm/als.ts
6812
7213
  var AsyncLocalStorage = class {
6813
7214
  /**
6814
- * Executes a callback with the specified store value
6815
- * @param store - Value to store during callback execution
6816
- * @param callback - Function to execute with the store value
6817
- * @returns Result of the callback function
7215
+ * Executes a callback function within a context containing the specified store value.
7216
+ * The store value is only available during the callback's execution and is automatically
7217
+ * cleared afterward.
7218
+ *
7219
+ * @param store - The context value to make available during callback execution
7220
+ * @param callback - Function to execute with the store value available
7221
+ * @returns Result of the callback function execution
7222
+ *
7223
+ * @example
7224
+ * ```
7225
+ * const als = new AsyncLocalStorage<number>();
7226
+ * als.run(42, () => {
7227
+ * console.log(als.getStore()); // Outputs: 42
7228
+ * });
7229
+ * ```
6818
7230
  */
6819
7231
  run(store, callback) {
6820
7232
  this.store = store;
@@ -6825,8 +7237,20 @@ var AsyncLocalStorage = class {
6825
7237
  }
6826
7238
  }
6827
7239
  /**
6828
- * Gets the currently stored value
6829
- * @returns Current store value or undefined if none exists
7240
+ * Retrieves the current store value from the async context.
7241
+ * Returns undefined if called outside of a `run()` callback execution.
7242
+ *
7243
+ * @returns Current store value or undefined if no context exists
7244
+ *
7245
+ * @example
7246
+ * ```
7247
+ * const als = new AsyncLocalStorage<string>();
7248
+ * console.log(als.getStore()); // Outputs: undefined
7249
+ *
7250
+ * als.run('hello', () => {
7251
+ * console.log(als.getStore()); // Outputs: 'hello'
7252
+ * });
7253
+ * ```
6830
7254
  */
6831
7255
  getStore() {
6832
7256
  return this.store;
@@ -9354,11 +9778,9 @@ export {
9354
9778
  cos,
9355
9779
  cot,
9356
9780
  count,
9357
- createColumn,
9358
9781
  createEntityFromRow,
9359
9782
  createEntityProxy,
9360
9783
  createExecutorFromQueryRunner,
9361
- createLiteral,
9362
9784
  createMssqlExecutor,
9363
9785
  createMysqlExecutor,
9364
9786
  createPooledExecutorFactory,