@postxl/generator 0.27.2 → 0.27.4
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/generators/indices/businesslogicmodule.generator.js +1 -0
- package/dist/generators/indices/businesslogicservice.generator.js +7 -6
- package/dist/generators/indices/datamockmodule.generator.js +1 -0
- package/dist/generators/indices/datamodule.generator.js +1 -0
- package/dist/generators/indices/repositories.generator.d.ts +1 -1
- package/dist/generators/indices/repositories.generator.js +1 -1
- package/dist/generators/indices/seed-template-decoder.generator.d.ts +1 -1
- package/dist/generators/indices/seed-template-decoder.generator.js +1 -1
- package/dist/generators/models/businesslogic.generator.js +6 -3
- package/dist/generators/models/repository.generator.d.ts +31 -1
- package/dist/generators/models/repository.generator.js +38 -10
- package/dist/prisma/parse.js +22 -5
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ const meta_1 = require("../../lib/meta");
|
|
|
6
6
|
/**
|
|
7
7
|
* Generates a business Logic module class.
|
|
8
8
|
*/
|
|
9
|
+
// TODO: https://github.com/PostXL/PostXL/issues/347
|
|
9
10
|
function generateBusinessLogicModule({ models, meta }) {
|
|
10
11
|
const mm = models
|
|
11
12
|
.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }))
|
|
@@ -6,6 +6,7 @@ const meta_1 = require("../../lib/meta");
|
|
|
6
6
|
/**
|
|
7
7
|
* Generates the business logic service class.
|
|
8
8
|
*/
|
|
9
|
+
// TODO: https://github.com/PostXL/PostXL/issues/347
|
|
9
10
|
function generateBusinessLogicService({ models, meta }) {
|
|
10
11
|
const mm = models
|
|
11
12
|
.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }))
|
|
@@ -23,12 +24,12 @@ function generateBusinessLogicService({ models, meta }) {
|
|
|
23
24
|
return `
|
|
24
25
|
import { Inject, Injectable, forwardRef } from '@nestjs/common'
|
|
25
26
|
|
|
26
|
-
${imports.generate()}
|
|
27
|
+
${imports.generate()}
|
|
27
28
|
|
|
28
|
-
@Injectable()
|
|
29
|
-
export class ${meta.businessLogic.serviceClassName} {
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
29
|
+
@Injectable()
|
|
30
|
+
export class ${meta.businessLogic.serviceClassName} {
|
|
31
|
+
constructor(${constructor}) {}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
33
34
|
}
|
|
34
35
|
exports.generateBusinessLogicService = generateBusinessLogicService;
|
|
@@ -30,6 +30,7 @@ const Types = __importStar(require("../../lib/schema/types"));
|
|
|
30
30
|
/**
|
|
31
31
|
* Generates a mocking class
|
|
32
32
|
*/
|
|
33
|
+
// TODO: https://github.com/PostXL/PostXL/issues/347
|
|
33
34
|
function generateDataMockModule({ models, meta }) {
|
|
34
35
|
const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
35
36
|
const imports = imports_1.ImportsGenerator.from(meta.data.dataMockModuleFilePath)
|
|
@@ -30,6 +30,7 @@ const Types = __importStar(require("../../lib/schema/types"));
|
|
|
30
30
|
/**
|
|
31
31
|
* Generates a data module class.
|
|
32
32
|
*/
|
|
33
|
+
// TODO: https://github.com/PostXL/PostXL/issues/347
|
|
33
34
|
function generateDataModule({ models, meta }) {
|
|
34
35
|
const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
35
36
|
const imports = imports_1.ImportsGenerator.from(meta.data.dataModuleFilePath)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SchemaMetaData } from '../../lib/meta';
|
|
2
2
|
import { Model } from '../../lib/schema/schema';
|
|
3
3
|
/**
|
|
4
|
-
* Generates an index file that exports all stubs.
|
|
4
|
+
* Generates an index file that exports all repository stubs.
|
|
5
5
|
*/
|
|
6
6
|
export declare function generateRepositoriesIndex({ models, meta }: {
|
|
7
7
|
models: Model[];
|
|
@@ -5,7 +5,7 @@ const exports_1 = require("../../lib/exports");
|
|
|
5
5
|
const imports_1 = require("../../lib/imports");
|
|
6
6
|
const meta_1 = require("../../lib/meta");
|
|
7
7
|
/**
|
|
8
|
-
* Generates an index file that exports all stubs.
|
|
8
|
+
* Generates an index file that exports all repository stubs.
|
|
9
9
|
*/
|
|
10
10
|
function generateRepositoriesIndex({ models, meta }) {
|
|
11
11
|
const exports = exports_1.ExportsGenerator.from(meta.data.repositoriesIndexFilePath);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SchemaMetaData } from '../../lib/meta';
|
|
2
2
|
import { Model } from '../../lib/schema/schema';
|
|
3
3
|
/**
|
|
4
|
-
* Creates a decoder for the Seed Excel template
|
|
4
|
+
* Creates a decoder for the Seed Excel template.
|
|
5
5
|
*/
|
|
6
6
|
export declare function generateSeedTemplateDecoder({ models, meta }: {
|
|
7
7
|
models: Model[];
|
|
@@ -8,7 +8,7 @@ const types_2 = require("../../lib/types");
|
|
|
8
8
|
// TODO: Remove hardcoded path that seems to be reused in multiple places!
|
|
9
9
|
const PXL_COMMON = (0, types_1.toPath)('@pxl/common');
|
|
10
10
|
/**
|
|
11
|
-
* Creates a decoder for the Seed Excel template
|
|
11
|
+
* Creates a decoder for the Seed Excel template.
|
|
12
12
|
*/
|
|
13
13
|
function generateSeedTemplateDecoder({ models, meta }) {
|
|
14
14
|
const imports = imports_1.ImportsGenerator.from(meta.seed.templateDecoderFilePath);
|
|
@@ -28,9 +28,11 @@ const imports_1 = require("../../lib/imports");
|
|
|
28
28
|
const meta_1 = require("../../lib/meta");
|
|
29
29
|
const fields_1 = require("../../lib/schema/fields");
|
|
30
30
|
const Types = __importStar(require("../../lib/schema/types"));
|
|
31
|
+
const repository_generator_1 = require("./repository.generator");
|
|
31
32
|
/**
|
|
32
33
|
* Generates business logic for a given model.
|
|
33
34
|
*/
|
|
35
|
+
// TODO: https://github.com/PostXL/PostXL/issues/347
|
|
34
36
|
function generateModelBusinessLogic({ model, meta }) {
|
|
35
37
|
const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
|
|
36
38
|
const imports = imports_1.ImportsGenerator.from(meta.businessLogic.serviceFilePath);
|
|
@@ -114,6 +116,7 @@ function generateModelBusinessLogic({ model, meta }) {
|
|
|
114
116
|
return item
|
|
115
117
|
}
|
|
116
118
|
`;
|
|
119
|
+
const methodTypeSignatures = (0, repository_generator_1.getRepositoryMethodsTypeSignatures)({ model, meta });
|
|
117
120
|
// prettier-ignore
|
|
118
121
|
return `
|
|
119
122
|
import { Inject, Injectable, forwardRef } from '@nestjs/common'
|
|
@@ -170,14 +173,14 @@ export class ${meta.businessLogic.serviceClassName} {
|
|
|
170
173
|
/**
|
|
171
174
|
* Creates a new ${meta.userFriendlyName}.
|
|
172
175
|
*/
|
|
173
|
-
public async create(item:
|
|
176
|
+
public async create(item: ${methodTypeSignatures.create.parameters[0]}): ${methodTypeSignatures.create.returnType} {
|
|
174
177
|
return this.${modelRepositoryVariableName}.create(item)
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
/**
|
|
178
181
|
* Updates the given ${meta.userFriendlyName}.
|
|
179
182
|
*/
|
|
180
|
-
public async update(item:
|
|
183
|
+
public async update(item: ${methodTypeSignatures.update.parameters[0]}): ${methodTypeSignatures.update.returnType} {
|
|
181
184
|
return this.${modelRepositoryVariableName}.update(item)
|
|
182
185
|
}
|
|
183
186
|
|
|
@@ -187,7 +190,7 @@ export class ${meta.businessLogic.serviceClassName} {
|
|
|
187
190
|
* Note: This does NOT delete any linked items.
|
|
188
191
|
* If the items is a dependency of another item, the deletion will fail!
|
|
189
192
|
*/
|
|
190
|
-
public async delete(id: ${
|
|
193
|
+
public async delete(id: ${methodTypeSignatures.delete.parameters[0]}): ${methodTypeSignatures.delete.returnType} {
|
|
191
194
|
return this.${modelRepositoryVariableName}.delete(id)
|
|
192
195
|
}
|
|
193
196
|
}
|
|
@@ -8,9 +8,39 @@ export declare function generateRepository({ model, meta }: {
|
|
|
8
8
|
meta: ModelMetaData;
|
|
9
9
|
}): string;
|
|
10
10
|
/**
|
|
11
|
-
* Generates a mock repository data structure for a given model: same a repository, but in memory only
|
|
11
|
+
* Generates a mock repository data structure for a given model: same a repository, but in memory only.
|
|
12
12
|
*/
|
|
13
13
|
export declare function generateMockRepository({ model: modelSource, meta: metaSource, }: {
|
|
14
14
|
model: Model;
|
|
15
15
|
meta: ModelMetaData;
|
|
16
16
|
}): string;
|
|
17
|
+
type FnSignature = {
|
|
18
|
+
/**
|
|
19
|
+
* A list of ordered TypeScript types where the first type in the list corresponds to the type of the
|
|
20
|
+
* first parameter and so on. Note that the parameters don't contain names, only types.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
*
|
|
24
|
+
* ```
|
|
25
|
+
* function foo(a: string, b: number, c: boolean) {}
|
|
26
|
+
* // ['string', 'number', 'boolean']
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
parameters: string[];
|
|
30
|
+
/**
|
|
31
|
+
* The return type of the function.
|
|
32
|
+
*/
|
|
33
|
+
returnType: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Returns a collection of type signatures for the repository methods of a given model.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getRepositoryMethodsTypeSignatures({ model, meta }: {
|
|
39
|
+
model: Model;
|
|
40
|
+
meta: ModelMetaData;
|
|
41
|
+
}): {
|
|
42
|
+
create: FnSignature;
|
|
43
|
+
update: FnSignature;
|
|
44
|
+
delete: FnSignature;
|
|
45
|
+
};
|
|
46
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateMockRepository = exports.generateRepository = void 0;
|
|
3
|
+
exports.getRepositoryMethodsTypeSignatures = exports.generateMockRepository = 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");
|
|
@@ -210,7 +210,7 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
210
210
|
}
|
|
211
211
|
exports.generateRepository = generateRepository;
|
|
212
212
|
/**
|
|
213
|
-
* Generates a mock repository data structure for a given model: same a repository, but in memory only
|
|
213
|
+
* Generates a mock repository data structure for a given model: same a repository, but in memory only.
|
|
214
214
|
*/
|
|
215
215
|
function generateMockRepository({ model: modelSource, meta: metaSource, }) {
|
|
216
216
|
// We re-use the repository block, but we change the meta data to use the mock repository name and the model to be in memory only
|
|
@@ -223,6 +223,7 @@ exports.generateMockRepository = generateMockRepository;
|
|
|
223
223
|
* Generates the main building blocks of the repository for in-memory model.
|
|
224
224
|
*/
|
|
225
225
|
function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
226
|
+
const methodTypeSignatures = getRepositoryMethodsTypeSignatures({ model, meta });
|
|
226
227
|
return {
|
|
227
228
|
constructorCode: '',
|
|
228
229
|
initCode: `
|
|
@@ -248,7 +249,7 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
248
249
|
createCode: `
|
|
249
250
|
// Non-mocked version is async - so we keep type-compatible signatures for create() and createWithId()
|
|
250
251
|
// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
|
|
251
|
-
public async create(item: ${
|
|
252
|
+
public async create(item: ${methodTypeSignatures.create.parameters[0]}): ${methodTypeSignatures.create.returnType} {
|
|
252
253
|
const newItem = await Promise.resolve(this.verifyItem(item))
|
|
253
254
|
|
|
254
255
|
this.set(newItem)
|
|
@@ -266,10 +267,9 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
266
267
|
|
|
267
268
|
return newItems
|
|
268
269
|
}`,
|
|
270
|
+
// prettier-ignore
|
|
269
271
|
updateCode: `
|
|
270
|
-
public async update(item:
|
|
271
|
-
id: ${model.brandedIdType}
|
|
272
|
-
}): Promise<${model.typeName}> {
|
|
272
|
+
public async update(item: ${methodTypeSignatures.update.parameters[0]}): ${methodTypeSignatures.update.returnType} {
|
|
273
273
|
const existingItem = this.get(item.id)
|
|
274
274
|
|
|
275
275
|
if (!existingItem) {
|
|
@@ -289,7 +289,7 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, blocks, }) {
|
|
|
289
289
|
return newItem
|
|
290
290
|
}`,
|
|
291
291
|
deleteCode: `
|
|
292
|
-
public async delete(id: ${
|
|
292
|
+
public async delete(id: ${methodTypeSignatures.delete.parameters[0]}): ${methodTypeSignatures.delete.returnType} {
|
|
293
293
|
const existingItem = this.get(id)
|
|
294
294
|
if (!existingItem) {
|
|
295
295
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
@@ -322,6 +322,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
322
322
|
.filter((s) => s != null)
|
|
323
323
|
.map((part) => `"${part}"`)
|
|
324
324
|
.join('.');
|
|
325
|
+
const methodTypeSignatures = getRepositoryMethodsTypeSignatures({ model, meta });
|
|
325
326
|
return {
|
|
326
327
|
constructorCode: `constructor(protected db: DbService) {}`,
|
|
327
328
|
initCode: `
|
|
@@ -371,7 +372,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
371
372
|
}
|
|
372
373
|
`,
|
|
373
374
|
createCode: `
|
|
374
|
-
public async create(item: ${
|
|
375
|
+
public async create(item: ${methodTypeSignatures.create.parameters[0]}): ${methodTypeSignatures.create.returnType} {
|
|
375
376
|
const newItem = this.${decoderFunctionName}(
|
|
376
377
|
await this.db.${meta.data.repository.getMethodFnName}.create({
|
|
377
378
|
data: this.toCreateItem(this.verifyItem(item)),
|
|
@@ -395,7 +396,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
395
396
|
}`,
|
|
396
397
|
// prettier-ignore
|
|
397
398
|
updateCode: `
|
|
398
|
-
public async update(item:
|
|
399
|
+
public async update(item: ${methodTypeSignatures.update.parameters[0]}): ${methodTypeSignatures.update.returnType} {
|
|
399
400
|
const existingItem = this.get(item.${idField.name})
|
|
400
401
|
if (!existingItem) {
|
|
401
402
|
throw new Error(\`Could not update ${meta.userFriendlyName} with id \${item.id}. Not found!\`)
|
|
@@ -427,7 +428,7 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
427
428
|
return newItem
|
|
428
429
|
}`,
|
|
429
430
|
deleteCode: `
|
|
430
|
-
public async delete(id: ${
|
|
431
|
+
public async delete(id: ${methodTypeSignatures.delete.parameters[0]}): ${methodTypeSignatures.delete.returnType} {
|
|
431
432
|
const existingItem = this.get(id)
|
|
432
433
|
if (!existingItem) {
|
|
433
434
|
throw new Error(\`Could not delete ${model.typeName} with id \${id}. Not found!\`)
|
|
@@ -449,6 +450,10 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
449
450
|
}`,
|
|
450
451
|
};
|
|
451
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Generates code chunks responsible for verifying the ID validity of a model instance and generating the id
|
|
455
|
+
* value of a model with auto-generated id.
|
|
456
|
+
*/
|
|
452
457
|
function generateIdBlocks({ model, meta }) {
|
|
453
458
|
const idField = model.idField;
|
|
454
459
|
if (!idField.isGenerated) {
|
|
@@ -462,6 +467,29 @@ function generateIdBlocks({ model, meta }) {
|
|
|
462
467
|
}
|
|
463
468
|
throw new Error(`Repository block only supports Id generation for number and strings! Found ${idField.schemaType} for model ${model.name} instead!`);
|
|
464
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Returns a collection of type signatures for the repository methods of a given model.
|
|
472
|
+
*/
|
|
473
|
+
// NOTE: We export this function as an interface simplification to the repository generator. Internally, we
|
|
474
|
+
// use the same functions as the ones used in this function which we don't want to expose.
|
|
475
|
+
function getRepositoryMethodsTypeSignatures({ model, meta }) {
|
|
476
|
+
const { verifyFunctionParameterType } = generateIdBlocks({ model, meta });
|
|
477
|
+
return {
|
|
478
|
+
create: {
|
|
479
|
+
parameters: [verifyFunctionParameterType],
|
|
480
|
+
returnType: `Promise<${model.typeName}>`,
|
|
481
|
+
},
|
|
482
|
+
update: {
|
|
483
|
+
parameters: [`Partial<${model.typeName}> & { ${model.idField.name}: ${model.brandedIdType} }`],
|
|
484
|
+
returnType: `Promise<${model.typeName}>`,
|
|
485
|
+
},
|
|
486
|
+
delete: {
|
|
487
|
+
parameters: [model.brandedIdType],
|
|
488
|
+
returnType: `Promise<void>`,
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
exports.getRepositoryMethodsTypeSignatures = getRepositoryMethodsTypeSignatures;
|
|
465
493
|
/**
|
|
466
494
|
* Generates the id block code chunks for a model that requires an ID field to be manually
|
|
467
495
|
* supplied to the create function.
|
package/dist/prisma/parse.js
CHANGED
|
@@ -117,7 +117,8 @@ function parseModel({ dmmfModel, enums, models, config, }) {
|
|
|
117
117
|
return Object.assign(Object.assign({ kind: 'relation' }, shared), { relatedModelBacklinkFieldName: refField.name, typeName: Types.toTypeName(dmmfField.type), unbrandedTypeName: getTsTypeForId(dmmfField), relationToModel: refModel });
|
|
118
118
|
}
|
|
119
119
|
if (dmmfField.isId) {
|
|
120
|
-
|
|
120
|
+
const isGeneratedField = isAutoIncrementField(dmmfField) || isUUIDField(dmmfField);
|
|
121
|
+
return Object.assign(Object.assign({ kind: 'id' }, shared), { isUnique: isUniqueField(dmmfField), isGenerated: isGeneratedField, unbrandedTypeName: getTsTypeForId(dmmfField), model: core });
|
|
121
122
|
}
|
|
122
123
|
if (dmmfField.kind === 'scalar') {
|
|
123
124
|
let validation = undefined;
|
|
@@ -198,12 +199,28 @@ function validateFields({ fields, model: { name } }) {
|
|
|
198
199
|
return { idField, defaultField, nameField };
|
|
199
200
|
}
|
|
200
201
|
function isAutoIncrementField(fieldDmmf) {
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
if (fieldDmmf.default === undefined) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (Array.isArray(fieldDmmf.default)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (typeof fieldDmmf.default === 'object') {
|
|
209
|
+
return fieldDmmf.default.name === 'autoincrement';
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
203
212
|
}
|
|
204
213
|
function isUUIDField(fieldDmmf) {
|
|
205
|
-
|
|
206
|
-
|
|
214
|
+
if (fieldDmmf.default === undefined) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(fieldDmmf.default)) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
if (typeof fieldDmmf.default === 'object') {
|
|
221
|
+
return fieldDmmf.default.name === 'uuid' || fieldDmmf.default.name === 'cuid';
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
207
224
|
}
|
|
208
225
|
function isUniqueField(fieldRaw) {
|
|
209
226
|
return fieldRaw.isUnique && fieldRaw.type === 'String';
|