@postxl/generator 0.33.4 → 0.35.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 +40 -22
- 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/businesslogic-update-service.generator.js +34 -0
- 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/{businesslogicservice.generator.js → businesslogic-view-service.generator.js} +9 -10
- package/dist/generators/indices/{datamockmodule.generator.js → datamock-module.generator.js} +8 -16
- package/dist/generators/indices/datamocker.generator.js +3 -7
- 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-view.generator.js +253 -0
- package/dist/generators/models/react.generator/modals.generator.js +20 -4
- package/dist/generators/models/repository.generator.d.ts +9 -0
- package/dist/generators/models/repository.generator.js +496 -148
- package/dist/generators/models/route.generator.js +45 -54
- package/dist/generators/models/seed.generator.js +6 -2
- package/dist/generators/models/types.generator.js +60 -13
- package/dist/lib/attributes.d.ts +32 -2
- 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/fields.d.ts +7 -4
- package/dist/lib/schema/fields.js +11 -4
- package/dist/lib/schema/schema.d.ts +32 -6
- package/dist/lib/schema/types.d.ts +4 -0
- package/dist/lib/utils/ast.d.ts +29 -0
- package/dist/lib/utils/ast.js +23 -0
- package/dist/lib/utils/jsdoc.d.ts +1 -1
- package/dist/lib/utils/jsdoc.js +8 -5
- package/dist/lib/utils/string.js +2 -1
- package/dist/prisma/attributes.js +45 -26
- package/dist/prisma/parse.js +44 -11
- package/package.json +1 -1
- 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/models/businesslogic.generator.js +0 -259
- /package/dist/generators/indices/{datamockmodule.generator.d.ts → datamock-module.generator.d.ts} +0 -0
|
@@ -13,21 +13,20 @@ 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
|
-
// NOTE: We first generate different parts of the code
|
|
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.
|
|
32
31
|
//
|
|
33
32
|
// Based on the model, the repository is generated slightly differently:
|
|
@@ -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,
|
|
@@ -132,36 +137,6 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
132
137
|
public count(): number {
|
|
133
138
|
return this.data.size
|
|
134
139
|
}
|
|
135
|
-
|
|
136
|
-
/**${(0, jsdoc_1.convertToJsDocComments)([
|
|
137
|
-
`Checks that item has the ${idField.name} field.`,
|
|
138
|
-
`In case none exists, ${idBlocks.verifyFunctionComment}`,
|
|
139
|
-
uniqueStringFieldsBlocks.verifyFunctionComment,
|
|
140
|
-
maxLengthBlocks.verifyFunctionComment,
|
|
141
|
-
])}
|
|
142
|
-
*/
|
|
143
|
-
|
|
144
|
-
private verifyItem(item: ${idBlocks.verifyFunctionParameterType}): ${model.typeName} {
|
|
145
|
-
${idBlocks.verifyCode}
|
|
146
|
-
|
|
147
|
-
${maxLengthBlocks.verifyCode.join('\n')}
|
|
148
|
-
|
|
149
|
-
${uniqueStringFieldsBlocks.verifyCode.join('\n')}
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
${idField.name},
|
|
153
|
-
${[...model.fields.values()]
|
|
154
|
-
.filter((f) => f.kind !== 'id')
|
|
155
|
-
.map((f) => `${f.name}: item.${f.name}`)
|
|
156
|
-
.join(',\n')}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private toCreateItem(item: ${model.typeName}) {
|
|
161
|
-
return {
|
|
162
|
-
${[...model.fields.values()].map((f) => `${f.sourceName}: item.${f.name}`).join(',\n')}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
140
|
|
|
166
141
|
${mainBlocks.createCode}
|
|
167
142
|
|
|
@@ -169,8 +144,16 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
169
144
|
|
|
170
145
|
${mainBlocks.updateCode}
|
|
171
146
|
|
|
147
|
+
${mainBlocks.updateManyCode}
|
|
148
|
+
|
|
149
|
+
${mainBlocks.upsertCode}
|
|
150
|
+
|
|
151
|
+
${mainBlocks.upsertManyCode}
|
|
152
|
+
|
|
172
153
|
${mainBlocks.deleteCode}
|
|
173
154
|
|
|
155
|
+
${mainBlocks.deleteManyCode}
|
|
156
|
+
|
|
174
157
|
${relationsBlocks.getterFunctions.join('\n')}
|
|
175
158
|
|
|
176
159
|
${maxLengthBlocks.ensureMaxLengthFunctions.join('\n')}
|
|
@@ -238,65 +221,211 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
238
221
|
return Promise.resolve()
|
|
239
222
|
}`,
|
|
240
223
|
reInitCode: `
|
|
241
|
-
public async reInit(
|
|
224
|
+
public async reInit({items, execution}: ${methodTypeSignatures.createMany.parameters[0]}): Promise<void> {
|
|
242
225
|
await this.init()
|
|
243
|
-
await this.createMany(
|
|
226
|
+
await this.createMany({items, execution})
|
|
244
227
|
}`,
|
|
245
228
|
deleteAllCode: `
|
|
246
229
|
public async deleteAll(): Promise<void> {
|
|
247
230
|
return this.init()
|
|
248
231
|
}`,
|
|
249
232
|
createCode: `
|
|
233
|
+
${(0, jsdoc_1.toJsDocComment)([
|
|
234
|
+
`Checks that item has the ${model.idField.name} field.`,
|
|
235
|
+
`In case none exists, ${blocks.idBlocks.verifyFunctionComment}`,
|
|
236
|
+
blocks.uniqueStringFieldsBlocks.verifyFunctionComment,
|
|
237
|
+
blocks.maxLengthBlocks.verifyFunctionComment,
|
|
238
|
+
])}
|
|
239
|
+
private verifyItem(
|
|
240
|
+
item: ${blocks.idBlocks.verifyFunctionParameterType}
|
|
241
|
+
): ${model.name} {
|
|
242
|
+
${blocks.idBlocks.verifyCode}
|
|
243
|
+
|
|
244
|
+
${blocks.maxLengthBlocks.verifyCode.join('\n')}
|
|
245
|
+
|
|
246
|
+
${blocks.uniqueStringFieldsBlocks.verifyCode.join('\n')}
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
${model.idField.name},
|
|
250
|
+
${model.fields
|
|
251
|
+
.filter((f) => f.kind !== 'id' && !f.attributes.isReadonly)
|
|
252
|
+
.map((f) => `${f.name}: item.${f.name}`)
|
|
253
|
+
.join(',\n')},
|
|
254
|
+
${model.createdAtField ? `${model.createdAtField.sourceName}: new Date(),` : ''}
|
|
255
|
+
${model.updatedAtField ? `${model.updatedAtField.sourceName}: new Date(),` : ''}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.create.jsDoc)}
|
|
250
260
|
// Non-mocked version is async - so we keep type-compatible signatures for create() and createWithId()
|
|
251
261
|
// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
|
|
252
|
-
public async create(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
262
|
+
public async create(
|
|
263
|
+
{ item, execution }: ${methodTypeSignatures.create.parameters[0]}
|
|
264
|
+
): ${methodTypeSignatures.create.returnType} {
|
|
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
|
+
}
|
|
257
280
|
}`,
|
|
258
281
|
createManyCode: `
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
+
})
|
|
263
290
|
|
|
264
|
-
|
|
265
|
-
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
|
|
266
309
|
}
|
|
267
|
-
|
|
268
|
-
return newItems
|
|
269
310
|
}`,
|
|
270
|
-
// prettier-ignore
|
|
271
311
|
updateCode: `
|
|
272
|
-
|
|
312
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.update.jsDoc)}
|
|
313
|
+
public async update(
|
|
314
|
+
{ item, execution }: ${methodTypeSignatures.update.parameters[0]}
|
|
315
|
+
): ${methodTypeSignatures.update.returnType} {
|
|
273
316
|
const existingItem = this.get(item.id)
|
|
274
317
|
|
|
275
318
|
if (!existingItem) {
|
|
276
319
|
throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
|
|
277
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')}
|
|
278
329
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
|
289
388
|
}`,
|
|
290
389
|
deleteCode: `
|
|
291
|
-
|
|
390
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.delete.jsDoc)}
|
|
391
|
+
public async delete(
|
|
392
|
+
{ id, execution }: ${methodTypeSignatures.delete.parameters[0]}
|
|
393
|
+
): ${methodTypeSignatures.delete.returnType} {
|
|
292
394
|
const existingItem = this.get(id)
|
|
293
395
|
if (!existingItem) {
|
|
294
396
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
295
397
|
}
|
|
296
|
-
|
|
297
|
-
|
|
398
|
+
const mutationId = await execution.startDeleteMutation({
|
|
399
|
+
model: '${meta.actions.actionScopeConstType}',
|
|
400
|
+
entityId: id,
|
|
401
|
+
sourceObject: existingItem,
|
|
402
|
+
})
|
|
403
|
+
try {
|
|
404
|
+
await Promise.resolve()
|
|
298
405
|
|
|
299
|
-
|
|
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
|
|
300
429
|
}`,
|
|
301
430
|
databaseDecoderCode: ``,
|
|
302
431
|
};
|
|
@@ -307,15 +436,10 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
307
436
|
function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }) {
|
|
308
437
|
const decoderFunctionName = meta.data.repository.decoderFnName;
|
|
309
438
|
const { idField } = model;
|
|
310
|
-
imports
|
|
311
|
-
|
|
312
|
-
.
|
|
313
|
-
|
|
314
|
-
from: (0, types_1.toFileName)('@pxl/db'),
|
|
315
|
-
})
|
|
316
|
-
.addImport({
|
|
317
|
-
items: [`format`, `pluralize`].map(types_1.toTypeName),
|
|
318
|
-
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),
|
|
319
443
|
});
|
|
320
444
|
const dbTableName = [model.sourceSchemaName, model.sourceName]
|
|
321
445
|
.filter((s) => s != null)
|
|
@@ -351,7 +475,9 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
351
475
|
${blocks.indexBlocks.initLogCode.join('\n')}
|
|
352
476
|
}`,
|
|
353
477
|
reInitCode: `
|
|
354
|
-
public async reInit(
|
|
478
|
+
public async reInit(
|
|
479
|
+
{ items, execution }: ${methodTypeSignatures.createMany.parameters[0]}
|
|
480
|
+
): Promise<void> {
|
|
355
481
|
if (!this.db.useE2ETestDB) {
|
|
356
482
|
const errorMsg =
|
|
357
483
|
'ReInit() shall only be called in tests using MockRepositories or in DB configured for E2E tests!'
|
|
@@ -359,7 +485,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
359
485
|
throw new Error(errorMsg)
|
|
360
486
|
}
|
|
361
487
|
|
|
362
|
-
await this.db.runOnlyOnTestDb(() => this.
|
|
488
|
+
await this.db.runOnlyOnTestDb(() => this.createMany({ items, execution }))
|
|
363
489
|
|
|
364
490
|
return this.init()
|
|
365
491
|
}`,
|
|
@@ -370,81 +496,247 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
370
496
|
return this.init()
|
|
371
497
|
}
|
|
372
498
|
`,
|
|
499
|
+
// prettier-ignore
|
|
373
500
|
createCode: `
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
)
|
|
501
|
+
${(0, jsdoc_1.toJsDocComment)([
|
|
502
|
+
`Checks that item has the ${idField.name} field.`,
|
|
503
|
+
`In case none exists, ${blocks.idBlocks.verifyFunctionComment}`,
|
|
504
|
+
blocks.uniqueStringFieldsBlocks.verifyFunctionComment,
|
|
505
|
+
blocks.maxLengthBlocks.verifyFunctionComment,
|
|
506
|
+
])}
|
|
507
|
+
private verifyItem(
|
|
508
|
+
item: ${blocks.idBlocks.verifyFunctionParameterType}
|
|
509
|
+
): ${blocks.idBlocks.createFunctionParameterType} {
|
|
510
|
+
${blocks.idBlocks.verifyCode}
|
|
511
|
+
|
|
512
|
+
${blocks.maxLengthBlocks.verifyCode.join('\n')}
|
|
513
|
+
|
|
514
|
+
${blocks.uniqueStringFieldsBlocks.verifyCode.join('\n')}
|
|
515
|
+
|
|
516
|
+
return {
|
|
517
|
+
${idField.name},
|
|
518
|
+
${model.fields
|
|
519
|
+
.filter((f) => f.kind !== 'id' && !f.attributes.isReadonly)
|
|
520
|
+
.map((f) => `${f.name}: item.${f.name}`)
|
|
521
|
+
.join(',\n')}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
380
524
|
|
|
381
|
-
|
|
382
|
-
return
|
|
525
|
+
private toCreateItem(item: ${blocks.idBlocks.createFunctionParameterType}) {
|
|
526
|
+
return {
|
|
527
|
+
${model.fields
|
|
528
|
+
.filter((f) => !f.attributes.isReadonly || f.kind === 'id')
|
|
529
|
+
.map((f) => `${f.sourceName}: item.${f.name}`)
|
|
530
|
+
.join(',\n')},
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.create.jsDoc)}
|
|
535
|
+
public async create(
|
|
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
|
+
)
|
|
549
|
+
|
|
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
|
+
}
|
|
383
557
|
}`,
|
|
558
|
+
// prettier-ignore
|
|
384
559
|
createManyCode: `
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
|
567
|
+
})
|
|
389
568
|
|
|
390
|
-
|
|
391
|
-
this.
|
|
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
|
+
}
|
|
585
|
+
|
|
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
|
|
392
595
|
}
|
|
393
|
-
|
|
394
|
-
return newItems
|
|
395
596
|
}`,
|
|
396
|
-
// prettier-ignore
|
|
397
597
|
updateCode: `
|
|
398
|
-
|
|
598
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.update.jsDoc)}
|
|
599
|
+
public async update(
|
|
600
|
+
{ item, execution }: ${methodTypeSignatures.update.parameters[0]}
|
|
601
|
+
): ${methodTypeSignatures.update.returnType} {
|
|
399
602
|
const existingItem = this.get(item.${idField.name})
|
|
400
603
|
if (!existingItem) {
|
|
401
604
|
throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
|
|
402
605
|
}
|
|
403
606
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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()]
|
|
625
|
+
.filter((f) => f.kind !== 'id' && !f.attributes.isReadonly)
|
|
416
626
|
.map((f) => f.isRequired
|
|
417
627
|
? `${f.sourceName}: item.${f.name} ?? existingItem.${f.name}`
|
|
418
628
|
: `${f.sourceName}: item.${f.name}`)
|
|
419
629
|
.join(',\n')}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
|
428
687
|
}`,
|
|
429
688
|
deleteCode: `
|
|
430
|
-
|
|
689
|
+
${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.delete.jsDoc)}
|
|
690
|
+
public async delete(
|
|
691
|
+
{ id, execution }: ${methodTypeSignatures.delete.parameters[0]}
|
|
692
|
+
): ${methodTypeSignatures.delete.returnType} {
|
|
431
693
|
const existingItem = this.get(id)
|
|
432
694
|
if (!existingItem) {
|
|
433
695
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
434
696
|
}
|
|
435
697
|
|
|
436
|
-
await
|
|
437
|
-
|
|
438
|
-
|
|
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
|
|
439
730
|
}`,
|
|
440
|
-
// prettier-ignore
|
|
441
731
|
databaseDecoderCode: `
|
|
442
732
|
/**
|
|
443
733
|
* Utility function that converts a given Database object to a TypeScript model instance
|
|
444
734
|
*/
|
|
445
|
-
private ${decoderFunctionName}(
|
|
446
|
-
|
|
447
|
-
|
|
735
|
+
private ${decoderFunctionName}(
|
|
736
|
+
item: Pick<DbType, ${model.fields.map((f) => `'${f.sourceName}'`).join(' | ')}>
|
|
737
|
+
): ${model.typeName} {
|
|
738
|
+
return ${meta.types.zodDecoderFnNames.fromDatabase}.parse({
|
|
739
|
+
${model.fields.map((f) => `${f.name}: item.${f.sourceName}`).join(',\n')}
|
|
448
740
|
})
|
|
449
741
|
}`,
|
|
450
742
|
};
|
|
@@ -472,19 +764,47 @@ function generateIdBlocks({ model, meta }) {
|
|
|
472
764
|
// NOTE: We export this function as an interface simplification to the repository generator. Internally, we
|
|
473
765
|
// use the same functions as the ones used in this function which we don't want to expose.
|
|
474
766
|
function getRepositoryMethodsTypeSignatures({ model, meta }) {
|
|
475
|
-
const
|
|
767
|
+
const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
|
|
476
768
|
return {
|
|
477
769
|
create: {
|
|
478
|
-
|
|
770
|
+
jsDoc: [`Creates a new ${meta.userFriendlyName} and returns it.`],
|
|
771
|
+
parameters: [`{item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.actionExecutionInterface}}`],
|
|
479
772
|
returnType: `Promise<${model.typeName}>`,
|
|
480
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
|
+
},
|
|
481
779
|
update: {
|
|
482
|
-
|
|
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}}`],
|
|
483
792
|
returnType: `Promise<${model.typeName}>`,
|
|
484
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
|
+
},
|
|
485
799
|
delete: {
|
|
486
|
-
|
|
487
|
-
|
|
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}[]>`,
|
|
488
808
|
},
|
|
489
809
|
};
|
|
490
810
|
}
|
|
@@ -499,14 +819,14 @@ function _generateIdBlocks_NoGeneration({ idField, model, meta, }) {
|
|
|
499
819
|
generateNextIdFunctionName: '',
|
|
500
820
|
initCode: '',
|
|
501
821
|
verifyFunctionComment: `an error is thrown as field has no default setting in schema.`,
|
|
502
|
-
|
|
503
|
-
verifyFunctionParameterType: model.typeName,
|
|
822
|
+
verifyFunctionParameterType: meta.types.dto.create,
|
|
504
823
|
verifyCode: `
|
|
505
824
|
if (item.${idField.name} === undefined) {
|
|
506
825
|
throw new Error('Id field ${idField.name} is required!')
|
|
507
826
|
}
|
|
508
827
|
const ${idField.name} = ${meta.types.toBrandedIdTypeFnName}(item.${idField.name})`,
|
|
509
828
|
setCode: '',
|
|
829
|
+
createFunctionParameterType: model.typeName,
|
|
510
830
|
};
|
|
511
831
|
}
|
|
512
832
|
/**
|
|
@@ -514,6 +834,8 @@ function _generateIdBlocks_NoGeneration({ idField, model, meta, }) {
|
|
|
514
834
|
* Given chunks make sure that the id is unique if provided or generate a new one if not.
|
|
515
835
|
*/
|
|
516
836
|
function _generateIdBlock_Int({ idField, model, meta, }) {
|
|
837
|
+
const generatedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
|
|
838
|
+
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
|
|
517
839
|
return {
|
|
518
840
|
libraryImports: '',
|
|
519
841
|
generateNextIdFunctionName: `
|
|
@@ -523,8 +845,14 @@ function _generateIdBlock_Int({ idField, model, meta, }) {
|
|
|
523
845
|
}`,
|
|
524
846
|
initCode: `this.currentMaxId = (await this.db.${meta.data.repository.getMethodFnName}.aggregate({ _max: { ${idField.sourceName}: true } }))._max.${idField.sourceName} ?? 0`,
|
|
525
847
|
verifyFunctionComment: 'the id is generated by increasing the highest former id and assigned to the item.',
|
|
526
|
-
|
|
848
|
+
// prettier-ignore
|
|
849
|
+
verifyFunctionParameterType: `(Omit<${model.typeName}, ${generatedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
|
|
527
850
|
verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
|
|
851
|
+
createFunctionParameterType:
|
|
852
|
+
// NOTE: In case we have readonly fields, we need to omit them from the create function.
|
|
853
|
+
readonlyFields.length === 0
|
|
854
|
+
? model.typeName
|
|
855
|
+
: `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
|
|
528
856
|
setCode: `if (item.id > this.currentMaxId) { this.currentMaxId = item.id }`,
|
|
529
857
|
};
|
|
530
858
|
}
|
|
@@ -533,6 +861,8 @@ function _generateIdBlock_Int({ idField, model, meta, }) {
|
|
|
533
861
|
* It allows you to provide a custom id or generates a new one if not.
|
|
534
862
|
*/
|
|
535
863
|
function _generateIdBlock_UUID({ idField, model, meta, }) {
|
|
864
|
+
const dbGeneratedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
|
|
865
|
+
const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
|
|
536
866
|
return {
|
|
537
867
|
libraryImports: `import { randomUUID } from 'crypto'`,
|
|
538
868
|
generateNextIdFunctionName: `
|
|
@@ -541,8 +871,14 @@ function _generateIdBlock_UUID({ idField, model, meta, }) {
|
|
|
541
871
|
}`,
|
|
542
872
|
initCode: '',
|
|
543
873
|
verifyFunctionComment: 'a new UUID is generated and assigned to the item.',
|
|
544
|
-
|
|
874
|
+
// prettier-ignore
|
|
875
|
+
verifyFunctionParameterType: `(Omit<${model.typeName}, ${dbGeneratedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
|
|
545
876
|
verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
|
|
877
|
+
createFunctionParameterType:
|
|
878
|
+
// NOTE: In case we have readonly fields, we need to omit them from the create function.
|
|
879
|
+
readonlyFields.length === 0
|
|
880
|
+
? model.typeName
|
|
881
|
+
: `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
|
|
546
882
|
setCode: '',
|
|
547
883
|
};
|
|
548
884
|
}
|
|
@@ -614,8 +950,12 @@ function generateUniqueFieldsBlocks({ model }) {
|
|
|
614
950
|
* Utility function that ensures that the ${f.name} field is unique
|
|
615
951
|
*/
|
|
616
952
|
private ${getEnsureUniqueFnName(f)}(item: { ${f.name}?: string }) {
|
|
617
|
-
if (!item.${f.name})
|
|
618
|
-
|
|
953
|
+
if (!item.${f.name}) {
|
|
954
|
+
return
|
|
955
|
+
}
|
|
956
|
+
if (!this.uniqueIds.${f.name}.has(item.${f.name})) {
|
|
957
|
+
return
|
|
958
|
+
}
|
|
619
959
|
let counter = 1
|
|
620
960
|
|
|
621
961
|
let ${f.name}: string
|
|
@@ -754,23 +1094,31 @@ function generateRelationsBlocks({ model, imports, }) {
|
|
|
754
1094
|
from: relationModelMeta.types.importPath,
|
|
755
1095
|
});
|
|
756
1096
|
result.mapDeclarations.push(`protected ${r.name}Map: Map<${relationModelMeta.types.brandedIdType}, Map<${model.brandedIdType}, ${model.typeName}>> = new Map()`);
|
|
757
|
-
// prettier-ignore
|
|
758
1097
|
result.getterFunctions.push(`
|
|
759
1098
|
/**
|
|
760
1099
|
* Function to retrieve all ${(0, string_1.pluralize)(model.name)} that are related to a ${r.name}
|
|
761
1100
|
*/
|
|
762
|
-
public ${fieldMeta.getByForeignKeyMethodFnName}(
|
|
1101
|
+
public ${fieldMeta.getByForeignKeyMethodFnName}(
|
|
1102
|
+
id: ${relationModelMeta.types.brandedIdType}
|
|
1103
|
+
): Map<${model.brandedIdType}, ${model.typeName}> {
|
|
763
1104
|
const result = this.${r.name}Map.get(id)
|
|
764
|
-
if (!result)
|
|
1105
|
+
if (!result) {
|
|
1106
|
+
return new Map()
|
|
1107
|
+
}
|
|
765
1108
|
return new Map(result)
|
|
766
1109
|
}
|
|
767
1110
|
|
|
768
1111
|
/**
|
|
769
1112
|
* Function to retrieve all ${model.brandedIdType}s that are related to a ${r.name}
|
|
770
1113
|
*/
|
|
771
|
-
public ${fieldMeta.getByForeignKeyIdsMethodFnName}(
|
|
1114
|
+
public ${fieldMeta.getByForeignKeyIdsMethodFnName}(
|
|
1115
|
+
id: ${relationModelMeta.types.brandedIdType}
|
|
1116
|
+
): ${model.brandedIdType}[] {
|
|
772
1117
|
const s = this.${r.name}Map.get(id)
|
|
773
|
-
if (!s)
|
|
1118
|
+
if (!s) {
|
|
1119
|
+
return []
|
|
1120
|
+
}
|
|
1121
|
+
|
|
774
1122
|
return Array.from(s.keys())
|
|
775
1123
|
}`);
|
|
776
1124
|
result.setCode.push(`
|