@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
@@ -92,16 +92,12 @@ function getFeatureImportPath(featurePath) {
92
92
  return segments.join("/");
93
93
  }
94
94
 
95
- // src/common/plugin.ts
96
- import path2 from "path";
97
- import { fileURLToPath } from "url";
98
-
99
95
  // src/common/prisma.ts
100
96
  import {
101
97
  getSchema
102
98
  } from "@mrleebo/prisma-ast";
103
99
  import fs2 from "fs";
104
- import path3 from "path";
100
+ import path2 from "path";
105
101
 
106
102
  // src/common/schemas.ts
107
103
  import { commandRegistry } from "@ingenyus/swarm";
@@ -158,7 +154,7 @@ var commonSchemas = {
158
154
  // src/common/templates.ts
159
155
  import { toKebabCase } from "@ingenyus/swarm";
160
156
  import { Eta } from "eta";
161
- import path4 from "path";
157
+ import path3 from "path";
162
158
  var TemplateUtility = class {
163
159
  constructor(fileSystem) {
164
160
  this.fileSystem = fileSystem;
@@ -166,14 +162,14 @@ var TemplateUtility = class {
166
162
  processTemplate(templatePath, replacements) {
167
163
  const declarations = Object.keys(replacements).map((key) => `${key}=it.${key}`).join(", ");
168
164
  const functionHeader = declarations ? `const ${declarations};` : void 0;
169
- const templateDir = path4.dirname(templatePath);
165
+ const templateDir = path3.dirname(templatePath);
170
166
  const eta = new Eta({
171
167
  autoTrim: false,
172
168
  autoEscape: false,
173
169
  views: templateDir,
174
170
  functionHeader
175
171
  });
176
- const templateName = path4.basename(templatePath).replace(/\.eta$/, "");
172
+ const templateName = path3.basename(templatePath).replace(/\.eta$/, "");
177
173
  if (this.fileSystem.existsSync(templatePath)) {
178
174
  return eta.render(templateName, replacements);
179
175
  } else {
@@ -191,11 +187,11 @@ var TemplateUtility = class {
191
187
  resolveTemplatePath(relativePath, generatorName, currentFileUrl) {
192
188
  const generatorDirName = toKebabCase(generatorName);
193
189
  const currentFilePath = new URL(currentFileUrl).pathname;
194
- const currentFileDir = path4.dirname(currentFilePath);
195
- const currentFileName = path4.basename(currentFilePath);
190
+ const currentFileDir = path3.dirname(currentFilePath);
191
+ const currentFileName = path3.basename(currentFilePath);
196
192
  const isInstalledPackage = currentFileDir.includes("node_modules") && currentFileDir.endsWith("/dist") && currentFileName === "index.js";
197
- const startDir = isInstalledPackage ? currentFileDir : path4.dirname(path4.dirname(currentFileDir));
198
- return path4.join(
193
+ const startDir = isInstalledPackage ? currentFileDir : path3.dirname(path3.dirname(currentFileDir));
194
+ return path3.join(
199
195
  startDir,
200
196
  "generators",
201
197
  generatorDirName,
@@ -207,26 +203,21 @@ var TemplateUtility = class {
207
203
 
208
204
  // src/generators/base/component-generator.base.ts
209
205
  import {
206
+ GeneratorRuntime,
210
207
  hasHelperMethodCall,
211
- logger as singletonLogger4,
212
208
  toCamelCase,
213
209
  toKebabCase as toKebabCase2,
214
210
  validateFeaturePath as validateFeaturePath3
215
211
  } from "@ingenyus/swarm";
216
- import path7 from "path";
212
+ import path6 from "path";
217
213
 
218
214
  // src/generators/feature/feature-generator.ts
219
- import {
220
- handleFatalError as handleFatalError2,
221
- logger as singletonLogger3,
222
- validateFeaturePath as validateFeaturePath2
223
- } from "@ingenyus/swarm";
224
- import path6 from "path";
215
+ import { handleFatalError as handleFatalError2, validateFeaturePath as validateFeaturePath2 } from "@ingenyus/swarm";
216
+ import path5 from "path";
225
217
 
226
218
  // src/generators/base/wasp-generator.base.ts
227
219
  import {
228
220
  GeneratorBase,
229
- logger as singletonLogger2,
230
221
  SwarmConfigManager,
231
222
  TemplateResolver
232
223
  } from "@ingenyus/swarm";
@@ -237,14 +228,14 @@ import {
237
228
  parseHelperMethodDefinition,
238
229
  logger as singletonLogger
239
230
  } from "@ingenyus/swarm";
240
- import path5 from "path";
231
+ import path4 from "path";
241
232
  var WaspConfigGenerator = class {
242
233
  constructor(logger = singletonLogger, fileSystem = realFileSystem) {
243
234
  this.logger = logger;
244
235
  this.fileSystem = fileSystem;
245
236
  this.templateUtility = new TemplateUtility(fileSystem);
246
237
  }
247
- path = path5;
238
+ path = path4;
248
239
  templateUtility;
249
240
  /**
250
241
  * Gets the template path for feature config templates.
@@ -273,7 +264,7 @@ var WaspConfigGenerator = class {
273
264
  this.logger.error(`Template not found: ${templatePath}`);
274
265
  return;
275
266
  }
276
- const configFilePath = path5.join(featureDir, `feature.wasp.ts`);
267
+ const configFilePath = path4.join(featureDir, `feature.wasp.ts`);
277
268
  if (this.fileSystem.existsSync(configFilePath)) {
278
269
  this.logger.warn(`Feature config already exists: ${configFilePath}`);
279
270
  return;
@@ -289,7 +280,7 @@ var WaspConfigGenerator = class {
289
280
  */
290
281
  update(featurePath, declaration) {
291
282
  const configDir = getFeatureDir(this.fileSystem, featurePath);
292
- const configFilePath = path5.join(configDir, `feature.wasp.ts`);
283
+ const configFilePath = path4.join(configDir, `feature.wasp.ts`);
293
284
  if (!this.fileSystem.existsSync(configFilePath)) {
294
285
  const templatePath = this.getTemplatePath("feature.wasp.eta");
295
286
  if (!this.fileSystem.existsSync(templatePath)) {
@@ -669,14 +660,6 @@ var WaspConfigGenerator = class {
669
660
 
670
661
  // src/generators/base/wasp-generator.base.ts
671
662
  var WaspGeneratorBase = class extends GeneratorBase {
672
- constructor(fileSystem = realFileSystem, logger = singletonLogger2) {
673
- super(fileSystem, logger);
674
- this.fileSystem = fileSystem;
675
- this.logger = logger;
676
- this.configGenerator = new WaspConfigGenerator(logger, fileSystem);
677
- this.templateUtility = new TemplateUtility(fileSystem);
678
- this.templateResolver = new TemplateResolver(fileSystem);
679
- }
680
663
  configGenerator;
681
664
  templateUtility;
682
665
  templateResolver;
@@ -684,6 +667,15 @@ var WaspGeneratorBase = class extends GeneratorBase {
684
667
  configLoaded = false;
685
668
  // Plugin name from swarm.config.json
686
669
  pluginName = PLUGIN_NAME;
670
+ constructor() {
671
+ super();
672
+ this.configGenerator = new WaspConfigGenerator(
673
+ this.logger,
674
+ this.fileSystem
675
+ );
676
+ this.templateUtility = new TemplateUtility(this.fileSystem);
677
+ this.templateResolver = new TemplateResolver(this.fileSystem);
678
+ }
687
679
  async loadSwarmConfig() {
688
680
  if (this.configLoaded) return;
689
681
  const configManager = new SwarmConfigManager();
@@ -734,7 +726,7 @@ var WaspGeneratorBase = class extends GeneratorBase {
734
726
  }
735
727
  /**
736
728
  * Generic existence check with force flag handling
737
- * Consolidates the pattern used in both file and config checks
729
+ * Consolidates the pattern used in both file and config existence checks
738
730
  */
739
731
  checkExistence(exists, itemDescription, force, errorMessage) {
740
732
  if (exists && !force) {
@@ -774,16 +766,14 @@ var schema = z2.object({
774
766
 
775
767
  // src/generators/feature/feature-generator.ts
776
768
  var FeatureGenerator = class extends WaspGeneratorBase {
777
- constructor(logger = singletonLogger3, fileSystem = realFileSystem) {
778
- super(fileSystem, logger);
779
- this.logger = logger;
780
- this.fileSystem = fileSystem;
781
- this.name = "feature";
782
- this.description = "Generates a feature directory containing a Wasp configuration file";
783
- }
784
769
  name;
785
770
  description;
786
771
  schema = schema;
772
+ constructor() {
773
+ super();
774
+ this.name = "feature";
775
+ this.description = "Generates a feature directory containing a Wasp configuration file";
776
+ }
787
777
  getDefaultTemplatePath(templateName) {
788
778
  return this.templateUtility.resolveTemplatePath(
789
779
  templateName,
@@ -799,18 +789,18 @@ var FeatureGenerator = class extends WaspGeneratorBase {
799
789
  const { target } = args;
800
790
  const segments = validateFeaturePath2(target);
801
791
  const normalisedPath = normaliseFeaturePath(target);
802
- const sourceRoot = path6.join(findWaspRoot(this.fileSystem), "src");
792
+ const sourceRoot = path5.join(findWaspRoot(this.fileSystem), "src");
803
793
  if (segments.length > 1) {
804
794
  const parentPath = segments.slice(0, -1).join("/");
805
795
  const parentNormalisedPath = normaliseFeaturePath(parentPath);
806
- const parentFeatureDir = path6.join(sourceRoot, parentNormalisedPath);
796
+ const parentFeatureDir = path5.join(sourceRoot, parentNormalisedPath);
807
797
  if (!this.fileSystem.existsSync(parentFeatureDir)) {
808
798
  handleFatalError2(
809
799
  `Parent feature '${parentPath}' does not exist. Please create it first.`
810
800
  );
811
801
  }
812
802
  }
813
- const featureDir = path6.join(sourceRoot, normalisedPath);
803
+ const featureDir = path5.join(sourceRoot, normalisedPath);
814
804
  this.fileSystem.mkdirSync(featureDir, { recursive: true });
815
805
  this.configGenerator.generate(normalisedPath);
816
806
  this.logger.success(`Generated feature: ${normalisedPath}`);
@@ -819,13 +809,6 @@ var FeatureGenerator = class extends WaspGeneratorBase {
819
809
 
820
810
  // src/generators/base/component-generator.base.ts
821
811
  var ComponentGeneratorBase = class extends WaspGeneratorBase {
822
- constructor(logger = singletonLogger4, fileSystem = realFileSystem, featureDirectoryGenerator = new FeatureGenerator(logger, fileSystem)) {
823
- super(fileSystem, logger);
824
- this.logger = logger;
825
- this.fileSystem = fileSystem;
826
- this.featureDirectoryGenerator = featureDirectoryGenerator;
827
- this.featureDirectoryGenerator = featureDirectoryGenerator;
828
- }
829
812
  getDefaultTemplatePath(templateName) {
830
813
  return this.templateUtility.resolveTemplatePath(
831
814
  templateName,
@@ -833,6 +816,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
833
816
  import.meta.url
834
817
  );
835
818
  }
819
+ featureDirectoryGenerator;
820
+ constructor() {
821
+ super();
822
+ const runtime = GeneratorRuntime.current();
823
+ if (runtime.featureGeneratorFactory) {
824
+ const factoryResult = runtime.featureGeneratorFactory(runtime);
825
+ this.featureDirectoryGenerator = factoryResult;
826
+ } else {
827
+ this.featureDirectoryGenerator = new FeatureGenerator();
828
+ }
829
+ }
836
830
  get name() {
837
831
  return toKebabCase2(this.componentType);
838
832
  }
@@ -847,7 +841,7 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
847
841
  const currentPath = pathSegments.join("/");
848
842
  const featureName = pathSegments[pathSegments.length - 1];
849
843
  const featureDir = getFeatureDir(this.fileSystem, currentPath);
850
- const configPath = path7.join(featureDir, `feature.wasp.ts`);
844
+ const configPath = path6.join(featureDir, `feature.wasp.ts`);
851
845
  if (this.fileSystem.existsSync(configPath)) {
852
846
  return configPath;
853
847
  }
@@ -909,18 +903,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
909
903
  }
910
904
  /**
911
905
  * Gets the appropriate directory for a feature based on its path.
912
- * @param fileSystem - The filesystem abstraction
913
906
  * @param featurePath - The full feature path
914
907
  * @param type - The type of file being generated
915
908
  * @returns The target directory and import path
916
909
  */
917
- getFeatureTargetDir(fileSystem, featurePath, type) {
910
+ getFeatureTargetDir(featurePath, type) {
918
911
  validateFeaturePath3(featurePath);
919
912
  const normalisedPath = normaliseFeaturePath(featurePath);
920
- const featureDir = getFeatureDir(fileSystem, normalisedPath);
913
+ const featureDir = getFeatureDir(this.fileSystem, normalisedPath);
921
914
  const typeKey = type.toLowerCase();
922
915
  const typeDirectory = TYPE_DIRECTORIES[typeKey];
923
- const targetDirectory = path7.join(featureDir, typeDirectory);
916
+ const targetDirectory = path6.join(featureDir, typeDirectory);
924
917
  const importDirectory = `@src/${normalisedPath}/${typeDirectory}`;
925
918
  return { targetDirectory, importDirectory };
926
919
  }
@@ -929,7 +922,6 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
929
922
  */
930
923
  ensureTargetDirectory(featurePath, type) {
931
924
  const { targetDirectory, importDirectory } = this.getFeatureTargetDir(
932
- this.fileSystem,
933
925
  featurePath,
934
926
  type
935
927
  );
@@ -1040,7 +1032,7 @@ var ApiGenerator = class extends ComponentGeneratorBase {
1040
1032
  force = false,
1041
1033
  entities,
1042
1034
  method,
1043
- path: path8,
1035
+ path: path7,
1044
1036
  auth,
1045
1037
  customMiddleware
1046
1038
  } = args;
@@ -1050,7 +1042,7 @@ var ApiGenerator = class extends ComponentGeneratorBase {
1050
1042
  feature,
1051
1043
  Array.isArray(entities) ? entities : entities ? [entities] : [],
1052
1044
  method,
1053
- path8,
1045
+ path7,
1054
1046
  apiFile,
1055
1047
  auth,
1056
1048
  importPath,
@@ -92,16 +92,12 @@ function getFeatureImportPath(featurePath) {
92
92
  return segments.join("/");
93
93
  }
94
94
 
95
- // src/common/plugin.ts
96
- import path2 from "path";
97
- import { fileURLToPath } from "url";
98
-
99
95
  // src/common/prisma.ts
100
96
  import {
101
97
  getSchema
102
98
  } from "@mrleebo/prisma-ast";
103
99
  import fs2 from "fs";
104
- import path3 from "path";
100
+ import path2 from "path";
105
101
 
106
102
  // src/common/schemas.ts
107
103
  import { commandRegistry } from "@ingenyus/swarm";
@@ -158,7 +154,7 @@ var commonSchemas = {
158
154
  // src/common/templates.ts
159
155
  import { toKebabCase } from "@ingenyus/swarm";
160
156
  import { Eta } from "eta";
161
- import path4 from "path";
157
+ import path3 from "path";
162
158
  var TemplateUtility = class {
163
159
  constructor(fileSystem) {
164
160
  this.fileSystem = fileSystem;
@@ -166,14 +162,14 @@ var TemplateUtility = class {
166
162
  processTemplate(templatePath, replacements) {
167
163
  const declarations = Object.keys(replacements).map((key) => `${key}=it.${key}`).join(", ");
168
164
  const functionHeader = declarations ? `const ${declarations};` : void 0;
169
- const templateDir = path4.dirname(templatePath);
165
+ const templateDir = path3.dirname(templatePath);
170
166
  const eta = new Eta({
171
167
  autoTrim: false,
172
168
  autoEscape: false,
173
169
  views: templateDir,
174
170
  functionHeader
175
171
  });
176
- const templateName = path4.basename(templatePath).replace(/\.eta$/, "");
172
+ const templateName = path3.basename(templatePath).replace(/\.eta$/, "");
177
173
  if (this.fileSystem.existsSync(templatePath)) {
178
174
  return eta.render(templateName, replacements);
179
175
  } else {
@@ -191,11 +187,11 @@ var TemplateUtility = class {
191
187
  resolveTemplatePath(relativePath, generatorName, currentFileUrl) {
192
188
  const generatorDirName = toKebabCase(generatorName);
193
189
  const currentFilePath = new URL(currentFileUrl).pathname;
194
- const currentFileDir = path4.dirname(currentFilePath);
195
- const currentFileName = path4.basename(currentFilePath);
190
+ const currentFileDir = path3.dirname(currentFilePath);
191
+ const currentFileName = path3.basename(currentFilePath);
196
192
  const isInstalledPackage = currentFileDir.includes("node_modules") && currentFileDir.endsWith("/dist") && currentFileName === "index.js";
197
- const startDir = isInstalledPackage ? currentFileDir : path4.dirname(path4.dirname(currentFileDir));
198
- return path4.join(
193
+ const startDir = isInstalledPackage ? currentFileDir : path3.dirname(path3.dirname(currentFileDir));
194
+ return path3.join(
199
195
  startDir,
200
196
  "generators",
201
197
  generatorDirName,
@@ -207,26 +203,21 @@ var TemplateUtility = class {
207
203
 
208
204
  // src/generators/base/component-generator.base.ts
209
205
  import {
206
+ GeneratorRuntime,
210
207
  hasHelperMethodCall,
211
- logger as singletonLogger4,
212
208
  toCamelCase,
213
209
  toKebabCase as toKebabCase2,
214
210
  validateFeaturePath as validateFeaturePath3
215
211
  } from "@ingenyus/swarm";
216
- import path7 from "path";
212
+ import path6 from "path";
217
213
 
218
214
  // src/generators/feature/feature-generator.ts
219
- import {
220
- handleFatalError as handleFatalError2,
221
- logger as singletonLogger3,
222
- validateFeaturePath as validateFeaturePath2
223
- } from "@ingenyus/swarm";
224
- import path6 from "path";
215
+ import { handleFatalError as handleFatalError2, validateFeaturePath as validateFeaturePath2 } from "@ingenyus/swarm";
216
+ import path5 from "path";
225
217
 
226
218
  // src/generators/base/wasp-generator.base.ts
227
219
  import {
228
220
  GeneratorBase,
229
- logger as singletonLogger2,
230
221
  SwarmConfigManager,
231
222
  TemplateResolver
232
223
  } from "@ingenyus/swarm";
@@ -237,14 +228,14 @@ import {
237
228
  parseHelperMethodDefinition,
238
229
  logger as singletonLogger
239
230
  } from "@ingenyus/swarm";
240
- import path5 from "path";
231
+ import path4 from "path";
241
232
  var WaspConfigGenerator = class {
242
233
  constructor(logger = singletonLogger, fileSystem = realFileSystem) {
243
234
  this.logger = logger;
244
235
  this.fileSystem = fileSystem;
245
236
  this.templateUtility = new TemplateUtility(fileSystem);
246
237
  }
247
- path = path5;
238
+ path = path4;
248
239
  templateUtility;
249
240
  /**
250
241
  * Gets the template path for feature config templates.
@@ -273,7 +264,7 @@ var WaspConfigGenerator = class {
273
264
  this.logger.error(`Template not found: ${templatePath}`);
274
265
  return;
275
266
  }
276
- const configFilePath = path5.join(featureDir, `feature.wasp.ts`);
267
+ const configFilePath = path4.join(featureDir, `feature.wasp.ts`);
277
268
  if (this.fileSystem.existsSync(configFilePath)) {
278
269
  this.logger.warn(`Feature config already exists: ${configFilePath}`);
279
270
  return;
@@ -289,7 +280,7 @@ var WaspConfigGenerator = class {
289
280
  */
290
281
  update(featurePath, declaration) {
291
282
  const configDir = getFeatureDir(this.fileSystem, featurePath);
292
- const configFilePath = path5.join(configDir, `feature.wasp.ts`);
283
+ const configFilePath = path4.join(configDir, `feature.wasp.ts`);
293
284
  if (!this.fileSystem.existsSync(configFilePath)) {
294
285
  const templatePath = this.getTemplatePath("feature.wasp.eta");
295
286
  if (!this.fileSystem.existsSync(templatePath)) {
@@ -669,14 +660,6 @@ var WaspConfigGenerator = class {
669
660
 
670
661
  // src/generators/base/wasp-generator.base.ts
671
662
  var WaspGeneratorBase = class extends GeneratorBase {
672
- constructor(fileSystem = realFileSystem, logger = singletonLogger2) {
673
- super(fileSystem, logger);
674
- this.fileSystem = fileSystem;
675
- this.logger = logger;
676
- this.configGenerator = new WaspConfigGenerator(logger, fileSystem);
677
- this.templateUtility = new TemplateUtility(fileSystem);
678
- this.templateResolver = new TemplateResolver(fileSystem);
679
- }
680
663
  configGenerator;
681
664
  templateUtility;
682
665
  templateResolver;
@@ -684,6 +667,15 @@ var WaspGeneratorBase = class extends GeneratorBase {
684
667
  configLoaded = false;
685
668
  // Plugin name from swarm.config.json
686
669
  pluginName = PLUGIN_NAME;
670
+ constructor() {
671
+ super();
672
+ this.configGenerator = new WaspConfigGenerator(
673
+ this.logger,
674
+ this.fileSystem
675
+ );
676
+ this.templateUtility = new TemplateUtility(this.fileSystem);
677
+ this.templateResolver = new TemplateResolver(this.fileSystem);
678
+ }
687
679
  async loadSwarmConfig() {
688
680
  if (this.configLoaded) return;
689
681
  const configManager = new SwarmConfigManager();
@@ -734,7 +726,7 @@ var WaspGeneratorBase = class extends GeneratorBase {
734
726
  }
735
727
  /**
736
728
  * Generic existence check with force flag handling
737
- * Consolidates the pattern used in both file and config checks
729
+ * Consolidates the pattern used in both file and config existence checks
738
730
  */
739
731
  checkExistence(exists, itemDescription, force, errorMessage) {
740
732
  if (exists && !force) {
@@ -774,16 +766,14 @@ var schema = z2.object({
774
766
 
775
767
  // src/generators/feature/feature-generator.ts
776
768
  var FeatureGenerator = class extends WaspGeneratorBase {
777
- constructor(logger = singletonLogger3, fileSystem = realFileSystem) {
778
- super(fileSystem, logger);
779
- this.logger = logger;
780
- this.fileSystem = fileSystem;
781
- this.name = "feature";
782
- this.description = "Generates a feature directory containing a Wasp configuration file";
783
- }
784
769
  name;
785
770
  description;
786
771
  schema = schema;
772
+ constructor() {
773
+ super();
774
+ this.name = "feature";
775
+ this.description = "Generates a feature directory containing a Wasp configuration file";
776
+ }
787
777
  getDefaultTemplatePath(templateName) {
788
778
  return this.templateUtility.resolveTemplatePath(
789
779
  templateName,
@@ -799,18 +789,18 @@ var FeatureGenerator = class extends WaspGeneratorBase {
799
789
  const { target } = args;
800
790
  const segments = validateFeaturePath2(target);
801
791
  const normalisedPath = normaliseFeaturePath(target);
802
- const sourceRoot = path6.join(findWaspRoot(this.fileSystem), "src");
792
+ const sourceRoot = path5.join(findWaspRoot(this.fileSystem), "src");
803
793
  if (segments.length > 1) {
804
794
  const parentPath = segments.slice(0, -1).join("/");
805
795
  const parentNormalisedPath = normaliseFeaturePath(parentPath);
806
- const parentFeatureDir = path6.join(sourceRoot, parentNormalisedPath);
796
+ const parentFeatureDir = path5.join(sourceRoot, parentNormalisedPath);
807
797
  if (!this.fileSystem.existsSync(parentFeatureDir)) {
808
798
  handleFatalError2(
809
799
  `Parent feature '${parentPath}' does not exist. Please create it first.`
810
800
  );
811
801
  }
812
802
  }
813
- const featureDir = path6.join(sourceRoot, normalisedPath);
803
+ const featureDir = path5.join(sourceRoot, normalisedPath);
814
804
  this.fileSystem.mkdirSync(featureDir, { recursive: true });
815
805
  this.configGenerator.generate(normalisedPath);
816
806
  this.logger.success(`Generated feature: ${normalisedPath}`);
@@ -819,13 +809,6 @@ var FeatureGenerator = class extends WaspGeneratorBase {
819
809
 
820
810
  // src/generators/base/component-generator.base.ts
821
811
  var ComponentGeneratorBase = class extends WaspGeneratorBase {
822
- constructor(logger = singletonLogger4, fileSystem = realFileSystem, featureDirectoryGenerator = new FeatureGenerator(logger, fileSystem)) {
823
- super(fileSystem, logger);
824
- this.logger = logger;
825
- this.fileSystem = fileSystem;
826
- this.featureDirectoryGenerator = featureDirectoryGenerator;
827
- this.featureDirectoryGenerator = featureDirectoryGenerator;
828
- }
829
812
  getDefaultTemplatePath(templateName) {
830
813
  return this.templateUtility.resolveTemplatePath(
831
814
  templateName,
@@ -833,6 +816,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
833
816
  import.meta.url
834
817
  );
835
818
  }
819
+ featureDirectoryGenerator;
820
+ constructor() {
821
+ super();
822
+ const runtime = GeneratorRuntime.current();
823
+ if (runtime.featureGeneratorFactory) {
824
+ const factoryResult = runtime.featureGeneratorFactory(runtime);
825
+ this.featureDirectoryGenerator = factoryResult;
826
+ } else {
827
+ this.featureDirectoryGenerator = new FeatureGenerator();
828
+ }
829
+ }
836
830
  get name() {
837
831
  return toKebabCase2(this.componentType);
838
832
  }
@@ -847,7 +841,7 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
847
841
  const currentPath = pathSegments.join("/");
848
842
  const featureName = pathSegments[pathSegments.length - 1];
849
843
  const featureDir = getFeatureDir(this.fileSystem, currentPath);
850
- const configPath = path7.join(featureDir, `feature.wasp.ts`);
844
+ const configPath = path6.join(featureDir, `feature.wasp.ts`);
851
845
  if (this.fileSystem.existsSync(configPath)) {
852
846
  return configPath;
853
847
  }
@@ -909,18 +903,17 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
909
903
  }
910
904
  /**
911
905
  * Gets the appropriate directory for a feature based on its path.
912
- * @param fileSystem - The filesystem abstraction
913
906
  * @param featurePath - The full feature path
914
907
  * @param type - The type of file being generated
915
908
  * @returns The target directory and import path
916
909
  */
917
- getFeatureTargetDir(fileSystem, featurePath, type) {
910
+ getFeatureTargetDir(featurePath, type) {
918
911
  validateFeaturePath3(featurePath);
919
912
  const normalisedPath = normaliseFeaturePath(featurePath);
920
- const featureDir = getFeatureDir(fileSystem, normalisedPath);
913
+ const featureDir = getFeatureDir(this.fileSystem, normalisedPath);
921
914
  const typeKey = type.toLowerCase();
922
915
  const typeDirectory = TYPE_DIRECTORIES[typeKey];
923
- const targetDirectory = path7.join(featureDir, typeDirectory);
916
+ const targetDirectory = path6.join(featureDir, typeDirectory);
924
917
  const importDirectory = `@src/${normalisedPath}/${typeDirectory}`;
925
918
  return { targetDirectory, importDirectory };
926
919
  }
@@ -929,7 +922,6 @@ var ComponentGeneratorBase = class extends WaspGeneratorBase {
929
922
  */
930
923
  ensureTargetDirectory(featurePath, type) {
931
924
  const { targetDirectory, importDirectory } = this.getFeatureTargetDir(
932
- this.fileSystem,
933
925
  featurePath,
934
926
  type
935
927
  );
@@ -1040,7 +1032,7 @@ var ApiGenerator = class extends ComponentGeneratorBase {
1040
1032
  force = false,
1041
1033
  entities,
1042
1034
  method,
1043
- path: path8,
1035
+ path: path7,
1044
1036
  auth,
1045
1037
  customMiddleware
1046
1038
  } = args;
@@ -1050,7 +1042,7 @@ var ApiGenerator = class extends ComponentGeneratorBase {
1050
1042
  feature,
1051
1043
  Array.isArray(entities) ? entities : entities ? [entities] : [],
1052
1044
  method,
1053
- path8,
1045
+ path7,
1054
1046
  apiFile,
1055
1047
  auth,
1056
1048
  importPath,
@@ -26,16 +26,12 @@ var realFileSystem = {
26
26
  statSync: fs.statSync
27
27
  };
28
28
 
29
- // src/common/plugin.ts
30
- import path from "path";
31
- import { fileURLToPath } from "url";
32
-
33
29
  // src/common/prisma.ts
34
30
  import {
35
31
  getSchema
36
32
  } from "@mrleebo/prisma-ast";
37
33
  import fs2 from "fs";
38
- import path2 from "path";
34
+ import path from "path";
39
35
 
40
36
  // src/common/schemas.ts
41
37
  import { commandRegistry } from "@ingenyus/swarm";