@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
@@ -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
  );
@@ -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
  );
@@ -24,16 +24,12 @@ var realFileSystem = {
24
24
  statSync: fs.statSync
25
25
  };
26
26
 
27
- // src/common/plugin.ts
28
- import path from "path";
29
- import { fileURLToPath } from "url";
30
-
31
27
  // src/common/prisma.ts
32
28
  import {
33
29
  getSchema
34
30
  } from "@mrleebo/prisma-ast";
35
31
  import fs2 from "fs";
36
- import path2 from "path";
32
+ import path from "path";
37
33
 
38
34
  // src/common/schemas.ts
39
35
  import { commandRegistry } from "@ingenyus/swarm";