@postxl/generator 0.17.0 → 0.19.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,
@@ -70,8 +70,7 @@ ${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,14 @@ function generateDataModule({ models, meta }) {
49
49
  }
50
50
  const moduleName = meta.data.moduleName;
51
51
  return `
52
- import { Provider, Type } from '@nestjs/common'
52
+ import { Provider } from '@nestjs/common'
53
53
  import { DynamicModule } from '@${meta.config.project}/common'
54
- import { DbModule, DbService } from '@${meta.config.project}/db'
54
+ import { DbModule } from '@${meta.config.project}/db'
55
55
 
56
- import { AsyncInit, Repository } from './repository.type'
56
+ import { Repository } from './repository.type'
57
57
 
58
58
  ${imports.generate()}
59
59
 
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
60
  export class ${moduleName} {
74
61
  /**
75
62
  * Internal cache for the module instance.
@@ -95,13 +82,13 @@ export class ${moduleName} {
95
82
  /**
96
83
  * The forRoot method should only be called once by the root module.
97
84
  */
98
- static forRoot({ loadData }: { loadData: boolean }): DynamicModule {
85
+ static forRoot(): DynamicModule {
99
86
  if (${moduleName}.cachedModule) {
100
87
  throw new Error('${moduleName} is already instantiated, please call .forRoot only once from root...')
101
88
  }
102
89
 
103
90
  const repositoryProviders = [
104
- ${mm.map(({ meta }) => `createRepositoryProvider(${meta.data.repositoryClassName}, loadData)`).join(',\n')}
91
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
105
92
  ]
106
93
 
107
94
  ${moduleName}.cachedModule = {
@@ -121,16 +108,16 @@ export class ${moduleName} {
121
108
  return ${moduleName}.cachedModule
122
109
  }
123
110
 
124
- const providers: Provider<Repository<any, any>>[] = [
125
- // createRepositoryProvider(TherapeuticAreaRepository, true),
126
- TestDataService,
111
+ const repositoryProviders = [
112
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
127
113
  ]
114
+ const providers = [TestDataService, ...repositoryProviders]
128
115
 
129
116
  ${moduleName}.cachedModule = {
130
117
  module: ${moduleName},
131
118
  global: true,
132
119
  imports: [DbModule.forRoot()],
133
- providers: [...providers],
120
+ providers,
134
121
  exports: providers,
135
122
  }
136
123
 
@@ -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
+ }
@@ -112,6 +112,7 @@ function quoteSingleQuote(str) {
112
112
  return str.replace(/'/g, "\\'");
113
113
  }
114
114
  function generateScalarFieldExample({ field, model, index, mode, }) {
115
+ var _a;
115
116
  const { hasExample, example } = generateFieldExample({ field, model, index, mode });
116
117
  switch (field.tsTypeName) {
117
118
  case 'string': {
@@ -143,6 +144,10 @@ function generateScalarFieldExample({ field, model, index, mode, }) {
143
144
  if (hasExample) {
144
145
  return `${example}`;
145
146
  }
147
+ //in case the field is configured with `IsDefaultField` attribute, the first item should be true, all other false
148
+ if (((_a = model.defaultField) === null || _a === void 0 ? void 0 : _a.name) === field.name) {
149
+ return index === 0 ? 'true' : 'false';
150
+ }
146
151
  return generateMockBoolean();
147
152
  }
148
153
  case 'Date': {
@@ -204,6 +209,9 @@ function generateMockDate() {
204
209
  return `new Date('${d.toISOString()}')`;
205
210
  }
206
211
  function generateRelationFieldExample({ field, index, model, mode, }) {
212
+ if (!field.isRequired) {
213
+ return 'null';
214
+ }
207
215
  const referenceId = faker_1.faker.datatype.number({ min: 1, max: mode.itemCount });
208
216
  const refModelMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
209
217
  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.19.0",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {