@postxl/generator 0.69.0 → 0.70.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.
Files changed (57) hide show
  1. package/README.md +1 -20
  2. package/dist/generator.js +41 -40
  3. package/dist/generators/indices/{datamodule.generator.d.ts → data/module.generator.d.ts} +2 -2
  4. package/dist/generators/indices/{datamodule.generator.js → data/module.generator.js} +4 -5
  5. package/dist/generators/indices/{dataservice.generator.d.ts → data/service.generator.d.ts} +2 -2
  6. package/dist/generators/indices/{dataservice.generator.js → data/service.generator.js} +5 -5
  7. package/dist/generators/indices/{data-types.generator.d.ts → data/types.generator.d.ts} +2 -2
  8. package/dist/generators/indices/{data-types.generator.js → data/types.generator.js} +2 -2
  9. package/dist/generators/indices/{importexport-convert-import-functions.generator.d.ts → import-export/importexport-convert-import-functions.generator.d.ts} +2 -2
  10. package/dist/generators/indices/{importexport-convert-import-functions.generator.js → import-export/importexport-convert-import-functions.generator.js} +4 -4
  11. package/dist/generators/indices/{importexport-exporter-class.generator.d.ts → import-export/importexport-exporter-class.generator.d.ts} +2 -2
  12. package/dist/generators/indices/{importexport-exporter-class.generator.js → import-export/importexport-exporter-class.generator.js} +4 -5
  13. package/dist/generators/indices/{importexport-import-service.generator.d.ts → import-export/importexport-import-service.generator.d.ts} +2 -2
  14. package/dist/generators/indices/{importexport-import-service.generator.js → import-export/importexport-import-service.generator.js} +4 -4
  15. package/dist/generators/indices/{importexport-types.generator.d.ts → import-export/importexport-types.generator.d.ts} +2 -2
  16. package/dist/generators/indices/{importexport-types.generator.js → import-export/importexport-types.generator.js} +2 -2
  17. package/dist/generators/indices/{routes-index.generator.js → routes.generator.js} +3 -0
  18. package/dist/generators/indices/seed-template.generator.js +2 -2
  19. package/dist/generators/indices/types.generator.js +13 -1
  20. package/dist/generators/indices/{businesslogic-actiontypes.generator.d.ts → update/actiontypes.generator.d.ts} +2 -2
  21. package/dist/generators/indices/{businesslogic-actiontypes.generator.js → update/actiontypes.generator.js} +3 -3
  22. package/dist/generators/indices/{businesslogic-update-module.generator.d.ts → update/module.generator.d.ts} +2 -2
  23. package/dist/generators/indices/{businesslogic-update-module.generator.js → update/module.generator.js} +2 -2
  24. package/dist/generators/indices/{businesslogic-update-service.generator.d.ts → update/service.generator.d.ts} +2 -2
  25. package/dist/generators/indices/{businesslogic-update-service.generator.js → update/service.generator.js} +2 -2
  26. package/dist/generators/indices/{businesslogic-view-module.generator.d.ts → view/module.generator.d.ts} +2 -2
  27. package/dist/generators/indices/{businesslogic-view-module.generator.js → view/module.generator.js} +2 -2
  28. package/dist/generators/indices/{businesslogic-view-service.generator.d.ts → view/service.generator.d.ts} +2 -2
  29. package/dist/generators/indices/{businesslogic-view-service.generator.js → view/service.generator.js} +2 -2
  30. package/dist/generators/models/importexport-decoder.generator.d.ts +1 -2
  31. package/dist/generators/models/importexport-decoder.generator.js +17 -46
  32. package/dist/generators/models/repository.generator.d.ts +0 -39
  33. package/dist/generators/models/repository.generator.js +103 -175
  34. package/dist/generators/models/route.generator.js +7 -3
  35. package/dist/generators/models/types.generator.js +27 -2
  36. package/dist/generators/models/{businesslogic-update.generator.d.ts → update/service.generator.d.ts} +2 -2
  37. package/dist/generators/models/update/service.generator.js +252 -0
  38. package/dist/generators/models/{businesslogic-view.generator.d.ts → view/service.generator.d.ts} +2 -2
  39. package/dist/generators/models/{businesslogic-view.generator.js → view/service.generator.js} +12 -18
  40. package/dist/lib/meta.d.ts +16 -31
  41. package/dist/lib/meta.js +2 -19
  42. package/dist/lib/schema/fields.d.ts +1 -1
  43. package/dist/lib/zod.d.ts +1 -1
  44. package/dist/prisma/parse.js +1 -1
  45. package/package.json +5 -8
  46. package/dist/generators/models/businesslogic-update.generator.js +0 -324
  47. /package/dist/generators/indices/{routes-index.generator.d.ts → routes.generator.d.ts} +0 -0
  48. /package/dist/generators/models/{react.generator → react}/context.generator.d.ts +0 -0
  49. /package/dist/generators/models/{react.generator → react}/context.generator.js +0 -0
  50. /package/dist/generators/models/{react.generator → react}/index.d.ts +0 -0
  51. /package/dist/generators/models/{react.generator → react}/index.js +0 -0
  52. /package/dist/generators/models/{react.generator → react}/library.generator.d.ts +0 -0
  53. /package/dist/generators/models/{react.generator → react}/library.generator.js +0 -0
  54. /package/dist/generators/models/{react.generator → react}/lookup.generator.d.ts +0 -0
  55. /package/dist/generators/models/{react.generator → react}/lookup.generator.js +0 -0
  56. /package/dist/generators/models/{react.generator → react}/modals.generator.d.ts +0 -0
  57. /package/dist/generators/models/{react.generator → react}/modals.generator.js +0 -0
