@postxl/generator 0.16.8 → 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
@@ -67,6 +67,7 @@ const businesslogicmodule_generator_1 = require("./generators/indices/businesslo
67
67
  const businesslogic_generator_1 = require("./generators/models/businesslogic.generator");
68
68
  const seed_template_decoder_generator_1 = require("./generators/indices/seed-template-decoder.generator");
69
69
  const seed_template_generator_1 = require("./generators/indices/seed-template.generator");
70
+ const seed_service_generator_1 = require("./generators/indices/seed-service.generator");
70
71
  const CONFIG_SCHEMA = zod_1.z
71
72
  .object({
72
73
  project: zod_1.z.string(),
@@ -197,7 +198,12 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
197
198
  generated.write(`/${meta.data.repositoriesConstFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesArray)({ models, meta }));
198
199
  generated.write(`/${meta.data.repositoriesIndexFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesIndex)({ models, meta }));
199
200
  generated.write(`/${meta.data.stubIndexFilePath}.ts`, (0, stubs_generator_1.generateStubsIndex)({ models, meta }));
200
- 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
+ }
201
207
  }
202
208
  if (!config.disableGenerators.businessLogic) {
203
209
  generated.write(`/${meta.businessLogic.indexFilePath}.ts`, (0, businesslogicindex_generator_1.generateBusinessLogicIndex)({ models, meta }));
@@ -206,6 +212,7 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
206
212
  }
207
213
  if (!config.disableGenerators.seed) {
208
214
  generated.write(`/${meta.seed.indexFilePath}.ts`, (0, seed_generator_1.generateSeedIndex)({ models, meta }));
215
+ generated.write(`/${meta.seed.serviceFilePath}.ts`, (0, seed_service_generator_1.generateSeedService)({ models, meta }));
209
216
  generated.write(`/${meta.seed.templateExcelFilePath}`, yield (0, seed_template_generator_1.generateSeedExcelTemplate)({ models }));
210
217
  generated.write(`/${meta.seed.templateDecoderFilePath}.ts`, (0, seed_template_decoder_generator_1.generateSeedTemplateDecoder)({ models, meta }));
211
218
  }
@@ -27,19 +27,45 @@ function generateBusinessLogicModule({ models, meta }) {
27
27
  });
28
28
  providers.push(meta.businessLogic.serviceClassName);
29
29
  }
30
+ const moduleName = meta.businessLogic.moduleName;
30
31
  return `
31
- import { Module } from '@nestjs/common'
32
+ import { DynamicModule } from '@${meta.config.project}/common'
32
33
 
33
34
  ${imports.generate()}
34
35
 
35
- const providers = [${providers.join(', ')}]
36
- @Module({
37
- imports: [${meta.data.moduleName}],
38
- providers,
39
- exports: providers,
40
- })
41
- export class BusinessLogicModule {}
42
36
 
37
+ export class ${moduleName} {
38
+ /**
39
+ * Internal cache for the module instance.
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
+ */
46
+ static getInstance(): DynamicModule {
47
+ if (!${moduleName}.cachedModule) throw new Error('${moduleName} must be called via .provide first!')
48
+ return ${moduleName}.cachedModule
49
+ }
50
+
51
+ /**
52
+ * The forRoot method should only be called once by the root module.
53
+ */
54
+ static forRoot(): DynamicModule {
55
+ if (${moduleName}.cachedModule) {
56
+ throw new Error('${moduleName} is already instantiated, please call .forRoot only once from root...')
57
+ }
58
+
59
+ const providers = [${providers.join(', ')}]
60
+ ${moduleName}.cachedModule = {
61
+ module: ${moduleName},
62
+ providers,
63
+ imports: [${meta.data.moduleName}.getInstance()],
64
+ exports: providers,
65
+ }
66
+ return ${moduleName}.cachedModule
67
+ }
68
+ }
43
69
  `;
44
70
  }
45
71
  exports.generateBusinessLogicModule = generateBusinessLogicModule;
@@ -69,33 +69,25 @@ import { DbModule } from '@${meta.config.project}/db'
69
69
  ${imports.generate()}
