metal-orm 1.0.88 → 1.0.90

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 (49) hide show
  1. package/dist/index.cjs +3818 -3783
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +765 -236
  4. package/dist/index.d.ts +765 -236
  5. package/dist/index.js +3763 -3775
  6. package/dist/index.js.map +1 -1
  7. package/package.json +3 -2
  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/dialect/abstract.ts +55 -81
  14. package/src/core/execution/db-executor.ts +4 -5
  15. package/src/core/execution/executors/mysql-executor.ts +7 -9
  16. package/src/decorators/bootstrap.ts +11 -8
  17. package/src/dto/apply-filter.ts +281 -0
  18. package/src/dto/dto-types.ts +229 -0
  19. package/src/dto/filter-types.ts +193 -0
  20. package/src/dto/index.ts +97 -0
  21. package/src/dto/openapi/generators/base.ts +29 -0
  22. package/src/dto/openapi/generators/column.ts +34 -0
  23. package/src/dto/openapi/generators/dto.ts +94 -0
  24. package/src/dto/openapi/generators/filter.ts +74 -0
  25. package/src/dto/openapi/generators/nested-dto.ts +532 -0
  26. package/src/dto/openapi/generators/pagination.ts +111 -0
  27. package/src/dto/openapi/generators/relation-filter.ts +210 -0
  28. package/src/dto/openapi/index.ts +17 -0
  29. package/src/dto/openapi/type-mappings.ts +191 -0
  30. package/src/dto/openapi/types.ts +83 -0
  31. package/src/dto/openapi/utilities.ts +45 -0
  32. package/src/dto/pagination-utils.ts +150 -0
  33. package/src/dto/transform.ts +193 -0
  34. package/src/index.ts +67 -65
  35. package/src/orm/unit-of-work.ts +13 -25
  36. package/src/query-builder/query-ast-service.ts +287 -300
  37. package/src/query-builder/relation-filter-utils.ts +159 -160
  38. package/src/query-builder/select.ts +137 -192
  39. package/src/core/ast/ast-validation.ts +0 -19
  40. package/src/core/ast/param-proxy.ts +0 -47
  41. package/src/core/ast/query-visitor.ts +0 -273
  42. package/src/openapi/index.ts +0 -4
  43. package/src/openapi/query-parameters.ts +0 -207
  44. package/src/openapi/schema-extractor-input.ts +0 -139
  45. package/src/openapi/schema-extractor-output.ts +0 -427
  46. package/src/openapi/schema-extractor-utils.ts +0 -110
  47. package/src/openapi/schema-extractor.ts +0 -111
  48. package/src/openapi/schema-types.ts +0 -176
  49. 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
+ };