@postxl/generator 0.4.0 → 0.6.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.
Files changed (94) hide show
  1. package/dist/{src/generator.js → generator.js} +42 -59
  2. package/dist/{src/generators → generators}/enums/react.generator.d.ts +1 -1
  3. package/dist/{src/generators → generators}/enums/react.generator.js +2 -2
  4. package/dist/{src/generators → generators}/indices/repositories.generator.js +2 -2
  5. package/dist/{src/generators → generators}/indices/seed.generator.js +1 -1
  6. package/dist/{src/generators → generators}/indices/stubs.generator.js +1 -1
  7. package/dist/{src/generators → generators}/indices/types.generator.js +2 -2
  8. package/dist/{src/generators → generators}/models/react.generator/index.d.ts +1 -1
  9. package/dist/{src/generators → generators}/models/react.generator/index.js +18 -13
  10. package/dist/{src/generators → generators}/models/react.generator/library.generator.d.ts +3 -0
  11. package/dist/{src/generators → generators}/models/react.generator/library.generator.js +3 -0
  12. package/dist/{src/generators → generators}/models/react.generator/lookup.generator.js +21 -16
  13. package/dist/{src/lib → lib}/exports.d.ts +17 -2
  14. package/dist/{src/lib → lib}/exports.js +24 -2
  15. package/package.json +6 -6
  16. package/dist/jest.config.d.ts +0 -3
  17. package/dist/jest.config.js +0 -17
  18. package/dist/src/lib/vfs.d.ts +0 -137
  19. package/dist/src/lib/vfs.js +0 -431
  20. package/dist/tests/attributes.test.d.ts +0 -1
  21. package/dist/tests/attributes.test.js +0 -76
  22. package/dist/tests/file.test.d.ts +0 -1
  23. package/dist/tests/file.test.js +0 -26
  24. package/dist/tests/utils/random.d.ts +0 -3
  25. package/dist/tests/utils/random.js +0 -15
  26. package/dist/tests/vfs.test.d.ts +0 -1
  27. package/dist/tests/vfs.test.js +0 -74
  28. package/dist/tsconfig.tsbuildinfo +0 -1
  29. /package/dist/{src/generator.d.ts → generator.d.ts} +0 -0
  30. /package/dist/{src/generators → generators}/enums/types.generator.d.ts +0 -0
  31. /package/dist/{src/generators → generators}/enums/types.generator.js +0 -0
  32. /package/dist/{src/generators → generators}/indices/datamockmodule.generator.d.ts +0 -0
  33. /package/dist/{src/generators → generators}/indices/datamockmodule.generator.js +0 -0
  34. /package/dist/{src/generators → generators}/indices/datamodule.generator.d.ts +0 -0
  35. /package/dist/{src/generators → generators}/indices/datamodule.generator.js +0 -0
  36. /package/dist/{src/generators → generators}/indices/dataservice.generator.d.ts +0 -0
  37. /package/dist/{src/generators → generators}/indices/dataservice.generator.js +0 -0
  38. /package/dist/{src/generators → generators}/indices/emptydatabasemigration.generator.d.ts +0 -0
  39. /package/dist/{src/generators → generators}/indices/emptydatabasemigration.generator.js +0 -0
  40. /package/dist/{src/generators → generators}/indices/repositories.generator.d.ts +0 -0
  41. /package/dist/{src/generators → generators}/indices/seed.generator.d.ts +0 -0
  42. /package/dist/{src/generators → generators}/indices/stubs.generator.d.ts +0 -0
  43. /package/dist/{src/generators → generators}/indices/testdataservice.generator.d.ts +0 -0
  44. /package/dist/{src/generators → generators}/indices/testdataservice.generator.js +0 -0
  45. /package/dist/{src/generators → generators}/indices/types.generator.d.ts +0 -0
  46. /package/dist/{src/generators → generators}/models/react.generator/context.generator.d.ts +0 -0
  47. /package/dist/{src/generators → generators}/models/react.generator/context.generator.js +0 -0
  48. /package/dist/{src/generators → generators}/models/react.generator/lookup.generator.d.ts +0 -0
  49. /package/dist/{src/generators → generators}/models/react.generator/modals.generator.d.ts +0 -0
  50. /package/dist/{src/generators → generators}/models/react.generator/modals.generator.js +0 -0
  51. /package/dist/{src/generators → generators}/models/repository.generator.d.ts +0 -0
  52. /package/dist/{src/generators → generators}/models/repository.generator.js +0 -0
  53. /package/dist/{src/generators → generators}/models/route.generator.d.ts +0 -0
  54. /package/dist/{src/generators → generators}/models/route.generator.js +0 -0
  55. /package/dist/{src/generators → generators}/models/seed.generator.d.ts +0 -0
  56. /package/dist/{src/generators → generators}/models/seed.generator.js +0 -0
  57. /package/dist/{src/generators → generators}/models/stub.generator.d.ts +0 -0
  58. /package/dist/{src/generators → generators}/models/stub.generator.js +0 -0
  59. /package/dist/{src/generators → generators}/models/types.generator.d.ts +0 -0
  60. /package/dist/{src/generators → generators}/models/types.generator.js +0 -0
  61. /package/dist/{src/lib → lib}/attributes.d.ts +0 -0
  62. /package/dist/{src/lib → lib}/attributes.js +0 -0
  63. /package/dist/{src/lib → lib}/imports.d.ts +0 -0
  64. /package/dist/{src/lib → lib}/imports.js +0 -0
  65. /package/dist/{src/lib → lib}/meta.d.ts +0 -0
  66. /package/dist/{src/lib → lib}/meta.js +0 -0
  67. /package/dist/{src/lib → lib}/schema/fields.d.ts +0 -0
  68. /package/dist/{src/lib → lib}/schema/fields.js +0 -0
  69. /package/dist/{src/lib → lib}/schema/schema.d.ts +0 -0
  70. /package/dist/{src/lib → lib}/schema/schema.js +0 -0
  71. /package/dist/{src/lib → lib}/schema/types.d.ts +0 -0
  72. /package/dist/{src/lib → lib}/schema/types.js +0 -0
  73. /package/dist/{src/lib → lib}/schema/zod.d.ts +0 -0
  74. /package/dist/{src/lib → lib}/schema/zod.js +0 -0
  75. /package/dist/{src/lib → lib}/serializer.d.ts +0 -0
  76. /package/dist/{src/lib → lib}/serializer.js +0 -0
  77. /package/dist/{src/lib → lib}/types.d.ts +0 -0
  78. /package/dist/{src/lib → lib}/types.js +0 -0
  79. /package/dist/{src/lib → lib}/utils/error.d.ts +0 -0
  80. /package/dist/{src/lib → lib}/utils/error.js +0 -0
  81. /package/dist/{src/lib → lib}/utils/file.d.ts +0 -0
  82. /package/dist/{src/lib → lib}/utils/file.js +0 -0
  83. /package/dist/{src/lib → lib}/utils/logger.d.ts +0 -0
  84. /package/dist/{src/lib → lib}/utils/logger.js +0 -0
  85. /package/dist/{src/lib → lib}/utils/string.d.ts +0 -0
  86. /package/dist/{src/lib → lib}/utils/string.js +0 -0
  87. /package/dist/{src/lib → lib}/utils/types.d.ts +0 -0
  88. /package/dist/{src/lib → lib}/utils/types.js +0 -0
  89. /package/dist/{src/prisma → prisma}/attributes.d.ts +0 -0
  90. /package/dist/{src/prisma → prisma}/attributes.js +0 -0
  91. /package/dist/{src/prisma → prisma}/client-path.d.ts +0 -0
  92. /package/dist/{src/prisma → prisma}/client-path.js +0 -0
  93. /package/dist/{src/prisma → prisma}/parse.d.ts +0 -0
  94. /package/dist/{src/prisma → prisma}/parse.js +0 -0
@@ -32,22 +32,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  step((generator = generator.apply(thisArg, _arguments || [])).next());
33
33
  });
34
34
  };
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.generate = void 0;
40
37
  const faker_1 = require("@faker-js/faker");
38
+ const lock_1 = require("@postxl/lock");
41
39
  const generator_helper_1 = require("@prisma/generator-helper");
42
40
  const internals_1 = require("@prisma/internals");
43
41
  const prettier = __importStar(require("prettier"));
44
42
  const zod_1 = require("zod");
45
- const chalk_1 = __importDefault(require("chalk"));
46
43
  const react_generator_1 = require("./generators/enums/react.generator");
47
44
  const types_generator_1 = require("./generators/enums/types.generator");
48
45
  const datamockmodule_generator_1 = require("./generators/indices/datamockmodule.generator");
49
46
  const datamodule_generator_1 = require("./generators/indices/datamodule.generator");
50
47
  const dataservice_generator_1 = require("./generators/indices/dataservice.generator");
48
+ const emptydatabasemigration_generator_1 = require("./generators/indices/emptydatabasemigration.generator");
51
49
  const repositories_generator_1 = require("./generators/indices/repositories.generator");
52
50
  const seed_generator_1 = require("./generators/indices/seed.generator");
53
51
  const stubs_generator_1 = require("./generators/indices/stubs.generator");
@@ -61,10 +59,8 @@ const stub_generator_1 = require("./generators/models/stub.generator");
61
59
  const types_generator_3 = require("./generators/models/types.generator");
62
60
  const meta_1 = require("./lib/meta");
63
61
  const types_1 = require("./lib/schema/types");
64
- const vfs_1 = require("./lib/vfs");
65
62
  const client_path_1 = require("./prisma/client-path");
66
63
  const parse_1 = require("./prisma/parse");
67
- const emptydatabasemigration_generator_1 = require("./generators/indices/emptydatabasemigration.generator");
68
64
  const configDecoder = zod_1.z
69
65
  .object({
70
66
  project: zod_1.z.string(),
@@ -133,102 +129,89 @@ const configDecoder = zod_1.z
133
129
  * Generates PXL files and flushes them to disk.
134
130
  */
135
131
  const generate = ({ models, enums, config, prismaClientPath, logger, }) => __awaiter(void 0, void 0, void 0, function* () {
136
- const vfs = new vfs_1.VirtualFS();
132
+ const root = yield lock_1.LockUtils.findProjectRoot();
133
+ if (root == undefined) {
134
+ throw new Error(`Could not find lock file. Make sure you are running the generator in a project folder.`);
135
+ }
137
136
  faker_1.faker.seed(config.randomSeed);
137
+ const vfs = yield lock_1.VirtualFS.fromLockFile(root);
138
+ const generated = new lock_1.VirtualFS();
138
139
  // Generate Models
139
140
  for (const model of models) {
140
141
  const meta = (0, meta_1.getModelMetadata)({ model });
141
142
  // Types
142
143
  if (!config.disableGenerators.types) {
143
- vfs.write(`/${meta.types.filePath}.ts`, (0, types_generator_3.generateModelTypes)({ model, meta }));
144
+ generated.write(`/${meta.types.filePath}.ts`, (0, types_generator_3.generateModelTypes)({ model, meta }));
144
145
  }
145
146
  // Seed
146
147
  if (!config.disableGenerators.seed) {
147
- vfs.write(`/${meta.seed.filePath}.ts`, (0, seed_generator_2.generateSeedModel)({ model, itemCount: 5, meta }));
148
+ generated.write(`/${meta.seed.filePath}.ts`, (0, seed_generator_2.generateSeedModel)({ model, itemCount: 5, meta }));
148
149
  }
149
150
  // Generate Repositories
150
151
  if (!config.disableGenerators.data) {
151
- vfs.write(`/${meta.data.stubFilePath}.ts`, (0, stub_generator_1.generateStub)({ model, meta }));
152
- vfs.write(`/${meta.data.repoFilePath}.ts`, (0, repository_generator_1.generateRepository)({ model, meta }));
152
+ generated.write(`/${meta.data.stubFilePath}.ts`, (0, stub_generator_1.generateStub)({ model, meta }));
153
+ generated.write(`/${meta.data.repoFilePath}.ts`, (0, repository_generator_1.generateRepository)({ model, meta }));
153
154
  }
154
155
  // Routes
155
156
  if (!config.disableGenerators.trpc) {
156
- vfs.write(`/${meta.trpc.routerFilePath}.ts`, (0, route_generator_1.generateRoute)({ model, meta }));
157
+ generated.write(`/${meta.trpc.routerFilePath}.ts`, (0, route_generator_1.generateRoute)({ model, meta }));
157
158
  }
158
159
  // React
159
160
  if (!config.disableGenerators.react) {
160
- vfs.copy((0, react_generator_2.generateReactComponentsForModel)({ model, meta }), meta.react.folderPath);
161
+ generated.copy((0, react_generator_2.generateReactComponentsForModel)({ model, meta }), meta.react.folderPath);
161
162
  }
162
- logger.log(`✅ ${model.name} generated!`);
163
+ logger.log(`- ${model.name} processed`);
163
164
  }
164
165
  // Generate Enums
165
166
  for (const enumerator of enums.values()) {
166
167
  const meta = (0, meta_1.getEnumMetadata)({ enumerator });
167
168
  if (!config.disableGenerators.types) {
168
- vfs.write(`/${meta.types.filePath}.ts`, (0, types_generator_1.generateEnumType)({ enumerator, prismaClientPath, meta }));
169
+ generated.write(`/${meta.types.filePath}.ts`, (0, types_generator_1.generateEnumType)({ enumerator, prismaClientPath, meta }));
169
170
  }
170
171
  if (!config.disableGenerators.react) {
171
- vfs.copy((0, react_generator_1.generateEnumReactComponents)({ enumerator, meta }), meta.react.folderPath);
172
+ generated.copy((0, react_generator_1.generateEnumReactComponents)({ enumerator, meta }), meta.react.folderPath);
172
173
  }
173
174
  }
174
175
  // Generate Index Files and Services
175
176
  const meta = (0, meta_1.getSchemaMetadata)({ config });
176
177
  if (!config.disableGenerators.data) {
177
- vfs.write(`/${meta.data.dataMockModuleFilePath}.ts`, (0, datamockmodule_generator_1.generateDataMockModule)({ models, meta }));
178
- vfs.write(`/${meta.data.dataModuleFilePath}.ts`, (0, datamodule_generator_1.generateDataModule)({ models, meta }));
179
- vfs.write(`/${meta.data.dataServiceFilePath}.ts`, (0, dataservice_generator_1.generateDataService)({ models, meta }));
180
- vfs.write(`/${meta.data.testDataServiceFilePath}.ts`, (0, testdataservice_generator_1.generateTestDataService)({ meta }));
181
- vfs.write(`/${meta.data.repositoriesConstFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesArray)({ models, meta }));
182
- vfs.write(`/${meta.data.repositoriesIndexFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesIndex)({ models, meta }));
183
- vfs.write(`/${meta.data.stubIndexFilePath}.ts`, (0, stubs_generator_1.generateStubsIndex)({ models, meta }));
184
- vfs.write(`/${meta.migrationsPath}/emptyDatabase.template.sql`, (0, emptydatabasemigration_generator_1.generateEmptyDatabaseStoredProcedure)({ models, meta }));
178
+ generated.write(`/${meta.data.dataMockModuleFilePath}.ts`, (0, datamockmodule_generator_1.generateDataMockModule)({ models, meta }));
179
+ generated.write(`/${meta.data.dataModuleFilePath}.ts`, (0, datamodule_generator_1.generateDataModule)({ models, meta }));
180
+ generated.write(`/${meta.data.dataServiceFilePath}.ts`, (0, dataservice_generator_1.generateDataService)({ models, meta }));
181
+ generated.write(`/${meta.data.testDataServiceFilePath}.ts`, (0, testdataservice_generator_1.generateTestDataService)({ meta }));
182
+ generated.write(`/${meta.data.repositoriesConstFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesArray)({ models, meta }));
183
+ generated.write(`/${meta.data.repositoriesIndexFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesIndex)({ models, meta }));
184
+ generated.write(`/${meta.data.stubIndexFilePath}.ts`, (0, stubs_generator_1.generateStubsIndex)({ models, meta }));
185
+ generated.write(`/${meta.migrationsPath}/emptyDatabase.template.sql`, (0, emptydatabasemigration_generator_1.generateEmptyDatabaseStoredProcedure)({ models, meta }));
185
186
  }
186
187
  if (!config.disableGenerators.seed) {
187
- vfs.write(`/${meta.seed.indexFilePath}.ts`, (0, seed_generator_1.generateSeedIndex)({ models, meta }));
188
+ generated.write(`/${meta.seed.indexFilePath}.ts`, (0, seed_generator_1.generateSeedIndex)({ models, meta }));
188
189
  }
189
190
  if (!config.disableGenerators.trpc) {
190
- vfs.write(`/${meta.trpc.routesFilePath}.ts`, (0, route_generator_1.generateRoutesIndex)({ models, meta }));
191
+ generated.write(`/${meta.trpc.routesFilePath}.ts`, (0, route_generator_1.generateRoutesIndex)({ models, meta }));
191
192
  }
192
193
  if (!config.disableGenerators.types) {
193
- vfs.write(`/${meta.types.indexFilePath}.ts`, (0, types_generator_2.generateTypesIndex)({ models, enums, meta }));
194
+ generated.write(`/${meta.types.indexFilePath}.ts`, (0, types_generator_2.generateTypesIndex)({ models, enums, meta }));
194
195
  }
195
196
  // -------------------------------------------------------------------------
196
197
  // Add disclaimer and format.
197
198
  const prettierConfig = yield prettier.resolveConfig(process.cwd());
198
- vfs.transform((path, content) => `${DISCLAIMER}\n${content}`);
199
- vfs.format(prettierConfig);
200
- const entries = yield vfs.flush(process.cwd(), config.force);
201
- const changes = entries.filter((e) => e.status === 'WRITTEN');
202
- const skipped = entries.filter((e) => e.status === 'SKIPPED');
203
- const unchanged = entries.filter((e) => e.status === 'UNCHANGED');
204
- if (skipped.length > 0) {
205
- logger.info(`PXL ${chalk_1.default.magenta(`skipped ${skipped.length} files`)} because checksums didn't match.`);
206
- }
207
- if (unchanged.length > 0) {
208
- logger.info(`PXL ${chalk_1.default.dim(`skipped ${unchanged.length} files`)} because no change occurded since last generation.`);
209
- }
210
- if (changes.length === 0) {
211
- logger.info(`PXL generated no files.`);
212
- return;
213
- }
214
- logger.info(`PXL ${chalk_1.default.green(`generated the following ${changes.length}`)} files:`);
215
- for (const file of changes) {
216
- logger.info(`+ [generated] ${file.path}`);
217
- }
218
- logger.info(`PXL finished! 🚀`);
199
+ generated.transformUTF8Files((path, content) => `${DISCLAIMER}\n${content}`);
200
+ generated.format(prettierConfig);
201
+ // -------------------------------------------------------------------------
202
+ // Merge with existing files.
203
+ vfs.copy(generated, './');
204
+ // Flush to disk.
205
+ const changes = yield vfs.flush(process.cwd(), { force: config.force });
206
+ const log = lock_1.ConsoleUtils.getFilesChangelog(changes);
207
+ console.info(log);
219
208
  });
220
209
  exports.generate = generate;
221
- const DISCLAIMER = `/**
222
- * DO NOT EDIT THIS FILE!
210
+ const DISCLAIMER = `
211
+ /**
212
+ * This file was generated by PostXL generator.
223
213
  *
224
- * This file was generated by generator.
225
- * Any manual changes will be overwritten.
226
- * To modify this file, edit the Prisma schema file and run
227
- * \`prisma generate\` or \`pnpm prisma generate\`
228
- * again!
229
- *
230
- * If you need to modify the structure of this file, please edit the generator
231
- * at \`packages/generator/\`
232
- *
214
+ * Feel free to manually edit it. The generator will not overwrite it. We suggest you
215
+ * remove the disclaimer to avoid confusion.
233
216
  **/
234
217
  `;
@@ -1,6 +1,6 @@
1
+ import { VirtualFS } from '@postxl/lock';
1
2
  import { EnumMetaData } from '../../lib/meta';
2
3
  import { Enum } from '../../lib/schema/schema';
3
- import { VirtualFS } from '../../lib/vfs';
4
4
  /**
5
5
  * Generates React components for a given enumerator.
6
6
  */
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateEnumReactComponents = void 0;
4
+ const lock_1 = require("@postxl/lock");
4
5
  const imports_1 = require("../../lib/imports");
5
- const vfs_1 = require("../../lib/vfs");
6
6
  /**
7
7
  * Generates React components for a given enumerator.
8
8
  */
9
9
  function generateEnumReactComponents({ enumerator, meta }) {
10
- const vfs = new vfs_1.VirtualFS({
10
+ const vfs = new lock_1.VirtualFS({
11
11
  'index.ts': `
12
12
  export * from './Select'
13
13
  `,
@@ -11,9 +11,9 @@ function generateRepositoriesIndex({ models, meta }) {
11
11
  const exports = exports_1.ExportsGenerator.from(meta.data.repositoriesIndexFilePath);
12
12
  for (const model of models) {
13
13
  const meta = (0, meta_1.getModelMetadata)({ model });
14
- exports.exportEverythingFrom(meta.data.repoFilePath);
14
+ exports.exportEverythingFromPath(meta.data.repoFilePath);
15
15
  }
16
- exports.exportEverythingFrom(meta.data.repositoriesConstFilePath);
16
+ exports.exportEverythingFromPath(meta.data.repositoriesConstFilePath);
17
17
  return exports.generate();
18
18
  }
19
19
  exports.generateRepositoriesIndex = generateRepositoriesIndex;
@@ -10,7 +10,7 @@ function generateSeedIndex({ models, meta }) {
10
10
  const exports = exports_1.ExportsGenerator.from(meta.seed.indexFilePath);
11
11
  for (const model of models) {
12
12
  const meta = (0, meta_1.getModelMetadata)({ model });
13
- exports.exportEverythingFrom(meta.seed.filePath);
13
+ exports.exportEverythingFromPath(meta.seed.filePath);
14
14
  }
15
15
  return exports.generate();
16
16
  }
@@ -10,7 +10,7 @@ function generateStubsIndex({ models, meta }) {
10
10
  const exports = exports_1.ExportsGenerator.from(meta.data.stubIndexFilePath);
11
11
  for (const model of models) {
12
12
  const meta = (0, meta_1.getModelMetadata)({ model });
13
- exports.exportEverythingFrom(meta.data.stubFilePath);
13
+ exports.exportEverythingFromPath(meta.data.stubFilePath);
14
14
  }
15
15
  return exports.generate();
16
16
  }
@@ -10,11 +10,11 @@ function generateTypesIndex({ models, enums, meta, }) {
10
10
  const exports = exports_1.ExportsGenerator.from(meta.types.indexFilePath);
11
11
  for (const model of models) {
12
12
  const meta = (0, meta_1.getModelMetadata)({ model });
13
- exports.exportEverythingFrom(meta.types.filePath);
13
+ exports.exportEverythingFromPath(meta.types.filePath);
14
14
  }
15
15
  for (const enumerator of enums) {
16
16
  const meta = (0, meta_1.getEnumMetadata)({ enumerator });
17
- exports.exportEverythingFrom(meta.types.filePath);
17
+ exports.exportEverythingFromPath(meta.types.filePath);
18
18
  }
19
19
  return exports.generate();
20
20
  }
@@ -1,6 +1,6 @@
1
+ import { VirtualFS } from '@postxl/lock';
1
2
  import { ModelMetaData } from '../../../lib/meta';
2
3
  import { Model } from '../../../lib/schema/schema';
3
- import { VirtualFS } from '../../../lib/vfs';
4
4
  /**
5
5
  * Generates generic React components for a given model.
6
6
  */
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateReactComponentsForModel = void 0;
4
- const vfs_1 = require("../../../lib/vfs");
4
+ const lock_1 = require("@postxl/lock");
5
+ const exports_1 = require("../../../lib/exports");
5
6
  const context_generator_1 = require("./context.generator");
6
7
  const library_generator_1 = require("./library.generator");
7
8
  const lookup_generator_1 = require("./lookup.generator");
@@ -10,23 +11,27 @@ const modals_generator_1 = require("./modals.generator");
10
11
  * Generates generic React components for a given model.
11
12
  */
12
13
  function generateReactComponentsForModel({ model, meta }) {
13
- const vfs = new vfs_1.VirtualFS({
14
- '/index.ts': `
15
- export * from './CreateModal'
16
- export * from './EditModal'
17
- export * from './DeleteModal'
18
-
19
- export * from './Form'
20
- export * from './context'
21
- export * from './Library'
22
- `,
23
- });
14
+ const vfs = new lock_1.VirtualFS({});
15
+ const exports = exports_1.ExportsGenerator.fromRoot()
16
+ .exportEverythingFromFile('./CreateModal')
17
+ .exportEverythingFromFile('./EditModal')
18
+ .exportEverythingFromFile('./DeleteModal')
19
+ .exportEverythingFromFile('./Form')
20
+ .exportEverythingFromFile('./context');
24
21
  vfs.write(`/context.tsx`, (0, context_generator_1.generateModelContext)({ model, meta }));
25
22
  vfs.write(`/CreateModal.tsx`, (0, modals_generator_1.generateModelCreateModalComponent)({ model, meta }));
26
23
  vfs.write(`/EditModal.tsx`, (0, modals_generator_1.generateEditModalModelComponent)({ model, meta }));
27
24
  vfs.write(`/DeleteModal.tsx`, (0, modals_generator_1.generateDeleteModalModelComponent)({ model, meta }));
28
25
  vfs.write(`/Form.tsx`, (0, lookup_generator_1.generateModelLookupComponents)({ model, meta }));
29
- vfs.write(`/Library.tsx`, (0, library_generator_1.generateModelLibraryComponents)({ model, meta }));
26
+ // NOTE: library generator expects that the model has a `name` field.
27
+ // Make sure that you don't make a dependency on this
28
+ // component without checking that a model has a name field.
29
+ const hasNameField = model.nameField != null;
30
+ if (hasNameField) {
31
+ vfs.write(`/Library.tsx`, (0, library_generator_1.generateModelLibraryComponents)({ model, meta }));
32
+ exports.exportEverythingFromFile('./Library');
33
+ }
34
+ vfs.write(`/index.ts`, exports.generate());
30
35
  return vfs;
31
36
  }
32
37
  exports.generateReactComponentsForModel = generateReactComponentsForModel;
@@ -2,6 +2,9 @@ import { ModelMetaData } from '../../../lib/meta';
2
2
  import { Model } from '../../../lib/schema/schema';
3
3
  /**
4
4
  * Generates components that may be used to list all entries of a given data type.
5
+ *
6
+ * NOTE: Library expects that the model has a `name` field. Make sure that you don't make a dependency on
7
+ * this component without checking that a model has a name field.
5
8
  */
6
9
  export declare function generateModelLibraryComponents({ model, meta }: {
7
10
  model: Model;
@@ -6,6 +6,9 @@ const fields_1 = require("../../../lib/schema/fields");
6
6
  const imports_1 = require("../../../lib/imports");
7
7
  /**
8
8
  * Generates components that may be used to list all entries of a given data type.
9
+ *
10
+ * NOTE: Library expects that the model has a `name` field. Make sure that you don't make a dependency on
11
+ * this component without checking that a model has a name field.
9
12
  */
10
13
  function generateModelLibraryComponents({ model, meta }) {
11
14
  const { react: { context, components }, } = meta;
@@ -17,6 +17,11 @@ function generateModelLookupComponents({ model, meta }) {
17
17
  from: meta.types.importPath,
18
18
  });
19
19
  const typeName = model.typeName;
20
+ // NOTE: Depending on the model definition - whether it has a `name` field or not - we'll either
21
+ // auto-populate the `label` property or not.
22
+ const hasNameField = model.nameField != null;
23
+ const tsOmittedFields = hasNameField ? `'label' | 'options' | 'loading'` : `'options' | 'loading'`;
24
+ const reactLabelField = hasNameField ? `label={(l) => l.name}` : '';
20
25
  return `
21
26
  import React, { useMemo } from 'react'
22
27
 
@@ -34,63 +39,63 @@ ${imports.generate()}
34
39
 
35
40
  export const ${components.forms.selectInputName} = ({
36
41
  ...delegated
37
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof SelectInput<${typeName}>>, 'label' | 'options' | 'loading'>) => {
42
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof SelectInput<${typeName}>>, ${tsOmittedFields}>) => {
38
43
  const { list, ready } = ${context.hookFnName}()
39
- return <SelectInput<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
44
+ return <SelectInput<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
40
45
  }
41
46
 
42
47
  export const ${components.forms.selectFieldName} = ({
43
48
  ...delegated
44
- }: Omit<React.ComponentPropsWithoutRef<typeof SelectField<${typeName}>>, 'label' | 'options' | 'loading'>) => {
49
+ }: Omit<React.ComponentPropsWithoutRef<typeof SelectField<${typeName}>>, ${tsOmittedFields}>) => {
45
50
  const { list, ready } = ${context.hookFnName}()
46
- return <SelectField<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
51
+ return <SelectField<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
47
52
  }
48
53
 
49
54
  // Menu Select
50
55
 
51
56
  export const ${components.forms.menuSelectInputName} = ({
52
57
  ...delegated
53
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof MenuSelectInput<${typeName}>>, 'label' | 'options' | 'loading'>) => {
58
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof MenuSelectInput<${typeName}>>, ${tsOmittedFields}>) => {
54
59
  const { list, ready } = ${context.hookFnName}()
55
- return <MenuSelectInput<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
60
+ return <MenuSelectInput<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
56
61
  }
57
62
 
58
63
  export const ${components.forms.menuSelectFieldName} = ({
59
64
  ...delegated
60
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof MenuSelectField<${typeName}>>, 'label' | 'options' | 'loading'>) => {
65
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof MenuSelectField<${typeName}>>, ${tsOmittedFields}>) => {
61
66
  const { list, ready } = ${context.hookFnName}()
62
- return <MenuSelectField<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
67
+ return <MenuSelectField<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
63
68
  }
64
69
 
65
70
  // Search
66
71
 
67
72
  export const ${components.forms.searchInputName} = ({
68
73
  ...delegated
69
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof SearchInput<${typeName}>>, 'label' | 'options' | 'loading'>) => {
74
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof SearchInput<${typeName}>>, ${tsOmittedFields}>) => {
70
75
  const { list, ready } = ${context.hookFnName}()
71
- return <SearchInput<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
76
+ return <SearchInput<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
72
77
  }
73
78
  export const ${components.forms.searchFieldName} = ({
74
79
  ...delegated
75
- }: Omit<React.ComponentPropsWithoutRef<typeof SearchField<${typeName}>>, 'label' | 'options' | 'loading'>) => {
80
+ }: Omit<React.ComponentPropsWithoutRef<typeof SearchField<${typeName}>>, ${tsOmittedFields}>) => {
76
81
  const { list, ready } = ${context.hookFnName}()
77
- return <SearchField<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
82
+ return <SearchField<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
78
83
  }
79
84
 
80
85
  // Table
81
86
 
82
87
  export const ${components.forms.tableSelectInputName} = ({
83
88
  ...delegated
84
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof TableSelectInput<${typeName}>>, 'label' | 'options' | 'loading'>) => {
89
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof TableSelectInput<${typeName}>>, ${tsOmittedFields}>) => {
85
90
  const { list, ready } = ${context.hookFnName}()
86
- return <TableSelectInput<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
91
+ return <TableSelectInput<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
87
92
  }
88
93
 
89
94
  export const ${components.forms.tableSelectFieldName} = ({
90
95
  ...delegated
91
- }: UnionOmit<React.ComponentPropsWithoutRef<typeof TableSelectField<${typeName}>>, 'label' | 'options' | 'loading'>) => {
96
+ }: UnionOmit<React.ComponentPropsWithoutRef<typeof TableSelectField<${typeName}>>, ${tsOmittedFields}>) => {
92
97
  const { list, ready } = ${context.hookFnName}()
93
- return <TableSelectField<${typeName}> options={list} label={(l) => l.name} loading={!ready} {...delegated} />
98
+ return <TableSelectField<${typeName}> options={list} ${reactLabelField} loading={!ready} {...delegated} />
94
99
  }
95
100
  `;
96
101
  }
@@ -8,17 +8,32 @@ export declare class ExportsGenerator {
8
8
  * Path of the file we're generating exports for.
9
9
  */
10
10
  private _path;
11
- constructor({ path }: {
11
+ /**
12
+ * Tells whether this generator acts as a root.
13
+ */
14
+ private isRoot;
15
+ constructor({ path, isRoot }: {
12
16
  path: string;
17
+ isRoot?: boolean;
13
18
  });
14
19
  /**
15
20
  * Creates a new instance of the exports generator.
16
21
  */
17
22
  static from(path: Types.Path): ExportsGenerator;
23
+ /**
24
+ * Creates a new instance of the exports generator from this folder (i.e. every path is relative to this folder).
25
+ */
26
+ static fromRoot(): ExportsGenerator;
27
+ /**
28
+ * Adds a given file to the collection of files we're exporting everything from.
29
+ */
30
+ exportEverythingFromPath(from: Types.Path): ExportsGenerator;
18
31
  /**
19
32
  * Adds a given file to the collection of files we're exporting everything from.
33
+ *
34
+ * NOTE: This should only be used when the generator is a root generator.
20
35
  */
21
- exportEverythingFrom(from: Types.Path): ExportsGenerator;
36
+ exportEverythingFromFile(file: string): ExportsGenerator;
22
37
  /**
23
38
  * Returns the TypeScript export statements.
24
39
  */
@@ -6,9 +6,10 @@ const file_1 = require("./utils/file");
6
6
  * A utility component that lets you generate TypeScript export statements that export all items from a given file.
7
7
  */
8
8
  class ExportsGenerator {
9
- constructor({ path }) {
9
+ constructor({ path, isRoot }) {
10
10
  this._path = path;
11
11
  this._exports = new Set();
12
+ this.isRoot = isRoot !== null && isRoot !== void 0 ? isRoot : false;
12
13
  }
13
14
  /**
14
15
  * Creates a new instance of the exports generator.
@@ -16,14 +17,35 @@ class ExportsGenerator {
16
17
  static from(path) {
17
18
  return new ExportsGenerator({ path });
18
19
  }
20
+ /**
21
+ * Creates a new instance of the exports generator from this folder (i.e. every path is relative to this folder).
22
+ */
23
+ static fromRoot() {
24
+ return new ExportsGenerator({ path: './', isRoot: true });
25
+ }
19
26
  /**
20
27
  * Adds a given file to the collection of files we're exporting everything from.
21
28
  */
22
- exportEverythingFrom(from) {
29
+ exportEverythingFromPath(from) {
30
+ if (this.isRoot) {
31
+ throw new Error(`Cannot use "exportEverythingFromPath" on a root generator.`);
32
+ }
23
33
  const resolvedPath = (0, file_1.getRelativePath)({ from: this._path, to: from });
24
34
  this._exports.add(resolvedPath);
25
35
  return this;
26
36
  }
37
+ /**
38
+ * Adds a given file to the collection of files we're exporting everything from.
39
+ *
40
+ * NOTE: This should only be used when the generator is a root generator.
41
+ */
42
+ exportEverythingFromFile(file) {
43
+ if (!this.isRoot) {
44
+ throw new Error(`Cannot use "exportEverythingFromFile" on a non-root generator.`);
45
+ }
46
+ this._exports.add(file);
47
+ return this;
48
+ }
27
49
  /**
28
50
  * Returns the TypeScript export statements.
29
51
  */
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.4.0",
4
- "main": "./dist/src/generator.js",
5
- "typings": "./dist/src/generator.d.ts",
3
+ "version": "0.6.0",
4
+ "main": "./dist/generator.js",
5
+ "typings": "./dist/generator.d.ts",
6
6
  "bin": {
7
- "@postxl/generator": "./dist/src/generator.js"
7
+ "@postxl/generator": "./dist/generator.js"
8
8
  },
9
9
  "files": [
10
10
  "dist"
@@ -17,11 +17,11 @@
17
17
  "@faker-js/faker": "7.6.0",
18
18
  "@prisma/generator-helper": "4.12.0",
19
19
  "@prisma/internals": "^4.12.0",
20
- "chalk": "^4.1.2",
21
20
  "fast-glob": "^3.2.12",
22
21
  "prettier": "^2.8.7",
23
22
  "remeda": "1.9.4",
24
- "zod": "3.21.4"
23
+ "zod": "3.21.4",
24
+ "@postxl/lock": "0.1.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@prisma/client": "4.12.0",
@@ -1,3 +0,0 @@
1
- import type { Config } from 'jest';
2
- declare const config: Config;
3
- export default config;
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- // import { pathsToModuleNameMapper } from 'ts-jest'
4
- // import { compilerOptions } from './tsconfig.json'
5
- const config = {
6
- verbose: true,
7
- // roots: ['<rootDir>/tests', '<rootDir>/src'],
8
- testEnvironment: 'node',
9
- transform: {
10
- '^.+\\.tsx?$': 'ts-jest',
11
- },
12
- testRegex: '(\\.|/)test\\.tsx?$',
13
- testPathIgnorePatterns: ['/node_modules/', '/__fixtures__/'],
14
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
15
- // moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/src/' }),
16
- };
17
- exports.default = config;