@reldens/storage 0.116.0 → 0.118.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/test-architecture.md +27 -17
- package/CLAUDE.md +67 -11
- package/README.md +204 -22
- package/bin/reldens-storage.js +43 -10
- package/index.js +53 -12
- package/lib/drizzle/drizzle-data-server.js +123 -0
- package/lib/drizzle/drizzle-driver.js +228 -0
- package/lib/drizzle/drizzle-models-generation.js +49 -0
- package/lib/drizzle/drizzle-modules-loader.js +32 -0
- package/lib/drizzle/drizzle-modules-validator.js +74 -0
- package/lib/entities-generator.js +36 -7
- package/lib/entity-templates/drizzle-model.template +28 -0
- package/lib/entity-templates/query-builder-model.template +17 -0
- package/lib/generators/base-generator.js +13 -0
- package/lib/generators/entities-generation.js +0 -13
- package/lib/generators/models-generation.js +179 -693
- package/lib/generators/relations-detection.js +171 -0
- package/lib/knex/knex-data-server.js +128 -0
- package/lib/knex/knex-driver.js +157 -0
- package/lib/knex/knex-modules-loader.js +28 -0
- package/lib/knex/knex-modules-validator.js +45 -0
- package/lib/kysely/kysely-data-server.js +128 -0
- package/lib/kysely/kysely-driver.js +176 -0
- package/lib/kysely/kysely-modules-loader.js +28 -0
- package/lib/kysely/kysely-modules-validator.js +53 -0
- package/lib/mikro-orm/mikro-orm-data-server.js +48 -29
- package/lib/mikro-orm/mikro-orm-driver.js +385 -121
- package/lib/mikro-orm/mikro-orm-models-generation.js +178 -0
- package/lib/mikro-orm/mikro-orm-modules-loader.js +50 -0
- package/lib/mikro-orm/mikro-orm-modules-validator.js +46 -0
- package/lib/mysql2-connection-config.js +38 -0
- package/lib/objection-js/objection-js-data-server.js +71 -125
- package/lib/objection-js/objection-js-driver.js +4 -1
- package/lib/objection-js/objection-js-models-generation.js +98 -0
- package/lib/objection-js/objection-modules-loader.js +28 -0
- package/lib/objection-js/objection-modules-validator.js +31 -0
- package/lib/package-resolver.js +45 -0
- package/lib/prisma/prisma-client-loader.js +11 -1
- package/lib/prisma/prisma-driver.js +16 -2
- package/lib/prisma/prisma-filter-processor.js +5 -6
- package/lib/prisma/prisma-models-generation.js +236 -0
- package/lib/prisma/prisma-schema-generator.js +5 -1
- package/lib/prisma/prisma-type-caster.js +14 -0
- package/lib/query-builder-driver.js +210 -0
- package/lib/query-builder-models-generation.js +80 -0
- package/lib/relations-loader.js +192 -0
- package/lib/type-mapper.js +38 -0
- package/package.json +7 -7
- package/tests/.env.test.example +6 -0
- package/tests/fixtures/categories-fixtures.js +8 -0
- package/tests/fixtures/expected-entities/entities/test-product-details-entity.js +72 -0
- package/tests/fixtures/expected-entities/entities-config.js +6 -4
- package/tests/fixtures/expected-entities/entities-translations.js +25 -14
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/registered-models-mikro-orm.js +2 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-categories-model.js +13 -8
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-product-details-model.js +80 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-products-model.js +20 -14
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-reviews-model.js +13 -12
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/registered-models-objection-js.js +2 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-product-details-model.js +33 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-products-model.js +9 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/registered-models-prisma.js +2 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-product-details-model.js +43 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-products-model.js +2 -0
- package/tests/fixtures/product-details-fixtures.js +22 -0
- package/tests/fixtures/reviews-fixtures.js +2 -1
- package/tests/fixtures/sql/test-schema.sql +23 -1
- package/tests/fixtures/table-columns-fixtures.js +97 -0
- package/tests/integration/test-cross-driver-equivalence.js +286 -0
- package/tests/integration/test-nested-filters.js +265 -408
- package/tests/integration/test-relations.js +199 -0
- package/tests/integration/test-reldens-sample-data.js +255 -0
- package/tests/integration/test-reldens-shape-relations.js +292 -0
- package/tests/run-tests.js +112 -60
- package/tests/unit/test-drivers.js +7 -1
- package/tests/unit/test-models-generation.js +174 -0
- package/tests/utils/column-value-assert.js +139 -0
- package/tests/utils/driver-registry.js +1 -1
- package/tests/utils/entity-projection.js +111 -0
- package/tests/utils/observed-value.js +41 -0
- package/tests/utils/projection-difference.js +151 -0
- package/tests/utils/relations-shape-support.js +104 -0
- package/tests/utils/reldens-schema-loader.js +274 -0
- package/tests/utils/test-helpers.js +152 -19
- package/tests/utils/test-runner.js +26 -5
- package/tests/utils/whole-result-assert.js +243 -0
|
@@ -1,693 +1,179 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Reldens - ModelsGeneration
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { FileHandler } = require('@reldens/server-utils');
|
|
8
|
-
const { Logger, sc } = require('@reldens/utils');
|
|
9
|
-
const {
|
|
10
|
-
const {
|
|
11
|
-
const {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let
|
|
53
|
-
if(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
let
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
let
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
{
|
|
181
|
-
let lowerColumn = columnName.toLowerCase();
|
|
182
|
-
let lowerTable = referencedTable.toLowerCase();
|
|
183
|
-
for(let prismaName of Object.keys(relationMetadata)){
|
|
184
|
-
let relation = relationMetadata[prismaName];
|
|
185
|
-
if(relation.model.toLowerCase() !== lowerTable){
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
if(relation.isList){
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
let lowerPrisma = prismaName.toLowerCase();
|
|
192
|
-
if(lowerPrisma.includes(lowerColumn.replace('_id', ''))){
|
|
193
|
-
return prismaName;
|
|
194
|
-
}
|
|
195
|
-
if(lowerPrisma.includes(lowerColumn)){
|
|
196
|
-
return prismaName;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
for(let prismaName of Object.keys(relationMetadata)){
|
|
200
|
-
let relation = relationMetadata[prismaName];
|
|
201
|
-
if(relation.model.toLowerCase() !== lowerTable){
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
if(relation.isList){
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
return prismaName;
|
|
208
|
-
}
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
buildPrismaReverseMappings(tableName, relationMetadata)
|
|
213
|
-
{
|
|
214
|
-
let mappings = {};
|
|
215
|
-
let reverseRelations = {};
|
|
216
|
-
for(let prismaName of Object.keys(relationMetadata)){
|
|
217
|
-
let relation = relationMetadata[prismaName];
|
|
218
|
-
if(this.isForwardRelation(relation)){
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
let relatedTable = relation.model.toLowerCase();
|
|
222
|
-
if(!reverseRelations[relatedTable]){
|
|
223
|
-
reverseRelations[relatedTable] = [];
|
|
224
|
-
}
|
|
225
|
-
reverseRelations[relatedTable].push({prismaName, relation});
|
|
226
|
-
}
|
|
227
|
-
for(let relatedTable of Object.keys(reverseRelations)){
|
|
228
|
-
let relations = reverseRelations[relatedTable];
|
|
229
|
-
let referenceCount = relations.length;
|
|
230
|
-
for(let relInfo of relations){
|
|
231
|
-
let reldensKey = this.generatePrismaReverseRelationKey(
|
|
232
|
-
relatedTable,
|
|
233
|
-
relInfo.prismaName,
|
|
234
|
-
tableName,
|
|
235
|
-
referenceCount
|
|
236
|
-
);
|
|
237
|
-
mappings[reldensKey] = relInfo.prismaName;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return mappings;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
isForwardRelation(relation)
|
|
244
|
-
{
|
|
245
|
-
return sc.hasOwn(relation, 'foreignKeys')
|
|
246
|
-
&& sc.isArray(relation.foreignKeys)
|
|
247
|
-
&& 0 < relation.foreignKeys.length;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
generatePrismaReverseRelationKey(relatedTable, prismaName, tableName, referenceCount)
|
|
251
|
-
{
|
|
252
|
-
if(1 === referenceCount){
|
|
253
|
-
return RELATION_PREFIX+relatedTable;
|
|
254
|
-
}
|
|
255
|
-
let columnHint = this.extractColumnHintFromPrismaName(prismaName, relatedTable, tableName);
|
|
256
|
-
if(columnHint){
|
|
257
|
-
return RELATION_PREFIX+relatedTable+'_'+columnHint;
|
|
258
|
-
}
|
|
259
|
-
return RELATION_PREFIX+relatedTable;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
extractColumnHintFromPrismaName(prismaName, relatedTable, tableName)
|
|
263
|
-
{
|
|
264
|
-
let lowerName = prismaName.toLowerCase();
|
|
265
|
-
let lowerTable = tableName.toLowerCase();
|
|
266
|
-
let lowerRelated = relatedTable.toLowerCase();
|
|
267
|
-
let toSuffix = 'to'+lowerTable;
|
|
268
|
-
if(!lowerName.endsWith(toSuffix)){
|
|
269
|
-
toSuffix = 'to'+lowerRelated;
|
|
270
|
-
if(!lowerName.endsWith(toSuffix)){
|
|
271
|
-
return null;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
let withoutSuffix = prismaName.slice(0, -toSuffix.length);
|
|
275
|
-
let lowerWithout = withoutSuffix.toLowerCase();
|
|
276
|
-
let prefixes = [
|
|
277
|
-
lowerRelated+'_'+lowerRelated+'_',
|
|
278
|
-
lowerRelated+'_',
|
|
279
|
-
lowerTable+'_'
|
|
280
|
-
];
|
|
281
|
-
for(let prefix of prefixes){
|
|
282
|
-
if(lowerWithout.startsWith(prefix)){
|
|
283
|
-
withoutSuffix = withoutSuffix.slice(prefix.length);
|
|
284
|
-
lowerWithout = withoutSuffix.toLowerCase();
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if(withoutSuffix.endsWith('_id')){
|
|
288
|
-
withoutSuffix = withoutSuffix.slice(0, -3);
|
|
289
|
-
}
|
|
290
|
-
return withoutSuffix.toLowerCase();
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
generateObjectionJsRelations(tableName, tableData)
|
|
294
|
-
{
|
|
295
|
-
let relations = this.detectObjectionJsRelations(tableName, tableData);
|
|
296
|
-
let reverseRelations = this.detectReverseObjectionJsRelations(tableName);
|
|
297
|
-
let allRelations = Object.assign({}, relations, reverseRelations);
|
|
298
|
-
if(0 === Object.keys(allRelations).length){
|
|
299
|
-
return '';
|
|
300
|
-
}
|
|
301
|
-
let relationMappings = [];
|
|
302
|
-
let requiredModels = [];
|
|
303
|
-
for(let relationKey of Object.keys(allRelations)){
|
|
304
|
-
let relation = allRelations[relationKey];
|
|
305
|
-
let tableReference = relation.referencedTable || relation.referencingTable;
|
|
306
|
-
let relatedModelClass = sc.capitalizedCamelCase(tableReference)+'Model';
|
|
307
|
-
if(!requiredModels.find(m => m.modelClass === relatedModelClass)){
|
|
308
|
-
requiredModels.push({
|
|
309
|
-
modelClass: relatedModelClass,
|
|
310
|
-
fileName: sc.kebabCase(tableReference)+'-model'
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
let relationMapping = ' '+relationKey+': {\n';
|
|
314
|
-
relationMapping += ' relation: this.'+relation.relationType+',\n';
|
|
315
|
-
relationMapping += ' modelClass: '+relatedModelClass+',\n';
|
|
316
|
-
relationMapping += ' join: {\n';
|
|
317
|
-
relationMapping += ' from: this.tableName+\'.'+relation.fromColumn+'\',\n';
|
|
318
|
-
relationMapping += ' to: '+relatedModelClass+'.tableName+\'.'+relation.toColumn+'\'\n';
|
|
319
|
-
relationMapping += ' }\n';
|
|
320
|
-
relationMapping += ' }';
|
|
321
|
-
relationMappings.push(relationMapping);
|
|
322
|
-
}
|
|
323
|
-
if(0 === relationMappings.length){
|
|
324
|
-
return '';
|
|
325
|
-
}
|
|
326
|
-
let requireStatements = [];
|
|
327
|
-
for(let modelInfo of requiredModels){
|
|
328
|
-
requireStatements.push(' const { '+modelInfo.modelClass+' } = require(\'./'+modelInfo.fileName+'\');');
|
|
329
|
-
}
|
|
330
|
-
let relationMappingsMethod = '\n static get relationMappings()\n {\n';
|
|
331
|
-
relationMappingsMethod += requireStatements.join('\n')+'\n';
|
|
332
|
-
relationMappingsMethod += ' return {\n';
|
|
333
|
-
relationMappingsMethod += relationMappings.join(',\n');
|
|
334
|
-
relationMappingsMethod += '\n };\n';
|
|
335
|
-
relationMappingsMethod += ' }';
|
|
336
|
-
return relationMappingsMethod;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
detectObjectionJsRelations(tableName, tableData)
|
|
340
|
-
{
|
|
341
|
-
let relations = {};
|
|
342
|
-
let referenceCounts = this.countReferencesPerTable(tableData);
|
|
343
|
-
for(let columnName of Object.keys(tableData.columns)){
|
|
344
|
-
let column = tableData.columns[columnName];
|
|
345
|
-
if(!sc.hasOwn(column, 'referencedTable')){
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
let relationKey = this.generateForwardRelationKey(column.referencedTable, columnName, referenceCounts);
|
|
349
|
-
let relationType = this.determineForwardRelationType(tableName, columnName, column);
|
|
350
|
-
relations[relationKey] = {
|
|
351
|
-
fromColumn: columnName,
|
|
352
|
-
toColumn: column.referencedColumn,
|
|
353
|
-
referencedTable: column.referencedTable,
|
|
354
|
-
relationType: relationType
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
return relations;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
detectReverseObjectionJsRelations(tableName)
|
|
361
|
-
{
|
|
362
|
-
let reverseRelations = {};
|
|
363
|
-
for(let otherTableName of Object.keys(this.allTablesData)){
|
|
364
|
-
if(otherTableName === tableName){
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
let otherTableData = this.allTablesData[otherTableName];
|
|
368
|
-
let referenceCounts = this.countReferencesToTable(tableName, otherTableData);
|
|
369
|
-
for(let columnName of Object.keys(otherTableData.columns)){
|
|
370
|
-
let column = otherTableData.columns[columnName];
|
|
371
|
-
if(!sc.hasOwn(column, 'referencedTable')){
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
if(column.referencedTable !== tableName){
|
|
375
|
-
continue;
|
|
376
|
-
}
|
|
377
|
-
let relationKey = this.generateReverseRelationKey(otherTableName, columnName, referenceCounts);
|
|
378
|
-
let relationType = this.determineReverseRelationType(otherTableName, columnName, column);
|
|
379
|
-
reverseRelations[relationKey] = {
|
|
380
|
-
fromColumn: column.referencedColumn,
|
|
381
|
-
toColumn: columnName,
|
|
382
|
-
referencingTable: otherTableName,
|
|
383
|
-
relationType: relationType
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return reverseRelations;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
countReferencesPerTable(tableData)
|
|
391
|
-
{
|
|
392
|
-
let counts = {};
|
|
393
|
-
for(let columnName of Object.keys(tableData.columns)){
|
|
394
|
-
let column = tableData.columns[columnName];
|
|
395
|
-
if(!sc.hasOwn(column, 'referencedTable')){
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
if(!counts[column.referencedTable]){
|
|
399
|
-
counts[column.referencedTable] = 0;
|
|
400
|
-
}
|
|
401
|
-
counts[column.referencedTable]++;
|
|
402
|
-
}
|
|
403
|
-
return counts;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
countReferencesToTable(targetTable, sourceTableData)
|
|
407
|
-
{
|
|
408
|
-
let count = 0;
|
|
409
|
-
for(let columnName of Object.keys(sourceTableData.columns)){
|
|
410
|
-
let column = sourceTableData.columns[columnName];
|
|
411
|
-
if(!sc.hasOwn(column, 'referencedTable')){
|
|
412
|
-
continue;
|
|
413
|
-
}
|
|
414
|
-
if(column.referencedTable === targetTable){
|
|
415
|
-
count++;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return count;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
generateForwardRelationKey(referencedTable, columnName, referenceCounts)
|
|
422
|
-
{
|
|
423
|
-
if(1 === referenceCounts[referencedTable]){
|
|
424
|
-
return RELATION_PREFIX+referencedTable;
|
|
425
|
-
}
|
|
426
|
-
let columnSuffix = columnName;
|
|
427
|
-
if(this.removeIdFromMultipleRelations){
|
|
428
|
-
columnSuffix = columnName.replace(/_id$/i, '');
|
|
429
|
-
}
|
|
430
|
-
return RELATION_PREFIX+referencedTable+'_'+columnSuffix;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
generateReverseRelationKey(referencingTable, columnName, referenceCount)
|
|
434
|
-
{
|
|
435
|
-
if(1 === referenceCount){
|
|
436
|
-
return RELATION_PREFIX+referencingTable;
|
|
437
|
-
}
|
|
438
|
-
let columnSuffix = columnName;
|
|
439
|
-
if(this.removeIdFromMultipleRelations){
|
|
440
|
-
columnSuffix = columnName.replace(/_id$/i, '');
|
|
441
|
-
}
|
|
442
|
-
return RELATION_PREFIX+referencingTable+'_'+columnSuffix;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
determineForwardRelationType(tableName, columnName, column)
|
|
446
|
-
{
|
|
447
|
-
return 'BelongsToOneRelation';
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
determineReverseRelationType(referencingTableName, referencingColumnName, referencingColumn)
|
|
451
|
-
{
|
|
452
|
-
if(!this.allTablesData[referencingTableName]){
|
|
453
|
-
return 'HasManyRelation';
|
|
454
|
-
}
|
|
455
|
-
let referencingTableData = this.allTablesData[referencingTableName];
|
|
456
|
-
let referencingColumnData = referencingTableData.columns[referencingColumnName];
|
|
457
|
-
if(!referencingColumnData){
|
|
458
|
-
return 'HasManyRelation';
|
|
459
|
-
}
|
|
460
|
-
if('UNI' === referencingColumnData.key || 'PRI' === referencingColumnData.key){
|
|
461
|
-
return 'HasOneRelation';
|
|
462
|
-
}
|
|
463
|
-
return 'HasManyRelation';
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
determineRelationType(column, isForwardRelation)
|
|
467
|
-
{
|
|
468
|
-
if(isForwardRelation){
|
|
469
|
-
return 'BelongsToOneRelation';
|
|
470
|
-
}
|
|
471
|
-
if('PRI' === column.key || 'UNI' === column.key){
|
|
472
|
-
return 'HasOneRelation';
|
|
473
|
-
}
|
|
474
|
-
return 'HasManyRelation';
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
getEntityPropertiesDefinition(columns, driverKey, tableName = null, tableData = null)
|
|
478
|
-
{
|
|
479
|
-
if('mikro-orm' === driverKey){
|
|
480
|
-
let entityProps = [];
|
|
481
|
-
if(!tableName || !tableData){
|
|
482
|
-
for(let columnName of Object.keys(columns)){
|
|
483
|
-
let column = columns[columnName];
|
|
484
|
-
let isPrimary = 'PRI' === column.key;
|
|
485
|
-
let type = TypeMapper.mapDbTypeToJsType(column.type);
|
|
486
|
-
let hasDefault = null !== column.default && undefined !== column.default;
|
|
487
|
-
let propDef = columnName+': { type: \''+type+'\'';
|
|
488
|
-
if(isPrimary){
|
|
489
|
-
propDef += ', primary: true';
|
|
490
|
-
}
|
|
491
|
-
if(column.nullable || hasDefault){
|
|
492
|
-
propDef += ', nullable: true';
|
|
493
|
-
}
|
|
494
|
-
propDef += ' }';
|
|
495
|
-
entityProps.push(propDef);
|
|
496
|
-
}
|
|
497
|
-
return entityProps.join(',\n ');
|
|
498
|
-
}
|
|
499
|
-
let relations = this.detectObjectionJsRelations(tableName, tableData);
|
|
500
|
-
let fkColumnsUsedByRelations = {};
|
|
501
|
-
for(let relationKey of Object.keys(relations)){
|
|
502
|
-
let relation = relations[relationKey];
|
|
503
|
-
if(relation.fromColumn){
|
|
504
|
-
fkColumnsUsedByRelations[relation.fromColumn] = true;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
for(let columnName of Object.keys(columns)){
|
|
508
|
-
let column = columns[columnName];
|
|
509
|
-
if(fkColumnsUsedByRelations[columnName]){
|
|
510
|
-
let type = TypeMapper.mapDbTypeToJsType(column.type);
|
|
511
|
-
let propDef = columnName+': { type: \''+type+'\', persist: false }';
|
|
512
|
-
entityProps.push(propDef);
|
|
513
|
-
continue;
|
|
514
|
-
}
|
|
515
|
-
let isPrimary = 'PRI' === column.key;
|
|
516
|
-
let type = TypeMapper.mapDbTypeToJsType(column.type);
|
|
517
|
-
let hasDefault = null !== column.default && undefined !== column.default;
|
|
518
|
-
let propDef = columnName+': { type: \''+type+'\'';
|
|
519
|
-
if(isPrimary){
|
|
520
|
-
propDef += ', primary: true';
|
|
521
|
-
}
|
|
522
|
-
if(column.nullable || hasDefault){
|
|
523
|
-
propDef += ', nullable: true';
|
|
524
|
-
}
|
|
525
|
-
propDef += ' }';
|
|
526
|
-
entityProps.push(propDef);
|
|
527
|
-
}
|
|
528
|
-
for(let relationKey of Object.keys(relations)){
|
|
529
|
-
let relation = relations[relationKey];
|
|
530
|
-
let relatedModelClass = sc.capitalizedCamelCase(relation.referencedTable)+'Model';
|
|
531
|
-
let relatedModelFile = sc.kebabCase(relation.referencedTable)+'-model';
|
|
532
|
-
let kind = sc.get(this.mikroOrmRelationKindMap, relation.relationType, 'm:1');
|
|
533
|
-
let propDef = relationKey+': {\n';
|
|
534
|
-
propDef += ' kind: \''+kind+'\',\n';
|
|
535
|
-
propDef += ' entity: () => require(\'./'+relatedModelFile+'\').'+relatedModelClass;
|
|
536
|
-
if(relation.fromColumn){
|
|
537
|
-
propDef += ',\n joinColumns: [\''+relation.fromColumn+'\']';
|
|
538
|
-
}
|
|
539
|
-
propDef += '\n }';
|
|
540
|
-
entityProps.push(propDef);
|
|
541
|
-
}
|
|
542
|
-
let reverseRelations = this.detectReverseObjectionJsRelations(tableName);
|
|
543
|
-
for(let relationKey of Object.keys(reverseRelations)){
|
|
544
|
-
let relation = reverseRelations[relationKey];
|
|
545
|
-
let relatedModelClass = sc.capitalizedCamelCase(relation.referencingTable)+'Model';
|
|
546
|
-
let relatedModelFile = sc.kebabCase(relation.referencingTable)+'-model';
|
|
547
|
-
let kind = sc.get(this.mikroOrmRelationKindMap, relation.relationType, '1:m');
|
|
548
|
-
let mappedBy = this.findMappedByKey(tableName, relation.referencingTable, relation);
|
|
549
|
-
let propDef = relationKey+': {\n';
|
|
550
|
-
propDef += ' kind: \''+kind+'\',\n';
|
|
551
|
-
propDef += ' entity: () => require(\'./'+relatedModelFile+'\').'+relatedModelClass;
|
|
552
|
-
if(mappedBy){
|
|
553
|
-
propDef += ',\n mappedBy: \''+mappedBy+'\'';
|
|
554
|
-
}
|
|
555
|
-
propDef += '\n }';
|
|
556
|
-
entityProps.push(propDef);
|
|
557
|
-
}
|
|
558
|
-
return entityProps.join(',\n ');
|
|
559
|
-
}
|
|
560
|
-
if('prisma' === driverKey){
|
|
561
|
-
let prismaProps = [];
|
|
562
|
-
for(let columnName of Object.keys(columns)){
|
|
563
|
-
let column = columns[columnName];
|
|
564
|
-
let prismaType = TypeMapper.mapDbTypeToPrismaType(column.type);
|
|
565
|
-
let isPrimary = 'PRI' === column.key;
|
|
566
|
-
let propDef = columnName+': {\n type: \''+prismaType+'\'';
|
|
567
|
-
if(isPrimary){
|
|
568
|
-
propDef += ',\n id: true';
|
|
569
|
-
}
|
|
570
|
-
if(column.nullable){
|
|
571
|
-
propDef += ',\n optional: true';
|
|
572
|
-
}
|
|
573
|
-
propDef += '\n }';
|
|
574
|
-
prismaProps.push(propDef);
|
|
575
|
-
}
|
|
576
|
-
return prismaProps.join(',\n ');
|
|
577
|
-
}
|
|
578
|
-
return '';
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
findMappedByKey(currentTable, referencingTable, reverseRelation)
|
|
582
|
-
{
|
|
583
|
-
if(!this.allTablesData[referencingTable]){
|
|
584
|
-
return RELATION_PREFIX+currentTable;
|
|
585
|
-
}
|
|
586
|
-
let referencingTableData = this.allTablesData[referencingTable];
|
|
587
|
-
let forwardRelations = this.detectObjectionJsRelations(referencingTable, referencingTableData);
|
|
588
|
-
for(let forwardKey of Object.keys(forwardRelations)){
|
|
589
|
-
let forward = forwardRelations[forwardKey];
|
|
590
|
-
if(forward.referencedTable === currentTable && forward.toColumn === reverseRelation.fromColumn){
|
|
591
|
-
return forwardKey;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
return RELATION_PREFIX+currentTable;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
generateFkMappings(tableName, tableData, driverKey)
|
|
598
|
-
{
|
|
599
|
-
if('mikro-orm' !== driverKey){
|
|
600
|
-
return '';
|
|
601
|
-
}
|
|
602
|
-
if(!tableName || !tableData){
|
|
603
|
-
return '';
|
|
604
|
-
}
|
|
605
|
-
let fkMappings = {};
|
|
606
|
-
let referenceCounts = this.countReferencesPerTable(tableData);
|
|
607
|
-
for(let columnName of Object.keys(tableData.columns)){
|
|
608
|
-
let column = tableData.columns[columnName];
|
|
609
|
-
if(!sc.hasOwn(column, 'referencedTable')){
|
|
610
|
-
continue;
|
|
611
|
-
}
|
|
612
|
-
let relationKey = this.generateForwardRelationKey(column.referencedTable, columnName, referenceCounts);
|
|
613
|
-
let relatedModelClass = sc.capitalizedCamelCase(column.referencedTable)+'Model';
|
|
614
|
-
fkMappings[columnName] = {
|
|
615
|
-
relationKey: relationKey,
|
|
616
|
-
entityName: relatedModelClass,
|
|
617
|
-
referencedColumn: column.referencedColumn,
|
|
618
|
-
nullable: column.nullable || false
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
if(0 === Object.keys(fkMappings).length){
|
|
622
|
-
return '';
|
|
623
|
-
}
|
|
624
|
-
return JSON.stringify(fkMappings, null, 4);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
generateRegisteredModelsFile(entitiesInfo, existingModels, driverKey, templatePath)
|
|
628
|
-
{
|
|
629
|
-
if(!FileHandler.exists(templatePath)){
|
|
630
|
-
Logger.critical('Registered models template file not found: '+templatePath);
|
|
631
|
-
return false;
|
|
632
|
-
}
|
|
633
|
-
let registeredTemplateContent = FileHandler.fetchFileContents(templatePath);
|
|
634
|
-
if(!registeredTemplateContent){
|
|
635
|
-
Logger.critical('Failed to read registered models template file: '+templatePath);
|
|
636
|
-
return false;
|
|
637
|
-
}
|
|
638
|
-
let allEntities = Object.assign({}, entitiesInfo);
|
|
639
|
-
let replacements = {
|
|
640
|
-
registeredModels: this.getRegisteredModels(allEntities, existingModels, driverKey),
|
|
641
|
-
registeredEntitiesObject: this.getRegisteredEntitiesObject(allEntities, existingModels, driverKey)
|
|
642
|
-
};
|
|
643
|
-
let registeredContent = this.applyReplacements(registeredTemplateContent, replacements);
|
|
644
|
-
let driverFolder = FileHandler.joinPaths(this.modelsFolder, driverKey);
|
|
645
|
-
let filePath = FileHandler.joinPaths(driverFolder, 'registered-models-'+driverKey+'.js');
|
|
646
|
-
if(!FileHandler.writeFile(filePath, registeredContent)){
|
|
647
|
-
Logger.critical('Failed to write registered models file: '+filePath);
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
Logger.info('Generated registered models file: '+filePath);
|
|
651
|
-
return true;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
getRegisteredModels(allEntities, existingModels, driverKey)
|
|
655
|
-
{
|
|
656
|
-
let registeredModels = [];
|
|
657
|
-
for(let tableName of Object.keys(allEntities)){
|
|
658
|
-
let entity = allEntities[tableName];
|
|
659
|
-
if(entity.driverKey && driverKey !== entity.driverKey){
|
|
660
|
-
if(!existingModels[tableName] || !existingModels[tableName][driverKey]){
|
|
661
|
-
continue;
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
let modelClassName = entity.modelClassName || sc.capitalizedCamelCase(tableName)+'Model';
|
|
665
|
-
let modelFileName = entity.modelFileName || sc.kebabCase(tableName)+'-model.js';
|
|
666
|
-
let variableName = 'mikro-orm' !== driverKey ? '{ '+modelClassName+' }' : sc.camelCase(tableName)+'Model';
|
|
667
|
-
registeredModels.push(
|
|
668
|
-
'const '+variableName+' = require(\'./'+modelFileName.replace('.js', '')+'\');'
|
|
669
|
-
);
|
|
670
|
-
}
|
|
671
|
-
return registeredModels.join('\n');
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
getRegisteredEntitiesObject(allEntities, existingModels, driverKey)
|
|
675
|
-
{
|
|
676
|
-
let registeredEntitiesObject = [];
|
|
677
|
-
for(let tableName of Object.keys(allEntities)){
|
|
678
|
-
let entity = allEntities[tableName];
|
|
679
|
-
if(entity.driverKey && driverKey !== entity.driverKey){
|
|
680
|
-
if(!existingModels[tableName] || !existingModels[tableName][driverKey]){
|
|
681
|
-
continue;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
let modelClassName = entity.modelClassName || sc.capitalizedCamelCase(tableName)+'Model';
|
|
685
|
-
let variableName = 'mikro-orm' === driverKey ? sc.camelCase(tableName)+'Model' : modelClassName;
|
|
686
|
-
registeredEntitiesObject.push(sc.camelCase(tableName)+': '+variableName);
|
|
687
|
-
}
|
|
688
|
-
return registeredEntitiesObject.join(',\n ');
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
module.exports.ModelsGeneration = ModelsGeneration;
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - ModelsGeneration
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { FileHandler } = require('@reldens/server-utils');
|
|
8
|
+
const { Logger, sc } = require('@reldens/utils');
|
|
9
|
+
const { BaseGenerator } = require('./base-generator');
|
|
10
|
+
const { RelationsDetection } = require('./relations-detection');
|
|
11
|
+
const { ObjectionJsModelsGeneration } = require('../objection-js/objection-js-models-generation');
|
|
12
|
+
const { MikroOrmModelsGeneration } = require('../mikro-orm/mikro-orm-models-generation');
|
|
13
|
+
const { PrismaModelsGeneration } = require('../prisma/prisma-models-generation');
|
|
14
|
+
const { QueryBuilderModelsGeneration } = require('../query-builder-models-generation');
|
|
15
|
+
const { DrizzleModelsGeneration } = require('../drizzle/drizzle-models-generation');
|
|
16
|
+
|
|
17
|
+
class ModelsGeneration extends BaseGenerator
|
|
18
|
+
{
|
|
19
|
+
|
|
20
|
+
constructor(props)
|
|
21
|
+
{
|
|
22
|
+
super();
|
|
23
|
+
this.modelsFolder = sc.get(props, 'modelsFolder', '');
|
|
24
|
+
this.templates = sc.get(props, 'templates', {});
|
|
25
|
+
this.generatedModels = {};
|
|
26
|
+
this.relationsDetection = new RelationsDetection(props);
|
|
27
|
+
this.driversGeneration = {
|
|
28
|
+
'objection-js': new ObjectionJsModelsGeneration(this.relationsDetection),
|
|
29
|
+
'mikro-orm': new MikroOrmModelsGeneration(this.relationsDetection),
|
|
30
|
+
'prisma': new PrismaModelsGeneration(this.relationsDetection),
|
|
31
|
+
'knex': new QueryBuilderModelsGeneration(this.relationsDetection),
|
|
32
|
+
'kysely': new QueryBuilderModelsGeneration(this.relationsDetection),
|
|
33
|
+
'drizzle': new DrizzleModelsGeneration(this.relationsDetection)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
driverGeneration(driverKey)
|
|
38
|
+
{
|
|
39
|
+
if(!sc.hasOwn(this.driversGeneration, driverKey)){
|
|
40
|
+
Logger.critical('Models generation not available for driver "'+driverKey+'".');
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return this.driversGeneration[driverKey];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async generateModelFile(tableName, tableData, driverKey, entityInfo, relationMetadata = {})
|
|
47
|
+
{
|
|
48
|
+
let driverGeneration = this.driverGeneration(driverKey);
|
|
49
|
+
if(!driverGeneration){
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
let modelTemplatePath = this.templates[driverKey];
|
|
53
|
+
if(!FileHandler.exists(modelTemplatePath)){
|
|
54
|
+
Logger.critical('Model template file "'+modelTemplatePath+'" not found for driver "'+driverKey+'".');
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
let modelTemplateContent = FileHandler.fetchFileContents(modelTemplatePath);
|
|
58
|
+
if(!modelTemplateContent){
|
|
59
|
+
Logger.critical('Failed to read model template file: '+modelTemplatePath);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
let modelContent = this.applyReplacements(
|
|
63
|
+
modelTemplateContent,
|
|
64
|
+
this.modelReplacements(tableName, tableData, driverGeneration, relationMetadata)
|
|
65
|
+
);
|
|
66
|
+
return this.writeModelFile(tableName, driverKey, modelContent);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
modelReplacements(tableName, tableData, driverGeneration, relationMetadata)
|
|
70
|
+
{
|
|
71
|
+
let fkMappingsJson = driverGeneration.generateFkMappings(tableName, tableData);
|
|
72
|
+
let fkMappingsAttachment = fkMappingsJson ? 'schema._fkMappings = '+fkMappingsJson+';' : '';
|
|
73
|
+
return {
|
|
74
|
+
modelClassName: sc.capitalizedCamelCase(tableName)+'Model',
|
|
75
|
+
tableName: driverGeneration.modelTableName(tableName),
|
|
76
|
+
modelPropertiesList: Object.keys(tableData.columns).join(', '),
|
|
77
|
+
modelPropertiesConstructor: Object.keys(tableData.columns)
|
|
78
|
+
.map(columnName => 'this.'+columnName+' = '+columnName+';')
|
|
79
|
+
.join('\n '),
|
|
80
|
+
modelRelations: driverGeneration.generateRelations(tableName, tableData, relationMetadata),
|
|
81
|
+
entityPropertiesDefinition: driverGeneration.generateEntityProperties(
|
|
82
|
+
tableData.columns,
|
|
83
|
+
tableName,
|
|
84
|
+
tableData
|
|
85
|
+
),
|
|
86
|
+
fkMappingsAttachment,
|
|
87
|
+
idColumn: driverGeneration.generateIdColumn(tableData.columns)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
writeModelFile(tableName, driverKey, modelContent)
|
|
92
|
+
{
|
|
93
|
+
let fileName = sc.kebabCase(tableName)+'-model.js';
|
|
94
|
+
let driverFolder = FileHandler.joinPaths(this.modelsFolder, driverKey);
|
|
95
|
+
FileHandler.createFolder(driverFolder);
|
|
96
|
+
if(!FileHandler.writeFile(FileHandler.joinPaths(driverFolder, fileName), modelContent)){
|
|
97
|
+
Logger.critical('Failed to write model file: '+fileName);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
Logger.info('Generated model file: '+fileName);
|
|
101
|
+
this.generatedModels[tableName] = {
|
|
102
|
+
modelClassName: sc.capitalizedCamelCase(tableName)+'Model',
|
|
103
|
+
modelFileName: fileName,
|
|
104
|
+
driverKey
|
|
105
|
+
};
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
generateRegisteredModelsFile(entitiesInfo, existingModels, driverKey, templatePath)
|
|
110
|
+
{
|
|
111
|
+
if(!FileHandler.exists(templatePath)){
|
|
112
|
+
Logger.critical('Registered models template file not found: '+templatePath);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
let registeredTemplateContent = FileHandler.fetchFileContents(templatePath);
|
|
116
|
+
if(!registeredTemplateContent){
|
|
117
|
+
Logger.critical('Failed to read registered models template file: '+templatePath);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
let allEntities = Object.assign({}, entitiesInfo);
|
|
121
|
+
let replacements = {
|
|
122
|
+
registeredModels: this.getRegisteredModels(allEntities, existingModels, driverKey),
|
|
123
|
+
registeredEntitiesObject: this.getRegisteredEntitiesObject(allEntities, existingModels, driverKey)
|
|
124
|
+
};
|
|
125
|
+
let registeredContent = this.applyReplacements(registeredTemplateContent, replacements);
|
|
126
|
+
let driverFolder = FileHandler.joinPaths(this.modelsFolder, driverKey);
|
|
127
|
+
let filePath = FileHandler.joinPaths(driverFolder, 'registered-models-'+driverKey+'.js');
|
|
128
|
+
if(!FileHandler.writeFile(filePath, registeredContent)){
|
|
129
|
+
Logger.critical('Failed to write registered models file: '+filePath);
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
Logger.info('Generated registered models file: '+filePath);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
isRegisteredEntity(entity, existingModels, tableName, driverKey)
|
|
137
|
+
{
|
|
138
|
+
if(!entity.driverKey || driverKey === entity.driverKey){
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
return Boolean(existingModels[tableName] && existingModels[tableName][driverKey]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
getRegisteredModels(allEntities, existingModels, driverKey)
|
|
145
|
+
{
|
|
146
|
+
let registeredModels = [];
|
|
147
|
+
for(let tableName of Object.keys(allEntities)){
|
|
148
|
+
let entity = allEntities[tableName];
|
|
149
|
+
if(!this.isRegisteredEntity(entity, existingModels, tableName, driverKey)){
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
let modelClassName = sc.get(entity, 'modelClassName', sc.capitalizedCamelCase(tableName)+'Model');
|
|
153
|
+
let modelFileName = sc.get(entity, 'modelFileName', sc.kebabCase(tableName)+'-model.js');
|
|
154
|
+
let variableName = 'mikro-orm' !== driverKey ? '{ '+modelClassName+' }' : sc.camelCase(tableName)+'Model';
|
|
155
|
+
registeredModels.push(
|
|
156
|
+
'const '+variableName+' = require(\'./'+modelFileName.replace('.js', '')+'\');'
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
return registeredModels.join('\n');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
getRegisteredEntitiesObject(allEntities, existingModels, driverKey)
|
|
163
|
+
{
|
|
164
|
+
let registeredEntitiesObject = [];
|
|
165
|
+
for(let tableName of Object.keys(allEntities)){
|
|
166
|
+
let entity = allEntities[tableName];
|
|
167
|
+
if(!this.isRegisteredEntity(entity, existingModels, tableName, driverKey)){
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
let modelClassName = sc.get(entity, 'modelClassName', sc.capitalizedCamelCase(tableName)+'Model');
|
|
171
|
+
let variableName = 'mikro-orm' === driverKey ? sc.camelCase(tableName)+'Model' : modelClassName;
|
|
172
|
+
registeredEntitiesObject.push(sc.camelCase(tableName)+': '+variableName);
|
|
173
|
+
}
|
|
174
|
+
return registeredEntitiesObject.join(',\n ');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports.ModelsGeneration = ModelsGeneration;
|