@postxl/generator 0.27.2 → 0.27.3

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.
@@ -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
- constructor(${constructor}) {}
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: Omit<${model.typeName}, '${model.idField.name}'> & Partial<{${model.idField.name}: ${model.idField.unbrandedTypeName}}>): Promise<${model.typeName}> {
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: Partial<${model.typeName}> & {id: ${model.brandedIdType}}): Promise<${model.typeName}> {
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: ${model.brandedIdType}): Promise<void> {
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: ${blocks.idBlocks.verifyFunctionParameterType}): Promise<${model.typeName}> {
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: Partial<${model.typeName}> & {
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: ${model.brandedIdType}): Promise<void> {
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: ${blocks.idBlocks.verifyFunctionParameterType}): Promise<${model.typeName}> {
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: Partial<${model.typeName}> & { ${idField.name}: ${model.brandedIdType} }): Promise<${model.typeName}> {
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: ${model.brandedIdType}): Promise<void> {
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.27.2",
3
+ "version": "0.27.3",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {