@postxl/generator 0.17.0 → 0.20.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/dist/generator.js CHANGED
@@ -198,7 +198,12 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
198
198
  generated.write(`/${meta.data.repositoriesConstFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesArray)({ models, meta }));
199
199
  generated.write(`/${meta.data.repositoriesIndexFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesIndex)({ models, meta }));
200
200
  generated.write(`/${meta.data.stubIndexFilePath}.ts`, (0, stubs_generator_1.generateStubsIndex)({ models, meta }));
201
- generated.write(`/${meta.migrationsPath}/emptyDatabase.template.sql`, (0, emptydatabasemigration_generator_1.generateEmptyDatabaseStoredProcedure)({ models, meta }));
201
+ // We only generate the empty database migration if the migration folder already has an existing migration
202
+ // Else we would generate a migration that deletes from tables that have not yet been created in the database
203
+ // We include this check here as the template does not come with any migration - hence this migration should also not be generated
204
+ if ((0, emptydatabasemigration_generator_1.prismaMigrationExists)(meta)) {
205
+ generated.write((0, emptydatabasemigration_generator_1.deriveEmptyDatabaseMigrationFilePath)(meta), (0, emptydatabasemigration_generator_1.generateEmptyDatabaseStoredProcedure)({ models, meta }));
206
+ }
202
207
  }
203
208
  if (!config.disableGenerators.businessLogic) {
204
209
  generated.write(`/${meta.businessLogic.indexFilePath}.ts`, (0, businesslogicindex_generator_1.generateBusinessLogicIndex)({ models, meta }));
@@ -33,17 +33,16 @@ import { DynamicModule } from '@${meta.config.project}/common'
33
33
 
34
34
  ${imports.generate()}
35
35
 
36
- const providers = [${providers.join(', ')}]
37
36
 
38
37
  export class ${moduleName} {
39
38
  /**
40
39
  * Internal cache for the module instance.
41
- */
42
- private static cachedModule: DynamicModule | undefined = undefined
43
-
44
- /**
45
- * The getInstance method should be called by any module that needs the module.
46
- */
40
+ */
41
+ private static cachedModule: DynamicModule | undefined = undefined
42
+
43
+ /**
44
+ * The getInstance method should be called by any module that needs the module.
45
+ */
47
46
  static getInstance(): DynamicModule {
48
47
  if (!${moduleName}.cachedModule) throw new Error('${moduleName} must be called via .provide first!')
49
48
  return ${moduleName}.cachedModule
@@ -51,12 +50,13 @@ export class ${moduleName} {
51
50
 
52
51
  /**
53
52
  * The forRoot method should only be called once by the root module.
54
- */
53
+ */
55
54
  static forRoot(): DynamicModule {
56
55
  if (${moduleName}.cachedModule) {
57
56
  throw new Error('${moduleName} is already instantiated, please call .forRoot only once from root...')
58
57
  }
59
-
58
+
59
+ const providers = [${providers.join(', ')}]
60
60
  ${moduleName}.cachedModule = {
61
61
  module: ${moduleName},
62
62
  providers,
@@ -63,15 +63,14 @@ function generateDataMockModule({ models, meta }) {
63
63
  }`)
64
64
  .join(', ');
65
65
  return `
66
- import { DynamicModule } from '@nestjs/common'
66
+ import { DynamicModule } from '@pxl/common'
67
67
  import { DbModule } from '@${meta.config.project}/db'
68
68
 
69
69
  ${imports.generate()}
70
70
 
71
71
  export class DataMockModule {
72
72
 
73
- // eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
74
- static async mock(seed?: MockData): Promise<DynamicModule> {
73
+ static mock(seed?: MockData): DynamicModule {
75
74
  const providers = [
76
75
  DataService,
77
76
  TestDataService,
@@ -49,27 +49,11 @@ function generateDataModule({ models, meta }) {
49
49
  }
50
50
  const moduleName = meta.data.moduleName;
51
51
  return `
52
- import { Provider, Type } from '@nestjs/common'
53
52
  import { DynamicModule } from '@${meta.config.project}/common'
54
- import { DbModule, DbService } from '@${meta.config.project}/db'
55
-
56
- import { AsyncInit, Repository } from './repository.type'
53
+ import { DbModule } from '@${meta.config.project}/db'
57
54
 
58
55
  ${imports.generate()}
59
56
 
60
- const createRepositoryProvider = <T extends AsyncInit>(t: Type<T>, loadData: boolean): Provider => ({
61
- inject: [DbService],
62
- provide: t,
63
- useFactory: async (dbService: DbService): Promise<T> => {
64
- const repository = new t(dbService)
65
- await dbService.isInitialized(t.name)
66
- if (loadData) {
67
- await repository.init()
68
- }
69
- return repository
70
- },
71
- })
72
-
73
57
  export class ${moduleName} {
74
58
  /**
75
59
  * Internal cache for the module instance.
@@ -95,13 +79,13 @@ export class ${moduleName} {
95
79
  /**
96
80
  * The forRoot method should only be called once by the root module.
97
81
  */
98
- static forRoot({ loadData }: { loadData: boolean }): DynamicModule {
82
+ static forRoot(): DynamicModule {
99
83
  if (${moduleName}.cachedModule) {
100
84
  throw new Error('${moduleName} is already instantiated, please call .forRoot only once from root...')
101
85
  }
102
86
 
103
87
  const repositoryProviders = [
104
- ${mm.map(({ meta }) => `createRepositoryProvider(${meta.data.repositoryClassName}, loadData)`).join(',\n')}
88
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
105
89
  ]
106
90
 
107
91
  ${moduleName}.cachedModule = {
@@ -121,16 +105,16 @@ export class ${moduleName} {
121
105
  return ${moduleName}.cachedModule
122
106
  }
123
107
 
124
- const providers: Provider<Repository<any, any>>[] = [
125
- // createRepositoryProvider(TherapeuticAreaRepository, true),
126
- TestDataService,
108
+ const repositoryProviders = [
109
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
127
110
  ]
111
+ const providers = [TestDataService, ...repositoryProviders]
128
112
 
129
113
  ${moduleName}.cachedModule = {
130
114
  module: ${moduleName},
131
115
  global: true,
132
116
  imports: [DbModule.forRoot()],
133
- providers: [...providers],
117
+ providers,
134
118
  exports: providers,
135
119
  }
136
120
 
@@ -18,7 +18,7 @@ function generateDataService({ models, meta }) {
18
18
  const constructor = mm
19
19
  .map(({ meta }) => `public ${meta.data.dataServiceName} :${meta.data.repositoryClassName}`)
20
20
  .join(',\n');
21
- const initializer = mm.map(({ meta }) => `this.${meta.data.dataServiceName}.init()`).join(',\n');
21
+ const initializer = mm.map(({ meta }) => `await this.${meta.data.dataServiceName}.init()`).join('\n');
22
22
  const excelExports = mm
23
23
  .map(({ meta }) => `${meta.data.excelExportTableName}: mapValues(this.${meta.data.dataServiceName}.getAll()),`)
24
24
  .join('\n');
@@ -40,7 +40,7 @@ export class DataService {
40
40
  }
41
41
 
42
42
  public async init(): Promise<void> {
43
- await Promise.all([${initializer}])
43
+ ${initializer}
44
44
  }
45
45
 
46
46
  public isEmpty(): boolean {
@@ -1,9 +1,20 @@
1
1
  import { SchemaMetaData } from '../../lib/meta';
2
2
  import { Model } from '../../lib/schema/schema';
3
3
  /**
4
- * Generates a data module class.
4
+ * Generates a the Prisma migration to create the `emptyDatabase` stored procedure.
5
5
  */
6
6
  export declare function generateEmptyDatabaseStoredProcedure({ models }: {
7
7
  models: Model[];
8
8
  meta: SchemaMetaData;
9
9
  }): string;
10
+ /**
11
+ * Generates a the full file path for the Prisma migration to create the `emptyDatabase` stored procedure.
12
+ *
13
+ * This is done by finding the first migration in the migrations folder and using its timestamp + 1.
14
+ * In case no migration is found, an error is shown!
15
+ */
16
+ export declare function deriveEmptyDatabaseMigrationFilePath(meta: SchemaMetaData): string;
17
+ /**
18
+ * Checks if any Prisma migration exists.
19
+ */
20
+ export declare function prismaMigrationExists(meta: SchemaMetaData): boolean;
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateEmptyDatabaseStoredProcedure = void 0;
6
+ exports.prismaMigrationExists = exports.deriveEmptyDatabaseMigrationFilePath = exports.generateEmptyDatabaseStoredProcedure = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
4
8
  /**
5
- * Generates a data module class.
9
+ * Generates a the Prisma migration to create the `emptyDatabase` stored procedure.
6
10
  */
7
11
  function generateEmptyDatabaseStoredProcedure({ models }) {
8
12
  const tables = models
@@ -24,3 +28,31 @@ $BODY$ LANGUAGE plpgsql;
24
28
  `;
25
29
  }
26
30
  exports.generateEmptyDatabaseStoredProcedure = generateEmptyDatabaseStoredProcedure;
31
+ /**
32
+ * Generates a the full file path for the Prisma migration to create the `emptyDatabase` stored procedure.
33
+ *
34
+ * This is done by finding the first migration in the migrations folder and using its timestamp + 1.
35
+ * In case no migration is found, an error is shown!
36
+ */
37
+ function deriveEmptyDatabaseMigrationFilePath(meta) {
38
+ const firstMigration = getFirstPrismaMigration(meta);
39
+ if (firstMigration === undefined) {
40
+ throw new Error(`No Prisma migration found in ${meta.migrationsPath}! Please run "prisma migrate dev" first.`);
41
+ }
42
+ const existingTimestamp = firstMigration.split('_')[0];
43
+ const nextTimestamp = (Number.parseInt(existingTimestamp) + 1).toString();
44
+ return `/${meta.migrationsPath}/${nextTimestamp}_emptyDatabase/migration.sql`;
45
+ }
46
+ exports.deriveEmptyDatabaseMigrationFilePath = deriveEmptyDatabaseMigrationFilePath;
47
+ /**
48
+ * Checks if any Prisma migration exists.
49
+ */
50
+ function prismaMigrationExists(meta) {
51
+ const firstMigration = getFirstPrismaMigration(meta);
52
+ return firstMigration !== undefined;
53
+ }
54
+ exports.prismaMigrationExists = prismaMigrationExists;
55
+ function getFirstPrismaMigration(meta) {
56
+ const folder = meta.migrationsPath;
57
+ return fs_1.default.readdirSync(folder).find((f) => fs_1.default.statSync(`${folder}/${f}`).isDirectory());
58
+ }
@@ -18,10 +18,12 @@ function generateSeedModel({ model, itemCount, meta, }) {
18
18
  });
19
19
  for (const relation of (0, fields_1.getRelationFields)(model)) {
20
20
  const depMeta = (0, meta_1.getModelMetadata)({ model: relation.relationToModel });
21
- imports.addImport({
22
- items: [depMeta.types.toBrandedIdTypeFnName],
23
- from: depMeta.types.importPath,
24
- });
21
+ if (relation.isRequired) {
22
+ imports.addImport({
23
+ items: [depMeta.types.toBrandedIdTypeFnName],
24
+ from: depMeta.types.importPath,
25
+ });
26
+ }
25
27
  }
26
28
  const mode = getExampleMode({ model, maxItemCount: itemCount });
27
29
  const examples = [];
@@ -112,6 +114,7 @@ function quoteSingleQuote(str) {
112
114
  return str.replace(/'/g, "\\'");
113
115
  }
114
116
  function generateScalarFieldExample({ field, model, index, mode, }) {
117
+ var _a;
115
118
  const { hasExample, example } = generateFieldExample({ field, model, index, mode });
116
119
  switch (field.tsTypeName) {
117
120
  case 'string': {
@@ -143,6 +146,10 @@ function generateScalarFieldExample({ field, model, index, mode, }) {
143
146
  if (hasExample) {
144
147
  return `${example}`;
145
148
  }
149
+ //in case the field is configured with `IsDefaultField` attribute, the first item should be true, all other false
150
+ if (((_a = model.defaultField) === null || _a === void 0 ? void 0 : _a.name) === field.name) {
151
+ return index === 0 ? 'true' : 'false';
152
+ }
146
153
  return generateMockBoolean();
147
154
  }
148
155
  case 'Date': {
@@ -204,6 +211,9 @@ function generateMockDate() {
204
211
  return `new Date('${d.toISOString()}')`;
205
212
  }
206
213
  function generateRelationFieldExample({ field, index, model, mode, }) {
214
+ if (!field.isRequired) {
215
+ return 'null';
216
+ }
207
217
  const referenceId = faker_1.faker.datatype.number({ min: 1, max: mode.itemCount });
208
218
  const refModelMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
209
219
  const brandingFn = refModelMeta.types.toBrandedIdTypeFnName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.17.0",
3
+ "version": "0.20.0",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {