@postxl/generator 0.69.0 → 0.69.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/generator.js +34 -33
  2. package/dist/generators/indices/{datamodule.generator.d.ts → data/module.generator.d.ts} +2 -2
  3. package/dist/generators/indices/{datamodule.generator.js → data/module.generator.js} +4 -5
  4. package/dist/generators/indices/{dataservice.generator.d.ts → data/service.generator.d.ts} +2 -2
  5. package/dist/generators/indices/{dataservice.generator.js → data/service.generator.js} +5 -5
  6. package/dist/generators/indices/{data-types.generator.d.ts → data/types.generator.d.ts} +2 -2
  7. package/dist/generators/indices/{data-types.generator.js → data/types.generator.js} +2 -2
  8. package/dist/generators/indices/{importexport-convert-import-functions.generator.d.ts → import-export/importexport-convert-import-functions.generator.d.ts} +2 -2
  9. package/dist/generators/indices/{importexport-convert-import-functions.generator.js → import-export/importexport-convert-import-functions.generator.js} +4 -4
  10. package/dist/generators/indices/{importexport-exporter-class.generator.d.ts → import-export/importexport-exporter-class.generator.d.ts} +2 -2
  11. package/dist/generators/indices/{importexport-exporter-class.generator.js → import-export/importexport-exporter-class.generator.js} +4 -5
  12. package/dist/generators/indices/{importexport-import-service.generator.d.ts → import-export/importexport-import-service.generator.d.ts} +2 -2
  13. package/dist/generators/indices/{importexport-import-service.generator.js → import-export/importexport-import-service.generator.js} +4 -4
  14. package/dist/generators/indices/{importexport-types.generator.d.ts → import-export/importexport-types.generator.d.ts} +2 -2
  15. package/dist/generators/indices/{importexport-types.generator.js → import-export/importexport-types.generator.js} +2 -2
  16. package/dist/generators/indices/types.generator.js +13 -1
  17. package/dist/generators/indices/{businesslogic-actiontypes.generator.d.ts → update/actiontypes.generator.d.ts} +2 -2
  18. package/dist/generators/indices/{businesslogic-actiontypes.generator.js → update/actiontypes.generator.js} +3 -3
  19. package/dist/generators/indices/{businesslogic-update-module.generator.d.ts → update/module.generator.d.ts} +2 -2
  20. package/dist/generators/indices/{businesslogic-update-module.generator.js → update/module.generator.js} +2 -2
  21. package/dist/generators/indices/{businesslogic-update-service.generator.d.ts → update/service.generator.d.ts} +2 -2
  22. package/dist/generators/indices/{businesslogic-update-service.generator.js → update/service.generator.js} +2 -2
  23. package/dist/generators/indices/{businesslogic-view-module.generator.d.ts → view/module.generator.d.ts} +2 -2
  24. package/dist/generators/indices/{businesslogic-view-module.generator.js → view/module.generator.js} +2 -2
  25. package/dist/generators/indices/{businesslogic-view-service.generator.d.ts → view/service.generator.d.ts} +2 -2
  26. package/dist/generators/indices/{businesslogic-view-service.generator.js → view/service.generator.js} +2 -2
  27. package/dist/generators/models/repository.generator.d.ts +0 -39
  28. package/dist/generators/models/repository.generator.js +100 -172
  29. package/dist/generators/models/route.generator.js +2 -2
  30. package/dist/generators/models/types.generator.js +27 -2
  31. package/dist/generators/models/{businesslogic-update.generator.d.ts → update/service.generator.d.ts} +2 -2
  32. package/dist/generators/models/update/service.generator.js +252 -0
  33. package/dist/generators/models/{businesslogic-view.generator.d.ts → view/service.generator.d.ts} +2 -2
  34. package/dist/generators/models/{businesslogic-view.generator.js → view/service.generator.js} +12 -18
  35. package/dist/lib/meta.d.ts +16 -8
  36. package/dist/lib/meta.js +2 -2
  37. package/package.json +1 -1
  38. package/dist/generators/models/businesslogic-update.generator.js +0 -324
  39. /package/dist/generators/models/{react.generator → react}/context.generator.d.ts +0 -0
  40. /package/dist/generators/models/{react.generator → react}/context.generator.js +0 -0
  41. /package/dist/generators/models/{react.generator → react}/index.d.ts +0 -0
  42. /package/dist/generators/models/{react.generator → react}/index.js +0 -0
  43. /package/dist/generators/models/{react.generator → react}/library.generator.d.ts +0 -0
  44. /package/dist/generators/models/{react.generator → react}/library.generator.js +0 -0
  45. /package/dist/generators/models/{react.generator → react}/lookup.generator.d.ts +0 -0
  46. /package/dist/generators/models/{react.generator → react}/lookup.generator.js +0 -0
  47. /package/dist/generators/models/{react.generator → react}/modals.generator.d.ts +0 -0
  48. /package/dist/generators/models/{react.generator → react}/modals.generator.js +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRepositoryMethodsTypeSignatures = exports.generateRepository = void 0;
3
+ exports.generateRepository = void 0;
4
4
  const imports_1 = require("../../lib/imports");
5
5
  const meta_1 = require("../../lib/meta");
6
6
  const fields_1 = require("../../lib/schema/fields");
@@ -21,29 +21,13 @@ function generateRepository({ model, meta }) {
21
21
  (0, types_1.toAnnotatedTypeName)(model.typeName),
22
22
  (0, types_1.toAnnotatedTypeName)(model.brandedIdType),
23
23
  meta.types.toBrandedIdTypeFnName,
24
- (0, types_1.toAnnotatedTypeName)(meta.types.dto.create),
25
- (0, types_1.toAnnotatedTypeName)(meta.types.dto.update),
26
- (0, types_1.toAnnotatedTypeName)(meta.types.dto.upsert),
24
+ meta.types.dto.create,
25
+ meta.types.dto.update,
26
+ meta.types.dto.upsert,
27
+ meta.types.dto.clone,
27
28
  ],
28
29
  [schemaMeta.actions.execution.interfaceLocation.import]: [schemaMeta.actions.execution.interface],
29
30
  });
30
- // NOTE: We first generate different parts of the code responsible for a particular task
31
- // and then we combine them into the final code block.
32
- //
33
- // Based on the model, the repository is generated slightly differently:
34
- // 1.) if the model has a default field, the repository will have a public variable "defaultValue"
35
- // that is set and verified during init,
36
- // 2.) if the model has a generated id, the repository will have a function "generateNextId" that
37
- // is used to generate the next id. The `create` and `createMany` functions will use this function
38
- // and allow being called with an id,
39
- // 3.) unique string fields are ensured to be unique,
40
- // 4.) max length string fields are ensured to not exceed their max length,
41
- // 5.) index for fields marked with index or unique attribute,
42
- // 6.) relations are indexed by the foreign key.
43
- //
44
- // The repository is generated differently based on whether the model is stored in the database or in memory.
45
- // If the model is stored in the database, all CUD operations will result in a database call. If the model is
46
- // stored in memory, all CUD operations will be performed in memory without any database calls.
47
31
  const idBlocks = generateIdBlocks({ model, meta });
48
32
  const defaultValueBlocks = generateDefaultBlocks({ model, meta });
49
33
  const uniqueStringFieldsBlocks = generateUniqueFieldsBlocks({ model, meta });
@@ -58,7 +42,6 @@ function generateRepository({ model, meta }) {
58
42
  [(0, types_1.toPackageName)('@postxl/runtime')]: [(0, types_1.toFunctionName)('format'), (0, types_1.toFunctionName)('pluralize')],
59
43
  });
60
44
  const userRepositorySpecificBlocks = generateUserRepositorySpecificBlocks_InDatabase({ model, meta, imports });
