@ingenyus/swarm-wasp 0.2.0 → 0.2.2

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 (47) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/common/index.d.ts +0 -1
  3. package/dist/common/index.d.ts.map +1 -1
  4. package/dist/common/index.js +9 -34
  5. package/dist/generators/action/action-generator.js +50 -58
  6. package/dist/generators/action/index.js +50 -58
  7. package/dist/generators/action/schema.js +1 -5
  8. package/dist/generators/api/api-generator.js +51 -59
  9. package/dist/generators/api/index.js +51 -59
  10. package/dist/generators/api/schema.js +1 -5
  11. package/dist/generators/api-namespace/api-namespace-generator.js +51 -59
  12. package/dist/generators/api-namespace/index.js +51 -59
  13. package/dist/generators/api-namespace/schema.js +1 -5
  14. package/dist/generators/base/component-generator.base.d.ts +4 -7
  15. package/dist/generators/base/component-generator.base.d.ts.map +1 -1
  16. package/dist/generators/base/component-generator.base.js +49 -57
  17. package/dist/generators/base/index.js +50 -58
  18. package/dist/generators/base/operation-generator.base.js +50 -58
  19. package/dist/generators/base/wasp-generator.base.d.ts +3 -5
  20. package/dist/generators/base/wasp-generator.base.d.ts.map +1 -1
  21. package/dist/generators/base/wasp-generator.base.js +22 -26
  22. package/dist/generators/config/index.js +12 -16
  23. package/dist/generators/config/wasp-config-generator.js +12 -16
  24. package/dist/generators/crud/crud-generator.js +50 -58
  25. package/dist/generators/crud/index.js +50 -58
  26. package/dist/generators/crud/schema.js +1 -5
  27. package/dist/generators/feature/feature-generator.d.ts +2 -4
  28. package/dist/generators/feature/feature-generator.d.ts.map +1 -1
  29. package/dist/generators/feature/feature-generator.js +32 -42
  30. package/dist/generators/feature/index.js +32 -42
  31. package/dist/generators/feature/schema.js +1 -5
  32. package/dist/generators/index.js +54 -62
  33. package/dist/generators/job/index.js +49 -57
  34. package/dist/generators/job/job-generator.js +49 -57
  35. package/dist/generators/job/schema.js +1 -5
  36. package/dist/generators/query/index.js +50 -58
  37. package/dist/generators/query/query-generator.js +50 -58
  38. package/dist/generators/query/schema.js +1 -5
  39. package/dist/generators/route/index.js +49 -57
  40. package/dist/generators/route/route-generator.js +49 -57
  41. package/dist/generators/route/schema.js +1 -5
  42. package/dist/index.js +60 -90
  43. package/dist/plugins/wasp.d.ts.map +1 -1
  44. package/package.json +2 -2
  45. package/dist/common/plugin.d.ts +0 -2
  46. package/dist/common/plugin.d.ts.map +0 -1
  47. package/dist/common/plugin.js +0 -41