70
70
 
71
71
  export class DataMockModule {
72
- private static cachedModule: DynamicModule | undefined = undefined
73
-
74
- static isInstantiated(): boolean {
75
- return !!DataMockModule.cachedModule
76
- }
77
- static getInstance(): DataModule {
78
- if (!DataMockModule.cachedModule) throw new Error('DataMockModule must be called via .mock first!')
79
- return DataMockModule.cachedModule
80
- }
81
-
82
- // eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
83
- static async mock(seed?: MockData): Promise<DynamicModule> {
72
+
73
+ static mock(seed?: MockData): DynamicModule {
84
74
  const providers = [
85
75
  DataService,
86
76
  TestDataService,
87
77
  ${providers}
88
78
  ]
89
79
 
90
- DataMockModule.cachedModule = {
80
+ const cachedModule = {
91
81
  module: DataModule,
92
82
  imports: [DbModule.provideMock()],
93
83
  providers: providers,
94
84
  exports: providers,
95
85
  global: true,
96
86
  }
97
-
98
- return DataMockModule.cachedModule
87
+
88
+ ${meta.data.moduleName}._storeMockModule(cachedModule)
89
+
90
+ return cachedModule
99
91
  }
100
92
  }
101
93
 
@@ -49,52 +49,52 @@ function generateDataModule({ models, meta }) {
49
49
  }
50
50
  const moduleName = meta.data.moduleName;
51
51
  return `
52
- import { DynamicModule, Provider, Type } from '@nestjs/common'
53
- import { DbModule, DbService } from '@${meta.config.project}/db'
52
+ import { Provider } from '@nestjs/common'
53
+ import { DynamicModule } from '@${meta.config.project}/common'
54
+ import { DbModule } from '@${meta.config.project}/db'
54
55
 
55
- import { AsyncInit, Repository } from './repository.type'
56
+ import { Repository } from './repository.type'
56
57
 
57
58
  ${imports.generate()}
58
59
 
59
- const createRepositoryProvider = <T extends AsyncInit>(t: Type<T>, loadData: boolean): Provider => ({
60
- inject: [DbService],
61
- provide: t,
62
- useFactory: async (dbService: DbService): Promise<T> => {
63
- const repository = new t(dbService)
64
- await dbService.isInitialized(t.name)
65
- if (loadData) {
66
- await repository.init()
67
- }
68
- return repository
69
- },
70
- })
71
-
72
60
  export class ${moduleName} {
61
+ /**
62
+ * Internal cache for the module instance.
63
+ */
73
64
  private static cachedModule: DynamicModule | undefined = undefined
74
65
 
75
- static isInstantiated(): boolean {
76
- return !!${moduleName}.cachedModule
77
- }
78
-
79
- static getInstance(): ${moduleName} {
66
+ /**
67
+ * The getInstance method should be called by any module that needs the module.
68
+ */
69
+ static getInstance(): DynamicModule {
80
70
  if (!${moduleName}.cachedModule) throw new Error('${moduleName} must be called via .provide first!')
81
71
  return ${moduleName}.cachedModule
82
72
  }
73
+
74
+ /**
75
+ * Stores another module instance in the cache.
76
+ * Note: This should only be used for testing purposes.
77
+ */
78
+ static _storeMockModule(module: DynamicModule): void {
79
+ ${moduleName}.cachedModule = module
80
+ }
83
81
 
84
- static provide({ loadData }: { loadData: boolean }): DynamicModule {
82
+ /**
83
+ * The forRoot method should only be called once by the root module.
84
+ */
85
+ static forRoot(): DynamicModule {
85
86
  if (${moduleName}.cachedModule) {
86
- console.warn('${moduleName} is already instantiated, skipping...')
87
- return ${moduleName}.cachedModule
87
+ throw new Error('${moduleName} is already instantiated, please call .forRoot only once from root...')
88
88
  }
89
89
 
90
90
  const repositoryProviders = [
91
- ${mm.map(({ meta }) => `createRepositoryProvider(${meta.data.repositoryClassName}, loadData)`).join(',\n')}
91
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
92
92
  ]
93
93
 
94
94
  ${moduleName}.cachedModule = {
95
95
  module: ${moduleName},
96
96
  global: true,
97
- imports: [DbModule.provide()],
97
+ imports: [DbModule.forRoot()],
98
98
  providers: [DataService, ...repositoryProviders],
99
99
  exports: [DataService, ...repositoryProviders],
100
100
  }
@@ -108,16 +108,16 @@ export class ${moduleName} {
108
108
  return ${moduleName}.cachedModule
109
109
  }
110
110
 
111
- const providers: Provider<Repository<any, any>>[] = [
112
- // createRepositoryProvider(TherapeuticAreaRepository, true),
113
- TestDataService,
111
+ const repositoryProviders = [
112
+ ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
114
113
  ]
114
+ const providers = [TestDataService, ...repositoryProviders]
115
115
 
116
116
  ${moduleName}.cachedModule = {
117
117
  module: ${moduleName},
118
118
  global: true,
119
- imports: [DbModule.provide()],
120
- providers: [...providers],
119
+ imports: [DbModule.forRoot()],
120
+ providers,
121
121
  exports: providers,
122
122
  }
123
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
+ }
@@ -0,0 +1,9 @@
1
+ import { SchemaMetaData } from '../../lib/meta';
2
+ import { Model } from '../../lib/schema/schema';
3
+ /**
4
+ * Generates index file for all seed files.
5
+ */
6
+ export declare function generateSeedService({ models, meta }: {
7
+ models: Model[];
8
+ meta: SchemaMetaData;
9
+ }): string;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSeedService = void 0;
4
+ const imports_1 = require("../../lib/imports");
5
+ const meta_1 = require("../../lib/meta");
6
+ /**
7
+ * Generates index file for all seed files.
8
+ */
9
+ function generateSeedService({ models, meta }) {
10
+ const imports = imports_1.ImportsGenerator.from(meta.seed.serviceFilePath).addImport({
11
+ from: meta.seed.templateDecoderFilePath,
12
+ items: [meta.seed.templateDecoderName],
13
+ });
14
+ const dataLoader = [];
15
+ for (const model of models) {
16
+ const modelMeta = (0, meta_1.getModelMetadata)({ model });
17
+ dataLoader.push(`await this.upload({ name: '${modelMeta.userFriendlyName}', data: data.${modelMeta.seed.constantName}, repo: this.dataService.${modelMeta.data.dataServiceName}, log })`);
18
+ }
19
+ return `
20
+ import { Injectable, Logger } from '@nestjs/common'
21
+ import { format, pluralize } from '@pxl/common'
22
+ import { DataService, Repository } from '@pxl/data'
23
+ import { DbService } from '@pxl/db'
24
+ import { XlPortService } from '@pxl/xlport'
25
+ ${imports.generate()}
26
+
27
+ import * as SEEDDATA from './data'
28
+
29
+ /**
30
+ * Configuration options for seeding
31
+ */
32
+ export type SeedServiceOptions = {
33
+ /**
34
+ * If true, the database will be emptied before seeding.
35
+ * This is only possible if the database is set to test database!
36
+ */
37
+ reset?: boolean
38
+ /**
39
+ * If true, the seed data will be logged to the console.
40
+ * Note: This is significantly slower - but can be useful for debugging.
41
+ */
42
+ log?: boolean
43
+ /**
44
+ * If true, data will be loaded into the repositories after seeding.
45
+ * This should be used on startup of the application, but typically
46
+ * not when running tests or from the CLI.
47
+ */
48
+ loadDataAfterSeeding?: boolean
49
+ }
50
+
51
+ const DEFAULTOPTIONS: SeedServiceOptions = { reset: false, log: false, loadDataAfterSeeding: false }
52
+ @Injectable()
53
+ export class SeedService {
54
+ private readonly logger = new Logger(SeedService.name)
55
+ constructor(
56
+ private readonly dataService: DataService,
57
+ private readonly xlPortService: XlPortService,
58
+ private dbService: DbService,
59
+ ) {}
60
+ /**
61
+ * Seeds the database with the given data. Any data not provided will be taken from the default seed data.
62
+ */
63
+ public async seed({ data, options = DEFAULTOPTIONS }: { data?: Partial<typeof SEEDDATA>; options?: SeedServiceOptions }) {
64
+ return this._seed({ data: { ...SEEDDATA, ...data }, options })
65
+ }
66
+
67
+ /**
68
+ * Seeds the database with the given data from an Excel file.
69
+ */
70
+ public async seedFromExcel({
71
+ templatePath = './template.xlsx',
72
+ options = DEFAULTOPTIONS,
73
+ }: {
74
+ templatePath?: string
75
+ options?: SeedServiceOptions
76
+ }) {
77
+ const xlData = this.xlPortService.importFromFile(templatePath)
78
+
79
+ const dataParsed = ${meta.seed.templateDecoderName}.safeParse(xlData)
80
+ if (!dataParsed.success) {
81
+ throw new Error(\`Error in parsing Excel seed data: \${JSON.stringify(dataParsed.error.message)}\`)
82
+ }
83
+ return this._seed({ data: dataParsed.data, options })
84
+ }
85
+
86
+ private async _seed({ data, options: { loadDataAfterSeeding, reset, log } }: { data: typeof SEEDDATA; options: SeedServiceOptions }) {
87
+ if (reset) {
88
+ this.logger.log('Resetting database')
89
+ await this.dbService.emptyDatabase()
90
+ } else {
91
+ const config = await this.dbService.config.findFirst({ where: { id: true } })
92
+ if (!config) {
93
+ throw new Error('Database is not initialized')
94
+ }
95
+ if (config.isSeeded) {
96
+ this.logger.log('Database is already seeded')
97
+ return
98
+ }
99
+ }
100
+
101
+ await this.uploadData({ data, log })
102
+
103
+ await this.dbService.config.update({
104
+ where: { id: true },
105
+ data: { isSeeded: true },
106
+ })
107
+
108
+ if (loadDataAfterSeeding) {
109
+ await this.dataService.init()
110
+ }
111
+
112
+ this.logger.log('✅ Done')
113
+ }
114
+
115
+ private async uploadData({ log = false, data }: { data: typeof SEEDDATA; log?: boolean }) {
116
+ // NOTE: the order of these calls is important, because of foreign key constraints
117
+ // The current order is based on the order of the models in the schema
118
+ // Change the order based on your needs.
119
+ // Attention: Depending on the dependencies in seed data, you may also have to take care of relations,
120
+ // e.g. by removing any foreign key first - and then update these after all data is created.
121
+ ${dataLoader.join('\n')}
122
+ }
123
+
124
+ private async upload<T extends { id: ID }, ID extends number | string | boolean>({
125
+ name,
126
+ data,
127
+ repo,
128
+ log = false,
129
+ onlyOnReset = true,
130
+ }: {
131
+ name: string
132
+ data: T[]
133
+ repo: Repository<T, ID>
134
+ log?: boolean
135
+ onlyOnReset?: boolean
136
+ }): Promise<void> {
137
+ if (repo.count() > 0 && onlyOnReset) {
138
+ this.logger.log(\`\${pluralize(name)} already exist, skipping\`)
139
+ return
140
+ }
141
+ if (!log) {
142
+ await repo.createMany(data)
143
+ } else {
144
+ let i = 0
145
+ for (const item of data) {
146
+ i++
147
+ console.log(name, i, item.id)
148
+ try {
149
+ await repo.createWithId?.(item)
150
+ } catch (error) {
151
+ console.log(item)
152
+ throw error
153
+ }
154
+ }
155
+ }
156
+
157
+ this.logger.log(\`✅ Created \${format(data.length)} \${pluralize(name)}\`)
158
+ }
159
+ }
160
+ `;
161
+ }
162
+ exports.generateSeedService = generateSeedService;
@@ -28,7 +28,7 @@ function generateSeedTemplateDecoder({ models, meta }) {
28
28
 
29
29
  ${decoders.join('\n')}
30
30
 
31
- export const seedTemplateDecoder = z
31
+ export const ${meta.seed.templateDecoderName} = z
32
32
  .object({${tableDecoders.join(',\n')}})
33
33
  .transform((item) => ({${renameTransforms.join(',\n')}}))
34
34
  `;
@@ -73,8 +73,6 @@ function generateTableDecoder({ model, meta, imports, }) {
73
73
  break;
74
74
  }
75
75
  case 'enum': {
76
- const refEnumMeta = (0, meta_1.getEnumMetadata)({ enumerator: field.enumerator });
77
- imports.addImport({ items: [field.enumerator.tsTypeName], from: refEnumMeta.types.importPath });
78
76
  fieldDecoders.push(`${fieldMeta.excelColumnName}: z.enum([${field.enumerator.values.map((v) => `'${v}'`).join(', ')}])${field.isRequired ? '' : '.nullable()'}`);
79
77
  break;
80
78
  }
@@ -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;
@@ -73,6 +73,10 @@ export type SchemaMetaData = {
73
73
  * Path to the index file for the seed package.
74
74
  */
75
75
  indexFilePath: Types.Path;
76
+ /**
77
+ * Path to the SeedService file.
78
+ */
79
+ serviceFilePath: Types.Path;
76
80
  /**
77
81
  * Path to seed Excel template file.
78
82
  */
@@ -81,6 +85,10 @@ export type SchemaMetaData = {
81
85
  * Path to template decoder file.
82
86
  */
83
87
  templateDecoderFilePath: Types.Path;
88
+ /**
89
+ * The name of the template decoder function.
90
+ */
91
+ templateDecoderName: Types.Fnction;
84
92
  /**
85
93
  * Path that may be used in the import statement.
86
94
  */
package/dist/lib/meta.js CHANGED
@@ -55,9 +55,11 @@ function getSchemaMetadata({ config }) {
55
55
  importPath: Types.toPath(`@${config.project}/trpc`),
56
56
  },
57
57
  seed: {
58
- indexFilePath: Types.toPath(`${config.paths.seedPath}index`),
58
+ indexFilePath: Types.toPath(`${config.paths.seedPath}data/index`),
59
+ serviceFilePath: Types.toPath(`${config.paths.seedPath}seed.service`),
59
60
  templateExcelFilePath: Types.toPath(`${config.paths.seedPath}template.xlsx`),
60
- templateDecoderFilePath: Types.toPath(`${config.paths.seedPath}seed-decoder`),
61
+ templateDecoderFilePath: Types.toPath(`${config.paths.seedPath}seed.decoder`),
62
+ templateDecoderName: Types.toFunction(`seedTemplateDecoder`),
61
63
  importPath: Types.toPath(`@${config.project}/seed`),
62
64
  randomSeed: config.randomSeed,
63
65
  },
@@ -108,7 +110,7 @@ function getModelMetadata({ model }) {
108
110
  dataRepositoryVariableName: Types.toVariableName(`data`),
109
111
  },
110
112
  seed: {
111
- filePath: Types.toPath(`${config.paths.seedPath}${uncapitalizedPlural}`),
113
+ filePath: Types.toPath(`${config.paths.seedPath}data/${uncapitalizedPlural}`),
112
114
  constantName: Types.toVariableName(`${uncapitalizedPlural}`),
113
115
  importPath: Types.toPath(`@${config.project}/seed`),
114
116
  excel: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.16.8",
3
+ "version": "0.19.0",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {
@@ -45,7 +45,7 @@
45
45
  "scripts": {
46
46
  "build": "tsc -p tsconfig.build.json",
47
47
  "prepublish": "tsc -p tsconfig.build.json",
48
- "dev": "tsc -b -w",
48
+ "dev": "tsc -p tsconfig.build.json -w",
49
49
  "test": "jest",
50
50
  "test:watch": "jest --watch",
51
51
  "test:types": "tsc --noEmit",