61
- const methodTypeSignatures = getRepositoryMethodsTypeSignatures({ model, meta });
62
45
  return `
63
46
  import { Injectable, Logger } from '@nestjs/common'
64
47
  ${idBlocks.libraryImports}
@@ -193,10 +176,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
193
176
  }
194
177
  }
195
178
 
196
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.create.jsDoc)}
179
+ ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} and returns it.`])}
197
180
  public async create(
198
- { item, execution }: ${methodTypeSignatures.create.parameters[0]}
199
- ): ${methodTypeSignatures.create.returnType} {
181
+ { item, execution }: { item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.execution.interface} }
182
+ ): Promise<${model.typeName}> {
200
183
  const mutationId = await execution.startCreateMutation({
201
184
  model: '${meta.actions.actionScopeConstType}',
202
185
  createObject: item
@@ -218,10 +201,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
218
201
  }
219
202
  }
220
203
 
221
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.createMany.jsDoc)}
204
+ ${(0, jsdoc_1.toJsDocComment)([`Creates multiple new ${meta.userFriendlyNamePlural} and returns them.`])}
222
205
  public async createMany(
223
- {items, execution}: ${methodTypeSignatures.createMany.parameters[0]}
224
- ): ${methodTypeSignatures.createMany.returnType} {
206
+ {items, execution}: { items: ${meta.types.dto.create}[], execution: ${schemaMeta.actions.execution.interface} }
207
+ ): Promise<${model.typeName}[]> {
225
208
  const mutationId = await execution.startCreateManyMutation({
226
209
  model: '${meta.actions.actionScopeConstType}',
227
210
  createObjects: items
@@ -256,10 +239,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
256
239
  }
257
240
  }
258
241
 
259
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.update.jsDoc)}
242
+ ${(0, jsdoc_1.toJsDocComment)([`Updates a ${meta.userFriendlyName} and returns it.`])}
260
243
  public async update(
261
- { item, execution }: ${methodTypeSignatures.update.parameters[0]}
262
- ): ${methodTypeSignatures.update.returnType} {
244
+ { item, execution }: { item: ${meta.types.dto.update}, execution: ${schemaMeta.actions.execution.interface} }
245
+ ): Promise<${model.typeName}> {
263
246
  const existingItem = await this.get(item.${idField.name})
264
247
  if (!existingItem) {
265
248
  throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
@@ -303,10 +286,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
303
286
  }
304
287
  }
305
288
 
306
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.updateMany.jsDoc)}
289
+ ${(0, jsdoc_1.toJsDocComment)([`Updates multiple ${meta.userFriendlyNamePlural} and returns them.`])}
307
290
  public async updateMany(
308
- { items, execution }: ${methodTypeSignatures.updateMany.parameters[0]}
309
- ): ${methodTypeSignatures.updateMany.returnType} {
291
+ { items, execution }: { items: ${meta.types.dto.update}[], execution: ${schemaMeta.actions.execution.interface} }
292
+ ): Promise<${model.typeName}[]> {
310
293
  const result: ${model.typeName}[] = []
311
294
  for (const item of items) {
312
295
  try {
@@ -319,10 +302,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
319
302
  return result
320
303
  }
321
304
 
322
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsert.jsDoc)}
305
+ ${(0, jsdoc_1.toJsDocComment)([`Creates or updates a ${meta.userFriendlyName} and returns it.`])}
323
306
  public async upsert(
324
- { item, execution }: ${methodTypeSignatures.upsert.parameters[0]}
325
- ): ${methodTypeSignatures.upsert.returnType} {
307
+ { item, execution }: { item: ${meta.types.dto.upsert}, execution: ${schemaMeta.actions.execution.interface} }
308
+ ): Promise<${model.typeName}> {
326
309
  const existingItem = item.${model.idField.name} ? (await this.get(item.${model.idField.name})) : null
327
310
  if (existingItem) {
328
311
  return this.update({ item: item as ${meta.types.dto.update}, execution })
@@ -331,10 +314,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
331
314
  }
332
315
  }
333
316
 
334
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.upsertMany.jsDoc)}
317
+ ${(0, jsdoc_1.toJsDocComment)([`Creates or updates multiple ${meta.userFriendlyNamePlural} and returns them.`])}
335
318
  public async upsertMany(
336
- { items, execution }: ${methodTypeSignatures.upsertMany.parameters[0]}
337
- ): ${methodTypeSignatures.upsertMany.returnType} {
319
+ { items, execution }: { items: ${meta.types.dto.upsert}[], execution: ${schemaMeta.actions.execution.interface} }
320
+ ): Promise<${model.typeName}[]> {
338
321
  const result: ${model.typeName}[] = []
339
322
  for (const item of items) {
340
323
  try {
@@ -347,10 +330,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
347
330
  return result
348
331
  }
349
332
 
350
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.delete.jsDoc)}
333
+ ${(0, jsdoc_1.toJsDocComment)([`Deletes a ${meta.userFriendlyName} and returns its id.`])}
351
334
  public async delete(
352
- { id, execution }: ${methodTypeSignatures.delete.parameters[0]}
353
- ): ${methodTypeSignatures.delete.returnType} {
335
+ { id, execution }: { id: ${model.brandedIdType}, execution: ${schemaMeta.actions.execution.interface} }
336
+ ): Promise<${model.brandedIdType}> {
354
337
  const existingItem = await this.get(id)
355
338
  if (!existingItem) {
356
339
  throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
@@ -374,10 +357,10 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
374
357
  }
375
358
  }
376
359
 
377
- ${(0, jsdoc_1.toJsDocComment)(methodTypeSignatures.deleteMany.jsDoc)}
360
+ ${(0, jsdoc_1.toJsDocComment)([`Deletes multiple ${meta.userFriendlyNamePlural} and returns their ids.`])}
378
361
  public async deleteMany(
379
- { ids, execution }: ${methodTypeSignatures.deleteMany.parameters[0]}
380
- ): ${methodTypeSignatures.deleteMany.returnType} {
362
+ { ids, execution }: { ids: ${model.brandedIdType}[], execution: ${schemaMeta.actions.execution.interface} }
363
+ ): Promise<${model.brandedIdType}[]> {
381
364
  const deletedIds: ${model.brandedIdType}[] = []
382
365
  for (const id of ids) {
383
366
  try {
@@ -390,6 +373,23 @@ export class ${meta.data.repository.className} implements Repository<${model.typ
390
373
  return deletedIds
391
374
  }
392
375
 
376
+ ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} shallow clone and returns it.`])}
377
+ public async clone({ id, item, execution }: {
378
+ id: ${model.brandedIdType}
379
+ item: (item: ${model.typeName}) => ${meta.types.dto.clone},
380
+ execution: ${schemaMeta.actions.execution.interface}
381
+ }): Promise<${model.typeName}> {
382
+ const source = await this.get(id)
383
+ if (!source) {
384
+ throw new Error(\`${meta.userFriendlyName} with id \${id} not found\`)
385
+ }
386
+
387
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
388
+ const { id: _, ...data } = { ...source, ...item(source) }
389
+
390
+ return await this.create({ item: data, execution })
391
+ }
392
+
393
393
  ${relationsBlocks.getterFunctions.join('\n')}
394
394
 
395
395
  ${maxLengthBlocks.ensureMaxLengthFunctions.join('\n')}
@@ -593,139 +593,67 @@ function generateSharedRootUserBlocks({ model, meta, imports, }) {
593
593
  function generateIdBlocks({ model, meta }) {
594
594
  const idField = model.idField;
595
595
  if (!idField.isGenerated) {
596
- return _generateIdBlocks_NoGeneration({ idField, model, meta });
596
+ return {
597
+ libraryImports: '',
598
+ generateNextIdFunctionName: '',
599
+ initCode: '',
600
+ verifyFunctionComment: `an error is thrown as field has no default setting in schema.`,
601
+ verifyFunctionParameterType: meta.types.dto.create,
602
+ verifyCode: `
603
+ if (item.${idField.name} === undefined) {
604
+ throw new Error('Id field ${idField.name} is required!')
605
+ }
606
+ const ${idField.name} = ${meta.types.toBrandedIdTypeFnName}(item.${idField.name})`,
607
+ setCode: '',
608
+ createFunctionParameterType: model.typeName,
609
+ };
597
610
  }
598
611
  if (idField.schemaType === 'Int') {
599
- return _generateIdBlock_Int({ idField, model, meta });
612
+ const generatedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
613
+ const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
614
+ return {
615
+ libraryImports: '',
616
+ generateNextIdFunctionName: `
617
+ protected currentMaxId = 0
618
+ public generateNextId(): ${model.brandedIdType} {
619
+ return ${meta.types.toBrandedIdTypeFnName}(++this.currentMaxId)
620
+ }`,
621
+ initCode: `this.currentMaxId = (await this.db.${meta.data.repository.getMethodFnName}.aggregate({ _max: { ${idField.sourceName}: true } }))._max.${idField.sourceName} ?? 0`,
622
+ verifyFunctionComment: 'the id is generated by increasing the highest former id and assigned to the item.',
623
+ // prettier-ignore
624
+ verifyFunctionParameterType: `(Omit<${model.typeName}, ${generatedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
625
+ verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
626
+ createFunctionParameterType:
627
+ // NOTE: In case we have readonly fields, we need to omit them from the create function.
628
+ readonlyFields.length === 0
629
+ ? model.typeName
630
+ : `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
631
+ setCode: `if (item.id > this.currentMaxId) { this.currentMaxId = item.id }`,
632
+ };
600
633
  }
601
634
  if (idField.schemaType === 'String') {
602
- return _generateIdBlock_UUID({ idField, model, meta });
603
- }
604
- throw new Error(`Repository block only supports Id generation for number and strings! Found ${idField.schemaType} for model ${model.name} instead!`);
605
- }
606
- /**
607
- * Returns a collection of type signatures for the repository methods of a given model.
608
- */
609
- // NOTE: We export this function as an interface simplification to the repository generator. Internally, we
610
- // use the same functions as the ones used in this function which we don't want to expose.
611
- function getRepositoryMethodsTypeSignatures({ model, meta }) {
612
- const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
613
- return {
614
- create: {
615
- jsDoc: [`Creates a new ${meta.userFriendlyName} and returns it.`],
616
- parameters: [`{item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.execution.interface}}`],
617
- returnType: `Promise<${model.typeName}>`,
618
- },
619
- createMany: {
620
- jsDoc: [`Creates multiple new ${meta.userFriendlyNamePlural} and returns them.`],
621
- parameters: [`{items: ${meta.types.dto.create}[], execution: ${schemaMeta.actions.execution.interface}}`],
622
- returnType: `Promise<${model.typeName}[]>`,
623
- },
624
- update: {
625
- jsDoc: [`Updates a ${meta.userFriendlyName} and returns it.`],
626
- parameters: [`{item: ${meta.types.dto.update}, execution: ${schemaMeta.actions.execution.interface}}`],
627
- returnType: `Promise<${model.typeName}>`,
628
- },
629
- updateMany: {
630
- jsDoc: [`Updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
631
- parameters: [`{items: ${meta.types.dto.update}[], execution: ${schemaMeta.actions.execution.interface}}`],
632
- returnType: `Promise<${model.typeName}[]>`,
633
- },
634
- upsert: {
635
- jsDoc: [`Creates or updates a ${meta.userFriendlyName} and returns it.`],
636
- parameters: [`{item: ${meta.types.dto.upsert}, execution: ${schemaMeta.actions.execution.interface}}`],
637
- returnType: `Promise<${model.typeName}>`,
638
- },
639
- upsertMany: {
640
- jsDoc: [`Creates or updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
641
- parameters: [`{items: ${meta.types.dto.upsert}[], execution: ${schemaMeta.actions.execution.interface}}`],
642
- returnType: `Promise<${model.typeName}[]>`,
643
- },
644
- delete: {
645
- jsDoc: [`Deletes a ${meta.userFriendlyName} and returns its id.`],
646
- parameters: [`{id: ${model.brandedIdType}, execution: ${schemaMeta.actions.execution.interface}}`],
647
- returnType: `Promise<${model.brandedIdType}>`,
648
- },
649
- deleteMany: {
650
- jsDoc: [`Deletes multiple ${meta.userFriendlyNamePlural} and returns their ids.`],
651
- parameters: [`{ids: ${model.brandedIdType}[], execution: ${schemaMeta.actions.execution.interface}}`],
652
- returnType: `Promise<${model.brandedIdType}[]>`,
653
- },
654
- };
655
- }
656
- exports.getRepositoryMethodsTypeSignatures = getRepositoryMethodsTypeSignatures;
657
- /**
658
- * Generates the id block code chunks for a model that requires an ID field to be manually
659
- * supplied to the create function.
660
- */
661
- function _generateIdBlocks_NoGeneration({ idField, model, meta, }) {
662
- return {
663
- libraryImports: '',
664
- generateNextIdFunctionName: '',
665
- initCode: '',
666
- verifyFunctionComment: `an error is thrown as field has no default setting in schema.`,
667
- verifyFunctionParameterType: meta.types.dto.create,
668
- verifyCode: `
669
- if (item.${idField.name} === undefined) {
670
- throw new Error('Id field ${idField.name} is required!')
671
- }
672
- const ${idField.name} = ${meta.types.toBrandedIdTypeFnName}(item.${idField.name})`,
673
- setCode: '',
674
- createFunctionParameterType: model.typeName,
675
- };
676
- }
677
- /**
678
- * Generates the id block code chunks for a model that has an integer id field.
679
- * Given chunks make sure that the id is unique if provided or generate a new one if not.
680
- */
681
- function _generateIdBlock_Int({ idField, model, meta, }) {
682
- const generatedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
683
- const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
684
- return {
685
- libraryImports: '',
686
- generateNextIdFunctionName: `
687
- protected currentMaxId = 0
688
- public generateNextId(): ${model.brandedIdType} {
689
- return ${meta.types.toBrandedIdTypeFnName}(++this.currentMaxId)
690
- }`,
691
- initCode: `this.currentMaxId = (await this.db.${meta.data.repository.getMethodFnName}.aggregate({ _max: { ${idField.sourceName}: true } }))._max.${idField.sourceName} ?? 0`,
692
- verifyFunctionComment: 'the id is generated by increasing the highest former id and assigned to the item.',
693
- // prettier-ignore
694
- verifyFunctionParameterType: `(Omit<${model.typeName}, ${generatedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
695
- verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
696
- createFunctionParameterType:
697
- // NOTE: In case we have readonly fields, we need to omit them from the create function.
698
- readonlyFields.length === 0
699
- ? model.typeName
700
- : `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
701
- setCode: `if (item.id > this.currentMaxId) { this.currentMaxId = item.id }`,
702
- };
703
- }
704
- /**
705
- * Generates the id block code chunks for a model that has a UUID id field.
706
- * It allows you to provide a custom id or generates a new one if not.
707
- */
708
- function _generateIdBlock_UUID({ idField, model, meta, }) {
709
- const dbGeneratedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
710
- const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
711
- return {
712
- libraryImports: `import { randomUUID } from 'crypto'`,
713
- generateNextIdFunctionName: `
635
+ const dbGeneratedFields = model.fields.filter((f) => f.kind === 'id' || f.attributes.isReadonly);
636
+ const readonlyFields = model.fields.filter((f) => f.attributes.isReadonly && f.kind !== 'id');
637
+ return {
638
+ libraryImports: `import { randomUUID } from 'crypto'`,
639
+ generateNextIdFunctionName: `
714
640
  public generateNextId(): ${model.brandedIdType} {
715
641
  return ${meta.types.toBrandedIdTypeFnName}(randomUUID())
716
642
  }`,
717
- initCode: '',
718
- verifyFunctionComment: 'a new UUID is generated and assigned to the item.',
719
- // prettier-ignore
720
- verifyFunctionParameterType: `(Omit<${model.typeName}, ${dbGeneratedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
721
- verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
722
- createFunctionParameterType:
723
- // NOTE: In case we have readonly fields, we need to omit them from the create function.
724
- readonlyFields.length === 0
725
- ? model.typeName
726
- : `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
727
- setCode: '',
728
- };
643
+ initCode: '',
644
+ verifyFunctionComment: 'a new UUID is generated and assigned to the item.',
645
+ // prettier-ignore
646
+ verifyFunctionParameterType: `(Omit<${model.typeName}, ${dbGeneratedFields.map((f) => `'${f.name}'`).join(' | ')}> & Partial<{${idField.name}: ${idField.unbrandedTypeName}}>)`,
647
+ verifyCode: `const ${idField.name} = (item.${idField.name} !== undefined) ? ${meta.types.toBrandedIdTypeFnName}(item.${idField.name}) : this.generateNextId()`,
648
+ createFunctionParameterType:
649
+ // NOTE: In case we have readonly fields, we need to omit them from the create function.
650
+ readonlyFields.length === 0
651
+ ? model.typeName
652
+ : `Omit<${model.typeName}, ${readonlyFields.map((f) => `'${f.name}'`).join(' |')}>`,
653
+ setCode: '',
654
+ };
655
+ }
656
+ throw new Error(`Repository block only supports Id generation for number and strings! Found ${idField.schemaType} for model ${model.name} instead!`);
729
657
  }
730
658
  /**
731
659
  * Returns the code chunks that define the default value property and its initialization.
@@ -8,9 +8,9 @@ const types_1 = require("../../lib/schema/types");
8
8
  */
9
9
  function generateRoute({ model, meta }) {
10
10
  const { idField, defaultField } = model;
11
- const { scopeName, dataRepositoryVariableName } = meta.update;
11
+ const { scopeName } = meta.update;
12
12
  const defaultValueMethod = `
13
- getDefault: procedure.query(({ ctx }) => ctx.view.${meta.data.dataServiceName}.${dataRepositoryVariableName}.defaultValue),
13
+ getDefault: procedure.query(({ ctx }) => ctx.view.${meta.data.dataServiceName}.data.defaultValue),
14
14
  `;
15
15
  const imports = imports_1.ImportsGenerator.from(meta.trpc.routerFilePath).addImports({
16
16
  [meta.types.importPath]: [
@@ -53,8 +53,6 @@ export type ${meta.types.typeName} = {
53
53
  .join('\n')}
54
54
  }
55
55
 
56
-
57
-
58
56
  /**
59
57
  * Branded Id type that should be used to identify an instance of a ${meta.userFriendlyName}.
60
58
  */
@@ -95,6 +93,33 @@ export type ${meta.types.dto.update} = ${schemaMeta.types.dto.update}<${meta.typ
95
93
  * Data transfer object for upserting a new or existing ${meta.userFriendlyName} instance.
96
94
  */
97
95
  export type ${meta.types.dto.upsert} = ${schemaMeta.types.dto.upsert}<${meta.types.typeName}, ${model.brandedIdType}>
96
+
97
+ /**
98
+ * Data transfer object for cloning a new ${meta.userFriendlyName} instance.
99
+ */
100
+ export type ${meta.types.dto.clone} = {
101
+ ${model.fields
102
+ .map((f) => {
103
+ const type = (0, typescript_1.getFieldType)(f);
104
+ // NOTE: ID field is always required to resolve the source.
105
+ if (f.kind === 'id') {
106
+ return `${f.name}: ${type}`;
107
+ }
108
+ if (f.isUnique) {
109
+ // NOTE: `unique` fields require a new value.
110
+ if (f.isRequired) {
111
+ return `${f.name}: ${type}`;
112
+ }
113
+ return `${f.name}: ${type} | null`;
114
+ }
115
+ // NOTE: Non-unique fields can be copied from the source.
116
+ if (f.isRequired) {
117
+ return `${f.name}?: ${type}`;
118
+ }
119
+ return `${f.name}?: ${type} | null`;
120
+ })
121
+ .join(', ')}
122
+ }
98
123
  `;
99
124
  }
100
125
  exports.generateModelTypes = generateModelTypes;
@@ -1,5 +1,5 @@
1
- import { ModelMetaData } from '../../lib/meta';
2
- import { Model } from '../../lib/schema/schema';
1
+ import { ModelMetaData } from '../../../lib/meta';
2
+ import { Model } from '../../../lib/schema/schema';
3
3
  /**
4
4
  * Generates update business logic for a given model.
5
5
  * The update logic handles all Create/Update/Delete/Upsert operations. See template's readme for more info.