metal-orm 1.0.89 → 1.0.91

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 (57) hide show
  1. package/dist/index.cjs +2968 -2983
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +784 -251
  4. package/dist/index.d.ts +784 -251
  5. package/dist/index.js +2913 -2975
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -3
  8. package/src/codegen/typescript.ts +29 -40
  9. package/src/core/ast/expression-builders.ts +34 -53
  10. package/src/core/ast/expression-nodes.ts +51 -72
  11. package/src/core/ast/expression-visitor.ts +219 -252
  12. package/src/core/ast/expression.ts +20 -21
  13. package/src/core/ddl/introspect/utils.ts +45 -45
  14. package/src/core/dialect/abstract.ts +55 -81
  15. package/src/core/execution/db-executor.ts +4 -5
  16. package/src/core/execution/executors/mysql-executor.ts +7 -9
  17. package/src/decorators/bootstrap.ts +29 -26
  18. package/src/dto/apply-filter.ts +279 -0
  19. package/src/dto/dto-types.ts +229 -0
  20. package/src/dto/filter-types.ts +193 -0
  21. package/src/dto/index.ts +97 -0
  22. package/src/dto/openapi/generators/base.ts +29 -0
  23. package/src/dto/openapi/generators/column.ts +34 -0
  24. package/src/dto/openapi/generators/dto.ts +94 -0
  25. package/src/dto/openapi/generators/filter.ts +74 -0
  26. package/src/dto/openapi/generators/nested-dto.ts +532 -0
  27. package/src/dto/openapi/generators/pagination.ts +111 -0
  28. package/src/dto/openapi/generators/relation-filter.ts +210 -0
  29. package/src/dto/openapi/index.ts +17 -0
  30. package/src/dto/openapi/type-mappings.ts +191 -0
  31. package/src/dto/openapi/types.ts +90 -0
  32. package/src/dto/openapi/utilities.ts +45 -0
  33. package/src/dto/pagination-utils.ts +150 -0
  34. package/src/dto/transform.ts +197 -0
  35. package/src/index.ts +5 -3
  36. package/src/orm/entity-context.ts +9 -9
  37. package/src/orm/entity.ts +74 -74
  38. package/src/orm/orm-session.ts +159 -159
  39. package/src/orm/relation-change-processor.ts +3 -3
  40. package/src/orm/runtime-types.ts +5 -5
  41. package/src/orm/unit-of-work.ts +13 -25
  42. package/src/query-builder/query-ast-service.ts +287 -300
  43. package/src/query-builder/relation-filter-utils.ts +159 -160
  44. package/src/query-builder/select.ts +137 -192
  45. package/src/schema/column-types.ts +4 -4
  46. package/src/schema/types.ts +5 -1
  47. package/src/core/ast/ast-validation.ts +0 -19
  48. package/src/core/ast/param-proxy.ts +0 -47
  49. package/src/core/ast/query-visitor.ts +0 -273
  50. package/src/openapi/index.ts +0 -4
  51. package/src/openapi/query-parameters.ts +0 -207
  52. package/src/openapi/schema-extractor-input.ts +0 -193
  53. package/src/openapi/schema-extractor-output.ts +0 -427
  54. package/src/openapi/schema-extractor-utils.ts +0 -110
  55. package/src/openapi/schema-extractor.ts +0 -120
  56. package/src/openapi/schema-types.ts +0 -187
  57. package/src/openapi/type-mappers.ts +0 -227
@@ -1,160 +1,159 @@
1
- import { ExpressionNode, OperandNode, isOperandNode } from '../core/ast/expression.js';
2
- import { OrderingTerm } from '../core/ast/query.js';
3
-
4
- type FilterTableCollector = {
5
- tables: Set<string>;
6
- hasSubquery: boolean;
7
- };
8
-
9
- export type SplitFilterExpressionsResult = {
10
- selfFilters: ExpressionNode[];
11
- crossFilters: ExpressionNode[];
12
- };
13
-
14
- export const splitFilterExpressions = (
15
- filter: ExpressionNode | undefined,
16
- allowedTables: Set<string>
17
- ): SplitFilterExpressionsResult => {
18
- const terms = flattenAnd(filter);
19
- const selfFilters: ExpressionNode[] = [];
20
- const crossFilters: ExpressionNode[] = [];
21
-
22
- for (const term of terms) {
23
- if (isExpressionSelfContained(term, allowedTables)) {
24
- selfFilters.push(term);
25
- } else {
26
- crossFilters.push(term);
27
- }
28
- }
29
-
30
- return { selfFilters, crossFilters };
31
- };
32
-
33
- const flattenAnd = (node?: ExpressionNode): ExpressionNode[] => {
34
- if (!node) return [];
35
- if (node.type === 'LogicalExpression' && node.operator === 'AND') {
36
- return node.operands.flatMap(operand => flattenAnd(operand));
37
- }
38
- return [node];
39
- };
40
-
41
- const isExpressionSelfContained = (expr: ExpressionNode, allowedTables: Set<string>): boolean => {
42
- const collector = collectReferencedTables(expr);
43
- if (collector.hasSubquery) return false;
44
- if (collector.tables.size === 0) return true;
45
- for (const table of collector.tables) {
46
- if (!allowedTables.has(table)) {
47
- return false;
48
- }
49
- }
50
- return true;
51
- };
52
-
53
- const collectReferencedTables = (expr: ExpressionNode): FilterTableCollector => {
54
- const collector: FilterTableCollector = {
55
- tables: new Set(),
56
- hasSubquery: false
57
- };
58
- collectFromExpression(expr, collector);
59
- return collector;
60
- };
61
-
62
- const collectFromExpression = (expr: ExpressionNode, collector: FilterTableCollector): void => {
63
- switch (expr.type) {
64
- case 'BinaryExpression':
65
- collectFromOperand(expr.left, collector);
66
- collectFromOperand(expr.right, collector);
67
- break;
68
- case 'LogicalExpression':
69
- expr.operands.forEach(operand => collectFromExpression(operand, collector));
70
- break;
71
- case 'NullExpression':
72
- collectFromOperand(expr.left, collector);
73
- break;
74
- case 'InExpression':
75
- collectFromOperand(expr.left, collector);
76
- if (Array.isArray(expr.right)) {
77
- expr.right.forEach(value => collectFromOperand(value, collector));
78
- } else {
79
- collector.hasSubquery = true;
80
- }
81
- break;
82
- case 'ExistsExpression':
83
- collector.hasSubquery = true;
84
- break;
85
- case 'BetweenExpression':
86
- collectFromOperand(expr.left, collector);
87
- collectFromOperand(expr.lower, collector);
88
- collectFromOperand(expr.upper, collector);
89
- break;
90
- case 'ArithmeticExpression':
91
- case 'BitwiseExpression':
92
- collectFromOperand(expr.left, collector);
93
- collectFromOperand(expr.right, collector);
94
- break;
95
- default:
96
- break;
97
- }
98
- };
99
-
100
- const collectFromOperand = (node: OperandNode, collector: FilterTableCollector): void => {
101
- switch (node.type) {
102
- case 'Column':
103
- collector.tables.add(node.table);
104
- break;
105
- case 'Function':
106
- node.args.forEach(arg => collectFromOperand(arg, collector));
107
- if (node.separator) {
108
- collectFromOperand(node.separator, collector);
109
- }
110
- if (node.orderBy) {
111
- node.orderBy.forEach(order => collectFromOrderingTerm(order.term, collector));
112
- }
113
- break;
114
- case 'JsonPath':
115
- collectFromOperand(node.column, collector);
116
- break;
117
- case 'ScalarSubquery':
118
- collector.hasSubquery = true;
119
- break;
120
- case 'CaseExpression':
121
- node.conditions.forEach(({ when, then }) => {
122
- collectFromExpression(when, collector);
123
- collectFromOperand(then, collector);
124
- });
125
- if (node.else) {
126
- collectFromOperand(node.else, collector);
127
- }
128
- break;
129
- case 'Cast':
130
- collectFromOperand(node.expression, collector);
131
- break;
132
- case 'WindowFunction':
133
- node.args.forEach(arg => collectFromOperand(arg, collector));
134
- node.partitionBy?.forEach(part => collectFromOperand(part, collector));
135
- node.orderBy?.forEach(order => collectFromOrderingTerm(order.term, collector));
136
- break;
137
- case 'Collate':
138
- collectFromOperand(node.expression, collector);
139
- break;
140
- case 'ArithmeticExpression':
141
- case 'BitwiseExpression':
142
- collectFromOperand(node.left, collector);
143
- collectFromOperand(node.right, collector);
144
- break;
145
- case 'Literal':
146
- case 'AliasRef':
147
- case 'Param':
148
- break;
149
- default:
150
- break;
151
- }
152
- };
153
-
154
- const collectFromOrderingTerm = (term: OrderingTerm, collector: FilterTableCollector): void => {
155
- if (isOperandNode(term)) {
156
- collectFromOperand(term, collector);
157
- return;
158
- }
159
- collectFromExpression(term, collector);
160
- };
1
+ import { ExpressionNode, OperandNode, isOperandNode } from '../core/ast/expression.js';
2
+ import { OrderingTerm } from '../core/ast/query.js';
3
+
4
+ type FilterTableCollector = {
5
+ tables: Set<string>;
6
+ hasSubquery: boolean;
7
+ };
8
+
9
+ export type SplitFilterExpressionsResult = {
10
+ selfFilters: ExpressionNode[];
11
+ crossFilters: ExpressionNode[];
12
+ };
13
+
14
+ export const splitFilterExpressions = (
15
+ filter: ExpressionNode | undefined,
16
+ allowedTables: Set<string>
17
+ ): SplitFilterExpressionsResult => {
18
+ const terms = flattenAnd(filter);
19
+ const selfFilters: ExpressionNode[] = [];
20
+ const crossFilters: ExpressionNode[] = [];
21
+
22
+ for (const term of terms) {
23
+ if (isExpressionSelfContained(term, allowedTables)) {
24
+ selfFilters.push(term);
25
+ } else {
26
+ crossFilters.push(term);
27
+ }
28
+ }
29
+
30
+ return { selfFilters, crossFilters };
31
+ };
32
+
33
+ const flattenAnd = (node?: ExpressionNode): ExpressionNode[] => {
34
+ if (!node) return [];
35
+ if (node.type === 'LogicalExpression' && node.operator === 'AND') {
36
+ return node.operands.flatMap(operand => flattenAnd(operand));
37
+ }
38
+ return [node];
39
+ };
40
+
41
+ const isExpressionSelfContained = (expr: ExpressionNode, allowedTables: Set<string>): boolean => {
42
+ const collector = collectReferencedTables(expr);
43
+ if (collector.hasSubquery) return false;
44
+ if (collector.tables.size === 0) return true;
45
+ for (const table of collector.tables) {
46
+ if (!allowedTables.has(table)) {
47
+ return false;
48
+ }
49
+ }
50
+ return true;
51
+ };
52
+
53
+ const collectReferencedTables = (expr: ExpressionNode): FilterTableCollector => {
54
+ const collector: FilterTableCollector = {
55
+ tables: new Set(),
56
+ hasSubquery: false
57
+ };
58
+ collectFromExpression(expr, collector);
59
+ return collector;
60
+ };
61
+
62
+ const collectFromExpression = (expr: ExpressionNode, collector: FilterTableCollector): void => {
63
+ switch (expr.type) {
64
+ case 'BinaryExpression':
65
+ collectFromOperand(expr.left, collector);
66
+ collectFromOperand(expr.right, collector);
67
+ break;
68
+ case 'LogicalExpression':
69
+ expr.operands.forEach(operand => collectFromExpression(operand, collector));
70
+ break;
71
+ case 'NullExpression':
72
+ collectFromOperand(expr.left, collector);
73
+ break;
74
+ case 'InExpression':
75
+ collectFromOperand(expr.left, collector);
76
+ if (Array.isArray(expr.right)) {
77
+ expr.right.forEach(value => collectFromOperand(value, collector));
78
+ } else {
79
+ collector.hasSubquery = true;
80
+ }
81
+ break;
82
+ case 'ExistsExpression':
83
+ collector.hasSubquery = true;
84
+ break;
85
+ case 'BetweenExpression':
86
+ collectFromOperand(expr.left, collector);
87
+ collectFromOperand(expr.lower, collector);
88
+ collectFromOperand(expr.upper, collector);
89
+ break;
90
+ case 'ArithmeticExpression':
91
+ case 'BitwiseExpression':
92
+ collectFromOperand(expr.left, collector);
93
+ collectFromOperand(expr.right, collector);
94
+ break;
95
+ default:
96
+ break;
97
+ }
98
+ };
99
+
100
+ const collectFromOperand = (node: OperandNode, collector: FilterTableCollector): void => {
101
+ switch (node.type) {
102
+ case 'Column':
103
+ collector.tables.add(node.table);
104
+ break;
105
+ case 'Function':
106
+ node.args.forEach(arg => collectFromOperand(arg, collector));
107
+ if (node.separator) {
108
+ collectFromOperand(node.separator, collector);
109
+ }
110
+ if (node.orderBy) {
111
+ node.orderBy.forEach(order => collectFromOrderingTerm(order.term, collector));
112
+ }
113
+ break;
114
+ case 'JsonPath':
115
+ collectFromOperand(node.column, collector);
116
+ break;
117
+ case 'ScalarSubquery':
118
+ collector.hasSubquery = true;
119
+ break;
120
+ case 'CaseExpression':
121
+ node.conditions.forEach(({ when, then }) => {
122
+ collectFromExpression(when, collector);
123
+ collectFromOperand(then, collector);
124
+ });
125
+ if (node.else) {
126
+ collectFromOperand(node.else, collector);
127
+ }
128
+ break;
129
+ case 'Cast':
130
+ collectFromOperand(node.expression, collector);
131
+ break;
132
+ case 'WindowFunction':
133
+ node.args.forEach(arg => collectFromOperand(arg, collector));
134
+ node.partitionBy?.forEach(part => collectFromOperand(part, collector));
135
+ node.orderBy?.forEach(order => collectFromOrderingTerm(order.term, collector));
136
+ break;
137
+ case 'Collate':
138
+ collectFromOperand(node.expression, collector);
139
+ break;
140
+ case 'ArithmeticExpression':
141
+ case 'BitwiseExpression':
142
+ collectFromOperand(node.left, collector);
143
+ collectFromOperand(node.right, collector);
144
+ break;
145
+ case 'Literal':
146
+ case 'AliasRef':
147
+ break;
148
+ default:
149
+ break;
150
+ }
151
+ };
152
+
153
+ const collectFromOrderingTerm = (term: OrderingTerm, collector: FilterTableCollector): void => {
154
+ if (isOperandNode(term)) {
155
+ collectFromOperand(term, collector);
156
+ return;
157
+ }
158
+ collectFromExpression(term, collector);
159
+ };