@@ -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.
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateModelBusinessLogicUpdate = void 0;
7
+ const assert_1 = __importDefault(require("assert"));
8
+ const imports_1 = require("../../../lib/imports");
9
+ const meta_1 = require("../../../lib/meta");
10
+ const fields_1 = require("../../../lib/schema/fields");
11
+ const types_1 = require("../../../lib/schema/types");
12
+ const types_2 = require("../../../lib/types");
13
+ const typescript_1 = require("../../../lib/typescript");
14
+ const jsdoc_1 = require("../../../lib/utils/jsdoc");
15
+ const zod_1 = require("../../../lib/zod");
16
+ /**
17
+ * Generates update business logic for a given model.
18
+ * The update logic handles all Create/Update/Delete/Upsert operations. See template's readme for more info.
19
+ */
20
+ function generateModelBusinessLogicUpdate({ model, meta }) {
21
+ const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
22
+ const { view, update, types, data } = meta;
23
+ const imports = imports_1.ImportsGenerator.from(meta.update.serviceClassLocation.path).addImports({
24
+ [data.repository.location.import]: data.repository.className,
25
+ [types.importPath]: [model.brandedIdType, types.typeName, types.toBrandedIdTypeFnName],
26
+ [view.serviceLocation.import]: [view.serviceClassName],
27
+ [schemaMeta.actions.execution.interfaceLocation.import]: [schemaMeta.actions.execution.interface],
28
+ [schemaMeta.actions.dispatcher.definitionLocation.import]: [schemaMeta.actions.dispatcher.definition],
29
+ [schemaMeta.update.serviceLocation.path]: schemaMeta.update.serviceClassName,
30
+ [schemaMeta.view.serviceLocation.import]: schemaMeta.view.serviceClassName,
31
+ });
32
+ for (const field of (0, fields_1.getRelationFields)(model)) {
33
+ // NOTE: We add `toBrandedType` functions for foreign models for decoders.
34
+ if (field.relationToModel.typeName === model.typeName) {
35
+ continue;
36
+ }
37
+ const refModelMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
38
+ imports.addImport({
39
+ from: refModelMeta.types.importPath,
40
+ items: [refModelMeta.types.toBrandedIdTypeFnName],
41
+ });
42
+ }
43
+ const cloneFn = generateCloneFn({ model, meta, imports });
44
+ return /* ts */ `
45
+ import { Inject, Injectable, forwardRef } from '@nestjs/common'
46
+ import { z } from 'zod'
47
+
48
+ ${imports.generate()}
49
+
50
+ export type Scope = "${meta.actions.actionScopeConstType}"
51
+
52
+ export type Actions = {
53
+ ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} and returns it.`])}
54
+ create: {
55
+ payload: CreatePayload
56
+ result: ${types.typeName}
57
+ }
58
+
59
+ ${(0, jsdoc_1.toJsDocComment)([`Updates a ${meta.userFriendlyName} and returns it.`])}
60
+ update: {
61
+ payload: UpdatePayload
62
+ result: ${types.typeName}
63
+ }
64
+
65
+ ${(0, jsdoc_1.toJsDocComment)([`Creates or updates a ${meta.userFriendlyName} and returns it.`])}
66
+ upsert: {
67
+ payload: UpsertPayload
68
+ result: ${types.typeName}
69
+ }
70
+
71
+ ${(0, jsdoc_1.toJsDocComment)([`Deletes a ${meta.userFriendlyName} and returns its id.`])}
72
+ delete: {
73
+ payload: ${model.brandedIdType}
74
+ result: ${model.brandedIdType}
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Zod decoder for validating the create input of a ${meta.userFriendlyName}.
80
+ */
81
+ export const ${meta.update.createInputDecoder} = z.object({
82
+ ${model.fields
83
+ .filter((f) => !f.attributes.isReadonly)
84
+ .map((f) => `${f.name}: z.${(0, zod_1.getZodDecoderDefinition)({ field: f })}`)
85
+ .join(',')}
86
+ })
87
+
88
+ type CreatePayload = z.infer<typeof ${meta.update.createInputDecoder}>
89
+
90
+ /**
91
+ * Zod decoder for validating the update input of a ${meta.userFriendlyName} .
92
+ */
93
+ export const ${meta.update.updateInputDecoder} = z.object({
94
+ ${model.fields
95
+ .filter((f) => !f.attributes.isReadonly || f.kind === 'id')
96
+ .map((f) => `${f.name}: z.${(0, zod_1.getZodDecoderDefinition)({ field: f, allowAnyOptionalField: f.kind !== 'id' })}`)
97
+ .join(',')}
98
+ })
99
+
100
+ type UpdatePayload = z.infer<typeof ${meta.update.updateInputDecoder}>
101
+
102
+ /**
103
+ * Zod decoder for validating the upsert input of a ${meta.userFriendlyName} .
104
+ */
105
+ export const ${meta.update.upsertInputDecoder} = z.union([
106
+ ${meta.update.updateInputDecoder},
107
+ ${meta.update.createInputDecoder}
108
+ ])
109
+
110
+ type UpsertPayload = z.infer<typeof ${meta.update.upsertInputDecoder}>
111
+
112
+ export type ${update.serviceInterfaceName} = ${schemaMeta.actions.dispatcher.definition}<Actions>
113
+
114
+ @Injectable()
115
+ export class ${update.serviceClassName} implements ${update.serviceInterfaceName} {
116
+
117
+ /**
118
+ * Instance of the ${meta.userFriendlyName} view service for convenience.
119
+ */
120
+ private view: ${view.serviceClassName}
121
+
122
+ constructor(
123
+ private readonly data: ${data.repository.className},
124
+
125
+ @Inject(forwardRef(() => ${schemaMeta.update.serviceClassName}))
126
+ private readonly updateService: ${schemaMeta.update.serviceClassName},
127
+
128
+ @Inject(forwardRef(() => ${schemaMeta.view.serviceClassName}))
129
+ private readonly viewService: ${schemaMeta.view.serviceClassName}
130
+ ) {
131
+ this.view = this.viewService.${view.serviceVariableName}
132
+ }
133
+
134
+ ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} and returns it.`])}
135
+ public async create({ data, execution }: {
136
+ data: CreatePayload;
137
+ execution: ${schemaMeta.actions.execution.interface}
138
+ }): Promise<${types.typeName}> {
139
+ return this.data.create({ item: data, execution })
140
+ }
141
+
142
+ ${(0, jsdoc_1.toJsDocComment)([`Updates a ${meta.userFriendlyName} and returns it.`])}
143
+ public async update({ data, execution }: {
144
+ data: UpdatePayload;
145
+ execution: ${schemaMeta.actions.execution.interface}
146
+ }): Promise<${types.typeName}> {
147
+ return this.data.update({ item: data, execution })
148
+ }
149
+
150
+ ${(0, jsdoc_1.toJsDocComment)([`Creates or updates a ${meta.userFriendlyName} and returns it.`])}
151
+ public async upsert({ data, execution }: {
152
+ data: UpsertPayload;
153
+ execution: ${schemaMeta.actions.execution.interface}
154
+ }): Promise<${types.typeName}> {
155
+ return this.data.upsert({ item: data, execution })
156
+ }
157
+
158
+ ${(0, jsdoc_1.toJsDocComment)([`Deletes a ${meta.userFriendlyName} instance and returns its id.`])}
159
+ public async delete({ data, execution }: {
160
+ data: ${model.brandedIdType};
161
+ execution: ${schemaMeta.actions.execution.interface}
162
+ }): Promise<${model.brandedIdType}> {
163
+ return this.data.delete({ id: data, execution })
164
+ }
165
+
166
+ ${cloneFn}
167
+ }
168
+ `;
169
+ }
170
+ exports.generateModelBusinessLogicUpdate = generateModelBusinessLogicUpdate;
171
+ function generateCloneFn({ model, meta, imports }) {
172
+ const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
173
+ for (const enumField of (0, fields_1.getEnumFields)(model)) {
174
+ const enumMeta = (0, meta_1.getEnumMetadata)(enumField);
175
+ imports.addTypeImport({
176
+ from: enumMeta.types.importPath,
177
+ items: [enumField.typeName],
178
+ });
179
+ }
180
+ const fnInputFields = model.fields
181
+ .filter((f) => {
182
+ switch (f.kind) {
183
+ case 'id':
184
+ case 'scalar':
185
+ case 'enum':
186
+ return true;
187
+ case 'relation':
188
+ return false;
189
+ default:
190
+ throw new types_2.ExhaustiveSwitchCheck(f);
191
+ }
192
+ })
193
+ .map((f) => {
194
+ const type = (0, typescript_1.getFieldType)(f);
195
+ switch (f.kind) {
196
+ case 'id':
197
+ return `${f.name}: ${type}`;
198
+ case 'scalar':
199
+ case 'enum':
200
+ if (f.isUnique) {
201
+ // NOTE: `unique` fields require a new value.
202
+ if (f.isRequired) {
203
+ return `${f.name}: ${type}`;
204
+ }
205
+ return `${f.name}: ${type} | null`;
206
+ }
207
+ // NOTE: Non-unique fields can be copied from the source.
208
+ if (f.isRequired) {
209
+ return `${f.name}?: ${type}`;
210
+ }
211
+ return `${f.name}?: ${type} | null`;
212
+ case 'relation':
213
+ (0, assert_1.default)(false);
214
+ break;
215
+ default:
216
+ throw new types_2.ExhaustiveSwitchCheck(f);
217
+ }
218
+ });
219
+ const foreignKeyMappings = (0, fields_1.getRelationFields)(model).map((f) => {
220
+ if (f.isRequired) {
221
+ return `${f.name}: mappings.get({ model: '${f.relationToModel.typeName}', id: item.${f.name} })`;
222
+ }
223
+ return `${f.name}: item.${f.name} ? mappings.get({ model: '${f.relationToModel.typeName}', id: item.${f.name} }) : null`;
224
+ });
225
+ if (foreignKeyMappings.length > 0) {
226
+ imports.addImports({
227
+ [schemaMeta.types.importPath]: [schemaMeta.types.idTypesIndex],
228
+ [(0, types_1.toPackageName)('@postxl/runtime')]: [(0, types_1.toClassName)('TypedMapping')],
229
+ });
230
+ }
231
+ return `
232
+ ${(0, jsdoc_1.toJsDocComment)([`Clones a ${meta.userFriendlyName} with mapped foreign ids.`])}
233
+ public async clone(
234
+ { data, execution }: {
235
+ data: { ${fnInputFields.join('; ')} },
236
+ execution: ${schemaMeta.actions.execution.interface}
237
+ },
238
+ ${foreignKeyMappings.length > 0 ? `mappings = new TypedMapping<${schemaMeta.types.idTypesIndex}>()` : ''}
239
+ ): Promise<${meta.types.typeName}> {
240
+ const clone = await this.data.clone({
241
+ id: data.id,
242
+ item: (${foreignKeyMappings.length > 0 ? 'item' : ''}) => ({
243
+ ...data,
244
+ ${foreignKeyMappings.join(',\n')}
245
+ }),
246
+ execution
247
+ })
248
+
249
+ return clone
250
+ }
251
+ `;
252
+ }
@@ -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 view business logic for a given model.
5
5
  * The view logic exposes all information and links of a model. See template's readme for more info.
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateModelBusinessLogicView = void 0;
4
- const imports_1 = require("../../lib/imports");
5
- const meta_1 = require("../../lib/meta");
6
- const fields_1 = require("../../lib/schema/fields");
7
- const types_1 = require("../../lib/schema/types");
8
- const types_2 = require("../../lib/types");
9
- const ast_1 = require("../../lib/utils/ast");
10
- const jsdoc_1 = require("../../lib/utils/jsdoc");
4
+ const imports_1 = require("../../../lib/imports");
5
+ const meta_1 = require("../../../lib/meta");
6
+ const fields_1 = require("../../../lib/schema/fields");
7
+ const types_1 = require("../../../lib/schema/types");
8
+ const types_2 = require("../../../lib/types");
9
+ const ast_1 = require("../../../lib/utils/ast");
10
+ const jsdoc_1 = require("../../../lib/utils/jsdoc");
11
11
  /**
12
12
  * Generates view business logic for a given model.
13
13
  * The view logic exposes all information and links of a model. See template's readme for more info.
@@ -20,12 +20,6 @@ function generateModelBusinessLogicView({ model, meta }) {
20
20
  [meta.types.importPath]: [(0, types_1.toAnnotatedTypeName)(model.brandedIdType), (0, types_1.toAnnotatedTypeName)(meta.types.typeName)],
21
21
  [schemaMeta.view.serviceLocation.path]: schemaMeta.view.serviceClassName,
22
22
  });
23
- /**
24
- * The name of the variable that holds the repository instance for the current model
25
- * (e.g. when we generate business logic service for Aggregation, the AggregationRepository
26
- * would be referenced using `this.data` variable).
27
- */
28
- const modelRepositoryVariableName = meta.view.dataRepositoryVariableName;
29
23
  /**
30
24
  * The name of the variable that holds the central business logic service instance.
31
25
  * Instead of injecting a repository instance for each model, we inject this single instance
@@ -33,7 +27,7 @@ function generateModelBusinessLogicView({ model, meta }) {
33
27
  */
34
28
  const viewServiceClassName = 'viewService';
35
29
  const constructorParameters = [
36
- `public readonly ${modelRepositoryVariableName}: ${meta.data.repository.className}`,
30
+ `public readonly data: ${meta.data.repository.className}`,
37
31
  `@Inject(forwardRef(() => ${schemaMeta.view.serviceClassName})) private readonly ${viewServiceClassName}: ${schemaMeta.view.serviceClassName}`,
38
32
  ];
39
33
  /**
@@ -76,7 +70,7 @@ function generateModelBusinessLogicView({ model, meta }) {
76
70
  * Linked: The ${meta.userFriendlyName} contains the linked (raw) items themselves, not only the ids.
77
71
  */
78
72
  public async getLinkedItem(id: ${model.brandedIdType}): Promise<${meta.types.linkedTypeName} | null> {
79
- const itemRaw = await this.${modelRepositoryVariableName}.get(id)
73
+ const itemRaw = await this.data.get(id)
80
74
  if (!itemRaw) {
81
75
  return null
82
76
  }
@@ -157,7 +151,7 @@ export class ${meta.view.serviceClassName} {
157
151
  * Raw: The ${meta.userFriendlyName} only contains linked Ids, not the linked items themselves.
158
152
  */
159
153
  public async get(id: ${model.brandedIdType}): Promise<${meta.types.typeName} | null> {
160
- return this.${modelRepositoryVariableName}.get(id)
154
+ return this.data.get(id)
161
155
  }
162
156
 
163
157
  ${hasLinkedItems ? linkedItemsGetterFn : ''}
@@ -166,7 +160,7 @@ export class ${meta.view.serviceClassName} {
166
160
  * Returns a map of all ${meta.userFriendlyNamePlural}.
167
161
  */
168
162
  public async getAll(): Promise<Map<${meta.types.brandedIdType}, ${model.typeName}>> {
169
- return this.${modelRepositoryVariableName}.getAll()
163
+ return this.data.getAll()
170
164
  }
171
165
 
172
166
  /**
@@ -181,7 +175,7 @@ export class ${meta.view.serviceClassName} {
181
175
  sort?: { field: keyof ${model.typeName}; ascending: boolean }
182
176
  cursor?: Cursor
183
177
  }) {
184
- const items = await this.${modelRepositoryVariableName}.getAllAsArray()
178
+ const items = await this.data.getAllAsArray()
185
179
  const filtered = !filter
186
180
  ? items
187
181
  : items.filter((item) => filterFn(item, filter.field, filter.operator, filter.value))
@@ -8,29 +8,6 @@ export type SchemaMetaData = {
8
8
  * Static meta data for the backend modules that are not generated
9
9
  */
10
10
  backendModules: {
11
- common: {
12
- /**
13
- * Path that may be used to import the common backend module.
14
- */
15
- importPath: Types.BackendModulePath;
16
- /**
17
- * Names of the functions that are provided by the common backend module.
18
- */
19
- functions: {
20
- excelNullOrBlankDecoder: Types.FunctionName;
21
- excelStringNullableDecoder: Types.FunctionName;
22
- excelStringDecoder: Types.FunctionName;
23
- excelNumberNullableDecoder: Types.FunctionName;
24
- excelNumberDecoder: Types.FunctionName;
25
- excelIntDecoder: Types.FunctionName;
26
- excelIntNullableDecoder: Types.FunctionName;
27
- excelBigIntDecoder: Types.FunctionName;
28
- excelBigIntNullableDecoder: Types.FunctionName;
29
- excelDateNullableDecoder: Types.FunctionName;
30
- excelDateDecoder: Types.FunctionName;
31
- excelBooleanDecoder: Types.FunctionName;
32
- };
33
- };
34
11
  auth: {
35
12
  /**
36
13
  * Path that may be used to import the auth backend module.
@@ -574,6 +551,18 @@ export type SchemaMetaData = {
574
551
  * Path that may be used to import the type definitions package.
575
552
  */
576
553
  importPath: Types.BackendModulePath;
554
+ /**
555
+ * Index of all branded ID types associated with the models.
556
+ *
557
+ * @example
558
+ * ```
559
+ * type SchemaIdTypes = {
560
+ * Post: PostId
561
+ * Comment: CommentId
562
+ * }
563
+ * ```
564
+ */
565
+ idTypesIndex: Types.TypeName;
577
566
  /**
578
567
  * Path and type names for the Data Transfer Objects (DTOs).
579
568
  */
@@ -824,10 +813,6 @@ export type ModelMetaData = {
824
813
  * Path to the view service for this model.
825
814
  */
826
815
  serviceLocation: Types.ModuleLocation;
827
- /**
828
- * The name of the variable that holds the repository instance for the current model
829
- */
830
- dataRepositoryVariableName: Types.VariableName;
831
816
  /**
832
817
  * The name of the variable that defines the filter operator decoder for the current model.
833
818
  */
@@ -883,10 +868,6 @@ export type ModelMetaData = {
883
868
  * The name of the function that decodes an Upsert object to a fully typed object (e.g. `aggregationUpsertDecoder`.)
884
869
  */
885
870
  upsertInputDecoder: Types.VariableName;
886
- /**
887
- * Name by which the business logic service exposes the data service.
888
- */
889
- dataRepositoryVariableName: Types.VariableName;
890
871
  };
891
872
  /**
892
873
  * Properties provided by the `seed` generators.
@@ -1067,6 +1048,10 @@ export type ModelMetaData = {
1067
1048
  * The name of the type that represents a DTO for upserting an existing object (e.g. `AggregationUpsertDTO`.)
1068
1049
  */
1069
1050
  upsert: Types.TypeName;
1051
+ /**
1052
+ * The name of the type that represents a DTO for cloning an existing object (e.g. `AggregationCloneDTO`.)
1053
+ */
1054
+ clone: Types.TypeName;
1070
1055
  };
1071
1056
  /**
1072
1057
  * The name of the file containing type definitions (e.g. `aggregation.type`).
package/dist/lib/meta.js CHANGED
@@ -32,23 +32,6 @@ const string_1 = require("./utils/string");
32
32
  function getSchemaMetadata({ config }) {
33
33
  return {
34
34
  backendModules: {
35
- common: {
36
- importPath: Types.toBackendModulePath(`@backend/common`),
37
- functions: {
38
- excelNullOrBlankDecoder: Types.toFunctionName(`excelNullOrBlankDecoder`),
39
- excelStringNullableDecoder: Types.toFunctionName(`excelStringNullableDecoder`),
40
- excelStringDecoder: Types.toFunctionName(`excelStringDecoder`),
41
- excelNumberNullableDecoder: Types.toFunctionName(`excelNumberNullableDecoder`),
42
- excelNumberDecoder: Types.toFunctionName(`excelNumberDecoder`),
43
- excelIntDecoder: Types.toFunctionName(`excelIntDecoder`),
44
- excelIntNullableDecoder: Types.toFunctionName(`excelIntNullableDecoder`),
45
- excelBigIntDecoder: Types.toFunctionName(`excelBigIntDecoder`),
46
- excelBigIntNullableDecoder: Types.toFunctionName(`excelBigIntNullableDecoder`),
47
- excelDateNullableDecoder: Types.toFunctionName(`excelDateNullableDecoder`),
48
- excelDateDecoder: Types.toFunctionName(`excelDateDecoder`),
49
- excelBooleanDecoder: Types.toFunctionName(`excelBooleanDecoder`),
50
- },
51
- },
52
35
  auth: {
53
36
  importPath: Types.toBackendModulePath(`@backend/auth`),
54
37
  },
@@ -237,6 +220,7 @@ function getSchemaMetadata({ config }) {
237
220
  types: {
238
221
  indexFilePath: Types.toPath(`${config.paths.modelTypeDefinitionsPath}index`),
239
222
  importPath: Types.toBackendModulePath(`@backend/types`),
223
+ idTypesIndex: Types.toTypeName(`SchemaIds`),
240
224
  dto: {
241
225
  path: Types.toPath(`${config.paths.modelTypeDefinitionsPath}dto.types`),
242
226
  genericModel: Types.toTypeName(`GenericModel`),
@@ -304,7 +288,6 @@ function getModelMetadata({ model }) {
304
288
  serviceClassName: Types.toClassName(`${PascalCase}ViewService`),
305
289
  serviceVariableName: Types.toVariableName(`${uncapitalizedPlural}`),
306
290
  serviceLocation: Types.toModuleLocation(`view`, `${config.paths.businessViewLogicPath}${camelCase}.view.service`),
307
- dataRepositoryVariableName: Types.toVariableName(`data`),
308
291
  cursorDecoder: Types.toVariableName(`CURSOR_DECODER`),
309
292
  filterOperatorDecoder: Types.toVariableName(`FILTER_OPERATOR_DECODER`),
310
293
  },
@@ -319,7 +302,6 @@ function getModelMetadata({ model }) {
319
302
  createInputDecoder: Types.toVariableName(`${camelCase}CreateInputDecoder`),
320
303
  updateInputDecoder: Types.toVariableName(`${camelCase}UpdateInputDecoder`),
321
304
  upsertInputDecoder: Types.toVariableName(`${camelCase}UpsertInputDecoder`),
322
- dataRepositoryVariableName: Types.toVariableName(`data`),
323
305
  },
324
306
  seed: {
325
307
  location: Types.toModuleLocation('seed-data', `${config.paths.seedDataPath}001-base-data/${uncapitalizedPlural}.seed`),
@@ -389,6 +371,7 @@ function getModelMetadata({ model }) {
389
371
  create: Types.toTypeName(`${PascalCase}CreateDTO`),
390
372
  update: Types.toTypeName(`${PascalCase}UpdateDTO`),
391
373
  upsert: Types.toTypeName(`${PascalCase}UpsertDTO`),
374
+ clone: Types.toTypeName(`${PascalCase}CloneDTO`),
392
375
  },
393
376
  typeName: Types.toTypeName(`${PascalCase}`),
394
377
  linkedTypeName: Types.toTypeName(`${PascalCase}Linked`),
@@ -14,7 +14,7 @@ export declare const getDefaultField: ({ fields }: {
14
14
  */
15
15
  export declare const getScalarFields: ({ fields, tsTypeName }: {
16
16
  fields: Field[];
17
- tsTypeName?: string | undefined;
17
+ tsTypeName?: string;
18
18
  }) => FieldScalar[];
19
19
  /**
20
20
  * List of all relation fields of the model.
package/dist/lib/zod.d.ts CHANGED
@@ -4,5 +4,5 @@ import { Field } from './schema/schema';
4
4
  */
5
5
  export declare const getZodDecoderDefinition: ({ field, allowAnyOptionalField, }: {
6
6
  field: Field;
7
- allowAnyOptionalField?: boolean | undefined;
7
+ allowAnyOptionalField?: boolean;
8
8
  }) => string;
@@ -65,7 +65,7 @@ exports.parsePrismaSchema = parsePrismaSchema;
65
65
  /**
66
66
  * These models are required for the generators/backend to work.
67
67
  */
68
- const SYSTEM_MODELS = ['User', 'Config', 'File', 'Action', 'Mutation'];
68
+ const SYSTEM_MODELS = ['User', 'File', 'Action', 'Mutation'];
69
69
  function ensurePXLSystemModelsExist(models) {
70
70
  for (const requiredModel of SYSTEM_MODELS) {
71
71
  if (!models.find((m) => m.name === requiredModel)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.69.0",
3
+ "version": "0.70.0",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {
@@ -20,22 +20,22 @@
20
20
  "exceljs": "4.3.0",
21
21
  "fast-glob": "3.2.12",
22
22
  "remeda": "1.9.4",
23
- "zod": "3.21.4",
23
+ "zod": "3.22.2",
24
24
  "@postxl/lock": "1.4.1",
25
25
  "@postxl/prettier": "0.0.1"
26
26
  },
27
27
  "devDependencies": {
28
+ "@jest/globals": "29.7.0",
28
29
  "@prisma/client": "5.8.1",
29
30
  "@types/eslint": "8.44.7",
30
- "@types/jest": "29.5.0",
31
31
  "@types/node": "18.15.10",
32
32
  "jest": "29.7.0",
33
33
  "prisma": "5.8.1",
34
- "ts-jest": "29.0.5",
34
+ "ts-jest": "29.1.3",
35
35
  "ts-node": "10.9.1",
36
36
  "ts-toolbelt": "9.6.0",
37
37
  "tsconfig-paths": "4.1.2",
38
- "typescript": "5.2.2"
38
+ "typescript": "5.4.5"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "prisma": "5.8.1"
@@ -44,9 +44,6 @@
44
44
  "autoDetect": true
45
45
  },
46
46
  "scripts": {
47
- "build": "tsc -p tsconfig.build.json",
48
- "prepublish": "tsc -p tsconfig.build.json",
49
- "dev": "tsc -p tsconfig.build.json -w",
50
47
  "test:generators": "./scripts/test.sh",
51
48
  "test:jest": "jest",
52
49
  "test:watch": "jest --watch",