@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 +6 -1
- package/dist/generators/indices/businesslogicmodule.generator.js +9 -9
- package/dist/generators/indices/datamockmodule.generator.js +2 -3
- package/dist/generators/indices/datamodule.generator.js +7 -23
- package/dist/generators/indices/dataservice.generator.js +2 -2
- package/dist/generators/indices/emptydatabasemigration.generator.d.ts +12 -1
- package/dist/generators/indices/emptydatabasemigration.generator.js +34 -2
- package/dist/generators/models/seed.generator.js +14 -4
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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 '@
|
|
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
|
-
|
|
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
|
|
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(
|
|
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 }) =>
|
|
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
|
|
125
|
-
|
|
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
|
|
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('
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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;
|