@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.
- package/README.md +1 -20
- package/dist/generator.js +41 -40
- package/dist/generators/indices/{datamodule.generator.d.ts → data/module.generator.d.ts} +2 -2
- package/dist/generators/indices/{datamodule.generator.js → data/module.generator.js} +4 -5
- package/dist/generators/indices/{dataservice.generator.d.ts → data/service.generator.d.ts} +2 -2
- package/dist/generators/indices/{dataservice.generator.js → data/service.generator.js} +5 -5
- package/dist/generators/indices/{data-types.generator.d.ts → data/types.generator.d.ts} +2 -2
- package/dist/generators/indices/{data-types.generator.js → data/types.generator.js} +2 -2
- package/dist/generators/indices/{importexport-convert-import-functions.generator.d.ts → import-export/importexport-convert-import-functions.generator.d.ts} +2 -2
- package/dist/generators/indices/{importexport-convert-import-functions.generator.js → import-export/importexport-convert-import-functions.generator.js} +4 -4
- package/dist/generators/indices/{importexport-exporter-class.generator.d.ts → import-export/importexport-exporter-class.generator.d.ts} +2 -2
- package/dist/generators/indices/{importexport-exporter-class.generator.js → import-export/importexport-exporter-class.generator.js} +4 -5
- package/dist/generators/indices/{importexport-import-service.generator.d.ts → import-export/importexport-import-service.generator.d.ts} +2 -2
- package/dist/generators/indices/{importexport-import-service.generator.js → import-export/importexport-import-service.generator.js} +4 -4
- package/dist/generators/indices/{importexport-types.generator.d.ts → import-export/importexport-types.generator.d.ts} +2 -2
- package/dist/generators/indices/{importexport-types.generator.js → import-export/importexport-types.generator.js} +2 -2
- package/dist/generators/indices/{routes-index.generator.js → routes.generator.js} +3 -0
- package/dist/generators/indices/seed-template.generator.js +2 -2
- package/dist/generators/indices/types.generator.js +13 -1
- package/dist/generators/indices/{businesslogic-actiontypes.generator.d.ts → update/actiontypes.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogic-actiontypes.generator.js → update/actiontypes.generator.js} +3 -3
- package/dist/generators/indices/{businesslogic-update-module.generator.d.ts → update/module.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogic-update-module.generator.js → update/module.generator.js} +2 -2
- package/dist/generators/indices/{businesslogic-update-service.generator.d.ts → update/service.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogic-update-service.generator.js → update/service.generator.js} +2 -2
- package/dist/generators/indices/{businesslogic-view-module.generator.d.ts → view/module.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogic-view-module.generator.js → view/module.generator.js} +2 -2
- package/dist/generators/indices/{businesslogic-view-service.generator.d.ts → view/service.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogic-view-service.generator.js → view/service.generator.js} +2 -2
- package/dist/generators/models/importexport-decoder.generator.d.ts +1 -2
- package/dist/generators/models/importexport-decoder.generator.js +17 -46
- package/dist/generators/models/repository.generator.d.ts +0 -39
- package/dist/generators/models/repository.generator.js +103 -175
- package/dist/generators/models/route.generator.js +7 -3
- package/dist/generators/models/types.generator.js +27 -2
- package/dist/generators/models/{businesslogic-update.generator.d.ts → update/service.generator.d.ts} +2 -2
- package/dist/generators/models/update/service.generator.js +252 -0
- package/dist/generators/models/{businesslogic-view.generator.d.ts → view/service.generator.d.ts} +2 -2
- package/dist/generators/models/{businesslogic-view.generator.js → view/service.generator.js} +12 -18
- package/dist/lib/meta.d.ts +16 -31
- package/dist/lib/meta.js +2 -19
- package/dist/lib/schema/fields.d.ts +1 -1
- package/dist/lib/zod.d.ts +1 -1
- package/dist/prisma/parse.js +1 -1
- package/package.json +5 -8
- package/dist/generators/models/businesslogic-update.generator.js +0 -324
- /package/dist/generators/indices/{routes-index.generator.d.ts → routes.generator.d.ts} +0 -0
- /package/dist/generators/models/{react.generator → react}/context.generator.d.ts +0 -0
- /package/dist/generators/models/{react.generator → react}/context.generator.js +0 -0
- /package/dist/generators/models/{react.generator → react}/index.d.ts +0 -0
- /package/dist/generators/models/{react.generator → react}/index.js +0 -0
- /package/dist/generators/models/{react.generator → react}/library.generator.d.ts +0 -0
- /package/dist/generators/models/{react.generator → react}/library.generator.js +0 -0
- /package/dist/generators/models/{react.generator → react}/lookup.generator.d.ts +0 -0
- /package/dist/generators/models/{react.generator → react}/lookup.generator.js +0 -0
- /package/dist/generators/models/{react.generator → react}/modals.generator.d.ts +0 -0
- /package/dist/generators/models/{react.generator → react}/modals.generator.js +0 -0
package/dist/generators/models/{businesslogic-update.generator.d.ts → update/service.generator.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModelMetaData } from '
|
|
2
|
-
import { Model } from '
|
|
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
|
+
}
|
package/dist/generators/models/{businesslogic-view.generator.d.ts → view/service.generator.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModelMetaData } from '
|
|
2
|
-
import { Model } from '
|
|
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.
|
package/dist/generators/models/{businesslogic-view.generator.js → view/service.generator.js}
RENAMED
|
@@ -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("
|
|
5
|
-
const meta_1 = require("
|
|
6
|
-
const fields_1 = require("
|
|
7
|
-
const types_1 = require("
|
|
8
|
-
const types_2 = require("
|
|
9
|
-
const ast_1 = require("
|
|
10
|
-
const jsdoc_1 = require("
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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))
|
package/dist/lib/meta.d.ts
CHANGED
|
@@ -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
|
|
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
package/dist/prisma/parse.js
CHANGED
|
@@ -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', '
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|