@@ -29,13 +29,13 @@ var CONFIG_TYPES = {
29
29
 
30
30
  // src/generators/base/component-generator.base.ts
31
31
  import {
32
+ GeneratorRuntime,
32
33
  hasHelperMethodCall,
33
- logger as singletonLogger4,
34
34
  toCamelCase,
35
35
  toKebabCase as toKebabCase2,
36
36
  validateFeaturePath as validateFeaturePath3
37
37
  } from "@ingenyus/swarm";
38
- import path7 from "path";
38
+ import path6 from "path";
39
39
 
40
40
  // src/common/filesystem.ts
41
41
  import { toPascalCase, validateFeaturePath } from "@ingenyus/swarm";
@@ -89,16 +89,12 @@ function getFeatureDir(fileSystem, featureName) {
89
89
  return path.join(waspRoot, "src", normalisedPath);
90
90
  }
91
91
 
92
- // src/common/plugin.ts
93
- import path2 from "path";
94
- import { fileURLToPath } from "url";
95
-
96
92
  // src/common/prisma.ts
97
93
  import {
98
94
  getSchema
99
95
  } from "@mrleebo/prisma-ast";
100
96
  import fs2 from "fs";
101
- import path3 from "path";
97
+ import path2 from "path";
102
98
 
103
99
  // src/common/schemas.ts
104
100
  import { commandRegistry } from "@ingenyus/swarm";
@@ -155,7 +151,7 @@ var commonSchemas = {
155
151
  // src/common/templates.ts
156
152
  import { toKebabCase } from "@ingenyus/swarm";
157
153
  import { Eta } from "eta";
158
- import path4 from "path";
154
+ import path3 from "path";
159
155
  var TemplateUtility = class {
160
156
  constructor(fileSystem) {
161
157
  this.fileSystem = fileSystem;
@@ -163,14 +159,14 @@ var TemplateUtility = class {
163
159
  processTemplate(templatePath, replacements) {
164
160
  const declarations = Object.keys(replacements).map((key) => `${key}=it.${key}`).join(", ");
165
161
  const functionHeader = declarations ? `const ${declarations};` : void 0;
166
- const templateDir = path4.dirname(templatePath);
162
+ const templateDir = path3.dirname(templatePath);
167
163
  const eta = new Eta({
168
164
  autoTrim: false,
169
165
  autoEscape: false,
170
166
  views: templateDir,
171
167
  functionHeader
172
168
  });
173
- const templateName = path4.basename(templatePath).replace(/\.eta$/, "");
169
+ const templateName = path3.basename(templatePath).replace(/\.eta$/, "");
174
170
  if (this.fileSystem.existsSync(templatePath)) {
175
171
  return eta.render(templateName, replacements);
176
172
  } else {
@@ -188,11 +184,11 @@ var TemplateUtility = class {
188
184
  resolveTemplatePath(relativePath, generatorName, currentFileUrl) {
189
185
  const generatorDirName = toKebabCase(generatorName);
190
186
  const currentFilePath = new URL(currentFileUrl).pathname;
191
- const currentFileDir = path4.dirname(currentFilePath);
192
- const currentFileName = path4.basename(currentFilePath);
187
+ const currentFileDir = path3.dirname(currentFilePath);
188
+ const currentFileName = path3.basename(currentFilePath);
193
189
  const isInstalledPackage = currentFileDir.includes("node_modules") && currentFileDir.endsWith("/dist") && currentFileName === "index.js";
194
- const startDir = isInstalledPackage ? currentFileDir : path4.dirname(path4.dirname(currentFileDir));
195
- return path4.join(
190
+ const startDir = isInstalledPackage ? currentFileDir : path3.dirname(path3.dirname(currentFileDir));
191
+ return path3.join(
196
192
  startDir,
197
193
  "generators",
198
194
  generatorDirName,
@@ -203,17 +199,12 @@ var TemplateUtility = class {
203
199
  };
204
200
 
205
201
  // src/generators/feature/feature-generator.ts
206
- import {
207
- handleFatalError as handleFatalError2,
208
- logger as singletonLogger3,
209
- validateFeaturePath as validateFeaturePath2
210
- } from "@ingenyus/swarm";
211
- import path6 from "path";
202
+ import { handleFatalError as handleFatalError2, validateFeaturePath as validateFeaturePath2 } from "@ingenyus/swarm";
203
+ import path5 from "path";
212
204
 
213
205
  // src/generators/base/wasp-generator.base.ts
214
206
  import {
215
207
  GeneratorBase,
216
- logger as singletonLogger2,
217
208
  SwarmConfigManager,
218
209
  TemplateResolver
219
210
  } from "@ingenyus/swarm";
@@ -224,14 +215,14 @@ import {
224
215
  parseHelperMethodDefinition,
225
216
  logger as singletonLogger
226
217
  } from "@ingenyus/swarm";
227
- import path5 from "path";
218
+ import path4 from "path";
228
219
  var WaspConfigGenerator = class {
229
220
  constructor(logger = singletonLogger, fileSystem = realFileSystem) {
230
221
  this.logger = logger;
231
222
  this.fileSystem = fileSystem;
232
223
  this.templateUtility = new TemplateUtility(fileSystem);
233
224
  }
234
- path = path5;
225
+ path = path4;
235
226
  templateUtility;
236
227
  /**
237
228
  * Gets the template path for feature config templates.
@@ -260,7 +251,7 @@ var WaspConfigGenerator = class {
260
251
  this.logger.error(`Template not found: ${templatePath}`);
261
252
  return;
262
253
  }
263
- const configFilePath = path5.join(featureDir, `feature.wasp.ts`);
254
+ const configFilePath = path4.join(featureDir, `feature.wasp.ts`);
264
255
  if (this.fileSystem.existsSync(configFilePath)) {
265
256
  this.logger.warn(`Feature config already exists: ${configFilePath}`);
266
257
  return;
@@ -276,7 +267,7 @@ var WaspConfigGenerator = class {
276
267
  */
277
268
  update(featurePath, declaration) {
278
269
  const configDir = getFeatureDir(this.fileSystem, featurePath);
279
- const configFilePath = path5.join(configDir, `feature.wasp.ts`);
270
+ const configFilePath = path4.join(configDir, `feature.wasp.ts`);
280
271
  if (!this.fileSystem.existsSync(configFilePath)) {
281
272
  const templatePath = this.getTemplatePath("feature.wasp.eta");
282
273
  if (!this.fileSystem.existsSync(templatePath)) {
@@ -656,14 +647,6 @@ var WaspConfigGenerator = class {
656
647
 
657
648
  // src/generators/base/wasp-generator.base.ts
658
649
  var WaspGeneratorBase = class extends GeneratorBase {
659
- constructor(fileSystem = realFileSystem, logger = singletonLogger2) {
660
- super(fileSystem, logger);
661
- this.fileSystem = fileSystem;
662
- this.logger = logger;
663
- this.configGenerator = new WaspConfigGenerator(logger, fileSystem);
664
- this.templateUtility = new TemplateUtility(fileSystem);
665
- this.templateResolver = new TemplateResolver(fileSystem);
666
- }
667
650
  configGenerator;
668
651
  templateUtility;
669
652
  templateResolver;
@@ -671,6 +654,15 @@ var WaspGeneratorBase = class extends GeneratorBase {
671
654
  configLoaded = false;
672
655
  // Plugin name from swarm.config.json
673
656
  pluginName = PLUGIN_NAME;
657
+ constructor() {
658
+ super();
659
+ this.configGenerator = new WaspConfigGenerator(
660
+ this.logger,
661
+ this.fileSystem
662
+ );
663
+ this.templateUtility = new TemplateUtility(this.fileSystem);
664
+ this.templateResolver = new TemplateResolver(this.fileSystem);
665
+ }
674
666
  async loadSwarmConfig() {
675
667
  if (this.configLoaded) return;
676
668
  const configManager = new SwarmConfigManager();
@@ -721,7 +713,7 @@ var WaspGeneratorBase = class extends GeneratorBase {
721
713
  }
722
714
  /**
723
715
  * Generic existence check with force flag handling
724
- * Consolidates the pattern used in both file and config checks
716
+ * Consolidates the pattern used in both file and config existence checks
725
717
  */
726
718
  checkExistence(exists, itemDescription, force, errorMessage) {
727
719
  if (exists && !force) {
@@ -761,16 +753,14 @@ var schema = z2.object({
761
753
 
762
754
  // src/generators/feature/feature-generator.ts
763
755
  var FeatureGenerator = class extends WaspGeneratorBase {
764
- constructor(logger = singletonLogger3, fileSystem = realFileSystem) {
765
- super(fileSystem, logger);
766
- this.logger = logger;
767
- this.fileSystem = fileSystem;
768
- this.name = "feature";
769
- this.description = "Generates a feature directory containing a Wasp configuration file";
770
- }
771
756
  name;
772
757
  description;
773
758
  schema = schema;
759
+ constructor() {
760
+ super();
761
+ this.name = "feature";
762
+ this.description = "Generates a feature directory containing a Wasp configuration file";
763
+ }
774
764
  getDefaultTemplatePath(templateName) {
775
765
  return this.templateUtility.resolveTemplatePath(
776
766
  templateName,
@@ -786,18 +776,18 @@ var FeatureGenerator = class extends WaspGeneratorBase {
786
776
  const { target } = args;
787
777
  const segments = validateFeaturePath2(target);
788
778
  const normalisedPath = normaliseFeaturePath(target);
789
- const sourceRoot = path6.join(findWaspRoot(this.fileSystem), "src");
779
+ const sourceRoot = path5.join(findWaspRoot(this.fileSystem), "src");
790
780
  if (segments.length > 1) {
791
781
  const parentPath = segments.slice(0, -1).join("/");
792
782
  const parentNormalisedPath = normaliseFeaturePath(parentPath);
793
- const parentFeatureDir = path6.join(sourceRoot, parentNormalisedPath);
783
+ const parentFeatureDir = path5.join(sourceRoot, parentNormalisedPath);
794
784
  if (!this.fileSystem.existsSync(parentFeatureDir)) {
795
785
  handleFatalError2(
796
786
  `Parent feature '${parentPath}' does not exist. Please create it first.`
797
787
  );
798
788
  }
799
789
  }
800
- const featureDir = path6.join(sourceRoot, normalisedPath);
790
+ const featureDir = path5.join(sourceRoot, normalisedPath);
801
791
  this.fileSystem.mkdirSync(featureDir, { recursive: true });
802
792
  this.configGenerator.generate(normalisedPath);
803
793
  this.logger.success(`Generated feature: ${normalisedPath}`);
@@ -806,13 +796,6 @@ var FeatureGenerator = class extends WaspGeneratorBase {
806
796
 
807
797
  // src/generators/base/component-generator.base.ts
808
798
  var ComponentGeneratorBase = class extends WaspGeneratorBase {
809
- constructor(logger = singletonLogger4, fileSystem = realFileSystem, featureDirectoryGenerator = new FeatureGenerator(logger, fileSystem)) {
810
- super(fileSystem, logger);
811
- this.logger = logger;
812
- this.fileSystem = fileSystem;
813
- this.featureDirectoryGenerator = featureDirectoryGenerator;
814
- this.featureDirectoryGenerator = featureDirectoryGenerator;
815
- }
816
799
  getDefaultTemplatePath(templateName) {
817
800
  return this.templateUtility.resolveTemplatePath(
818
801
  templateName,
@@ -820,6 +803,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
820
803
  import.meta.url
821
804
  );
822
805
  }
806
+ featureDirectoryGenerator;
807
+ constructor() {
808
+ super();
809
+ const runtime = GeneratorRuntime.current();
810
+ if (runtime.featureGeneratorFactory) {
811
+ const factoryResult = runtime.featureGeneratorFactory(runtime);
812
+ this.featureDirectoryGenerator = factoryResult;
813
+ } else {
814
+ this.featureDirectoryGenerator = new FeatureGenerator();
815
+ }
816
+ }
823
817
  get name() {
824
818
  return toKebabCase2(this.componentType);
825
819
  }
@@ -834,7 +828,7 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
834
828
  const currentPath = pathSegments.join("/");
835
829
  const featureName = pathSegments[pathSegments.length - 1];
836
830
  const featureDir = getFeatureDir(this.fileSystem, currentPath);
837
- const configPath = path7.join(featureDir, `feature.wasp.ts`);
831
+ const configPath = path6.join(featureDir, `feature.wasp.ts`);
838
832
  if (this.fileSystem.existsSync(configPath)) {
839
833
  return configPath;
840
834
  }
@@ -896,18 +890,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
896
890
  }
897
891
  /**
898
892
  * Gets the appropriate directory for a feature based on its path.
899
- * @param fileSystem - The filesystem abstraction
900
893
  * @param featurePath - The full feature path
901
894
  * @param type - The type of file being generated
902
895
  * @returns The target directory and import path
903
896
  */
904
- getFeatureTargetDir(fileSystem, featurePath, type) {
897
+ getFeatureTargetDir(featurePath, type) {
905
898
  validateFeaturePath3(featurePath);
906
899
  const normalisedPath = normaliseFeaturePath(featurePath);
907
- const featureDir = getFeatureDir(fileSystem, normalisedPath);
900
+ const featureDir = getFeatureDir(this.fileSystem, normalisedPath);
908
901
  const typeKey = type.toLowerCase();
909
902
  const typeDirectory = TYPE_DIRECTORIES[typeKey];
910
- const targetDirectory = path7.join(featureDir, typeDirectory);
903
+ const targetDirectory = path6.join(featureDir, typeDirectory);
911
904
  const importDirectory = `@src/${normalisedPath}/${typeDirectory}`;
912
905
  return { targetDirectory, importDirectory };
913
906
  }
@@ -916,7 +909,6 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
916
909
  */
917
910
  ensureTargetDirectory(featurePath, type) {
918
911
  const { targetDirectory, importDirectory } = this.getFeatureTargetDir(
919
- this.fileSystem,
920
912
  featurePath,
921
913
  type
922
914
  );
@@ -15,16 +15,12 @@ var realFileSystem = {
15
15
  statSync: fs.statSync
16
16
  };
17
17
 
18
- // src/common/plugin.ts
19
- import path from "path";
20
- import { fileURLToPath } from "url";
21
-
22
18
  // src/common/prisma.ts
23
19
  import {
24
20
  getSchema
25
21
  } from "@mrleebo/prisma-ast";
26
22
  import fs2 from "fs";
27
- import path2 from "path";
23
+ import path from "path";
28
24
 
29
25
  // src/common/schemas.ts
30
26
  import { commandRegistry } from "@ingenyus/swarm";
@@ -40,13 +40,13 @@ var CONFIG_TYPES = {
40
40
 
41
41
  // src/generators/base/component-generator.base.ts
42
42
  import {
43
+ GeneratorRuntime,
43
44
  hasHelperMethodCall,
44
- logger as singletonLogger4,
45
45
  toCamelCase,
46
46
  toKebabCase as toKebabCase2,
47
47
  validateFeaturePath as validateFeaturePath3
48
48
  } from "@ingenyus/swarm";
49
- import path7 from "path";
49
+ import path6 from "path";
50
50
 
51
51
  // src/common/filesystem.ts
52
52
  import { toPascalCase, validateFeaturePath } from "@ingenyus/swarm";
@@ -119,19 +119,15 @@ function getFeatureImportPath(featurePath) {
119
119
  return segments.join("/");
120
120
  }
121
121
 
122
- // src/common/plugin.ts
123
- import path2 from "path";
124
- import { fileURLToPath } from "url";
125
-
126
122
  // src/common/prisma.ts
127
123
  import {
128
124
  getSchema
129
125
  } from "@mrleebo/prisma-ast";
130
126
  import fs2 from "fs";
131
- import path3 from "path";
127
+ import path2 from "path";
132
128
  async function getEntityMetadata(modelName) {
133
129
  try {
134
- const schemaPath = path3.join(process.cwd(), "schema.prisma");
130
+ const schemaPath = path2.join(process.cwd(), "schema.prisma");
135
131
  const schemaContent = fs2.readFileSync(schemaPath, "utf8");
136
132
  const schema3 = getSchema(schemaContent);
137
133
  const model = schema3.list?.find(
@@ -306,7 +302,7 @@ var commonSchemas = {
306
302
  // src/common/templates.ts
307
303
  import { toKebabCase } from "@ingenyus/swarm";
308
304
  import { Eta } from "eta";
309
- import path4 from "path";
305
+ import path3 from "path";
310
306
  var TemplateUtility = class {
311
307
  constructor(fileSystem) {
312
308
  this.fileSystem = fileSystem;
@@ -314,14 +310,14 @@ var TemplateUtility = class {
314
310
  processTemplate(templatePath, replacements) {
315
311
  const declarations = Object.keys(replacements).map((key) => `${key}=it.${key}`).join(", ");
316
312
  const functionHeader = declarations ? `const ${declarations};` : void 0;
317
- const templateDir = path4.dirname(templatePath);
313
+ const templateDir = path3.dirname(templatePath);
318
314
  const eta = new Eta({
319
315
  autoTrim: false,
320
316
  autoEscape: false,
321
317
  views: templateDir,
322
318
  functionHeader
323
319
  });
324
- const templateName = path4.basename(templatePath).replace(/\.eta$/, "");
320
+ const templateName = path3.basename(templatePath).replace(/\.eta$/, "");
325
321
  if (this.fileSystem.existsSync(templatePath)) {
326
322
  return eta.render(templateName, replacements);
327
323
  } else {
@@ -339,11 +335,11 @@ var TemplateUtility = class {
339
335
  resolveTemplatePath(relativePath, generatorName, currentFileUrl) {
340
336
  const generatorDirName = toKebabCase(generatorName);
341
337
  const currentFilePath = new URL(currentFileUrl).pathname;
342
- const currentFileDir = path4.dirname(currentFilePath);
343
- const currentFileName = path4.basename(currentFilePath);
338
+ const currentFileDir = path3.dirname(currentFilePath);
339
+ const currentFileName = path3.basename(currentFilePath);
344
340
  const isInstalledPackage = currentFileDir.includes("node_modules") && currentFileDir.endsWith("/dist") && currentFileName === "index.js";
345
- const startDir = isInstalledPackage ? currentFileDir : path4.dirname(path4.dirname(currentFileDir));
346
- return path4.join(
341
+ const startDir = isInstalledPackage ? currentFileDir : path3.dirname(path3.dirname(currentFileDir));
342
+ return path3.join(
347
343
  startDir,
348
344
  "generators",
349
345
  generatorDirName,
@@ -354,17 +350,12 @@ var TemplateUtility = class {
354
350
  };
355
351
 
356
352
  // src/generators/feature/feature-generator.ts
357
- import {
358
- handleFatalError as handleFatalError2,
359
- logger as singletonLogger3,
360
- validateFeaturePath as validateFeaturePath2
361
- } from "@ingenyus/swarm";
362
- import path6 from "path";
353
+ import { handleFatalError as handleFatalError2, validateFeaturePath as validateFeaturePath2 } from "@ingenyus/swarm";
354
+ import path5 from "path";
363
355
 
364
356
  // src/generators/base/wasp-generator.base.ts
365
357
  import {
366
358
  GeneratorBase,
367
- logger as singletonLogger2,
368
359
  SwarmConfigManager,
369
360
  TemplateResolver
370
361
  } from "@ingenyus/swarm";
@@ -375,14 +366,14 @@ import {
375
366
  parseHelperMethodDefinition,
376
367
  logger as singletonLogger
377
368
  } from "@ingenyus/swarm";
378
- import path5 from "path";
369
+ import path4 from "path";
379
370
  var WaspConfigGenerator = class {
380
371
  constructor(logger = singletonLogger, fileSystem = realFileSystem) {
381
372
  this.logger = logger;
382
373
  this.fileSystem = fileSystem;
383
374
  this.templateUtility = new TemplateUtility(fileSystem);
384
375
  }
385
- path = path5;
376
+ path = path4;
386
377
  templateUtility;
387
378
  /**
388
379
  * Gets the template path for feature config templates.
@@ -411,7 +402,7 @@ var WaspConfigGenerator = class {
411
402
  this.logger.error(`Template not found: ${templatePath}`);
412
403
  return;
413
404
  }
414
- const configFilePath = path5.join(featureDir, `feature.wasp.ts`);
405
+ const configFilePath = path4.join(featureDir, `feature.wasp.ts`);
415
406
  if (this.fileSystem.existsSync(configFilePath)) {
416
407
  this.logger.warn(`Feature config already exists: ${configFilePath}`);
417
408
  return;
@@ -427,7 +418,7 @@ var WaspConfigGenerator = class {
427
418
  */
428
419
  update(featurePath, declaration) {
429
420
  const configDir = getFeatureDir(this.fileSystem, featurePath);
430
- const configFilePath = path5.join(configDir, `feature.wasp.ts`);
421
+ const configFilePath = path4.join(configDir, `feature.wasp.ts`);
431
422
  if (!this.fileSystem.existsSync(configFilePath)) {
432
423
  const templatePath = this.getTemplatePath("feature.wasp.eta");
433
424
  if (!this.fileSystem.existsSync(templatePath)) {
@@ -807,14 +798,6 @@ var WaspConfigGenerator = class {
807
798
 
808
799
  // src/generators/base/wasp-generator.base.ts
809
800
  var WaspGeneratorBase = class extends GeneratorBase {
810
- constructor(fileSystem = realFileSystem, logger = singletonLogger2) {
811
- super(fileSystem, logger);
812
- this.fileSystem = fileSystem;
813
- this.logger = logger;
814
- this.configGenerator = new WaspConfigGenerator(logger, fileSystem);
815
- this.templateUtility = new TemplateUtility(fileSystem);
816
- this.templateResolver = new TemplateResolver(fileSystem);
817
- }
818
801
  configGenerator;
819
802
  templateUtility;
820
803
  templateResolver;
@@ -822,6 +805,15 @@ var WaspGeneratorBase = class extends GeneratorBase {
822
805
  configLoaded = false;
823
806
  // Plugin name from swarm.config.json
824
807
  pluginName = PLUGIN_NAME;
808
+ constructor() {
809
+ super();
810
+ this.configGenerator = new WaspConfigGenerator(
811
+ this.logger,
812
+ this.fileSystem
813
+ );
814
+ this.templateUtility = new TemplateUtility(this.fileSystem);
815
+ this.templateResolver = new TemplateResolver(this.fileSystem);
816
+ }
825
817
  async loadSwarmConfig() {
826
818
  if (this.configLoaded) return;
827
819
  const configManager = new SwarmConfigManager();
@@ -872,7 +864,7 @@ var WaspGeneratorBase = class extends GeneratorBase {
872
864
  }
873
865
  /**
874
866
  * Generic existence check with force flag handling
875
- * Consolidates the pattern used in both file and config checks
867
+ * Consolidates the pattern used in both file and config existence checks
876
868
  */
877
869
  checkExistence(exists, itemDescription, force, errorMessage) {
878
870
  if (exists && !force) {
@@ -912,16 +904,14 @@ var schema = z2.object({
912
904
 
913
905
  // src/generators/feature/feature-generator.ts
914
906
  var FeatureGenerator = class extends WaspGeneratorBase {
915
- constructor(logger = singletonLogger3, fileSystem = realFileSystem) {
916
- super(fileSystem, logger);
917
- this.logger = logger;
918
- this.fileSystem = fileSystem;
919
- this.name = "feature";
920
- this.description = "Generates a feature directory containing a Wasp configuration file";
921
- }
922
907
  name;
923
908
  description;
924
909
  schema = schema;
910
+ constructor() {
911
+ super();
912
+ this.name = "feature";
913
+ this.description = "Generates a feature directory containing a Wasp configuration file";
914
+ }
925
915
  getDefaultTemplatePath(templateName) {
926
916
  return this.templateUtility.resolveTemplatePath(
927
917
  templateName,
@@ -937,18 +927,18 @@ var FeatureGenerator = class extends WaspGeneratorBase {
937
927
  const { target } = args;
938
928
  const segments = validateFeaturePath2(target);
939
929
  const normalisedPath = normaliseFeaturePath(target);
940
- const sourceRoot = path6.join(findWaspRoot(this.fileSystem), "src");
930
+ const sourceRoot = path5.join(findWaspRoot(this.fileSystem), "src");
941
931
  if (segments.length > 1) {
942
932
  const parentPath = segments.slice(0, -1).join("/");
943
933
  const parentNormalisedPath = normaliseFeaturePath(parentPath);
944
- const parentFeatureDir = path6.join(sourceRoot, parentNormalisedPath);
934
+ const parentFeatureDir = path5.join(sourceRoot, parentNormalisedPath);
945
935
  if (!this.fileSystem.existsSync(parentFeatureDir)) {
946
936
  handleFatalError2(
947
937
  `Parent feature '${parentPath}' does not exist. Please create it first.`
948
938
  );
949
939
  }
950
940
  }
951
- const featureDir = path6.join(sourceRoot, normalisedPath);
941
+ const featureDir = path5.join(sourceRoot, normalisedPath);
952
942
  this.fileSystem.mkdirSync(featureDir, { recursive: true });
953
943
  this.configGenerator.generate(normalisedPath);
954
944
  this.logger.success(`Generated feature: ${normalisedPath}`);
@@ -957,13 +947,6 @@ var FeatureGenerator = class extends WaspGeneratorBase {
957
947
 
958
948
  // src/generators/base/component-generator.base.ts
959
949
  var ComponentGeneratorBase = class extends WaspGeneratorBase {
960
- constructor(logger = singletonLogger4, fileSystem = realFileSystem, featureDirectoryGenerator = new FeatureGenerator(logger, fileSystem)) {
961
- super(fileSystem, logger);
962
- this.logger = logger;
963
- this.fileSystem = fileSystem;
964
- this.featureDirectoryGenerator = featureDirectoryGenerator;
965
- this.featureDirectoryGenerator = featureDirectoryGenerator;
966
- }
967
950
  getDefaultTemplatePath(templateName) {
968
951
  return this.templateUtility.resolveTemplatePath(
969
952
  templateName,
@@ -971,6 +954,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
971
954
  import.meta.url
972
955
  );
973
956
  }
957
+ featureDirectoryGenerator;
958
+ constructor() {
959
+ super();
960
+ const runtime = GeneratorRuntime.current();
961
+ if (runtime.featureGeneratorFactory) {
962
+ const factoryResult = runtime.featureGeneratorFactory(runtime);
963
+ this.featureDirectoryGenerator = factoryResult;
964
+ } else {
965
+ this.featureDirectoryGenerator = new FeatureGenerator();
966
+ }
967
+ }
974
968
  get name() {
975
969
  return toKebabCase2(this.componentType);
976
970
  }
@@ -985,7 +979,7 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
985
979
  const currentPath = pathSegments.join("/");
986
980
  const featureName = pathSegments[pathSegments.length - 1];
987
981
  const featureDir = getFeatureDir(this.fileSystem, currentPath);
988
- const configPath = path7.join(featureDir, `feature.wasp.ts`);
982
+ const configPath = path6.join(featureDir, `feature.wasp.ts`);
989
983
  if (this.fileSystem.existsSync(configPath)) {
990
984
  return configPath;
991
985
  }
@@ -1047,18 +1041,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
1047
1041
  }
1048
1042
  /**
1049
1043
  * Gets the appropriate directory for a feature based on its path.
1050
- * @param fileSystem - The filesystem abstraction
1051
1044
  * @param featurePath - The full feature path
1052
1045
  * @param type - The type of file being generated
1053
1046
  * @returns The target directory and import path
1054
1047
  */
1055
- getFeatureTargetDir(fileSystem, featurePath, type) {
1048
+ getFeatureTargetDir(featurePath, type) {
1056
1049
  validateFeaturePath3(featurePath);
1057
1050
  const normalisedPath = normaliseFeaturePath(featurePath);
1058
- const featureDir = getFeatureDir(fileSystem, normalisedPath);
1051
+ const featureDir = getFeatureDir(this.fileSystem, normalisedPath);
1059
1052
  const typeKey = type.toLowerCase();
1060
1053
  const typeDirectory = TYPE_DIRECTORIES[typeKey];
1061
- const targetDirectory = path7.join(featureDir, typeDirectory);
1054
+ const targetDirectory = path6.join(featureDir, typeDirectory);
1062
1055
  const importDirectory = `@src/${normalisedPath}/${typeDirectory}`;
1063
1056
  return { targetDirectory, importDirectory };
1064
1057
  }
@@ -1067,7 +1060,6 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
1067
1060
  */
1068
1061
  ensureTargetDirectory(featurePath, type) {
1069
1062
  const { targetDirectory, importDirectory } = this.getFeatureTargetDir(
1070
- this.fileSystem,
1071
1063
  featurePath,
1072
1064
  type
1073
1065
  );