metal-orm 1.1.9 → 1.1.11

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 (77) hide show
  1. package/README.md +769 -764
  2. package/dist/index.cjs +2255 -284
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +559 -39
  5. package/dist/index.d.ts +559 -39
  6. package/dist/index.js +2227 -284
  7. package/dist/index.js.map +1 -1
  8. package/package.json +17 -12
  9. package/scripts/generate-entities/render.mjs +21 -12
  10. package/scripts/generate-entities/schema.mjs +87 -73
  11. package/scripts/generate-entities/tree-detection.mjs +67 -61
  12. package/src/bulk/bulk-context.ts +83 -0
  13. package/src/bulk/bulk-delete-executor.ts +87 -0
  14. package/src/bulk/bulk-executor.base.ts +73 -0
  15. package/src/bulk/bulk-insert-executor.ts +74 -0
  16. package/src/bulk/bulk-types.ts +70 -0
  17. package/src/bulk/bulk-update-executor.ts +192 -0
  18. package/src/bulk/bulk-upsert-executor.ts +93 -0
  19. package/src/bulk/bulk-utils.ts +91 -0
  20. package/src/bulk/index.ts +18 -0
  21. package/src/codegen/typescript.ts +30 -21
  22. package/src/core/ast/expression-builders.ts +107 -10
  23. package/src/core/ast/expression-nodes.ts +52 -22
  24. package/src/core/ast/expression-visitor.ts +23 -13
  25. package/src/core/ddl/introspect/mysql.ts +113 -36
  26. package/src/core/dialect/abstract.ts +30 -17
  27. package/src/core/dialect/mysql/index.ts +20 -5
  28. package/src/core/execution/db-executor.ts +96 -64
  29. package/src/core/execution/executors/better-sqlite3-executor.ts +94 -0
  30. package/src/core/execution/executors/mssql-executor.ts +66 -34
  31. package/src/core/execution/executors/mysql-executor.ts +98 -66
  32. package/src/core/execution/executors/postgres-executor.ts +33 -11
  33. package/src/core/execution/executors/sqlite-executor.ts +86 -30
  34. package/src/decorators/bootstrap.ts +482 -398
  35. package/src/decorators/column-decorator.ts +87 -96
  36. package/src/decorators/decorator-metadata.ts +100 -24
  37. package/src/decorators/entity.ts +27 -24
  38. package/src/decorators/relations.ts +231 -149
  39. package/src/decorators/transformers/transformer-decorators.ts +26 -29
  40. package/src/decorators/validators/country-validators-decorators.ts +9 -15
  41. package/src/dto/apply-filter.ts +568 -551
  42. package/src/index.ts +16 -9
  43. package/src/orm/entity-hydration.ts +116 -72
  44. package/src/orm/entity-metadata.ts +347 -301
  45. package/src/orm/entity-relations.ts +264 -207
  46. package/src/orm/entity.ts +199 -199
  47. package/src/orm/execute.ts +13 -13
  48. package/src/orm/lazy-batch/morph-many.ts +70 -0
  49. package/src/orm/lazy-batch/morph-one.ts +69 -0
  50. package/src/orm/lazy-batch/morph-to.ts +59 -0
  51. package/src/orm/lazy-batch.ts +4 -1
  52. package/src/orm/orm-session.ts +170 -104
  53. package/src/orm/pooled-executor-factory.ts +99 -58
  54. package/src/orm/query-logger.ts +49 -40
  55. package/src/orm/relation-change-processor.ts +198 -96
  56. package/src/orm/relations/belongs-to.ts +143 -143
  57. package/src/orm/relations/has-many.ts +204 -204
  58. package/src/orm/relations/has-one.ts +174 -174
  59. package/src/orm/relations/many-to-many.ts +288 -288
  60. package/src/orm/relations/morph-many.ts +156 -0
  61. package/src/orm/relations/morph-one.ts +151 -0
  62. package/src/orm/relations/morph-to.ts +162 -0
  63. package/src/orm/save-graph.ts +116 -1
  64. package/src/query-builder/expression-table-mapper.ts +5 -0
  65. package/src/query-builder/hydration-manager.ts +345 -345
  66. package/src/query-builder/hydration-planner.ts +178 -148
  67. package/src/query-builder/relation-conditions.ts +171 -151
  68. package/src/query-builder/relation-cte-builder.ts +5 -1
  69. package/src/query-builder/relation-filter-utils.ts +9 -6
  70. package/src/query-builder/relation-include-strategies.ts +44 -2
  71. package/src/query-builder/relation-join-strategies.ts +8 -1
  72. package/src/query-builder/relation-service.ts +250 -241
  73. package/src/query-builder/select/select-operations.ts +110 -105
  74. package/src/query-builder/update-include.ts +4 -0
  75. package/src/schema/relation.ts +296 -188
  76. package/src/schema/types.ts +138 -123
  77. package/src/tree/tree-decorator.ts +127 -137
