@postxl/generator 0.13.0 → 0.15.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 +20 -0
- package/dist/generators/indices/businesslogicindex.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogicindex.generator.js +19 -0
- package/dist/generators/indices/businesslogicmodule.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogicmodule.generator.js +43 -0
- package/dist/generators/indices/businesslogicservice.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogicservice.generator.js +32 -0
- package/dist/generators/indices/datamockmodule.generator.js +2 -2
- package/dist/generators/indices/datamodule.generator.js +22 -21
- package/dist/generators/indices/dataservice.generator.js +1 -1
- package/dist/generators/indices/seed-template-decoder.generator.d.ts +9 -0
- package/dist/generators/indices/seed-template-decoder.generator.js +137 -0
- package/dist/generators/indices/seed-template.generator.d.ts +9 -0
- package/dist/generators/indices/seed-template.generator.js +80 -0
- package/dist/generators/models/businesslogic.generator.d.ts +9 -0
- package/dist/generators/models/businesslogic.generator.js +172 -0
- package/dist/generators/models/react.generator/context.generator.js +5 -3
- package/dist/generators/models/react.generator/library.generator.js +6 -3
- package/dist/generators/models/react.generator/lookup.generator.js +1 -1
- package/dist/generators/models/react.generator/modals.generator.d.ts +1 -1
- package/dist/generators/models/react.generator/modals.generator.js +128 -65
- package/dist/generators/models/repository.generator.js +38 -15
- package/dist/generators/models/route.generator.js +6 -6
- package/dist/generators/models/seed.generator.js +49 -25
- package/dist/generators/models/stub.generator.js +21 -14
- package/dist/generators/models/types.generator.js +34 -3
- package/dist/lib/attributes.d.ts +1 -1
- package/dist/lib/imports.d.ts +1 -1
- package/dist/lib/imports.js +12 -3
- package/dist/lib/meta.d.ts +150 -14
- package/dist/lib/meta.js +34 -1
- package/dist/lib/schema/fields.d.ts +5 -1
- package/dist/lib/schema/schema.d.ts +26 -1
- package/dist/lib/schema/schema.js +1 -1
- package/dist/lib/schema/types.d.ts +2 -2
- package/dist/lib/utils/file.js +2 -0
- package/dist/lib/utils/logger.d.ts +5 -5
- package/dist/lib/utils/string.d.ts +5 -0
- package/dist/lib/utils/string.js +10 -2
- package/dist/prisma/attributes.js +20 -9
- package/dist/prisma/parse.js +17 -3
- package/package.json +3 -2
package/dist/generator.js
CHANGED
|
@@ -61,11 +61,18 @@ const meta_1 = require("./lib/meta");
|
|
|
61
61
|
const types_1 = require("./lib/schema/types");
|
|
62
62
|
const client_path_1 = require("./prisma/client-path");
|
|
63
63
|
const parse_1 = require("./prisma/parse");
|
|
64
|
+
const businesslogicservice_generator_1 = require("./generators/indices/businesslogicservice.generator");
|
|
65
|
+
const businesslogicindex_generator_1 = require("./generators/indices/businesslogicindex.generator");
|
|
66
|
+
const businesslogicmodule_generator_1 = require("./generators/indices/businesslogicmodule.generator");
|
|
67
|
+
const businesslogic_generator_1 = require("./generators/models/businesslogic.generator");
|
|
68
|
+
const seed_template_decoder_generator_1 = require("./generators/indices/seed-template-decoder.generator");
|
|
69
|
+
const seed_template_generator_1 = require("./generators/indices/seed-template.generator");
|
|
64
70
|
const CONFIG_SCHEMA = zod_1.z
|
|
65
71
|
.object({
|
|
66
72
|
project: zod_1.z.string(),
|
|
67
73
|
pathToTypes: zod_1.z.string().optional(),
|
|
68
74
|
pathToDataLib: zod_1.z.string().optional(),
|
|
75
|
+
pathToBusinessLogic: zod_1.z.string().optional(),
|
|
69
76
|
pathToSeedLib: zod_1.z.string().optional(),
|
|
70
77
|
trpcRoutesFolder: zod_1.z.string().optional(),
|
|
71
78
|
reactFolderOutput: zod_1.z.string().optional(),
|
|
@@ -84,6 +91,7 @@ const CONFIG_SCHEMA = zod_1.z
|
|
|
84
91
|
project: s.project,
|
|
85
92
|
paths: {
|
|
86
93
|
dataLibPath: (0, types_1.toPath)(s.pathToDataLib || 'repos'),
|
|
94
|
+
businessLogicPath: (0, types_1.toPath)(s.pathToBusinessLogic || 'repos'),
|
|
87
95
|
reactFolderPath: (0, types_1.toPath)(s.reactFolderOutput || 'react'),
|
|
88
96
|
modelTypeDefinitionsPath: (0, types_1.toPath)(s.pathToTypes || 'types'),
|
|
89
97
|
seedPath: (0, types_1.toPath)(s.pathToSeedLib || 'seed'),
|
|
@@ -95,6 +103,7 @@ const CONFIG_SCHEMA = zod_1.z
|
|
|
95
103
|
disableGenerators: {
|
|
96
104
|
types: s.pathToTypes === undefined,
|
|
97
105
|
data: s.pathToDataLib === undefined,
|
|
106
|
+
businessLogic: s.pathToBusinessLogic === undefined,
|
|
98
107
|
seed: s.pathToSeedLib === undefined,
|
|
99
108
|
trpc: s.trpcRoutesFolder === undefined,
|
|
100
109
|
react: s.reactFolderOutput === undefined,
|
|
@@ -154,6 +163,10 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
|
|
|
154
163
|
generated.write(`/${meta.data.repoFilePath}.ts`, (0, repository_generator_1.generateRepository)({ model, meta }));
|
|
155
164
|
generated.write(`/${meta.data.mockRepoFilePath}.ts`, (0, repository_generator_1.generateMockRepository)({ model, meta }));
|
|
156
165
|
}
|
|
166
|
+
// Business Logic
|
|
167
|
+
if (!config.disableGenerators.businessLogic) {
|
|
168
|
+
generated.write(`/${meta.businessLogic.serviceFilePath}.ts`, (0, businesslogic_generator_1.generateModelBusinessLogic)({ model, meta }));
|
|
169
|
+
}
|
|
157
170
|
// Routes
|
|
158
171
|
if (!config.disableGenerators.trpc) {
|
|
159
172
|
generated.write(`/${meta.trpc.routerFilePath}.ts`, (0, route_generator_1.generateRoute)({ model, meta }));
|
|
@@ -186,8 +199,15 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
|
|
|
186
199
|
generated.write(`/${meta.data.stubIndexFilePath}.ts`, (0, stubs_generator_1.generateStubsIndex)({ models, meta }));
|
|
187
200
|
generated.write(`/${meta.migrationsPath}/emptyDatabase.template.sql`, (0, emptydatabasemigration_generator_1.generateEmptyDatabaseStoredProcedure)({ models, meta }));
|
|
188
201
|
}
|
|
202
|
+
if (!config.disableGenerators.businessLogic) {
|
|
203
|
+
generated.write(`/${meta.businessLogic.indexFilePath}.ts`, (0, businesslogicindex_generator_1.generateBusinessLogicIndex)({ models, meta }));
|
|
204
|
+
generated.write(`/${meta.businessLogic.moduleFilePath}.ts`, (0, businesslogicmodule_generator_1.generateBusinessLogicModule)({ models, meta }));
|
|
205
|
+
generated.write(`/${meta.businessLogic.serviceFilePath}.ts`, (0, businesslogicservice_generator_1.generateBusinessLogicService)({ models, meta }));
|
|
206
|
+
}
|
|
189
207
|
if (!config.disableGenerators.seed) {
|
|
190
208
|
generated.write(`/${meta.seed.indexFilePath}.ts`, (0, seed_generator_1.generateSeedIndex)({ models, meta }));
|
|
209
|
+
generated.write(`/${meta.seed.templateExcelFilePath}`, yield (0, seed_template_generator_1.generateSeedExcelTemplate)({ models }));
|
|
210
|
+
generated.write(`/${meta.seed.templateDecoderFilePath}.ts`, (0, seed_template_decoder_generator_1.generateSeedTemplateDecoder)({ models, meta }));
|
|
191
211
|
}
|
|
192
212
|
if (!config.disableGenerators.trpc) {
|
|
193
213
|
generated.write(`/${meta.trpc.routesFilePath}.ts`, (0, route_generator_1.generateRoutesIndex)({ models, meta }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SchemaMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Generates index file for all businessLogic files.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateBusinessLogicIndex({ models, meta }: {
|
|
7
|
+
models: Model[];
|
|
8
|
+
meta: SchemaMetaData;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBusinessLogicIndex = void 0;
|
|
4
|
+
const exports_1 = require("../../lib/exports");
|
|
5
|
+
const meta_1 = require("../../lib/meta");
|
|
6
|
+
/**
|
|
7
|
+
* Generates index file for all businessLogic files.
|
|
8
|
+
*/
|
|
9
|
+
function generateBusinessLogicIndex({ models, meta }) {
|
|
10
|
+
const exports = exports_1.ExportsGenerator.from(meta.businessLogic.indexFilePath);
|
|
11
|
+
exports.exportEverythingFromPath(meta.businessLogic.serviceFilePath);
|
|
12
|
+
exports.exportEverythingFromPath(meta.businessLogic.moduleFilePath);
|
|
13
|
+
for (const model of models) {
|
|
14
|
+
const meta = (0, meta_1.getModelMetadata)({ model });
|
|
15
|
+
exports.exportEverythingFromPath(meta.businessLogic.serviceFilePath);
|
|
16
|
+
}
|
|
17
|
+
return exports.generate();
|
|
18
|
+
}
|
|
19
|
+
exports.generateBusinessLogicIndex = generateBusinessLogicIndex;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SchemaMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a business Logic module class.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateBusinessLogicModule({ models, meta }: {
|
|
7
|
+
models: Model[];
|
|
8
|
+
meta: SchemaMetaData;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBusinessLogicModule = void 0;
|
|
4
|
+
const imports_1 = require("../../lib/imports");
|
|
5
|
+
const meta_1 = require("../../lib/meta");
|
|
6
|
+
/**
|
|
7
|
+
* Generates a business Logic module class.
|
|
8
|
+
*/
|
|
9
|
+
function generateBusinessLogicModule({ models, meta }) {
|
|
10
|
+
const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
11
|
+
const imports = imports_1.ImportsGenerator.from(meta.businessLogic.moduleFilePath)
|
|
12
|
+
.addImport({
|
|
13
|
+
items: [meta.data.moduleName],
|
|
14
|
+
from: meta.data.importPath,
|
|
15
|
+
})
|
|
16
|
+
.addImport({
|
|
17
|
+
items: [meta.businessLogic.serviceClassName],
|
|
18
|
+
from: meta.businessLogic.serviceFilePath,
|
|
19
|
+
});
|
|
20
|
+
const providers = [meta.businessLogic.serviceClassName];
|
|
21
|
+
for (const { meta } of mm) {
|
|
22
|
+
imports.addImport({
|
|
23
|
+
items: [meta.businessLogic.serviceClassName],
|
|
24
|
+
from: meta.businessLogic.serviceFilePath,
|
|
25
|
+
});
|
|
26
|
+
providers.push(meta.businessLogic.serviceClassName);
|
|
27
|
+
}
|
|
28
|
+
return `
|
|
29
|
+
import { Module } from '@nestjs/common'
|
|
30
|
+
|
|
31
|
+
${imports.generate()}
|
|
32
|
+
|
|
33
|
+
const providers = [${providers.join(', ')}]
|
|
34
|
+
@Module({
|
|
35
|
+
imports: [${meta.data.moduleName}],
|
|
36
|
+
providers,
|
|
37
|
+
exports: providers,
|
|
38
|
+
})
|
|
39
|
+
export class BusinessLogicModule {}
|
|
40
|
+
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
exports.generateBusinessLogicModule = generateBusinessLogicModule;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SchemaMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Generates the business logic service class.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateBusinessLogicService({ models, meta }: {
|
|
7
|
+
models: Model[];
|
|
8
|
+
meta: SchemaMetaData;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBusinessLogicService = void 0;
|
|
4
|
+
const imports_1 = require("../../lib/imports");
|
|
5
|
+
const meta_1 = require("../../lib/meta");
|
|
6
|
+
/**
|
|
7
|
+
* Generates the business logic service class.
|
|
8
|
+
*/
|
|
9
|
+
function generateBusinessLogicService({ models, meta }) {
|
|
10
|
+
const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
11
|
+
const imports = imports_1.ImportsGenerator.from(meta.businessLogic.serviceFilePath);
|
|
12
|
+
for (const { meta } of mm) {
|
|
13
|
+
imports.addImport({
|
|
14
|
+
items: [meta.businessLogic.serviceClassName],
|
|
15
|
+
from: meta.businessLogic.serviceFilePath,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const constructor = mm
|
|
19
|
+
.map(({ meta }) => `public ${meta.businessLogic.serviceVariableName} :${meta.businessLogic.serviceClassName}`)
|
|
20
|
+
.join(',\n');
|
|
21
|
+
return `
|
|
22
|
+
import { Injectable } from '@nestjs/common'
|
|
23
|
+
|
|
24
|
+
${imports.generate()}
|
|
25
|
+
|
|
26
|
+
@Injectable()
|
|
27
|
+
export class ${meta.businessLogic.serviceClassName} {
|
|
28
|
+
constructor(${constructor}) {}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
exports.generateBusinessLogicService = generateBusinessLogicService;
|
|
@@ -24,9 +24,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateDataMockModule = void 0;
|
|
27
|
+
const imports_1 = require("../../lib/imports");
|
|
27
28
|
const meta_1 = require("../../lib/meta");
|
|
28
29
|
const Types = __importStar(require("../../lib/schema/types"));
|
|
29
|
-
const imports_1 = require("../../lib/imports");
|
|
30
30
|
/**
|
|
31
31
|
* Generates a mocking class
|
|
32
32
|
*/
|
|
@@ -51,7 +51,7 @@ function generateDataMockModule({ models, meta }) {
|
|
|
51
51
|
imports.addImport({ items: [meta.data.mockRepositoryClassName], from: meta.data.mockRepoFilePath });
|
|
52
52
|
}
|
|
53
53
|
const providers = mm
|
|
54
|
-
.map(({ meta
|
|
54
|
+
.map(({ meta }) => `{
|
|
55
55
|
provide: ${meta.data.repositoryClassName},
|
|
56
56
|
useFactory: async () => {
|
|
57
57
|
const repository = new ${meta.data.mockRepositoryClassName}()
|
|
@@ -24,9 +24,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateDataModule = void 0;
|
|
27
|
+
const imports_1 = require("../../lib/imports");
|
|
27
28
|
const meta_1 = require("../../lib/meta");
|
|
28
29
|
const Types = __importStar(require("../../lib/schema/types"));
|
|
29
|
-
const imports_1 = require("../../lib/imports");
|
|
30
30
|
/**
|
|
31
31
|
* Generates a data module class.
|
|
32
32
|
*/
|
|
@@ -47,6 +47,7 @@ function generateDataModule({ models, meta }) {
|
|
|
47
47
|
from: meta.data.repoFilePath,
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
const moduleName = meta.data.moduleName;
|
|
50
51
|
return `
|
|
51
52
|
import { DynamicModule, Provider, Type } from '@nestjs/common'
|
|
52
53
|
import { DbModule, DbService } from '@${meta.config.project}/db'
|
|
@@ -68,43 +69,43 @@ const createRepositoryProvider = <T extends AsyncInit>(t: Type<T>, loadData: boo
|
|
|
68
69
|
},
|
|
69
70
|
})
|
|
70
71
|
|
|
71
|
-
export class
|
|
72
|
+
export class ${moduleName} {
|
|
72
73
|
private static cachedModule: DynamicModule | undefined = undefined
|
|
73
74
|
|
|
74
75
|
static isInstantiated(): boolean {
|
|
75
|
-
return
|
|
76
|
+
return !!${moduleName}.cachedModule
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
static getInstance():
|
|
79
|
-
if (
|
|
80
|
-
return
|
|
79
|
+
static getInstance(): ${moduleName} {
|
|
80
|
+
if (!${moduleName}.cachedModule) throw new Error('${moduleName} must be called via .provide first!')
|
|
81
|
+
return ${moduleName}.cachedModule
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
static provide({ loadData }: { loadData: boolean }): DynamicModule {
|
|
84
|
-
if (
|
|
85
|
-
console.warn('
|
|
86
|
-
return
|
|
85
|
+
if (${moduleName}.cachedModule) {
|
|
86
|
+
console.warn('${moduleName} is already instantiated, skipping...')
|
|
87
|
+
return ${moduleName}.cachedModule
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
const repositoryProviders
|
|
90
|
-
${mm.map(({ meta }) => meta.data.repositoryClassName).join(',\n')}
|
|
91
|
-
]
|
|
90
|
+
const repositoryProviders = [
|
|
91
|
+
${mm.map(({ meta }) => `createRepositoryProvider(${meta.data.repositoryClassName}, loadData)`).join(',\n')}
|
|
92
|
+
]
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
module:
|
|
94
|
+
${moduleName}.cachedModule = {
|
|
95
|
+
module: ${moduleName},
|
|
95
96
|
global: true,
|
|
96
97
|
imports: [DbModule.provide()],
|
|
97
98
|
providers: [DataService, ...repositoryProviders],
|
|
98
99
|
exports: [DataService, ...repositoryProviders],
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
return
|
|
102
|
+
return ${moduleName}.cachedModule
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
static provideE2E(): DynamicModule {
|
|
105
|
-
if (
|
|
106
|
-
console.warn('
|
|
107
|
-
return
|
|
106
|
+
if (${moduleName}.cachedModule) {
|
|
107
|
+
console.warn('${moduleName} is already instantiated, skipping...')
|
|
108
|
+
return ${moduleName}.cachedModule
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
const providers: Provider<Repository<any, any>>[] = [
|
|
@@ -112,15 +113,15 @@ export class DataModule {
|
|
|
112
113
|
TestDataService,
|
|
113
114
|
]
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
module:
|
|
116
|
+
${moduleName}.cachedModule = {
|
|
117
|
+
module: ${moduleName},
|
|
117
118
|
global: true,
|
|
118
119
|
imports: [DbModule.provide()],
|
|
119
120
|
providers: [...providers],
|
|
120
121
|
exports: providers,
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
return
|
|
124
|
+
return ${moduleName}.cachedModule
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
`;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateDataService = void 0;
|
|
4
|
-
const meta_1 = require("../../lib/meta");
|
|
5
4
|
const imports_1 = require("../../lib/imports");
|
|
5
|
+
const meta_1 = require("../../lib/meta");
|
|
6
6
|
/**
|
|
7
7
|
* Generates a generic data service object that may be used on the server to access database.
|
|
8
8
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SchemaMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a decoder for the Seed Excel template
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateSeedTemplateDecoder({ models, meta }: {
|
|
7
|
+
models: Model[];
|
|
8
|
+
meta: SchemaMetaData;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateSeedTemplateDecoder = void 0;
|
|
4
|
+
const imports_1 = require("../../lib/imports");
|
|
5
|
+
const meta_1 = require("../../lib/meta");
|
|
6
|
+
const types_1 = require("../../lib/schema/types");
|
|
7
|
+
const types_2 = require("../../lib/types");
|
|
8
|
+
// TODO: Remove hardcoded path that seems to be reused in multiple places!
|
|
9
|
+
const PXL_COMMON = (0, types_1.toPath)('@pxl/common');
|
|
10
|
+
/**
|
|
11
|
+
* Creates a decoder for the Seed Excel template
|
|
12
|
+
*/
|
|
13
|
+
function generateSeedTemplateDecoder({ models, meta }) {
|
|
14
|
+
const imports = imports_1.ImportsGenerator.from(meta.seed.templateDecoderFilePath);
|
|
15
|
+
const decoders = [];
|
|
16
|
+
const tableDecoders = [];
|
|
17
|
+
const renameTransforms = [];
|
|
18
|
+
for (const model of [...models].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
19
|
+
const modelMeta = (0, meta_1.getModelMetadata)({ model });
|
|
20
|
+
decoders.push(generateTableDecoder({ model, meta: modelMeta, imports }));
|
|
21
|
+
tableDecoders.push(`${modelMeta.seed.excel.tableName}: z.array(${modelMeta.seed.decoder.schemaName})`);
|
|
22
|
+
renameTransforms.push(`${modelMeta.seed.decoder.dataName}: item['${modelMeta.seed.excel.tableName}']`);
|
|
23
|
+
}
|
|
24
|
+
return `
|
|
25
|
+
import * as z from 'zod'
|
|
26
|
+
|
|
27
|
+
${imports.generate()}
|
|
28
|
+
|
|
29
|
+
${decoders.join('\n')}
|
|
30
|
+
|
|
31
|
+
export const seedTemplateDecoder = z
|
|
32
|
+
.object({${tableDecoders.join(',\n')}})
|
|
33
|
+
.transform((item) => ({${renameTransforms.join(',\n')}}))
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
exports.generateSeedTemplateDecoder = generateSeedTemplateDecoder;
|
|
37
|
+
function generateTableDecoder({ model, meta, imports, }) {
|
|
38
|
+
const fieldDecoders = [];
|
|
39
|
+
const renameTransforms = [];
|
|
40
|
+
for (const field of model.fields) {
|
|
41
|
+
const fieldMeta = (0, meta_1.getFieldMetadata)({ field });
|
|
42
|
+
renameTransforms.push(`${field.name}: item['${fieldMeta.excelColumnName}']`);
|
|
43
|
+
switch (field.kind) {
|
|
44
|
+
case 'id': {
|
|
45
|
+
imports.addImport({
|
|
46
|
+
items: [meta.types.toBrandedIdTypeFnName],
|
|
47
|
+
from: meta.types.importPath,
|
|
48
|
+
});
|
|
49
|
+
fieldDecoders.push(`${fieldMeta.excelColumnName}: ${toExcelDecoder({
|
|
50
|
+
typeName: field.unbrandedTypeName,
|
|
51
|
+
nullable: false,
|
|
52
|
+
imports,
|
|
53
|
+
})}.transform((id: ${field.unbrandedTypeName}) => ${meta.types.toBrandedIdTypeFnName}(id))`);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'scalar': {
|
|
57
|
+
fieldDecoders.push(`${fieldMeta.excelColumnName}: ${toExcelDecoder({
|
|
58
|
+
typeName: field.typeName,
|
|
59
|
+
nullable: !field.isRequired,
|
|
60
|
+
imports,
|
|
61
|
+
})}`);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case 'relation': {
|
|
65
|
+
const refModel = field.relationToModel;
|
|
66
|
+
const refMeta = (0, meta_1.getModelMetadata)({ model: refModel });
|
|
67
|
+
imports.addImport({
|
|
68
|
+
items: [refMeta.types.toBrandedIdTypeFnName],
|
|
69
|
+
from: refMeta.types.importPath,
|
|
70
|
+
});
|
|
71
|
+
fieldDecoders.push(`${fieldMeta.excelColumnName}: ${toExcelDecoder({
|
|
72
|
+
typeName: field.unbrandedTypeName,
|
|
73
|
+
nullable: !field.isRequired,
|
|
74
|
+
imports,
|
|
75
|
+
})}.transform((id: ${field.unbrandedTypeName}${field.isRequired ? '' : '| null'}) => ${field.isRequired ? '' : ' id === null ? null : '}${refMeta.types.toBrandedIdTypeFnName}(id))`);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'enum': {
|
|
79
|
+
const refEnumMeta = (0, meta_1.getEnumMetadata)({ enumerator: field.enumerator });
|
|
80
|
+
imports.addImport({
|
|
81
|
+
items: [field.enumerator.typeName],
|
|
82
|
+
from: refEnumMeta.types.importPath,
|
|
83
|
+
});
|
|
84
|
+
fieldDecoders.push(`${fieldMeta.excelColumnName}: z.enum([${field.enumerator.values.map((v) => `'${v}'`).join(', ')}])${field.isRequired ? '' : '.nullable()'}`);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
default: {
|
|
88
|
+
throw new types_2.ExhaustiveSwitchCheck(field);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return `
|
|
93
|
+
/**
|
|
94
|
+
* The schema for the ${model.name} table
|
|
95
|
+
*/
|
|
96
|
+
const ${meta.seed.decoder.schemaName} = z
|
|
97
|
+
.object({${fieldDecoders.join(',\n')}})
|
|
98
|
+
.transform((item) => ({${renameTransforms.join(',\n')}}))
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The type of the ${model.name} table
|
|
102
|
+
*/
|
|
103
|
+
export type ${meta.seed.decoder.decoderTypeName} = z.infer<typeof ${meta.seed.decoder.schemaName}>
|
|
104
|
+
|
|
105
|
+
export const ${meta.seed.decoder.decoderName} = z.array(${meta.seed.decoder.schemaName})
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
function toExcelDecoder({ typeName, nullable, imports, }) {
|
|
109
|
+
switch (typeName) {
|
|
110
|
+
case 'string': {
|
|
111
|
+
const decoder = (0, types_1.toFunction)(nullable ? 'excelStringNullableDecoder' : 'excelStringDecoder');
|
|
112
|
+
imports.addImport({
|
|
113
|
+
items: [decoder],
|
|
114
|
+
from: PXL_COMMON,
|
|
115
|
+
});
|
|
116
|
+
return decoder;
|
|
117
|
+
}
|
|
118
|
+
case 'boolean':
|
|
119
|
+
imports.addImport({
|
|
120
|
+
items: [(0, types_1.toFunction)('excelBooleanDecoder')],
|
|
121
|
+
from: PXL_COMMON,
|
|
122
|
+
});
|
|
123
|
+
return 'excelBooleanDecoder';
|
|
124
|
+
case 'number':
|
|
125
|
+
return `z.number()${nullable ? '.nullable()' : ''}`;
|
|
126
|
+
case 'Date': {
|
|
127
|
+
const decoder = (0, types_1.toFunction)(nullable ? 'excelDateNullableDecoder' : 'excelDateDecoder');
|
|
128
|
+
imports.addImport({
|
|
129
|
+
items: [decoder],
|
|
130
|
+
from: PXL_COMMON,
|
|
131
|
+
});
|
|
132
|
+
return decoder;
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
throw new Error('Unknown type');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Creates an Excel template file that can be used to manage Seed data.
|
|
5
|
+
* The template file contains a sheet for each model, with the column for each field.
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateSeedExcelTemplate({ models }: {
|
|
8
|
+
models: Model[];
|
|
9
|
+
}): Promise<Buffer>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.generateSeedExcelTemplate = void 0;
|
|
36
|
+
const Excel = __importStar(require("exceljs"));
|
|
37
|
+
const meta_1 = require("../../lib/meta");
|
|
38
|
+
/**
|
|
39
|
+
* Creates an Excel template file that can be used to manage Seed data.
|
|
40
|
+
* The template file contains a sheet for each model, with the column for each field.
|
|
41
|
+
*/
|
|
42
|
+
function generateSeedExcelTemplate({ models }) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const wb = initializeWorkbook();
|
|
45
|
+
for (const model of [...models].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
46
|
+
const meta = (0, meta_1.getModelMetadata)({ model });
|
|
47
|
+
addModel({ model, meta, wb });
|
|
48
|
+
}
|
|
49
|
+
const buffer = Buffer.from(yield wb.xlsx.writeBuffer());
|
|
50
|
+
return buffer;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
exports.generateSeedExcelTemplate = generateSeedExcelTemplate;
|
|
54
|
+
function initializeWorkbook() {
|
|
55
|
+
const wb = new Excel.Workbook();
|
|
56
|
+
wb.creator = 'XLPort';
|
|
57
|
+
wb.lastModifiedBy = 'XLPort';
|
|
58
|
+
wb.created = new Date();
|
|
59
|
+
wb.modified = new Date();
|
|
60
|
+
return wb;
|
|
61
|
+
}
|
|
62
|
+
function addModel({ model, meta, wb }) {
|
|
63
|
+
const ws = wb.addWorksheet(model.name);
|
|
64
|
+
const table = ws.addTable({
|
|
65
|
+
name: meta.seed.excel.tableName,
|
|
66
|
+
ref: 'A1',
|
|
67
|
+
headerRow: true,
|
|
68
|
+
totalsRow: false,
|
|
69
|
+
style: {
|
|
70
|
+
theme: 'TableStyleMedium2',
|
|
71
|
+
showRowStripes: true,
|
|
72
|
+
},
|
|
73
|
+
columns: model.fields.map((field) => ({
|
|
74
|
+
name: (0, meta_1.getFieldMetadata)({ field }).excelColumnName,
|
|
75
|
+
})),
|
|
76
|
+
rows: [],
|
|
77
|
+
});
|
|
78
|
+
table.addRow(model.fields.map(() => null));
|
|
79
|
+
table.commit();
|
|
80
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ModelMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Generates business logic for a given model.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateModelBusinessLogic({ model, meta }: {
|
|
7
|
+
model: Model;
|
|
8
|
+
meta: ModelMetaData;
|
|
9
|
+
}): string;
|