@postxl/generator 0.34.0 → 0.36.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/dist/generator.js +91 -32
- package/dist/generators/indices/businesslogic-actiontypes.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-actiontypes.generator.js +39 -0
- package/dist/generators/indices/businesslogic-update-index.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-update-index.generator.js +20 -0
- package/dist/generators/indices/businesslogic-update-module.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-update-module.generator.js +69 -0
- package/dist/generators/indices/businesslogic-update-service.generator.d.ts +9 -0
- package/dist/generators/indices/{businesslogicservice.generator.js → businesslogic-update-service.generator.js} +9 -10
- package/dist/generators/indices/businesslogic-view-index.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-view-index.generator.js +19 -0
- package/dist/generators/indices/{businesslogicindex.generator.d.ts → businesslogic-view-module.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogicmodule.generator.js → businesslogic-view-module.generator.js} +22 -26
- package/dist/generators/indices/{businesslogicservice.generator.d.ts → businesslogic-view-service.generator.d.ts} +1 -1
- package/dist/generators/indices/businesslogic-view-service.generator.js +34 -0
- package/dist/generators/indices/{datamockmodule.generator.js → datamock-module.generator.js} +8 -16
- package/dist/generators/indices/datamocker.generator.js +46 -40
- package/dist/generators/indices/datamodule.generator.js +7 -13
- package/dist/generators/indices/{businesslogicmodule.generator.d.ts → dispatcher-service.generator.d.ts} +2 -2
- package/dist/generators/indices/dispatcher-service.generator.js +81 -0
- package/dist/generators/indices/seed-migration.generator.d.ts +9 -0
- package/dist/generators/indices/seed-migration.generator.js +35 -0
- package/dist/generators/indices/seed-service.generator.d.ts +1 -1
- package/dist/generators/indices/seed-service.generator.js +327 -123
- package/dist/generators/indices/seed-template-decoder.generator.js +22 -6
- package/dist/generators/indices/{seed.generator.d.ts → seeddata-type.generator.d.ts} +2 -2
- package/dist/generators/indices/seeddata-type.generator.js +42 -0
- package/dist/generators/indices/types.generator.d.ts +1 -1
- package/dist/generators/indices/types.generator.js +8 -6
- package/dist/generators/models/businesslogic-update.generator.d.ts +10 -0
- package/dist/generators/models/businesslogic-update.generator.js +243 -0
- package/dist/generators/models/businesslogic-view.generator.d.ts +10 -0
- package/dist/generators/models/{businesslogic.generator.js → businesslogic-view.generator.js} +24 -72
- package/dist/generators/models/react.generator/modals.generator.js +2 -2
- package/dist/generators/models/repository.generator.d.ts +9 -0
- package/dist/generators/models/repository.generator.js +420 -131
- package/dist/generators/models/route.generator.js +45 -55
- package/dist/generators/models/seed.generator.js +6 -2
- package/dist/generators/models/types.generator.js +60 -13
- package/dist/lib/attributes.d.ts +5 -0
- package/dist/lib/imports.d.ts +23 -2
- package/dist/lib/imports.js +19 -1
- package/dist/lib/meta.d.ts +287 -34
- package/dist/lib/meta.js +87 -16
- package/dist/lib/schema/schema.d.ts +24 -6
- package/dist/lib/schema/types.d.ts +4 -0
- package/dist/lib/utils/jsdoc.d.ts +1 -1
- package/dist/lib/utils/jsdoc.js +8 -6
- package/dist/lib/utils/string.js +2 -1
- package/dist/lib/vfs.d.ts +33 -0
- package/dist/lib/vfs.js +157 -0
- package/dist/prisma/attributes.js +7 -3
- package/dist/prisma/parse.js +25 -5
- package/package.json +8 -3
- package/dist/generators/indices/businesslogicindex.generator.js +0 -19
- package/dist/generators/indices/seed.generator.js +0 -17
- package/dist/generators/indices/testdataservice.generator.d.ts +0 -9
- package/dist/generators/indices/testdataservice.generator.js +0 -78
- package/dist/generators/models/businesslogic.generator.d.ts +0 -9
- /package/dist/generators/indices/{datamockmodule.generator.d.ts → datamock-module.generator.d.ts} +0 -0
|
@@ -13,19 +13,18 @@ const string_1 = require("../../lib/utils/string");
|
|
|
13
13
|
*/
|
|
14
14
|
function generateRepository({ model, meta }) {
|
|
15
15
|
const { idField } = model;
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
from: meta.types.importPath,
|
|
16
|
+
const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
|
|
17
|
+
const imports = imports_1.ImportsGenerator.from(meta.data.repoFilePath).addImports({
|
|
18
|
+
[schemaMeta.data.repositoryTypeFilePath]: schemaMeta.data.repositoryTypeName,
|
|
19
|
+
[meta.types.importPath]: [
|
|
20
|
+
model.typeName,
|
|
21
|
+
model.brandedIdType,
|
|
22
|
+
meta.types.toBrandedIdTypeFnName,
|
|
23
|
+
meta.types.dto.create,
|
|
24
|
+
meta.types.dto.update,
|
|
25
|
+
meta.types.dto.upsert,
|
|
26
|
+
],
|
|
27
|
+
[schemaMeta.actions.importPath]: [schemaMeta.actions.actionExecutionInterface],
|
|
29
28
|
});
|
|
30
29
|
// NOTE: We first generate different parts of the code responsible for a particular task
|
|
31
30
|
// and then we combine them into the final code block.
|
|
@@ -40,6 +39,10 @@ function generateRepository({ model, meta }) {
|
|
|
40
39
|
// 4.) max length string fields are ensured to not exceed their max length,
|
|
41
40
|
// 5.) index for fields marked with index attribute,
|
|
42
41
|
// 6.) relations are indexed by the foreign key.
|
|
42
|
+
//
|
|
43
|
+
// The repository is generated differently based on whether the model is stored in the database or in memory.
|
|
44
|
+
// If the model is stored in the database, all CUD operations will result in a database call. If the model is
|
|
45
|
+
// stored in memory, all CUD operations will be performed in memory without any database calls.
|
|
43
46
|
const idBlocks = generateIdBlocks({ model, meta });
|
|
44
47
|
const defaultValueBlocks = generateDefaultBlocks({ model, meta });
|
|
45
48
|
const uniqueStringFieldsBlocks = generateUniqueFieldsBlocks({ model, meta });
|
|
@@ -51,6 +54,7 @@ function generateRepository({ model, meta }) {
|
|
|
51
54
|
mainBlocks = _generateMainBuildingBlocks_InMemoryOnly({
|
|
52
55
|
model,
|
|
53
56
|
meta,
|
|
57
|
+
schemaMeta,
|
|
54
58
|
blocks: {
|
|
55
59
|
uniqueStringFieldsBlocks,
|
|
56
60
|
defaultValueBlocks,
|
|
@@ -64,6 +68,7 @@ function generateRepository({ model, meta }) {
|
|
|
64
68
|
mainBlocks = generateMainBuildingBlocks_InDatabase({
|
|
65
69
|
model,
|
|
66
70
|
meta,
|
|
71
|
+
schemaMeta,
|
|
67
72
|
imports,
|
|
68
73
|
blocks: {
|
|
69
74
|
uniqueStringFieldsBlocks,
|
|
@@ -139,8 +144,16 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
139
144
|
|
|
140
145
|
${mainBlocks.updateCode}
|
|
141
146
|
|
|
147
|
+
${mainBlocks.updateManyCode}
|
|
148
|
+
|
|
149
|
+
${mainBlocks.upsertCode}
|
|
150
|
+
|
|
151
|
+
${mainBlocks.upsertManyCode}
|
|
152
|
+
|
|
142
153
|
${mainBlocks.deleteCode}
|
|
143
154
|
|
|
155
|
+
${mainBlocks.deleteManyCode}
|
|
156
|
+
|
|
144
157
|
${relationsBlocks.getterFunctions.join('\n')}
|
|
145
158
|
|
|
146
159
|
${maxLengthBlocks.ensureMaxLengthFunctions.join('\n')}
|
|
@@ -208,22 +221,24 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
208
221
|
return Promise.resolve()
|
|
209
222
|
}`,
|
|
210
223
|
reInitCode: `
|
|
211
|
-
public async reInit(
|
|
224
|
+
public async reInit({items, execution}: ${methodTypeSignatures.createMany.parameters[0]}): Promise<void> {
|
|
212
225
|
await this.init()
|
|
213
|
-
await this.createMany(
|
|
226
|
+
await this.createMany({items, execution})
|
|
214
227
|
}`,
|
|
215
228
|
deleteAllCode: `
|
|
216
229
|
public async deleteAll(): Promise<void> {
|
|
217
230
|
return this.init()
|
|
218
231
|
}`,
|
|
219
232
|
createCode: `
|
|
220
|
-
${(0, jsdoc_1.
|
|
233
|
+
${(0, jsdoc_1.toJsDocComment)([
|
|
221
234
|
`Checks that item has the ${model.idField.name} field.`,
|
|
222
235
|
`In case none exists, ${blocks.idBlocks.verifyFunctionComment}`,
|
|
223
236
|
blocks.uniqueStringFieldsBlocks.verifyFunctionComment,
|
|
224
237
|
blocks.maxLengthBlocks.verifyFunctionComment,
|
|
225
238
|
])}
|
|
226
|
-
private verifyItem(
|
|
239
|
+
private verifyItem(
|
|
240
|
+
item: ${blocks.idBlocks.verifyFunctionParameterType}
|
|
241
|
+
): ${model.name} {
|
|
227
242
|
${blocks.idBlocks.verifyCode}
|
|
228
243
|
|
|
229
244
|
${blocks.maxLengthBlocks.verifyCode.join('\n')}
|
|
@@ -239,61 +254,178 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
239
254
|
${model.createdAtField ? `${model.createdAtField.sourceName}: new Date(),` : ''}
|
|
240
255
|
${model.updatedAtField ? `${model.updatedAtField.sourceName}: new Date(),` : ''}
|
|
241
256
|
}
|
|
242
|
-
}
|
|
243
|
-
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.create.jsDoc)}
|
|
244
260
|
// Non-mocked version is async - so we keep type-compatible signatures for create() and createWithId()
|
|
245
261
|
// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
|
|
246
262
|
public async create(
|
|
247
|
-
item: ${methodTypeSignatures.create.parameters[0]}
|
|
263
|
+
{ item, execution }: ${methodTypeSignatures.create.parameters[0]}
|
|
248
264
|
): ${methodTypeSignatures.create.returnType} {
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
265
|
+
const mutationId = await execution.startCreateMutation({
|
|
266
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
267
|
+
createObject: item
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
const newItem = await Promise.resolve(this.verifyItem(item))
|
|
272
|
+
|
|
273
|
+
this.set(newItem)
|
|
274
|
+
await execution.finishCreateMutation({ mutationId, createdObject: newItem, entityId: newItem.id })
|
|
275
|
+
return newItem
|
|
276
|
+
} catch (error) {
|
|
277
|
+
await execution.errorMutation({ mutationId, error })
|
|
278
|
+
throw error
|
|
279
|
+
}
|
|
253
280
|
}`,
|
|
254
281
|
createManyCode: `
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
282
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.createMany.jsDoc)}
|
|
283
|
+
public async createMany(
|
|
284
|
+
{ items, execution }: ${methodTypeSignatures.createMany.parameters[0]}
|
|
285
|
+
): ${methodTypeSignatures.createMany.returnType} {
|
|
286
|
+
const mutationId = await execution.startCreateManyMutation({
|
|
287
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
288
|
+
createObjects: items
|
|
289
|
+
})
|
|
259
290
|
|
|
260
|
-
|
|
261
|
-
this.
|
|
291
|
+
try {
|
|
292
|
+
const newItems = items.map((item) => this.verifyItem(item))
|
|
293
|
+
|
|
294
|
+
await Promise.resolve()
|
|
295
|
+
|
|
296
|
+
for (const item of newItems) {
|
|
297
|
+
this.set(item)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
await execution.finishCreateManyMutation({
|
|
301
|
+
mutationId,
|
|
302
|
+
createdObjects: newItems,
|
|
303
|
+
entityIds: newItems.map((i) => i.id),
|
|
304
|
+
})
|
|
305
|
+
return newItems
|
|
306
|
+
} catch (error) {
|
|
307
|
+
await execution.errorMutation({ mutationId, error })
|
|
308
|
+
throw error
|
|
262
309
|
}
|
|
263
|
-
|
|
264
|
-
return newItems
|
|
265
310
|
}`,
|
|
266
|
-
// prettier-ignore
|
|
267
311
|
updateCode: `
|
|
268
|
-
|
|
312
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.update.jsDoc)}
|
|
313
|
+
public async update(
|
|
314
|
+
{ item, execution }: ${methodTypeSignatures.update.parameters[0]}
|
|
315
|
+
): ${methodTypeSignatures.update.returnType} {
|
|
269
316
|
const existingItem = this.get(item.id)
|
|
270
317
|
|
|
271
318
|
if (!existingItem) {
|
|
272
319
|
throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
|
|
273
320
|
}
|
|
321
|
+
const mutationId = await execution.startUpdateMutation({
|
|
322
|
+
model: 'post',
|
|
323
|
+
entityId: item.id,
|
|
324
|
+
sourceObject: existingItem,
|
|
325
|
+
updateObject: item,
|
|
326
|
+
})
|
|
327
|
+
try {
|
|
328
|
+
${blocks.maxLengthBlocks.updateCode.join('\n')}
|
|
274
329
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
330
|
+
${blocks.uniqueStringFieldsBlocks.updateCode.join('\n')}
|
|
331
|
+
|
|
332
|
+
const newItem = await Promise.resolve({ ...existingItem, ...item })
|
|
333
|
+
${model.updatedAtField ? `newItem.${model.updatedAtField.name} = new Date()` : ''}
|
|
334
|
+
|
|
335
|
+
this.remove(existingItem)
|
|
336
|
+
this.set(newItem)
|
|
337
|
+
|
|
338
|
+
await execution.finishUpdateMutation({ mutationId, updatedObject: newItem })
|
|
339
|
+
return newItem
|
|
340
|
+
} catch (error) {
|
|
341
|
+
await execution.errorMutation({ mutationId, error })
|
|
342
|
+
throw error
|
|
343
|
+
}
|
|
344
|
+
}`,
|
|
345
|
+
updateManyCode: `
|
|
346
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.updateMany.jsDoc)}
|
|
347
|
+
public async updateMany(
|
|
348
|
+
{ items, execution }: ${methodTypeSignatures.updateMany.parameters[0]}
|
|
349
|
+
): ${methodTypeSignatures.updateMany.returnType} {
|
|
350
|
+
const result: ${model.typeName}[] = []
|
|
351
|
+
for (const item of items) {
|
|
352
|
+
try {
|
|
353
|
+
const updated = await this.update({ item, execution })
|
|
354
|
+
result.push(updated)
|
|
355
|
+
} catch {
|
|
356
|
+
/* empty */
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return result
|
|
360
|
+
}`,
|
|
361
|
+
upsertCode: `
|
|
362
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsert.jsDoc)}
|
|
363
|
+
public async upsert(
|
|
364
|
+
{ item, execution }: ${methodTypeSignatures.upsert.parameters[0]}
|
|
365
|
+
): ${methodTypeSignatures.upsert.returnType} {
|
|
366
|
+
const existingItem = item.${model.idField.name} ? this.get(item.${model.idField.name}) : null
|
|
367
|
+
if (existingItem) {
|
|
368
|
+
return this.update({ item: item as ${meta.types.dto.update}, execution })
|
|
369
|
+
} else {
|
|
370
|
+
return this.create({ item: item as ${meta.types.dto.create}, execution })
|
|
371
|
+
}
|
|
372
|
+
}`,
|
|
373
|
+
upsertManyCode: `
|
|
374
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsertMany.jsDoc)}
|
|
375
|
+
public async upsertMany(
|
|
376
|
+
{ items, execution }: ${methodTypeSignatures.upsertMany.parameters[0]}
|
|
377
|
+
): ${methodTypeSignatures.upsertMany.returnType} {
|
|
378
|
+
const result: ${model.typeName}[] = []
|
|
379
|
+
for (const item of items) {
|
|
380
|
+
try {
|
|
381
|
+
const updated = await this.upsert({ item, execution })
|
|
382
|
+
result.push(updated)
|
|
383
|
+
} catch {
|
|
384
|
+
/* empty */
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return result
|
|
286
388
|
}`,
|
|
287
389
|
deleteCode: `
|
|
288
|
-
|
|
390
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.delete.jsDoc)}
|
|
391
|
+
public async delete(
|
|
392
|
+
{ id, execution }: ${methodTypeSignatures.delete.parameters[0]}
|
|
393
|
+
): ${methodTypeSignatures.delete.returnType} {
|
|
289
394
|
const existingItem = this.get(id)
|
|
290
395
|
if (!existingItem) {
|
|
291
396
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
292
397
|
}
|
|
293
|
-
|
|
294
|
-
|
|
398
|
+
const mutationId = await execution.startDeleteMutation({
|
|
399
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
400
|
+
entityId: id,
|
|
401
|
+
sourceObject: existingItem,
|
|
402
|
+
})
|
|
403
|
+
try {
|
|
404
|
+
await Promise.resolve()
|
|
295
405
|
|
|
296
|
-
|
|
406
|
+
this.remove(existingItem)
|
|
407
|
+
await execution.finishDeleteMutation({ mutationId })
|
|
408
|
+
return id
|
|
409
|
+
} catch (error) {
|
|
410
|
+
await execution.errorMutation({ mutationId, error })
|
|
411
|
+
throw error
|
|
412
|
+
}
|
|
413
|
+
}`,
|
|
414
|
+
deleteManyCode: `
|
|
415
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.deleteMany.jsDoc)}
|
|
416
|
+
public async deleteMany(
|
|
417
|
+
{ ids, execution }: ${methodTypeSignatures.deleteMany.parameters[0]}
|
|
418
|
+
): ${methodTypeSignatures.deleteMany.returnType} {
|
|
419
|
+
const deletedIds: ${model.brandedIdType}[] = []
|
|
420
|
+
for (const id of ids) {
|
|
421
|
+
try {
|
|
422
|
+
await this.delete({ id, execution })
|
|
423
|
+
deletedIds.push(id)
|
|
424
|
+
} catch {
|
|
425
|
+
/* empty */
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return deletedIds
|
|
297
429
|
}`,
|
|
298
430
|
databaseDecoderCode: ``,
|
|
299
431
|
};
|
|
@@ -304,15 +436,10 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
304
436
|
function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }) {
|
|
305
437
|
const decoderFunctionName = meta.data.repository.decoderFnName;
|
|
306
438
|
const { idField } = model;
|
|
307
|
-
imports
|
|
308
|
-
|
|
309
|
-
.
|
|
310
|
-
|
|
311
|
-
from: (0, types_1.toFileName)('@pxl/db'),
|
|
312
|
-
})
|
|
313
|
-
.addImport({
|
|
314
|
-
items: [`format`, `pluralize`].map(types_1.toTypeName),
|
|
315
|
-
from: (0, types_1.toFileName)('@pxl/common'),
|
|
439
|
+
imports.addImports({
|
|
440
|
+
[meta.types.importPath]: [meta.types.zodDecoderFnNames.fromDatabase],
|
|
441
|
+
[(0, types_1.toFileName)('@pxl/db')]: [`DbService`, `${model.sourceName} as DbType`].map(types_1.toTypeName),
|
|
442
|
+
[(0, types_1.toFileName)('@pxl/common')]: [`format`, `pluralize`].map(types_1.toTypeName),
|
|
316
443
|
});
|
|
317
444
|
const dbTableName = [model.sourceSchemaName, model.sourceName]
|
|
318
445
|
.filter((s) => s != null)
|
|
@@ -348,7 +475,9 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
348
475
|
${blocks.indexBlocks.initLogCode.join('\n')}
|
|
349
476
|
}`,
|
|
350
477
|
reInitCode: `
|
|
351
|
-
public async reInit(
|
|
478
|
+
public async reInit(
|
|
479
|
+
{ items, execution }: ${methodTypeSignatures.createMany.parameters[0]}
|
|
480
|
+
): Promise<void> {
|
|
352
481
|
if (!this.db.useE2ETestDB) {
|
|
353
482
|
const errorMsg =
|
|
354
483
|
'ReInit() shall only be called in tests using MockRepositories or in DB configured for E2E tests!'
|
|
@@ -356,7 +485,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
356
485
|
throw new Error(errorMsg)
|
|
357
486
|
}
|
|
358
487
|
|
|
359
|
-
await this.db.runOnlyOnTestDb(() => this.
|
|
488
|
+
await this.db.runOnlyOnTestDb(() => this.createMany({ items, execution }))
|
|
360
489
|
|
|
361
490
|
return this.init()
|
|
362
491
|
}`,
|
|
@@ -367,8 +496,9 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
367
496
|
return this.init()
|
|
368
497
|
}
|
|
369
498
|
`,
|
|
499
|
+
// prettier-ignore
|
|
370
500
|
createCode: `
|
|
371
|
-
${(0, jsdoc_1.
|
|
501
|
+
${(0, jsdoc_1.toJsDocComment)([
|
|
372
502
|
`Checks that item has the ${idField.name} field.`,
|
|
373
503
|
`In case none exists, ${blocks.idBlocks.verifyFunctionComment}`,
|
|
374
504
|
blocks.uniqueStringFieldsBlocks.verifyFunctionComment,
|
|
@@ -395,98 +525,218 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
395
525
|
private toCreateItem(item: ${blocks.idBlocks.createFunctionParameterType}) {
|
|
396
526
|
return {
|
|
397
527
|
${model.fields
|
|
398
|
-
.filter((f) => !f.attributes.isReadonly)
|
|
528
|
+
.filter((f) => !f.attributes.isReadonly || f.kind === 'id')
|
|
399
529
|
.map((f) => `${f.sourceName}: item.${f.name}`)
|
|
400
530
|
.join(',\n')},
|
|
401
531
|
}
|
|
402
532
|
}
|
|
403
533
|
|
|
534
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.create.jsDoc)}
|
|
404
535
|
public async create(
|
|
405
|
-
item: ${methodTypeSignatures.create.parameters[0]}
|
|
406
|
-
): ${methodTypeSignatures.create.returnType} {
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
536
|
+
{ item, execution }: ${methodTypeSignatures.create.parameters[0]}
|
|
537
|
+
): ${methodTypeSignatures.create.returnType} {
|
|
538
|
+
const mutationId = await execution.startCreateMutation({
|
|
539
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
540
|
+
createObject: item
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
const newItem = this.${decoderFunctionName}(
|
|
545
|
+
await this.db.${meta.data.repository.getMethodFnName}.create({
|
|
546
|
+
data: this.toCreateItem(this.verifyItem(item)),
|
|
547
|
+
}),
|
|
548
|
+
)
|
|
412
549
|
|
|
413
|
-
|
|
414
|
-
|
|
550
|
+
this.set(newItem)
|
|
551
|
+
await execution.finishCreateMutation({ mutationId, createdObject: newItem, entityId: newItem.id })
|
|
552
|
+
return newItem
|
|
553
|
+
} catch (error) {
|
|
554
|
+
await execution.errorMutation({ mutationId, error })
|
|
555
|
+
throw error
|
|
556
|
+
}
|
|
415
557
|
}`,
|
|
558
|
+
// prettier-ignore
|
|
416
559
|
createManyCode: `
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
${model.idField.sourceName}: { in: newItems.map(i => i.${model.idField.name}) }
|
|
425
|
-
}
|
|
560
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.createMany.jsDoc)}
|
|
561
|
+
public async createMany(
|
|
562
|
+
{items, execution}: ${methodTypeSignatures.createMany.parameters[0]}
|
|
563
|
+
): ${methodTypeSignatures.createMany.returnType} {
|
|
564
|
+
const mutationId = await execution.startCreateManyMutation({
|
|
565
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
566
|
+
createObjects: items
|
|
426
567
|
})
|
|
568
|
+
|
|
569
|
+
try {
|
|
570
|
+
const newItems = items.map((item) => this.verifyItem(item))
|
|
571
|
+
|
|
572
|
+
await this.db.${meta.data.repository.getMethodFnName}.createMany({ data: newItems.map(i => this.toCreateItem(i)) })
|
|
573
|
+
|
|
574
|
+
const dbItems = await this.db.${meta.data.repository.getMethodFnName}.findMany({
|
|
575
|
+
where: {
|
|
576
|
+
${model.idField.sourceName}: { in: newItems.map(i => i.${model.idField.name}) }
|
|
577
|
+
}
|
|
578
|
+
})
|
|
579
|
+
|
|
580
|
+
const result = dbItems.map((item) => this.${decoderFunctionName}(item))
|
|
581
|
+
|
|
582
|
+
for (const item of result) {
|
|
583
|
+
this.set(item)
|
|
584
|
+
}
|
|
427
585
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
586
|
+
await execution.finishCreateManyMutation({
|
|
587
|
+
mutationId,
|
|
588
|
+
createdObjects: result,
|
|
589
|
+
entityIds: newItems.map((i) => i.id),
|
|
590
|
+
})
|
|
591
|
+
return result
|
|
592
|
+
} catch (error) {
|
|
593
|
+
await execution.errorMutation({ mutationId, error })
|
|
594
|
+
throw error
|
|
432
595
|
}
|
|
433
|
-
|
|
434
|
-
return result
|
|
435
596
|
}`,
|
|
436
|
-
// prettier-ignore
|
|
437
597
|
updateCode: `
|
|
438
|
-
|
|
598
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.update.jsDoc)}
|
|
599
|
+
public async update(
|
|
600
|
+
{ item, execution }: ${methodTypeSignatures.update.parameters[0]}
|
|
601
|
+
): ${methodTypeSignatures.update.returnType} {
|
|
439
602
|
const existingItem = this.get(item.${idField.name})
|
|
440
603
|
if (!existingItem) {
|
|
441
604
|
throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
|
|
442
605
|
}
|
|
443
606
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
607
|
+
const mutationId = await execution.startUpdateMutation({
|
|
608
|
+
model: 'post',
|
|
609
|
+
entityId: item.id,
|
|
610
|
+
sourceObject: existingItem,
|
|
611
|
+
updateObject: item,
|
|
612
|
+
})
|
|
613
|
+
try {
|
|
614
|
+
${blocks.maxLengthBlocks.updateCode.join('\n')}
|
|
615
|
+
|
|
616
|
+
${blocks.uniqueStringFieldsBlocks.updateCode.join('\n')}
|
|
617
|
+
|
|
618
|
+
const newItem = this.${decoderFunctionName}(
|
|
619
|
+
await this.db.${meta.data.repository.getMethodFnName}.update({
|
|
620
|
+
where: {
|
|
621
|
+
${idField.sourceName}: item.${idField.name},
|
|
622
|
+
},
|
|
623
|
+
data: {
|
|
624
|
+
${[...model.fields.values()]
|
|
455
625
|
.filter((f) => f.kind !== 'id' && !f.attributes.isReadonly)
|
|
456
626
|
.map((f) => f.isRequired
|
|
457
627
|
? `${f.sourceName}: item.${f.name} ?? existingItem.${f.name}`
|
|
458
628
|
: `${f.sourceName}: item.${f.name}`)
|
|
459
629
|
.join(',\n')}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
630
|
+
},
|
|
631
|
+
}),
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
this.remove(existingItem)
|
|
635
|
+
this.set(newItem)
|
|
636
|
+
|
|
637
|
+
await execution.finishUpdateMutation({ mutationId, updatedObject: newItem })
|
|
638
|
+
return newItem
|
|
639
|
+
} catch (error) {
|
|
640
|
+
await execution.errorMutation({ mutationId, error })
|
|
641
|
+
throw error
|
|
642
|
+
}
|
|
643
|
+
}`,
|
|
644
|
+
updateManyCode: `
|
|
645
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.updateMany.jsDoc)}
|
|
646
|
+
public async updateMany(
|
|
647
|
+
{ items, execution }: ${methodTypeSignatures.updateMany.parameters[0]}
|
|
648
|
+
): ${methodTypeSignatures.updateMany.returnType} {
|
|
649
|
+
const result: ${model.typeName}[] = []
|
|
650
|
+
for (const item of items) {
|
|
651
|
+
try {
|
|
652
|
+
const updated = await this.update({ item, execution })
|
|
653
|
+
result.push(updated)
|
|
654
|
+
} catch {
|
|
655
|
+
/* empty */
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return result
|
|
659
|
+
}`,
|
|
660
|
+
upsertCode: `
|
|
661
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsert.jsDoc)}
|
|
662
|
+
public async upsert(
|
|
663
|
+
{ item, execution }: ${methodTypeSignatures.upsert.parameters[0]}
|
|
664
|
+
): ${methodTypeSignatures.upsert.returnType} {
|
|
665
|
+
const existingItem = item.${model.idField.name} ? this.get(item.${model.idField.name}) : null
|
|
666
|
+
if (existingItem) {
|
|
667
|
+
return this.update({ item: item as ${meta.types.dto.update}, execution })
|
|
668
|
+
} else {
|
|
669
|
+
return this.create({ item: item as ${meta.types.dto.create}, execution })
|
|
670
|
+
}
|
|
671
|
+
}`,
|
|
672
|
+
upsertManyCode: `
|
|
673
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsertMany.jsDoc)}
|
|
674
|
+
public async upsertMany(
|
|
675
|
+
{ items, execution }: ${methodTypeSignatures.upsertMany.parameters[0]}
|
|
676
|
+
): ${methodTypeSignatures.upsertMany.returnType} {
|
|
677
|
+
const result: ${model.typeName}[] = []
|
|
678
|
+
for (const item of items) {
|
|
679
|
+
try {
|
|
680
|
+
const updated = await this.upsert({ item, execution })
|
|
681
|
+
result.push(updated)
|
|
682
|
+
} catch {
|
|
683
|
+
/* empty */
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return result
|
|
468
687
|
}`,
|
|
469
688
|
deleteCode: `
|
|
470
|
-
|
|
689
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.delete.jsDoc)}
|
|
690
|
+
public async delete(
|
|
691
|
+
{ id, execution }: ${methodTypeSignatures.delete.parameters[0]}
|
|
692
|
+
): ${methodTypeSignatures.delete.returnType} {
|
|
471
693
|
const existingItem = this.get(id)
|
|
472
694
|
if (!existingItem) {
|
|
473
695
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
474
696
|
}
|
|
475
697
|
|
|
476
|
-
await
|
|
477
|
-
|
|
478
|
-
|
|
698
|
+
const mutationId = await execution.startDeleteMutation({
|
|
699
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
700
|
+
entityId: id,
|
|
701
|
+
sourceObject: existingItem,
|
|
702
|
+
})
|
|
703
|
+
try {
|
|
704
|
+
|
|
705
|
+
await this.db.${meta.data.repository.getMethodFnName}.delete({ where: { ${idField.sourceName}:id } })
|
|
706
|
+
|
|
707
|
+
this.remove(existingItem)
|
|
708
|
+
await execution.finishDeleteMutation({ mutationId })
|
|
709
|
+
return id
|
|
710
|
+
} catch (error) {
|
|
711
|
+
await execution.errorMutation({ mutationId, error })
|
|
712
|
+
throw error
|
|
713
|
+
}
|
|
714
|
+
}`,
|
|
715
|
+
deleteManyCode: `
|
|
716
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.deleteMany.jsDoc)}
|
|
717
|
+
public async deleteMany(
|
|
718
|
+
{ ids, execution }: ${methodTypeSignatures.deleteMany.parameters[0]}
|
|
719
|
+
): ${methodTypeSignatures.deleteMany.returnType} {
|
|
720
|
+
const deletedIds: ${model.brandedIdType}[] = []
|
|
721
|
+
for (const id of ids) {
|
|
722
|
+
try {
|
|
723
|
+
await this.delete({ id, execution })
|
|
724
|
+
deletedIds.push(id)
|
|
725
|
+
} catch {
|
|
726
|
+
/* empty */
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return deletedIds
|
|
479
730
|
}`,
|
|
480
|
-
// prettier-ignore
|
|
481
731
|
databaseDecoderCode: `
|
|
482
732
|
/**
|
|
483
733
|
* Utility function that converts a given Database object to a TypeScript model instance
|
|
484
734
|
*/
|
|
485
735
|
private ${decoderFunctionName}(
|
|
486
|
-
item: Pick<DbType, ${
|
|
736
|
+
item: Pick<DbType, ${model.fields.map((f) => `'${f.sourceName}'`).join(' | ')}>
|
|
487
737
|
): ${model.typeName} {
|
|
488
|
-
return ${meta.types.
|
|
489
|
-
${
|
|
738
|
+
return ${meta.types.zodDecoderFnNames.fromDatabase}.parse({
|
|
739
|
+
${model.fields.map((f) => `${f.name}: item.${f.sourceName}`).join(',\n')}
|
|
490
740
|
})
|
|
491
741
|
}`,
|
|
492
742
|
};
|
|
@@ -514,19 +764,47 @@ function generateIdBlocks({ model, meta }) {
|
|
|
514
764
|
// NOTE: We export this function as an interface simplification to the repository generator. Internally, we
|
|
515
765
|
// use the same functions as the ones used in this function which we don't want to expose.
|
|
516
766
|
function getRepositoryMethodsTypeSignatures({ model, meta }) {
|
|
517
|
-
const
|
|
767
|
+
const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
|
|
518
768
|
return {
|
|
519
769
|
create: {
|
|
520
|
-
|
|
770
|
+
jsDoc: [`Creates a new ${meta.userFriendlyName} and returns it.`],
|
|
771
|
+
parameters: [`{item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
521
772
|
returnType: `Promise<${model.typeName}>`,
|
|
522
773
|
},
|
|
774
|
+
createMany: {
|
|
775
|
+
jsDoc: [`Creates multiple new ${meta.userFriendlyNamePlural} and returns them.`],
|
|
776
|
+
parameters: [`{items: ${meta.types.dto.create}[], execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
777
|
+
returnType: `Promise<${model.typeName}[]>`,
|
|
778
|
+
},
|
|
523
779
|
update: {
|
|
524
|
-
|
|
780
|
+
jsDoc: [`Updates a ${meta.userFriendlyName} and returns it.`],
|
|
781
|
+
parameters: [`{item: ${meta.types.dto.update}, execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
782
|
+
returnType: `Promise<${model.typeName}>`,
|
|
783
|
+
},
|
|
784
|
+
updateMany: {
|
|
785
|
+
jsDoc: [`Updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
|
|
786
|
+
parameters: [`{items: ${meta.types.dto.update}[], execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
787
|
+
returnType: `Promise<${model.typeName}[]>`,
|
|
788
|
+
},
|
|
789
|
+
upsert: {
|
|
790
|
+
jsDoc: [`Creates or updates a ${meta.userFriendlyName} and returns it.`],
|
|
791
|
+
parameters: [`{item: ${meta.types.dto.upsert}, execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
525
792
|
returnType: `Promise<${model.typeName}>`,
|
|
526
793
|
},
|
|
794
|
+
upsertMany: {
|
|
795
|
+
jsDoc: [`Creates or updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
|
|
796
|
+
parameters: [`{items: ${meta.types.dto.upsert}[], execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
797
|
+
returnType: `Promise<${model.typeName}[]>`,
|
|
798
|
+
},
|
|
527
799
|
delete: {
|
|
528
|
-
|
|
529
|
-
|
|
800
|
+
jsDoc: [`Deletes a ${meta.userFriendlyName} and returns its id.`],
|
|
801
|
+
parameters: [`{id: ${model.brandedIdType}, execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
802
|
+
returnType: `Promise<${model.brandedIdType}>`,
|
|
803
|
+
},
|
|
804
|
+
deleteMany: {
|
|
805
|
+
jsDoc: [`Deletes multiple ${meta.userFriendlyNamePlural} and returns their ids.`],
|
|
806
|
+
parameters: [`{ids: ${model.brandedIdType}[], execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
807
|
+
returnType: `Promise<${model.brandedIdType}[]>`,
|
|
530
808
|
},
|
|
531
809
|
};
|
|
532
810
|
}
|
|
@@ -541,8 +819,7 @@ function _generateIdBlocks_NoGeneration({ idField, model, meta, }) {
|
|
|
541
819
|
generateNextIdFunctionName: '',
|
|
542
820
|
initCode: '',
|
|
543
821
|
verifyFunctionComment: `an error is thrown as field has no default setting in schema.`,
|
|
544
|
-
|
|
545
|
-
verifyFunctionParameterType: model.typeName,
|
|
822
|
+
verifyFunctionParameterType: meta.types.dto.create,
|
|
546
823
|
verifyCode: `
|
|
547
824
|
if (item.${idField.name} === undefined) {
|
|
548
825
|
throw new Error('Id field ${idField.name} is required!')
|
|
@@ -558,7 +835,7 @@ function _generateIdBlocks_NoGeneration({ idField, model, meta, }) {
|
|
|
558
835
|
*/
|
|
559
836
|
function _generateIdBlock_Int({ idField, model, meta, }) {
|
|
560
837
|
const generatedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
|
|
561
|
-
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly);
|
|
838
|
+
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
|
|
562
839
|
return {
|
|
563
840
|
libraryImports: '',
|
|
564
841
|
generateNextIdFunctionName: `
|
|
@@ -585,7 +862,7 @@ function _generateIdBlock_Int({ idField, model, meta, }) {
|
|
|
585
862
|
*/
|
|
586
863
|
function _generateIdBlock_UUID({ idField, model, meta, }) {
|
|
587
864
|
const dbGeneratedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
|
|
588
|
-
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly);
|
|
865
|
+
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
|
|
589
866
|
return {
|
|
590
867
|
libraryImports: `import { randomUUID } from 'crypto'`,
|
|
591
868
|
generateNextIdFunctionName: `
|
|
@@ -673,8 +950,12 @@ function generateUniqueFieldsBlocks({ model }) {
|
|
|
673
950
|
* Utility function that ensures that the ${f.name} field is unique
|
|
674
951
|
*/
|
|
675
952
|
private ${getEnsureUniqueFnName(f)}(item: { ${f.name}?: string }) {
|
|
676
|
-
if (!item.${f.name})
|
|
677
|
-
|
|
953
|
+
if (!item.${f.name}) {
|
|
954
|
+
return
|
|
955
|
+
}
|
|
956
|
+
if (!this.uniqueIds.${f.name}.has(item.${f.name})) {
|
|
957
|
+
return
|
|
958
|
+
}
|
|
678
959
|
let counter = 1
|
|
679
960
|
|
|
680
961
|
let ${f.name}: string
|
|
@@ -813,23 +1094,31 @@ function generateRelationsBlocks({ model, imports, }) {
|
|
|
813
1094
|
from: relationModelMeta.types.importPath,
|
|
814
1095
|
});
|
|
815
1096
|
result.mapDeclarations.push(`protected ${r.name}Map: Map<${relationModelMeta.types.brandedIdType}, Map<${model.brandedIdType}, ${model.typeName}>> = new Map()`);
|
|
816
|
-
// prettier-ignore
|
|
817
1097
|
result.getterFunctions.push(`
|
|
818
1098
|
/**
|
|
819
1099
|
* Function to retrieve all ${(0, string_1.pluralize)(model.name)} that are related to a ${r.name}
|
|
820
1100
|
*/
|
|
821
|
-
public ${fieldMeta.getByForeignKeyMethodFnName}(
|
|
1101
|
+
public ${fieldMeta.getByForeignKeyMethodFnName}(
|
|
1102
|
+
id: ${relationModelMeta.types.brandedIdType}
|
|
1103
|
+
): Map<${model.brandedIdType}, ${model.typeName}> {
|
|
822
1104
|
const result = this.${r.name}Map.get(id)
|
|
823
|
-
if (!result)
|
|
1105
|
+
if (!result) {
|
|
1106
|
+
return new Map()
|
|
1107
|
+
}
|
|
824
1108
|
return new Map(result)
|
|
825
1109
|
}
|
|
826
1110
|
|
|
827
1111
|
/**
|
|
828
1112
|
* Function to retrieve all ${model.brandedIdType}s that are related to a ${r.name}
|
|
829
1113
|
*/
|
|
830
|
-
public ${fieldMeta.getByForeignKeyIdsMethodFnName}(
|
|
1114
|
+
public ${fieldMeta.getByForeignKeyIdsMethodFnName}(
|
|
1115
|
+
id: ${relationModelMeta.types.brandedIdType}
|
|
1116
|
+
): ${model.brandedIdType}[] {
|
|
831
1117
|
const s = this.${r.name}Map.get(id)
|
|
832
|
-
if (!s)
|
|
1118
|
+
if (!s) {
|
|
1119
|
+
return []
|
|
1120
|
+
}
|
|
1121
|
+
|
|
833
1122
|
return Array.from(s.keys())
|
|
834
1123
|
}`);
|
|
835
1124
|
result.setCode.push(`
|