@@ -1,188 +1,296 @@
1
- import type { TableDef } from './table.js';
2
-
3
- /**
4
- * Types of relationships supported between tables
5
- */
6
- export const RelationKinds = {
7
- /** One-to-one relationship */
8
- HasOne: 'HAS_ONE',
9
- /** One-to-many relationship */
10
- HasMany: 'HAS_MANY',
11
- /** Many-to-one relationship */
12
- BelongsTo: 'BELONGS_TO',
13
- /** Many-to-many relationship with pivot metadata */
14
- BelongsToMany: 'BELONGS_TO_MANY'
15
- } as const;
16
-
17
- /**
18
- * Type representing the supported relationship kinds
19
- */
20
- export type RelationType = (typeof RelationKinds)[keyof typeof RelationKinds];
21
-
22
- export type CascadeMode = 'none' | 'all' | 'persist' | 'remove' | 'link';
23
-
24
- /**
25
- * One-to-many relationship definition
26
- */
27
- export interface HasManyRelation<TTarget extends TableDef = TableDef> {
28
- type: typeof RelationKinds.HasMany;
29
- target: TTarget;
30
- foreignKey: string;
31
- localKey?: string;
32
- cascade?: CascadeMode;
33
- }
34
-
35
- /**
36
- * One-to-one relationship definition
37
- */
38
- export interface HasOneRelation<TTarget extends TableDef = TableDef> {
39
- type: typeof RelationKinds.HasOne;
40
- target: TTarget;
41
- foreignKey: string;
42
- localKey?: string;
43
- cascade?: CascadeMode;
44
- }
45
-
46
- /**
47
- * Many-to-one relationship definition
48
- */
49
- export interface BelongsToRelation<TTarget extends TableDef = TableDef> {
50
- type: typeof RelationKinds.BelongsTo;
51
- target: TTarget;
52
- foreignKey: string;
53
- localKey?: string;
54
- cascade?: CascadeMode;
55
- }
56
-
57
- /**
58
- * Many-to-many relationship definition with rich pivot metadata
59
- */
60
- export interface BelongsToManyRelation<
61
- TTarget extends TableDef = TableDef,
62
- TPivot extends TableDef = TableDef
63
- > {
64
- type: typeof RelationKinds.BelongsToMany;
65
- target: TTarget;
66
- pivotTable: TPivot;
67
- pivotForeignKeyToRoot: string;
68
- pivotForeignKeyToTarget: string;
69
- localKey?: string;
70
- targetKey?: string;
71
- pivotPrimaryKey?: string;
72
- defaultPivotColumns?: string[];
73
- cascade?: CascadeMode;
74
- }
75
-
76
- /**
77
- * Union type representing any supported relationship definition
78
- */
79
- export type RelationDef =
80
- | HasManyRelation
81
- | HasOneRelation
82
- | BelongsToRelation
83
- | BelongsToManyRelation;
84
-
85
- /**
86
- * Creates a one-to-many relationship definition
87
- * @param target - Target table of the relationship
88
- * @param foreignKey - Foreign key column name on the child table
89
- * @param localKey - Local key column name (optional)
90
- * @returns HasManyRelation definition
91
- *
92
- * @example
93
- * ```typescript
94
- * hasMany(usersTable, 'user_id')
95
- * ```
96
- */
97
- export const hasMany = <TTarget extends TableDef>(
98
- target: TTarget,
99
- foreignKey: string,
100
- localKey?: string,
101
- cascade?: CascadeMode
102
- ): HasManyRelation<TTarget> => ({
103
- type: RelationKinds.HasMany,
104
- target,
105
- foreignKey,
106
- localKey,
107
- cascade
108
- });
109
-
110
- /**
111
- * Creates a one-to-one relationship definition
112
- * @param target - Target table of the relationship
113
- * @param foreignKey - Foreign key column name on the child table
114
- * @param localKey - Local key column name (optional)
115
- * @returns HasOneRelation definition
116
- */
117
- export const hasOne = <TTarget extends TableDef>(
118
- target: TTarget,
119
- foreignKey: string,
120
- localKey?: string,
121
- cascade?: CascadeMode
122
- ): HasOneRelation<TTarget> => ({
123
- type: RelationKinds.HasOne,
124
- target,
125
- foreignKey,
126
- localKey,
127
- cascade
128
- });
129
-
130
- /**
131
- * Creates a many-to-one relationship definition
132
- * @param target - Target table of the relationship
133
- * @param foreignKey - Foreign key column name on the child table
134
- * @param localKey - Local key column name (optional)
135
- * @returns BelongsToRelation definition
136
- *
137
- * @example
138
- * ```typescript
139
- * belongsTo(usersTable, 'user_id')
140
- * ```
141
- */
142
- export const belongsTo = <TTarget extends TableDef>(
143
- target: TTarget,
144
- foreignKey: string,
145
- localKey?: string,
146
- cascade?: CascadeMode
147
- ): BelongsToRelation<TTarget> => ({
148
- type: RelationKinds.BelongsTo,
149
- target,
150
- foreignKey,
151
- localKey,
152
- cascade
153
- });
154
-
155
- /**
156
- * Creates a many-to-many relationship definition with pivot metadata
157
- * @param target - Target table
158
- * @param pivotTable - Intermediate pivot table definition
159
- * @param options - Pivot metadata configuration
160
- * @returns BelongsToManyRelation definition
161
- */
162
- export const belongsToMany = <
163
- TTarget extends TableDef,
164
- TPivot extends TableDef = TableDef
165
- >(
166
- target: TTarget,
167
- pivotTable: TPivot,
168
- options: {
169
- pivotForeignKeyToRoot: string;
170
- pivotForeignKeyToTarget: string;
171
- localKey?: string;
172
- targetKey?: string;
173
- pivotPrimaryKey?: string;
174
- defaultPivotColumns?: string[];
175
- cascade?: CascadeMode;
176
- }
177
- ): BelongsToManyRelation<TTarget, TPivot> => ({
178
- type: RelationKinds.BelongsToMany,
179
- target,
180
- pivotTable,
181
- pivotForeignKeyToRoot: options.pivotForeignKeyToRoot,
182
- pivotForeignKeyToTarget: options.pivotForeignKeyToTarget,
183
- localKey: options.localKey,
184
- targetKey: options.targetKey,
185
- pivotPrimaryKey: options.pivotPrimaryKey,
186
- defaultPivotColumns: options.defaultPivotColumns,
187
- cascade: options.cascade
188
- });
1
+ import type { TableDef } from './table.js';
2
+
3
+ /**
4
+ * Types of relationships supported between tables
5
+ */
6
+ export const RelationKinds = {
7
+ /** One-to-one relationship */
8
+ HasOne: 'HAS_ONE',
9
+ /** One-to-many relationship */
10
+ HasMany: 'HAS_MANY',
11
+ /** Many-to-one relationship */
12
+ BelongsTo: 'BELONGS_TO',
13
+ /** Many-to-many relationship with pivot metadata */
14
+ BelongsToMany: 'BELONGS_TO_MANY',
15
+ /** Polymorphic inverse (child side) */
16
+ MorphTo: 'MORPH_TO',
17
+ /** Polymorphic one-to-one (parent side) */
18
+ MorphOne: 'MORPH_ONE',
19
+ /** Polymorphic one-to-many (parent side) */
20
+ MorphMany: 'MORPH_MANY'
21
+ } as const;
22
+
23
+ /**
24
+ * Type representing the supported relationship kinds
25
+ */
26
+ export type RelationType = (typeof RelationKinds)[keyof typeof RelationKinds];
27
+
28
+ export type CascadeMode = 'none' | 'all' | 'persist' | 'remove' | 'link';
29
+
30
+ /**
31
+ * One-to-many relationship definition
32
+ */
33
+ export interface HasManyRelation<TTarget extends TableDef = TableDef> {
34
+ type: typeof RelationKinds.HasMany;
35
+ target: TTarget;
36
+ foreignKey: string;
37
+ localKey?: string;
38
+ cascade?: CascadeMode;
39
+ }
40
+
41
+ /**
42
+ * One-to-one relationship definition
43
+ */
44
+ export interface HasOneRelation<TTarget extends TableDef = TableDef> {
45
+ type: typeof RelationKinds.HasOne;
46
+ target: TTarget;
47
+ foreignKey: string;
48
+ localKey?: string;
49
+ cascade?: CascadeMode;
50
+ }
51
+
52
+ /**
53
+ * Many-to-one relationship definition
54
+ */
55
+ export interface BelongsToRelation<TTarget extends TableDef = TableDef> {
56
+ type: typeof RelationKinds.BelongsTo;
57
+ target: TTarget;
58
+ foreignKey: string;
59
+ localKey?: string;
60
+ cascade?: CascadeMode;
61
+ }
62
+
63
+ /**
64
+ * Many-to-many relationship definition with rich pivot metadata
65
+ */
66
+ export interface BelongsToManyRelation<
67
+ TTarget extends TableDef = TableDef,
68
+ TPivot extends TableDef = TableDef
69
+ > {
70
+ type: typeof RelationKinds.BelongsToMany;
71
+ target: TTarget;
72
+ pivotTable: TPivot;
73
+ pivotForeignKeyToRoot: string;
74
+ pivotForeignKeyToTarget: string;
75
+ localKey?: string;
76
+ targetKey?: string;
77
+ pivotPrimaryKey?: string;
78
+ defaultPivotColumns?: string[];
79
+ cascade?: CascadeMode;
80
+ }
81
+
82
+ /**
83
+ * Polymorphic inverse relationship (child side).
84
+ * The child row stores a type + id pair that can point to any of the listed targets.
85
+ */
86
+ export interface MorphToRelation<TTargets extends Record<string, TableDef> = Record<string, TableDef>> {
87
+ type: typeof RelationKinds.MorphTo;
88
+ typeField: string;
89
+ idField: string;
90
+ targets: TTargets;
91
+ targetKey?: string;
92
+ cascade?: CascadeMode;
93
+ }
94
+
95
+ /**
96
+ * Polymorphic one-to-one relationship (parent side).
97
+ */
98
+ export interface MorphOneRelation<TTarget extends TableDef = TableDef> {
99
+ type: typeof RelationKinds.MorphOne;
100
+ target: TTarget;
101
+ morphName: string;
102
+ typeField: string;
103
+ idField: string;
104
+ typeValue: string;
105
+ localKey?: string;
106
+ cascade?: CascadeMode;
107
+ }
108
+
109
+ /**
110
+ * Polymorphic one-to-many relationship (parent side).
111
+ */
112
+ export interface MorphManyRelation<TTarget extends TableDef = TableDef> {
113
+ type: typeof RelationKinds.MorphMany;
114
+ target: TTarget;
115
+ morphName: string;
116
+ typeField: string;
117
+ idField: string;
118
+ typeValue: string;
119
+ localKey?: string;
120
+ cascade?: CascadeMode;
121
+ }
122
+
123
+ /**
124
+ * Union type representing any supported relationship definition
125
+ */
126
+ export type RelationDef =
127
+ | HasManyRelation
128
+ | HasOneRelation
129
+ | BelongsToRelation
130
+ | BelongsToManyRelation
131
+ | MorphToRelation
132
+ | MorphOneRelation
133
+ | MorphManyRelation;
134
+
135
+ /**
136
+ * Creates a one-to-many relationship definition
137
+ * @param target - Target table of the relationship
138
+ * @param foreignKey - Foreign key column name on the child table
139
+ * @param localKey - Local key column name (optional)
140
+ * @returns HasManyRelation definition
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * hasMany(usersTable, 'user_id')
145
+ * ```
146
+ */
147
+ export const hasMany = <TTarget extends TableDef>(
148
+ target: TTarget,
149
+ foreignKey: string,
150
+ localKey?: string,
151
+ cascade?: CascadeMode
152
+ ): HasManyRelation<TTarget> => ({
153
+ type: RelationKinds.HasMany,
154
+ target,
155
+ foreignKey,
156
+ localKey,
157
+ cascade
158
+ });
159
+
160
+ /**
161
+ * Creates a one-to-one relationship definition
162
+ * @param target - Target table of the relationship
163
+ * @param foreignKey - Foreign key column name on the child table
164
+ * @param localKey - Local key column name (optional)
165
+ * @returns HasOneRelation definition
166
+ */
167
+ export const hasOne = <TTarget extends TableDef>(
168
+ target: TTarget,
169
+ foreignKey: string,
170
+ localKey?: string,
171
+ cascade?: CascadeMode
172
+ ): HasOneRelation<TTarget> => ({
173
+ type: RelationKinds.HasOne,
174
+ target,
175
+ foreignKey,
176
+ localKey,
177
+ cascade
178
+ });
179
+
180
+ /**
181
+ * Creates a many-to-one relationship definition
182
+ * @param target - Target table of the relationship
183
+ * @param foreignKey - Foreign key column name on the child table
184
+ * @param localKey - Local key column name (optional)
185
+ * @returns BelongsToRelation definition
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * belongsTo(usersTable, 'user_id')
190
+ * ```
191
+ */
192
+ export const belongsTo = <TTarget extends TableDef>(
193
+ target: TTarget,
194
+ foreignKey: string,
195
+ localKey?: string,
196
+ cascade?: CascadeMode
197
+ ): BelongsToRelation<TTarget> => ({
198
+ type: RelationKinds.BelongsTo,
199
+ target,
200
+ foreignKey,
201
+ localKey,
202
+ cascade
203
+ });
204
+
205
+ /**
206
+ * Creates a many-to-many relationship definition with pivot metadata
207
+ * @param target - Target table
208
+ * @param pivotTable - Intermediate pivot table definition
209
+ * @param options - Pivot metadata configuration
210
+ * @returns BelongsToManyRelation definition
211
+ */
212
+ export const belongsToMany = <
213
+ TTarget extends TableDef,
214
+ TPivot extends TableDef = TableDef
215
+ >(
216
+ target: TTarget,
217
+ pivotTable: TPivot,
218
+ options: {
219
+ pivotForeignKeyToRoot: string;
220
+ pivotForeignKeyToTarget: string;
221
+ localKey?: string;
222
+ targetKey?: string;
223
+ pivotPrimaryKey?: string;
224
+ defaultPivotColumns?: string[];
225
+ cascade?: CascadeMode;
226
+ }
227
+ ): BelongsToManyRelation<TTarget, TPivot> => ({
228
+ type: RelationKinds.BelongsToMany,
229
+ target,
230
+ pivotTable,
231
+ pivotForeignKeyToRoot: options.pivotForeignKeyToRoot,
232
+ pivotForeignKeyToTarget: options.pivotForeignKeyToTarget,
233
+ localKey: options.localKey,
234
+ targetKey: options.targetKey,
235
+ pivotPrimaryKey: options.pivotPrimaryKey,
236
+ defaultPivotColumns: options.defaultPivotColumns,
237
+ cascade: options.cascade
238
+ });
239
+
240
+ export const isSingleTargetRelation = (
241
+ rel: RelationDef
242
+ ): rel is Exclude<RelationDef, MorphToRelation> =>
243
+ rel.type !== RelationKinds.MorphTo;
244
+
245
+ export const isMorphRelation = (rel: RelationDef): rel is
246
+ MorphToRelation | MorphOneRelation | MorphManyRelation =>
247
+ rel.type === RelationKinds.MorphTo ||
248
+ rel.type === RelationKinds.MorphOne ||
249
+ rel.type === RelationKinds.MorphMany;
250
+
251
+ export const morphTo = <TTargets extends Record<string, TableDef>>(opts: {
252
+ typeField: string;
253
+ idField: string;
254
+ targets: TTargets;
255
+ targetKey?: string;
256
+ cascade?: CascadeMode;
257
+ }): MorphToRelation<TTargets> => ({
258
+ type: RelationKinds.MorphTo,
259
+ ...opts
260
+ });
261
+
262
+ export const morphOne = <TTarget extends TableDef>(target: TTarget, opts: {
263
+ as: string;
264
+ typeValue: string;
265
+ localKey?: string;
266
+ typeField?: string;
267
+ idField?: string;
268
+ cascade?: CascadeMode;
269
+ }): MorphOneRelation<TTarget> => ({
270
+ type: RelationKinds.MorphOne,
271
+ target,
272
+ morphName: opts.as,
273
+ typeField: opts.typeField ?? `${opts.as}Type`,
274
+ idField: opts.idField ?? `${opts.as}Id`,
275
+ typeValue: opts.typeValue,
276
+ localKey: opts.localKey,
277
+ cascade: opts.cascade
278
+ });
279
+
280
+ export const morphMany = <TTarget extends TableDef>(target: TTarget, opts: {
281
+ as: string;
282
+ typeValue: string;
283
+ localKey?: string;
284
+ typeField?: string;
285
+ idField?: string;
286
+ cascade?: CascadeMode;
287
+ }): MorphManyRelation<TTarget> => ({
288
+ type: RelationKinds.MorphMany,
289
+ target,
290
+ morphName: opts.as,
291
+ typeField: opts.typeField ?? `${opts.as}Type`,
292
+ idField: opts.idField ?? `${opts.as}Id`,
293
+ typeValue: opts.typeValue,
294
+ localKey: opts.localKey,
295
+ cascade: opts.cascade
296
+ });