@solid-stack/mason 1.0.33 → 1.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs CHANGED
@@ -4,8 +4,8 @@
4
4
  var cac = require('cac');
5
5
  var p19 = require('@clack/prompts');
6
6
  var pc13 = require('picocolors');
7
- var fs14 = require('fs');
8
- var path2 = require('path');
7
+ var fs17 = require('fs');
8
+ var path26 = require('path');
9
9
  var url = require('url');
10
10
  var Handlebars = require('handlebars');
11
11
  var child_process = require('child_process');
@@ -34,14 +34,14 @@ function _interopNamespace(e) {
34
34
 
35
35
  var p19__namespace = /*#__PURE__*/_interopNamespace(p19);
36
36
  var pc13__default = /*#__PURE__*/_interopDefault(pc13);
37
- var fs14__default = /*#__PURE__*/_interopDefault(fs14);
38
- var path2__default = /*#__PURE__*/_interopDefault(path2);
37
+ var fs17__default = /*#__PURE__*/_interopDefault(fs17);
38
+ var path26__default = /*#__PURE__*/_interopDefault(path26);
39
39
  var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
40
40
 
41
41
  function writeFileSafely(absolutePath, content, options = {}) {
42
42
  const projectRoot = options.projectRoot || process.cwd();
43
- const relPath = path2__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
44
- const existedBefore = fs14__default.default.existsSync(absolutePath);
43
+ const relPath = path26__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
44
+ const existedBefore = fs17__default.default.existsSync(absolutePath);
45
45
  if (options.dryRun) {
46
46
  return {
47
47
  relativePath: relPath,
@@ -60,11 +60,11 @@ function writeFileSafely(absolutePath, content, options = {}) {
60
60
  existedBefore: true
61
61
  };
62
62
  }
63
- const dir = path2__default.default.dirname(absolutePath);
64
- if (!fs14__default.default.existsSync(dir)) {
65
- fs14__default.default.mkdirSync(dir, { recursive: true });
63
+ const dir = path26__default.default.dirname(absolutePath);
64
+ if (!fs17__default.default.existsSync(dir)) {
65
+ fs17__default.default.mkdirSync(dir, { recursive: true });
66
66
  }
67
- fs14__default.default.writeFileSync(absolutePath, content, "utf-8");
67
+ fs17__default.default.writeFileSync(absolutePath, content, "utf-8");
68
68
  return {
69
69
  relativePath: relPath,
70
70
  absolutePath,
@@ -155,17 +155,17 @@ function toStubName(ifaceName) {
155
155
  return `Stub${base}`;
156
156
  }
157
157
  function loadMasonConfig(startDir = process.cwd()) {
158
- let current = path2__default.default.resolve(startDir);
158
+ let current = path26__default.default.resolve(startDir);
159
159
  while (true) {
160
- const configPath = path2__default.default.join(current, "mason.config.json");
161
- if (fs14__default.default.existsSync(configPath)) {
160
+ const configPath = path26__default.default.join(current, "mason.config.json");
161
+ if (fs17__default.default.existsSync(configPath)) {
162
162
  try {
163
- return JSON.parse(fs14__default.default.readFileSync(configPath, "utf-8"));
163
+ return JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
164
164
  } catch {
165
165
  return null;
166
166
  }
167
167
  }
168
- const parent = path2__default.default.dirname(current);
168
+ const parent = path26__default.default.dirname(current);
169
169
  if (parent === current) break;
170
170
  current = parent;
171
171
  }
@@ -175,70 +175,60 @@ function getEffectiveMode(projectRoot, flags) {
175
175
  if (flags?.registry) return "registry";
176
176
  const config = loadMasonConfig(projectRoot);
177
177
  if (config?.mode) return config.mode;
178
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "index.json")) && (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "features")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "shared")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared")))) {
178
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "index.json")) && (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "features")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "shared")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared")))) {
179
179
  return "registry";
180
180
  }
181
181
  return "app";
182
182
  }
183
183
  function getConfiguredFeaturesDir(projectRoot, flags) {
184
- if (flags?.target) return path2__default.default.resolve(projectRoot, flags.target);
185
- if (flags?.dest) return path2__default.default.resolve(projectRoot, flags.dest);
184
+ if (flags?.target) return path26__default.default.resolve(projectRoot, flags.target);
185
+ if (flags?.dest) return path26__default.default.resolve(projectRoot, flags.dest);
186
186
  const config = loadMasonConfig(projectRoot);
187
187
  if (config?.paths?.features) {
188
- return path2__default.default.resolve(projectRoot, config.paths.features);
188
+ return path26__default.default.resolve(projectRoot, config.paths.features);
189
189
  }
190
190
  const mode = getEffectiveMode(projectRoot, flags);
191
191
  if (mode === "registry") {
192
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
193
- return path2__default.default.join(projectRoot, "src/features");
192
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features"))) {
193
+ return path26__default.default.join(projectRoot, "src/features");
194
194
  }
195
- return path2__default.default.join(projectRoot, "features");
195
+ return path26__default.default.join(projectRoot, "features");
196
196
  }
197
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
198
- return path2__default.default.join(projectRoot, "src/features");
197
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features"))) {
198
+ return path26__default.default.join(projectRoot, "src/features");
199
199
  }
200
- return path2__default.default.join(projectRoot, "features");
200
+ return path26__default.default.join(projectRoot, "features");
201
201
  }
202
202
  function getConfiguredSharedDir(projectRoot, flags) {
203
- if (flags?.target) return path2__default.default.resolve(projectRoot, flags.target);
204
- if (flags?.dest) return path2__default.default.resolve(projectRoot, flags.dest);
203
+ if (flags?.target) return path26__default.default.resolve(projectRoot, flags.target);
204
+ if (flags?.dest) return path26__default.default.resolve(projectRoot, flags.dest);
205
205
  const config = loadMasonConfig(projectRoot);
206
206
  if (config?.paths?.shared) {
207
- return path2__default.default.resolve(projectRoot, config.paths.shared);
207
+ return path26__default.default.resolve(projectRoot, config.paths.shared);
208
208
  }
209
209
  const mode = getEffectiveMode(projectRoot, flags);
210
210
  if (mode === "registry") {
211
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
212
- return path2__default.default.join(projectRoot, "src/shared");
211
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared"))) {
212
+ return path26__default.default.join(projectRoot, "src/shared");
213
213
  }
214
- return path2__default.default.join(projectRoot, "shared");
214
+ return path26__default.default.join(projectRoot, "shared");
215
215
  }
216
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
217
- return path2__default.default.join(projectRoot, "src/shared");
216
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared"))) {
217
+ return path26__default.default.join(projectRoot, "src/shared");
218
218
  }
219
- return path2__default.default.join(projectRoot, "shared");
220
- }
221
- function loadLintConfig(projectRoot) {
222
- const configPath = path2__default.default.join(projectRoot, "mason-lint.config.json");
223
- if (fs14__default.default.existsSync(configPath)) {
224
- try {
225
- return JSON.parse(fs14__default.default.readFileSync(configPath, "utf-8"));
226
- } catch {
227
- }
228
- }
229
- return { baseErrorPath: "src/errors/AppError.ts" };
219
+ return path26__default.default.join(projectRoot, "shared");
230
220
  }
231
221
 
232
222
  // src/utils/project.ts
233
223
  function findProjectRoot(startDir = process.cwd()) {
234
- let current = path2__default.default.resolve(startDir);
224
+ let current = path26__default.default.resolve(startDir);
235
225
  while (true) {
236
- if (fs14__default.default.existsSync(path2__default.default.join(current, "package.json"))) {
226
+ if (fs17__default.default.existsSync(path26__default.default.join(current, "package.json"))) {
237
227
  return current;
238
228
  }
239
- const parent = path2__default.default.dirname(current);
229
+ const parent = path26__default.default.dirname(current);
240
230
  if (parent === current) {
241
- return path2__default.default.resolve(startDir);
231
+ return path26__default.default.resolve(startDir);
242
232
  }
243
233
  current = parent;
244
234
  }
@@ -251,9 +241,9 @@ function resolveSharedDir(projectRoot, flags) {
251
241
  }
252
242
  function listExistingFeatures(projectRoot) {
253
243
  const featuresDir = resolveFeaturesDir(projectRoot);
254
- if (!fs14__default.default.existsSync(featuresDir)) return [];
244
+ if (!fs17__default.default.existsSync(featuresDir)) return [];
255
245
  try {
256
- const entries = fs14__default.default.readdirSync(featuresDir, { withFileTypes: true });
246
+ const entries = fs17__default.default.readdirSync(featuresDir, { withFileTypes: true });
257
247
  return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
258
248
  } catch {
259
249
  return [];
@@ -263,14 +253,14 @@ function listDomainInterfaces(projectRoot, featureName) {
263
253
  const results = [];
264
254
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
265
255
  for (const feat of features) {
266
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
267
- if (!fs14__default.default.existsSync(domainDir)) continue;
256
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
257
+ if (!fs17__default.default.existsSync(domainDir)) continue;
268
258
  try {
269
- const files = fs14__default.default.readdirSync(domainDir);
259
+ const files = fs17__default.default.readdirSync(domainDir);
270
260
  for (const file of files) {
271
261
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
272
262
  const name = file.replace(/\.ts$/, "");
273
- const fullPath = path2__default.default.join(domainDir, file);
263
+ const fullPath = path26__default.default.join(domainDir, file);
274
264
  if (/^I[A-Z]/.test(name)) {
275
265
  results.push({
276
266
  name,
@@ -279,7 +269,7 @@ function listDomainInterfaces(projectRoot, featureName) {
279
269
  });
280
270
  } else {
281
271
  try {
282
- const content = fs14__default.default.readFileSync(fullPath, "utf-8");
272
+ const content = fs17__default.default.readFileSync(fullPath, "utf-8");
283
273
  if (/export\s+(?:abstract\s+class|interface)\s+(\w+)/.test(content)) {
284
274
  results.push({
285
275
  name,
@@ -301,17 +291,17 @@ function listDomainEntities(projectRoot, featureName) {
301
291
  const results = [];
302
292
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
303
293
  for (const feat of features) {
304
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
305
- if (!fs14__default.default.existsSync(domainDir)) continue;
294
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
295
+ if (!fs17__default.default.existsSync(domainDir)) continue;
306
296
  try {
307
- const files = fs14__default.default.readdirSync(domainDir);
297
+ const files = fs17__default.default.readdirSync(domainDir);
308
298
  for (const file of files) {
309
299
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
310
300
  const name = file.replace(/\.ts$/, "");
311
301
  if (!/^I[A-Z]/.test(name)) {
312
302
  results.push({
313
303
  name,
314
- fullPath: path2__default.default.join(domainDir, file),
304
+ fullPath: path26__default.default.join(domainDir, file),
315
305
  feature: feat
316
306
  });
317
307
  }
@@ -326,16 +316,16 @@ function listUseCases(projectRoot, featureName) {
326
316
  const results = [];
327
317
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
328
318
  for (const feat of features) {
329
- const useCasesDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
330
- if (!fs14__default.default.existsSync(useCasesDir)) continue;
319
+ const useCasesDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
320
+ if (!fs17__default.default.existsSync(useCasesDir)) continue;
331
321
  try {
332
- const files = fs14__default.default.readdirSync(useCasesDir);
322
+ const files = fs17__default.default.readdirSync(useCasesDir);
333
323
  for (const file of files) {
334
324
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
335
325
  const name = file.replace(/\.ts$/, "");
336
326
  results.push({
337
327
  name,
338
- fullPath: path2__default.default.join(useCasesDir, file),
328
+ fullPath: path26__default.default.join(useCasesDir, file),
339
329
  feature: feat
340
330
  });
341
331
  }
@@ -361,33 +351,33 @@ hbs.registerHelper("join", (arr, sep) => {
361
351
  });
362
352
  var cachedTemplatesDir = null;
363
353
  function getTemplatesDir() {
364
- if (cachedTemplatesDir && fs14__default.default.existsSync(cachedTemplatesDir)) {
354
+ if (cachedTemplatesDir && fs17__default.default.existsSync(cachedTemplatesDir)) {
365
355
  return cachedTemplatesDir;
366
356
  }
367
- const currentDir = typeof __dirname !== "undefined" ? __dirname : path2__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bin.cjs', document.baseURI).href))));
368
- const cand1 = path2__default.default.resolve(currentDir, "../../templates");
369
- if (fs14__default.default.existsSync(cand1)) {
357
+ const currentDir = typeof __dirname !== "undefined" ? __dirname : path26__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bin.cjs', document.baseURI).href))));
358
+ const cand1 = path26__default.default.resolve(currentDir, "../../templates");
359
+ if (fs17__default.default.existsSync(cand1)) {
370
360
  cachedTemplatesDir = cand1;
371
361
  return cand1;
372
362
  }
373
- const cand2 = path2__default.default.resolve(currentDir, "../templates");
374
- if (fs14__default.default.existsSync(cand2)) {
363
+ const cand2 = path26__default.default.resolve(currentDir, "../templates");
364
+ if (fs17__default.default.existsSync(cand2)) {
375
365
  cachedTemplatesDir = cand2;
376
366
  return cand2;
377
367
  }
378
- const cand3 = path2__default.default.resolve(currentDir, "templates");
379
- if (fs14__default.default.existsSync(cand3)) {
368
+ const cand3 = path26__default.default.resolve(currentDir, "templates");
369
+ if (fs17__default.default.existsSync(cand3)) {
380
370
  cachedTemplatesDir = cand3;
381
371
  return cand3;
382
372
  }
383
373
  let curr = currentDir;
384
374
  while (true) {
385
- const candTemplates = path2__default.default.join(curr, "templates");
386
- if (fs14__default.default.existsSync(candTemplates)) {
375
+ const candTemplates = path26__default.default.join(curr, "templates");
376
+ if (fs17__default.default.existsSync(candTemplates)) {
387
377
  cachedTemplatesDir = candTemplates;
388
378
  return candTemplates;
389
379
  }
390
- const parent = path2__default.default.dirname(curr);
380
+ const parent = path26__default.default.dirname(curr);
391
381
  if (parent === curr) break;
392
382
  curr = parent;
393
383
  }
@@ -395,8 +385,8 @@ function getTemplatesDir() {
395
385
  }
396
386
  var templateCache = /* @__PURE__ */ new Map();
397
387
  function loadTemplate(relativePath) {
398
- const fullPath = path2__default.default.isAbsolute(relativePath) ? relativePath : path2__default.default.join(getTemplatesDir(), relativePath);
399
- return fs14__default.default.readFileSync(fullPath, "utf-8");
388
+ const fullPath = path26__default.default.isAbsolute(relativePath) ? relativePath : path26__default.default.join(getTemplatesDir(), relativePath);
389
+ return fs17__default.default.readFileSync(fullPath, "utf-8");
400
390
  }
401
391
  function renderTemplateFile(relativePath, context) {
402
392
  let compiled = templateCache.get(relativePath);
@@ -483,8 +473,8 @@ function generateDomainEntityCode(name, kind = "interface", properties = []) {
483
473
  function generateDomain(options) {
484
474
  const projectRoot = options.projectRoot || findProjectRoot();
485
475
  const entityName = toPascalCase(options.name);
486
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
487
- const filePath = path2__default.default.join(targetDir, `${entityName}.ts`);
476
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
477
+ const filePath = path26__default.default.join(targetDir, `${entityName}.ts`);
488
478
  const code = generateDomainEntityCode(
489
479
  entityName,
490
480
  options.kind || "interface",
@@ -533,8 +523,8 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
533
523
  function generateInterface(options) {
534
524
  const projectRoot = options.projectRoot || findProjectRoot();
535
525
  const ifaceName = ensureInterfacePrefix(options.name);
536
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
537
- const filePath = path2__default.default.join(targetDir, `${ifaceName}.ts`);
526
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
527
+ const filePath = path26__default.default.join(targetDir, `${ifaceName}.ts`);
538
528
  const code = generateInterfaceCode(
539
529
  ifaceName,
540
530
  options.kind || "abstractClass",
@@ -769,7 +759,7 @@ function parseInterfaceMethodsAndImports(content, targetIfaceName) {
769
759
  };
770
760
  }
771
761
  function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
772
- if (customPath && fs14__default.default.existsSync(customPath)) {
762
+ if (customPath && fs17__default.default.existsSync(customPath)) {
773
763
  return { filePath: customPath, ifaceName };
774
764
  }
775
765
  const candidateNames = [
@@ -779,22 +769,22 @@ function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
779
769
  ];
780
770
  const features = featureName ? [featureName, ...listExistingFeatures(projectRoot).filter((f) => f !== featureName)] : listExistingFeatures(projectRoot);
781
771
  for (const feat of features) {
782
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
783
- if (!fs14__default.default.existsSync(domainDir)) continue;
772
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
773
+ if (!fs17__default.default.existsSync(domainDir)) continue;
784
774
  for (const cand of candidateNames) {
785
- const p1 = path2__default.default.join(domainDir, `${cand}.ts`);
786
- if (fs14__default.default.existsSync(p1)) {
775
+ const p1 = path26__default.default.join(domainDir, `${cand}.ts`);
776
+ if (fs17__default.default.existsSync(p1)) {
787
777
  return { filePath: p1, ifaceName: cand, feature: feat };
788
778
  }
789
779
  }
790
780
  }
791
781
  for (const cand of candidateNames) {
792
- const p1 = path2__default.default.join(projectRoot, "domain", `${cand}.ts`);
793
- if (fs14__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
794
- const p22 = path2__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
795
- if (fs14__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
796
- const p32 = path2__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
797
- if (fs14__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
782
+ const p1 = path26__default.default.join(projectRoot, "domain", `${cand}.ts`);
783
+ if (fs17__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
784
+ const p22 = path26__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
785
+ if (fs17__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
786
+ const p32 = path26__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
787
+ if (fs17__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
798
788
  }
799
789
  return null;
800
790
  }
@@ -817,7 +807,7 @@ function loadInterfaceHierarchy(projectRoot, initialIfaceName, featureName, cust
817
807
  while (currentFile && !visited.has(currentFile)) {
818
808
  visited.add(currentFile);
819
809
  try {
820
- const content = fs14__default.default.readFileSync(currentFile, "utf-8");
810
+ const content = fs17__default.default.readFileSync(currentFile, "utf-8");
821
811
  const parsed = parseInterfaceMethodsAndImports(content, currentName);
822
812
  for (const m of parsed.methods) {
823
813
  if (!allMethods.some((existing) => existing.name === m.name)) {
@@ -893,7 +883,7 @@ function generateStubCode(stubClassName, ifaceName, entityName, featureName, met
893
883
  const entitiesVar = `${entityVar}s`;
894
884
  const idKey = `${entityVar}Id`;
895
885
  const impPath = ifaceImportPath || `../domain/${ifaceName}.js`;
896
- const entityImportPath = ifaceImportPath ? `${path2__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
886
+ const entityImportPath = ifaceImportPath ? `${path26__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
897
887
  const importsByFrom = /* @__PURE__ */ new Map();
898
888
  for (const imp of domainImports) {
899
889
  if (imp.name === ifaceName || imp.name === baseEntity) continue;
@@ -942,7 +932,7 @@ function generateConcreteInfraCode(className, ifaceName, dependencies = [], meth
942
932
  if (baseEntity) {
943
933
  finalMethods = synthesizeCrudMethods(baseEntity);
944
934
  if (!finalDomainImports.some((imp) => imp.name === baseEntity)) {
945
- const importPath = ifaceImportPath ? `${path2__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
935
+ const importPath = ifaceImportPath ? `${path26__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
946
936
  finalDomainImports.push({
947
937
  name: baseEntity,
948
938
  from: importPath,
@@ -987,8 +977,8 @@ function generateInfrastructure(options) {
987
977
  const projectRoot = options.projectRoot || findProjectRoot();
988
978
  const className = toPascalCase(options.name);
989
979
  const isFeatureScope = options.scope !== "global" && Boolean(options.feature);
990
- const targetDir = options.targetDir || (isFeatureScope ? path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path2__default.default.join(projectRoot, "infrastructure"));
991
- const filePath = path2__default.default.join(targetDir, `${className}.ts`);
980
+ const targetDir = options.targetDir || (isFeatureScope ? path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path26__default.default.join(projectRoot, "infrastructure"));
981
+ const filePath = path26__default.default.join(targetDir, `${className}.ts`);
992
982
  let code;
993
983
  if (options.implementsInterface) {
994
984
  const rawIfaceName = options.implementsInterface;
@@ -1002,7 +992,7 @@ function generateInfrastructure(options) {
1002
992
  const ifaceFilePath = hierarchy.ifaceFilePath;
1003
993
  let ifaceImportPath;
1004
994
  if (ifaceFilePath) {
1005
- let rel = path2__default.default.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
995
+ let rel = path26__default.default.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
1006
996
  if (!rel.startsWith(".")) rel = "./" + rel;
1007
997
  ifaceImportPath = rel;
1008
998
  } else if (isFeatureScope) {
@@ -1015,8 +1005,8 @@ function generateInfrastructure(options) {
1015
1005
  if (new RegExp(`\\b${item.name}\\b`).test(allSignatures)) {
1016
1006
  let fromPath;
1017
1007
  if (imp.specifier.startsWith(".") && ifaceFilePath) {
1018
- const absTarget = path2__default.default.resolve(path2__default.default.dirname(ifaceFilePath), imp.specifier);
1019
- let rel = path2__default.default.relative(targetDir, absTarget).replace(/\\/g, "/");
1008
+ const absTarget = path26__default.default.resolve(path26__default.default.dirname(ifaceFilePath), imp.specifier);
1009
+ let rel = path26__default.default.relative(targetDir, absTarget).replace(/\\/g, "/");
1020
1010
  if (!rel.startsWith(".")) rel = "./" + rel;
1021
1011
  fromPath = rel;
1022
1012
  } else {
@@ -1203,8 +1193,8 @@ function generateUseCase(options) {
1203
1193
  const files = [];
1204
1194
  const projectRoot = options.projectRoot || findProjectRoot();
1205
1195
  const ucName = toPascalCase(options.name);
1206
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1207
- const filePath = path2__default.default.join(targetDir, `${ucName}.ts`);
1196
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1197
+ const filePath = path26__default.default.join(targetDir, `${ucName}.ts`);
1208
1198
  const code = generateUseCaseCode(
1209
1199
  ucName,
1210
1200
  options.dependencies || [],
@@ -1220,7 +1210,7 @@ function generateUseCase(options) {
1220
1210
  })
1221
1211
  );
1222
1212
  if (options.includeTest) {
1223
- const testPath = path2__default.default.join(targetDir, `${ucName}.test.ts`);
1213
+ const testPath = path26__default.default.join(targetDir, `${ucName}.test.ts`);
1224
1214
  const testCode = generateUseCaseTestCode(ucName, options.dependencies || []);
1225
1215
  files.push(
1226
1216
  writeFileSafely(testPath, testCode, {
@@ -1288,10 +1278,10 @@ function generateHttpHandler(options) {
1288
1278
  const files = [];
1289
1279
  const projectRoot = options.projectRoot || findProjectRoot();
1290
1280
  const className = toPascalCase(options.name);
1291
- const pxDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1292
- const handlersDir = path2__default.default.join(pxDir, "handlers");
1293
- const pxIndexPath = path2__default.default.join(pxDir, "index.ts");
1294
- if (!fs14__default.default.existsSync(pxIndexPath)) {
1281
+ const pxDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1282
+ const handlersDir = path26__default.default.join(pxDir, "handlers");
1283
+ const pxIndexPath = path26__default.default.join(pxDir, "index.ts");
1284
+ if (!fs17__default.default.existsSync(pxIndexPath)) {
1295
1285
  const featurePath = options.routePrefix || `/${options.feature.toLowerCase()}`;
1296
1286
  const pxIndexContent = renderTemplate(expressIndexTemplate, {
1297
1287
  routePath: featurePath
@@ -1304,7 +1294,7 @@ function generateHttpHandler(options) {
1304
1294
  })
1305
1295
  );
1306
1296
  }
1307
- const handlerFilePath = path2__default.default.join(handlersDir, `${className}.ts`);
1297
+ const handlerFilePath = path26__default.default.join(handlersDir, `${className}.ts`);
1308
1298
  const code = generateHttpHandlerCode(
1309
1299
  className,
1310
1300
  options.method || "get",
@@ -1325,11 +1315,11 @@ function generateHttpHandler(options) {
1325
1315
  return files;
1326
1316
  }
1327
1317
  function updateOrGenerateDiProvider(featureDir, featureName, bindings = [], options = {}) {
1328
- const providerPath = path2__default.default.join(featureDir, "diProvider.ts");
1318
+ const providerPath = path26__default.default.join(featureDir, "diProvider.ts");
1329
1319
  const pascalFeature = toPascalCase(featureName);
1330
1320
  const providerModuleName = `${pascalFeature}Provider`;
1331
- if (fs14__default.default.existsSync(providerPath) && !options.overwrite) {
1332
- let content = fs14__default.default.readFileSync(providerPath, "utf-8");
1321
+ if (fs17__default.default.existsSync(providerPath) && !options.overwrite) {
1322
+ let content = fs17__default.default.readFileSync(providerPath, "utf-8");
1333
1323
  content = content.replace(/\n*export\s+const\s+ScaffoldProvider\s*=[^;]+;?/g, "");
1334
1324
  for (const b of bindings) {
1335
1325
  const ifaceImp = b.ifaceImportPath || `./domain/${b.ifaceName}.js`;
@@ -1388,7 +1378,7 @@ function generateFeature(options) {
1388
1378
  const projectRoot = options.projectRoot || findProjectRoot();
1389
1379
  const rawName = options.name.trim();
1390
1380
  const featureName = toCamelCase(rawName);
1391
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), featureName);
1381
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), featureName);
1392
1382
  const routePath = options.routePath || `/${featureName}`;
1393
1383
  const rawEntities = [];
1394
1384
  if (options.entityNames && options.entityNames.length > 0) {
@@ -1409,7 +1399,7 @@ function generateFeature(options) {
1409
1399
  const domainFile = generateDomain({
1410
1400
  name: ent,
1411
1401
  feature: featureName,
1412
- targetDir: path2__default.default.join(targetDir, "domain"),
1402
+ targetDir: path26__default.default.join(targetDir, "domain"),
1413
1403
  projectRoot,
1414
1404
  dryRun: options.dryRun,
1415
1405
  overwrite: options.overwrite,
@@ -1429,7 +1419,7 @@ function generateFeature(options) {
1429
1419
  const ifaceFile = generateInterface({
1430
1420
  name: ifaceName,
1431
1421
  feature: featureName,
1432
- targetDir: path2__default.default.join(targetDir, "domain"),
1422
+ targetDir: path26__default.default.join(targetDir, "domain"),
1433
1423
  entityName: ent,
1434
1424
  projectRoot,
1435
1425
  dryRun: options.dryRun,
@@ -1446,7 +1436,7 @@ function generateFeature(options) {
1446
1436
  const stubFile = generateInfrastructure({
1447
1437
  name: stubName,
1448
1438
  feature: featureName,
1449
- targetDir: path2__default.default.join(targetDir, "infrastructure"),
1439
+ targetDir: path26__default.default.join(targetDir, "infrastructure"),
1450
1440
  kind: "stub",
1451
1441
  implementsInterface: ifaceName,
1452
1442
  entityName: ent,
@@ -1488,7 +1478,7 @@ function generateFeature(options) {
1488
1478
  const ucFiles = generateUseCase({
1489
1479
  name: ucName,
1490
1480
  feature: featureName,
1491
- targetDir: path2__default.default.join(targetDir, "useCases"),
1481
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1492
1482
  dependencies: options.includeInterface !== false ? [ifaceName] : [],
1493
1483
  inputProperties: [{ name: idParam, type: "string" }],
1494
1484
  outputProperties: [{ name: entVar, type: primaryEntity }],
@@ -1533,7 +1523,7 @@ function generateFeature(options) {
1533
1523
  const ucFiles = generateUseCase({
1534
1524
  name: ucName,
1535
1525
  feature: featureName,
1536
- targetDir: path2__default.default.join(targetDir, "useCases"),
1526
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1537
1527
  dependencies: deps,
1538
1528
  inputProperties: [{ name: entVar, type: ent }],
1539
1529
  outputProperties: [{ name: entVar, type: ent }],
@@ -1566,7 +1556,7 @@ function generateFeature(options) {
1566
1556
  const ucFiles = generateUseCase({
1567
1557
  name: ucName,
1568
1558
  feature: featureName,
1569
- targetDir: path2__default.default.join(targetDir, "useCases"),
1559
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1570
1560
  dependencies: deps,
1571
1561
  inputProperties: [{ name: idParam, type: "string" }],
1572
1562
  outputProperties: [{ name: entVar, type: ent }],
@@ -1599,7 +1589,7 @@ function generateFeature(options) {
1599
1589
  const ucFiles = generateUseCase({
1600
1590
  name: ucName,
1601
1591
  feature: featureName,
1602
- targetDir: path2__default.default.join(targetDir, "useCases"),
1592
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1603
1593
  dependencies: deps,
1604
1594
  inputProperties: [
1605
1595
  { name: "page", type: "number", optional: true },
@@ -1643,7 +1633,7 @@ function generateFeature(options) {
1643
1633
  const ucFiles = generateUseCase({
1644
1634
  name: ucName,
1645
1635
  feature: featureName,
1646
- targetDir: path2__default.default.join(targetDir, "useCases"),
1636
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1647
1637
  dependencies: deps,
1648
1638
  inputProperties: [{ name: entVar, type: ent }],
1649
1639
  outputProperties: [{ name: entVar, type: ent }],
@@ -1676,7 +1666,7 @@ function generateFeature(options) {
1676
1666
  const ucFiles = generateUseCase({
1677
1667
  name: ucName,
1678
1668
  feature: featureName,
1679
- targetDir: path2__default.default.join(targetDir, "useCases"),
1669
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1680
1670
  dependencies: deps,
1681
1671
  inputProperties: [{ name: idParam, type: "string" }],
1682
1672
  outputProperties: [{ name: "success", type: "boolean" }],
@@ -1713,7 +1703,7 @@ function generateFeature(options) {
1713
1703
  const ucFiles = generateUseCase({
1714
1704
  name: ucName,
1715
1705
  feature: featureName,
1716
- targetDir: path2__default.default.join(targetDir, "useCases"),
1706
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1717
1707
  dependencies: customUc.dependencies || [],
1718
1708
  inputProperties: customUc.inputProperties || [],
1719
1709
  outputProperties: customUc.outputProperties || [],
@@ -1745,8 +1735,8 @@ function generateFeature(options) {
1745
1735
  }
1746
1736
  }
1747
1737
  if (options.includeExpress !== false) {
1748
- const pxDir = path2__default.default.join(targetDir, "pxExpress");
1749
- const pxIndexPath = path2__default.default.join(pxDir, "index.ts");
1738
+ const pxDir = path26__default.default.join(targetDir, "pxExpress");
1739
+ const pxIndexPath = path26__default.default.join(pxDir, "index.ts");
1750
1740
  if (!files.some((f) => f.absolutePath === pxIndexPath)) {
1751
1741
  const pxIndexContent = renderTemplate(expressIndexTemplate, { routePath });
1752
1742
  files.push(
@@ -1876,7 +1866,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1876
1866
  }
1877
1867
  const normalizedName = toCamelCase(name);
1878
1868
  const baseFeaturesDir = resolveFeaturesDir(projectRoot, flags);
1879
- const defaultDir = path2__default.default.relative(projectRoot, path2__default.default.join(baseFeaturesDir, normalizedName));
1869
+ const defaultDir = path26__default.default.relative(projectRoot, path26__default.default.join(baseFeaturesDir, normalizedName));
1880
1870
  let targetDirRel = defaultDir;
1881
1871
  if (!flags.yes && !flags.target && !flags.dest) {
1882
1872
  targetDirRel = handleCancel(
@@ -1887,7 +1877,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1887
1877
  })
1888
1878
  ).trim();
1889
1879
  }
1890
- const targetDir = flags.dest ? path2__default.default.resolve(projectRoot, flags.dest) : flags.target ? path2__default.default.resolve(projectRoot, flags.target) : path2__default.default.resolve(projectRoot, targetDirRel);
1880
+ const targetDir = flags.dest ? path26__default.default.resolve(projectRoot, flags.dest) : flags.target ? path26__default.default.resolve(projectRoot, flags.target) : path26__default.default.resolve(projectRoot, targetDirRel);
1891
1881
  let includeExpress = flags.express !== void 0 ? Boolean(flags.express) : true;
1892
1882
  let routePath = `/${normalizedName}`;
1893
1883
  let includeDomain = true;
@@ -2129,8 +2119,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2129
2119
  };
2130
2120
  const files = generateFeature(options);
2131
2121
  if (isRegistry) {
2132
- const registryPath = path2__default.default.join(targetDir, "registry.json");
2133
- if (!fs14__default.default.existsSync(registryPath)) {
2122
+ const registryPath = path26__default.default.join(targetDir, "registry.json");
2123
+ if (!fs17__default.default.existsSync(registryPath)) {
2134
2124
  const manifest = {
2135
2125
  name: toKebabCase(normalizedName),
2136
2126
  type: "feature",
@@ -2156,7 +2146,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2156
2146
  printGeneratedFiles(files, options.dryRun);
2157
2147
  p19__namespace.outro(
2158
2148
  pc13__default.default.green(
2159
- `\u2713 Feature '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2149
+ `\u2713 Feature '${normalizedName}' initialized in ${path26__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2160
2150
  )
2161
2151
  );
2162
2152
  }
@@ -2167,7 +2157,7 @@ function generateShared(options) {
2167
2157
  const pascalName = toPascalCase(rawName);
2168
2158
  const camelName = toCamelCase(rawName);
2169
2159
  const kebabName = toKebabCase(rawName);
2170
- const targetDir = options.targetDir || path2__default.default.join(resolveSharedDir(projectRoot), kebabName);
2160
+ const targetDir = options.targetDir || path26__default.default.join(resolveSharedDir(projectRoot), kebabName);
2171
2161
  const fileDefs = [];
2172
2162
  const facadeContent = `import { MakeInjectable, type DepsType } from "@solid-stack/di";
2173
2163
  import { I${pascalName}Engine } from "./ports/I${pascalName}Engine.js";
@@ -2179,7 +2169,7 @@ export class ${pascalName} {
2179
2169
  }
2180
2170
  `;
2181
2171
  fileDefs.push({
2182
- absolutePath: path2__default.default.join(targetDir, `${pascalName}.ts`),
2172
+ absolutePath: path26__default.default.join(targetDir, `${pascalName}.ts`),
2183
2173
  content: facadeContent
2184
2174
  });
2185
2175
  const portContent = `export abstract class I${pascalName}Engine {
@@ -2187,7 +2177,7 @@ export class ${pascalName} {
2187
2177
  }
2188
2178
  `;
2189
2179
  fileDefs.push({
2190
- absolutePath: path2__default.default.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2180
+ absolutePath: path26__default.default.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2191
2181
  content: portContent
2192
2182
  });
2193
2183
  const concreteContent = `import { MakeInjectable } from "@solid-stack/di";
@@ -2199,7 +2189,7 @@ export class Default${pascalName}Engine implements I${pascalName}Engine {
2199
2189
  }
2200
2190
  `;
2201
2191
  fileDefs.push({
2202
- absolutePath: path2__default.default.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2192
+ absolutePath: path26__default.default.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2203
2193
  content: concreteContent
2204
2194
  });
2205
2195
  if (options.includeStub !== false) {
@@ -2212,7 +2202,7 @@ export class Stub${pascalName}Engine implements I${pascalName}Engine {
2212
2202
  }
2213
2203
  `;
2214
2204
  fileDefs.push({
2215
- absolutePath: path2__default.default.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2205
+ absolutePath: path26__default.default.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2216
2206
  content: stubContent
2217
2207
  });
2218
2208
  }
@@ -2227,7 +2217,7 @@ export const diProvider = (c: Container): void => {
2227
2217
  export default diProvider;
2228
2218
  `;
2229
2219
  fileDefs.push({
2230
- absolutePath: path2__default.default.join(targetDir, "diProvider.ts"),
2220
+ absolutePath: path26__default.default.join(targetDir, "diProvider.ts"),
2231
2221
  content: providerContent
2232
2222
  });
2233
2223
  if (options.isRegistry) {
@@ -2244,7 +2234,7 @@ export default diProvider;
2244
2234
  files: []
2245
2235
  };
2246
2236
  fileDefs.push({
2247
- absolutePath: path2__default.default.join(targetDir, "registry.json"),
2237
+ absolutePath: path26__default.default.join(targetDir, "registry.json"),
2248
2238
  content: JSON.stringify(registryManifest, null, 2) + "\n"
2249
2239
  });
2250
2240
  }
@@ -2281,7 +2271,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2281
2271
  }
2282
2272
  const normalizedName = toKebabCase(name);
2283
2273
  const baseSharedDir = resolveSharedDir(projectRoot, flags);
2284
- const defaultDir = path2__default.default.relative(projectRoot, path2__default.default.join(baseSharedDir, normalizedName));
2274
+ const defaultDir = path26__default.default.relative(projectRoot, path26__default.default.join(baseSharedDir, normalizedName));
2285
2275
  let targetDirRel = defaultDir;
2286
2276
  if (!flags.yes && !flags.target && !flags.dest) {
2287
2277
  targetDirRel = handleCancel(
@@ -2292,7 +2282,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2292
2282
  })
2293
2283
  ).trim();
2294
2284
  }
2295
- const targetDir = flags.dest ? path2__default.default.resolve(projectRoot, flags.dest) : flags.target ? path2__default.default.resolve(projectRoot, flags.target) : path2__default.default.resolve(projectRoot, targetDirRel);
2285
+ const targetDir = flags.dest ? path26__default.default.resolve(projectRoot, flags.dest) : flags.target ? path26__default.default.resolve(projectRoot, flags.target) : path26__default.default.resolve(projectRoot, targetDirRel);
2296
2286
  let description = flags.description || "";
2297
2287
  let includeStub = true;
2298
2288
  if (!flags.yes) {
@@ -2326,7 +2316,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2326
2316
  printGeneratedFiles(files, Boolean(flags.dryRun));
2327
2317
  p19__namespace.outro(
2328
2318
  pc13__default.default.green(
2329
- `\u2713 Shared module '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2319
+ `\u2713 Shared module '${normalizedName}' initialized in ${path26__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2330
2320
  )
2331
2321
  );
2332
2322
  }
@@ -2753,7 +2743,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2753
2743
  const infraFile = generateInfrastructure(options);
2754
2744
  files.push(infraFile);
2755
2745
  if (registerInProvider && scope === "feature" && feature && implementsInterface) {
2756
- const featureDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feature);
2746
+ const featureDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feature);
2757
2747
  const providerFile = updateOrGenerateDiProvider(
2758
2748
  featureDir,
2759
2749
  feature,
@@ -2915,7 +2905,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2915
2905
  files.push(stubFile);
2916
2906
  }
2917
2907
  if (registerInProvider && generateStub) {
2918
- const featureDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feature);
2908
+ const featureDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feature);
2919
2909
  const providerFile = updateOrGenerateDiProvider(
2920
2910
  featureDir,
2921
2911
  feature,
@@ -3103,21 +3093,21 @@ function generateInjectable(options) {
3103
3093
  const className = toPascalCase(options.name);
3104
3094
  let targetDir = "";
3105
3095
  if (options.customPath) {
3106
- targetDir = path2__default.default.isAbsolute(options.customPath) ? options.customPath : path2__default.default.join(projectRoot, options.customPath);
3096
+ targetDir = path26__default.default.isAbsolute(options.customPath) ? options.customPath : path26__default.default.join(projectRoot, options.customPath);
3107
3097
  } else if (options.location === "feature-service" && options.feature) {
3108
- targetDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3098
+ targetDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3109
3099
  } else if (options.location === "feature-transformer" && options.feature) {
3110
- targetDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3100
+ targetDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3111
3101
  } else if (options.location === "module") {
3112
- targetDir = path2__default.default.join(projectRoot, "modules", className);
3102
+ targetDir = path26__default.default.join(projectRoot, "modules", className);
3113
3103
  } else {
3114
- targetDir = options.feature ? path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path2__default.default.join(projectRoot, "shared", className.toLowerCase());
3104
+ targetDir = options.feature ? path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path26__default.default.join(projectRoot, "shared", className.toLowerCase());
3115
3105
  }
3116
- const filePath = path2__default.default.join(targetDir, `${className}.ts`);
3106
+ const filePath = path26__default.default.join(targetDir, `${className}.ts`);
3117
3107
  let ifaceName;
3118
3108
  if (options.generateInterface) {
3119
3109
  ifaceName = `I${className}`;
3120
- const ifacePath = path2__default.default.join(targetDir, `${ifaceName}.ts`);
3110
+ const ifacePath = path26__default.default.join(targetDir, `${ifaceName}.ts`);
3121
3111
  const ifaceContent = renderTemplate(injectableInterfaceTemplate, { ifaceName });
3122
3112
  files.push(
3123
3113
  writeFileSafely(ifacePath, ifaceContent, {
@@ -3246,7 +3236,7 @@ async function runEnvInit(flags = {}) {
3246
3236
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3247
3237
  const s = p19__namespace.spinner();
3248
3238
  s.start("Scanning for .example environment files...");
3249
- const files = fs14__default.default.readdirSync(projectRoot);
3239
+ const files = fs17__default.default.readdirSync(projectRoot);
3250
3240
  const exampleFiles = files.filter((file) => file.startsWith(".env") && file.endsWith(".example")).sort();
3251
3241
  if (exampleFiles.length === 0) {
3252
3242
  s.stop("No .example files found.");
@@ -3256,11 +3246,11 @@ async function runEnvInit(flags = {}) {
3256
3246
  s.message(`Found ${exampleFiles.length} template(s). Generating...`);
3257
3247
  const generatedFiles = [];
3258
3248
  for (const exampleFile of exampleFiles) {
3259
- const sourcePath = path2__default.default.join(projectRoot, exampleFile);
3249
+ const sourcePath = path26__default.default.join(projectRoot, exampleFile);
3260
3250
  const targetFile = exampleFile.replace(/\.example$/, "");
3261
- const targetPath = path2__default.default.join(projectRoot, targetFile);
3251
+ const targetPath = path26__default.default.join(projectRoot, targetFile);
3262
3252
  let overwrite = flags.overwrite;
3263
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs14__default.default.existsSync(targetPath)) {
3253
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17__default.default.existsSync(targetPath)) {
3264
3254
  overwrite = await p19__namespace.confirm({
3265
3255
  message: `${targetFile} already exists. Overwrite?`,
3266
3256
  initialValue: false
@@ -3270,7 +3260,7 @@ async function runEnvInit(flags = {}) {
3270
3260
  process.exit(0);
3271
3261
  }
3272
3262
  }
3273
- const content = fs14__default.default.readFileSync(sourcePath, "utf-8");
3263
+ const content = fs17__default.default.readFileSync(sourcePath, "utf-8");
3274
3264
  const genFile = writeFileSafely(targetPath, content, {
3275
3265
  projectRoot,
3276
3266
  dryRun: Boolean(flags.dryRun),
@@ -3288,7 +3278,7 @@ var EnvEditor = class {
3288
3278
  filePath;
3289
3279
  constructor(filePath) {
3290
3280
  this.filePath = filePath;
3291
- this.lines = fs14__default.default.existsSync(filePath) ? fs14__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3281
+ this.lines = fs17__default.default.existsSync(filePath) ? fs17__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3292
3282
  }
3293
3283
  getLines() {
3294
3284
  return [...this.lines];
@@ -3352,18 +3342,18 @@ var EnvEditor = class {
3352
3342
  });
3353
3343
  }
3354
3344
  save() {
3355
- const dir = path2__default.default.dirname(this.filePath);
3356
- if (!fs14__default.default.existsSync(dir)) {
3357
- fs14__default.default.mkdirSync(dir, { recursive: true });
3345
+ const dir = path26__default.default.dirname(this.filePath);
3346
+ if (!fs17__default.default.existsSync(dir)) {
3347
+ fs17__default.default.mkdirSync(dir, { recursive: true });
3358
3348
  }
3359
- fs14__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3349
+ fs17__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3360
3350
  }
3361
3351
  };
3362
3352
  function discoverEnvironments(projectRoot) {
3363
- if (!fs14__default.default.existsSync(projectRoot)) {
3353
+ if (!fs17__default.default.existsSync(projectRoot)) {
3364
3354
  return ["local", "dev", "prod"];
3365
3355
  }
3366
- const files = fs14__default.default.readdirSync(projectRoot);
3356
+ const files = fs17__default.default.readdirSync(projectRoot);
3367
3357
  const envs = /* @__PURE__ */ new Set();
3368
3358
  for (const file of files) {
3369
3359
  if (file.startsWith(".env")) {
@@ -3388,7 +3378,7 @@ async function runEnvInitExamples(flags = {}) {
3388
3378
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3389
3379
  const s = p19__namespace.spinner();
3390
3380
  s.start("Scanning for local environment files...");
3391
- const files = fs14__default.default.readdirSync(projectRoot, { withFileTypes: true });
3381
+ const files = fs17__default.default.readdirSync(projectRoot, { withFileTypes: true });
3392
3382
  const envFiles = files.filter((dirent) => dirent.isFile() && dirent.name.startsWith(".env") && !dirent.name.endsWith(".example")).map((dirent) => dirent.name).sort();
3393
3383
  if (envFiles.length === 0) {
3394
3384
  s.stop("No local .env files found.");
@@ -3398,11 +3388,11 @@ async function runEnvInitExamples(flags = {}) {
3398
3388
  s.message(`Found ${envFiles.length} local .env file(s). Generating templates...`);
3399
3389
  const generatedFiles = [];
3400
3390
  for (const envFile of envFiles) {
3401
- const sourcePath = path2__default.default.join(projectRoot, envFile);
3391
+ const sourcePath = path26__default.default.join(projectRoot, envFile);
3402
3392
  const targetFile = `${envFile}.example`;
3403
- const targetPath = path2__default.default.join(projectRoot, targetFile);
3393
+ const targetPath = path26__default.default.join(projectRoot, targetFile);
3404
3394
  let overwrite = flags.overwrite;
3405
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs14__default.default.existsSync(targetPath)) {
3395
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17__default.default.existsSync(targetPath)) {
3406
3396
  overwrite = await p19__namespace.confirm({
3407
3397
  message: `${targetFile} already exists. Overwrite with redacted values?`,
3408
3398
  initialValue: true
@@ -3435,12 +3425,12 @@ function isInteractive(flags) {
3435
3425
  function getAllExistingKeys(projectRoot, envs) {
3436
3426
  const keys = /* @__PURE__ */ new Set();
3437
3427
  for (const env of envs) {
3438
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3439
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3440
- if (fs14__default.default.existsSync(localPath)) {
3428
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3429
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3430
+ if (fs17__default.default.existsSync(localPath)) {
3441
3431
  new EnvEditor(localPath).getKeys().forEach((k) => keys.add(k));
3442
3432
  }
3443
- if (fs14__default.default.existsSync(examplePath)) {
3433
+ if (fs17__default.default.existsSync(examplePath)) {
3444
3434
  new EnvEditor(examplePath).getKeys().forEach((k) => keys.add(k));
3445
3435
  }
3446
3436
  }
@@ -3512,8 +3502,8 @@ async function runEnvAdd(key, value, flags = {}) {
3512
3502
  })
3513
3503
  );
3514
3504
  }
3515
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3516
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3505
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3506
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3517
3507
  if (flags.dryRun) {
3518
3508
  p19__namespace.log.info(
3519
3509
  pc13__default.default.cyan(`[DRY RUN] Would set ${targetKey}=${envVal} in ${resolveEnvFilename(env, false)}`)
@@ -3560,8 +3550,8 @@ async function runEnvUpdate(key, value, flags = {}) {
3560
3550
  );
3561
3551
  }
3562
3552
  const envsWithKey = allEnvs.filter((env) => {
3563
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3564
- return fs14__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3553
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3554
+ return fs17__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3565
3555
  });
3566
3556
  let targetEnvs = [];
3567
3557
  if (flags.env) {
@@ -3587,7 +3577,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3587
3577
  return { key: targetKey, environments: [] };
3588
3578
  }
3589
3579
  for (const env of targetEnvs) {
3590
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3580
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3591
3581
  const localEditor = new EnvEditor(localPath);
3592
3582
  const currentVal = localEditor.getValue(targetKey);
3593
3583
  let newVal = value;
@@ -3617,7 +3607,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3617
3607
  } else {
3618
3608
  localEditor.set(targetKey, newVal);
3619
3609
  localEditor.save();
3620
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3610
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3621
3611
  const exampleEditor = new EnvEditor(examplePath);
3622
3612
  if (!exampleEditor.has(targetKey)) {
3623
3613
  exampleEditor.set(targetKey, "");
@@ -3653,9 +3643,9 @@ async function runEnvDelete(key, flags = {}) {
3653
3643
  );
3654
3644
  }
3655
3645
  const envsWithKey = allEnvs.filter((env) => {
3656
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3657
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3658
- return fs14__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs14__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3646
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3647
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3648
+ return fs17__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs17__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3659
3649
  });
3660
3650
  let targetEnvs = [];
3661
3651
  if (flags.env) {
@@ -3693,19 +3683,19 @@ async function runEnvDelete(key, flags = {}) {
3693
3683
  }
3694
3684
  }
3695
3685
  for (const env of targetEnvs) {
3696
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3697
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3686
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3687
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3698
3688
  if (flags.dryRun) {
3699
3689
  p19__namespace.log.info(
3700
3690
  pc13__default.default.cyan(`[DRY RUN] Would delete ${targetKey} from ${resolveEnvFilename(env, false)} and ${resolveEnvFilename(env, true)}`)
3701
3691
  );
3702
3692
  } else {
3703
- if (fs14__default.default.existsSync(localPath)) {
3693
+ if (fs17__default.default.existsSync(localPath)) {
3704
3694
  const localEditor = new EnvEditor(localPath);
3705
3695
  localEditor.delete(targetKey);
3706
3696
  localEditor.save();
3707
3697
  }
3708
- if (fs14__default.default.existsSync(examplePath)) {
3698
+ if (fs17__default.default.existsSync(examplePath)) {
3709
3699
  const exampleEditor = new EnvEditor(examplePath);
3710
3700
  exampleEditor.delete(targetKey);
3711
3701
  exampleEditor.save();
@@ -3730,10 +3720,10 @@ async function runEnvAudit(flags = {}) {
3730
3720
  for (const env of envs) {
3731
3721
  const localFile = resolveEnvFilename(env, false);
3732
3722
  const exampleFile = resolveEnvFilename(env, true);
3733
- const localPath = path2__default.default.join(projectRoot, localFile);
3734
- const examplePath = path2__default.default.join(projectRoot, exampleFile);
3735
- const localExists = fs14__default.default.existsSync(localPath);
3736
- const exampleExists = fs14__default.default.existsSync(examplePath);
3723
+ const localPath = path26__default.default.join(projectRoot, localFile);
3724
+ const examplePath = path26__default.default.join(projectRoot, exampleFile);
3725
+ const localExists = fs17__default.default.existsSync(localPath);
3726
+ const exampleExists = fs17__default.default.existsSync(examplePath);
3737
3727
  const localEditor = new EnvEditor(localPath);
3738
3728
  const exampleEditor = new EnvEditor(examplePath);
3739
3729
  const localKeys = localExists ? localEditor.getKeys() : [];
@@ -4060,25 +4050,25 @@ function normalizeRegistryUrl(urlOrPath, baseDir) {
4060
4050
  return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`;
4061
4051
  }
4062
4052
  if (baseDir && (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed === "." || trimmed === "..")) {
4063
- return path2__default.default.resolve(baseDir, trimmed);
4053
+ return path26__default.default.resolve(baseDir, trimmed);
4064
4054
  }
4065
4055
  return trimmed;
4066
4056
  }
4067
4057
  function findLocalRegistry(startDir = process.cwd()) {
4068
- let current = path2__default.default.resolve(startDir);
4058
+ let current = path26__default.default.resolve(startDir);
4069
4059
  while (true) {
4070
- const candidate = path2__default.default.join(current, "mason-registry");
4071
- if (fs14__default.default.existsSync(candidate) && fs14__default.default.existsSync(path2__default.default.join(candidate, "index.json"))) {
4060
+ const candidate = path26__default.default.join(current, "mason-registry");
4061
+ if (fs17__default.default.existsSync(candidate) && fs17__default.default.existsSync(path26__default.default.join(candidate, "index.json"))) {
4072
4062
  return candidate;
4073
4063
  }
4074
- const parent = path2__default.default.dirname(current);
4064
+ const parent = path26__default.default.dirname(current);
4075
4065
  if (parent === current) break;
4076
4066
  current = parent;
4077
4067
  }
4078
4068
  return null;
4079
4069
  }
4080
4070
  function getRegistryBase(projectRoot, override) {
4081
- const rootDir = projectRoot ? path2__default.default.resolve(projectRoot) : process.cwd();
4071
+ const rootDir = projectRoot ? path26__default.default.resolve(projectRoot) : process.cwd();
4082
4072
  if (override && override.trim()) {
4083
4073
  return normalizeRegistryUrl(override.trim(), rootDir);
4084
4074
  }
@@ -4086,30 +4076,30 @@ function getRegistryBase(projectRoot, override) {
4086
4076
  return normalizeRegistryUrl(process.env.MASON_REGISTRY_URL.trim(), rootDir);
4087
4077
  }
4088
4078
  const configLocations = [
4089
- path2__default.default.join(rootDir, "mason.config.json"),
4090
- path2__default.default.join(process.cwd(), "mason.config.json")
4079
+ path26__default.default.join(rootDir, "mason.config.json"),
4080
+ path26__default.default.join(process.cwd(), "mason.config.json")
4091
4081
  ];
4092
4082
  for (const configPath of configLocations) {
4093
- if (fs14__default.default.existsSync(configPath)) {
4083
+ if (fs17__default.default.existsSync(configPath)) {
4094
4084
  try {
4095
- const config = JSON.parse(fs14__default.default.readFileSync(configPath, "utf-8"));
4085
+ const config = JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
4096
4086
  if (config.registry && typeof config.registry === "string") {
4097
- return normalizeRegistryUrl(config.registry.trim(), path2__default.default.dirname(configPath));
4087
+ return normalizeRegistryUrl(config.registry.trim(), path26__default.default.dirname(configPath));
4098
4088
  }
4099
4089
  } catch {
4100
4090
  }
4101
4091
  }
4102
4092
  }
4103
4093
  const pkgLocations = [
4104
- path2__default.default.join(rootDir, "package.json"),
4105
- path2__default.default.join(process.cwd(), "package.json")
4094
+ path26__default.default.join(rootDir, "package.json"),
4095
+ path26__default.default.join(process.cwd(), "package.json")
4106
4096
  ];
4107
4097
  for (const pkgPath of pkgLocations) {
4108
- if (fs14__default.default.existsSync(pkgPath)) {
4098
+ if (fs17__default.default.existsSync(pkgPath)) {
4109
4099
  try {
4110
- const pkg = JSON.parse(fs14__default.default.readFileSync(pkgPath, "utf-8"));
4100
+ const pkg = JSON.parse(fs17__default.default.readFileSync(pkgPath, "utf-8"));
4111
4101
  if (pkg.mason?.registry && typeof pkg.mason.registry === "string") {
4112
- return normalizeRegistryUrl(pkg.mason.registry.trim(), path2__default.default.dirname(pkgPath));
4102
+ return normalizeRegistryUrl(pkg.mason.registry.trim(), path26__default.default.dirname(pkgPath));
4113
4103
  }
4114
4104
  } catch {
4115
4105
  }
@@ -4157,16 +4147,16 @@ async function fetchRegistryFile(registryBase, relPath) {
4157
4147
  if (baseDir.startsWith("file://")) {
4158
4148
  baseDir = url.fileURLToPath(baseDir);
4159
4149
  }
4160
- let filePath = path2__default.default.resolve(baseDir, cleanRelPath);
4161
- if (!fs14__default.default.existsSync(filePath)) {
4162
- const inSrcPath = path2__default.default.resolve(baseDir, "src", cleanRelPath);
4163
- if (fs14__default.default.existsSync(inSrcPath)) {
4150
+ let filePath = path26__default.default.resolve(baseDir, cleanRelPath);
4151
+ if (!fs17__default.default.existsSync(filePath)) {
4152
+ const inSrcPath = path26__default.default.resolve(baseDir, "src", cleanRelPath);
4153
+ if (fs17__default.default.existsSync(inSrcPath)) {
4164
4154
  filePath = inSrcPath;
4165
4155
  } else {
4166
4156
  throw new Error(`Registry file not found at ${filePath}`);
4167
4157
  }
4168
4158
  }
4169
- return fs14__default.default.promises.readFile(filePath, "utf-8");
4159
+ return fs17__default.default.promises.readFile(filePath, "utf-8");
4170
4160
  }
4171
4161
  async function fetchRegistryIndex(registryBase) {
4172
4162
  const content = await fetchRegistryFile(registryBase, "index.json");
@@ -4228,19 +4218,19 @@ function findClosestMatch(target, candidates) {
4228
4218
  return null;
4229
4219
  }
4230
4220
  function detectPackageManager(projectRoot) {
4231
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
4232
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
4233
- if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lockb")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lock"))) return "bun";
4221
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
4222
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
4223
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "bun.lockb")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "bun.lock"))) return "bun";
4234
4224
  return "npm";
4235
4225
  }
4236
4226
  function getMissingNpmPackages(projectRoot, requiredPackages) {
4237
4227
  if (!requiredPackages || requiredPackages.length === 0) return [];
4238
- const pkgJsonPath = path2__default.default.join(projectRoot, "package.json");
4239
- if (!fs14__default.default.existsSync(pkgJsonPath)) {
4228
+ const pkgJsonPath = path26__default.default.join(projectRoot, "package.json");
4229
+ if (!fs17__default.default.existsSync(pkgJsonPath)) {
4240
4230
  return requiredPackages;
4241
4231
  }
4242
4232
  try {
4243
- const pkg = JSON.parse(fs14__default.default.readFileSync(pkgJsonPath, "utf-8"));
4233
+ const pkg = JSON.parse(fs17__default.default.readFileSync(pkgJsonPath, "utf-8"));
4244
4234
  const installed = /* @__PURE__ */ new Set([
4245
4235
  ...Object.keys(pkg.dependencies || {}),
4246
4236
  ...Object.keys(pkg.devDependencies || {}),
@@ -4279,12 +4269,12 @@ function installNpmPackages(projectRoot, packages, pm) {
4279
4269
  });
4280
4270
  }
4281
4271
  function getAllFiles(dir, baseDir = dir) {
4282
- if (!fs14__default.default.existsSync(dir)) return [];
4283
- const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
4272
+ if (!fs17__default.default.existsSync(dir)) return [];
4273
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
4284
4274
  const files = [];
4285
4275
  for (const entry of entries) {
4286
- const fullPath = path2__default.default.join(dir, entry.name);
4287
- const relPath = path2__default.default.relative(baseDir, fullPath).replace(/\\/g, "/");
4276
+ const fullPath = path26__default.default.join(dir, entry.name);
4277
+ const relPath = path26__default.default.relative(baseDir, fullPath).replace(/\\/g, "/");
4288
4278
  if (entry.isDirectory()) {
4289
4279
  if (entry.name === "__tests__" || entry.name.startsWith(".")) {
4290
4280
  continue;
@@ -4300,13 +4290,13 @@ function getAllFiles(dir, baseDir = dir) {
4300
4290
  return files.sort();
4301
4291
  }
4302
4292
  function computeDirectoryHash(dirPath, files) {
4303
- if (!fs14__default.default.existsSync(dirPath)) return "";
4293
+ if (!fs17__default.default.existsSync(dirPath)) return "";
4304
4294
  const hash = crypto.createHash("sha256");
4305
4295
  const fileList = (getAllFiles(dirPath)).sort();
4306
4296
  for (const relativePath of fileList) {
4307
- const absolutePath = path2__default.default.join(dirPath, relativePath);
4308
- if (!fs14__default.default.existsSync(absolutePath)) continue;
4309
- const content = fs14__default.default.readFileSync(absolutePath, "utf8");
4297
+ const absolutePath = path26__default.default.join(dirPath, relativePath);
4298
+ if (!fs17__default.default.existsSync(absolutePath)) continue;
4299
+ const content = fs17__default.default.readFileSync(absolutePath, "utf8");
4310
4300
  const normalizedContent = content.replace(/\r\n/g, "\n");
4311
4301
  hash.update(relativePath);
4312
4302
  hash.update(normalizedContent);
@@ -4344,17 +4334,17 @@ function getModuleBaseDir(projectRoot, modType) {
4344
4334
  return modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4345
4335
  }
4346
4336
  const folder = modType === "shared" ? "shared" : "features";
4347
- return path2__default.default.join(projectRoot, "src", folder);
4337
+ return path26__default.default.join(projectRoot, "src", folder);
4348
4338
  }
4349
4339
  function getExistingModuleDir(projectRoot, modType, modName) {
4350
4340
  const folder = modType === "shared" ? "shared" : "features";
4351
4341
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4352
- const inConfigured = path2__default.default.join(configuredDir, modName);
4353
- if (fs14__default.default.existsSync(inConfigured)) return inConfigured;
4354
- const inSrc = path2__default.default.join(projectRoot, "src", folder, modName);
4355
- if (fs14__default.default.existsSync(inSrc)) return inSrc;
4356
- const inRoot = path2__default.default.join(projectRoot, folder, modName);
4357
- if (fs14__default.default.existsSync(inRoot)) return inRoot;
4342
+ const inConfigured = path26__default.default.join(configuredDir, modName);
4343
+ if (fs17__default.default.existsSync(inConfigured)) return inConfigured;
4344
+ const inSrc = path26__default.default.join(projectRoot, "src", folder, modName);
4345
+ if (fs17__default.default.existsSync(inSrc)) return inSrc;
4346
+ const inRoot = path26__default.default.join(projectRoot, folder, modName);
4347
+ if (fs17__default.default.existsSync(inRoot)) return inRoot;
4358
4348
  return null;
4359
4349
  }
4360
4350
  function checkModuleExists(projectRoot, modType, modName) {
@@ -4365,14 +4355,14 @@ function getAvailableLocalModules(projectRoot, modType) {
4365
4355
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4366
4356
  const dirs = [
4367
4357
  configuredDir,
4368
- path2__default.default.join(projectRoot, "src", folder),
4369
- path2__default.default.join(projectRoot, folder)
4358
+ path26__default.default.join(projectRoot, "src", folder),
4359
+ path26__default.default.join(projectRoot, folder)
4370
4360
  ];
4371
4361
  const set = /* @__PURE__ */ new Set();
4372
4362
  for (const dir of dirs) {
4373
- if (fs14__default.default.existsSync(dir)) {
4363
+ if (fs17__default.default.existsSync(dir)) {
4374
4364
  try {
4375
- const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
4365
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
4376
4366
  for (const e of entries) {
4377
4367
  if (e.isDirectory() && !e.name.startsWith(".")) {
4378
4368
  set.add(e.name);
@@ -4574,7 +4564,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4574
4564
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticAlias}/`);
4575
4565
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
4576
4566
  const baseDir = getModuleBaseDir(projectRoot, modType);
4577
- const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, programmaticAlias));
4567
+ const displayDest = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, programmaticAlias));
4578
4568
  p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4579
4569
  resolutions.set(key, {
4580
4570
  type: modType,
@@ -4762,7 +4752,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4762
4752
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${newName}/`);
4763
4753
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${newName}`);
4764
4754
  const baseDir = getModuleBaseDir(projectRoot, modType);
4765
- const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, newName));
4755
+ const displayDest = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, newName));
4766
4756
  p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4767
4757
  resolutions.set(key, {
4768
4758
  type: modType,
@@ -4814,7 +4804,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4814
4804
  continue;
4815
4805
  }
4816
4806
  const folder = res.type === "shared" ? "shared" : "features";
4817
- const targetDir = path2__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4807
+ const targetDir = path26__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4818
4808
  const isOverwrite = Boolean(flags.overwrite || res.action === "overwrite");
4819
4809
  if (key !== rootKey) {
4820
4810
  p19__namespace.log.step(
@@ -4824,30 +4814,30 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4824
4814
  if (res.action === "overwrite" && !flags.dryRun) {
4825
4815
  const existingDir = getExistingModuleDir(projectRoot, res.type, res.targetName);
4826
4816
  if (existingDir && existingDir !== targetDir) {
4827
- fs14__default.default.rmSync(existingDir, { recursive: true, force: true });
4817
+ fs17__default.default.rmSync(existingDir, { recursive: true, force: true });
4828
4818
  }
4829
- if (fs14__default.default.existsSync(targetDir)) {
4830
- fs14__default.default.rmSync(targetDir, { recursive: true, force: true });
4819
+ if (fs17__default.default.existsSync(targetDir)) {
4820
+ fs17__default.default.rmSync(targetDir, { recursive: true, force: true });
4831
4821
  }
4832
4822
  }
4833
4823
  for (const file of res.manifest.files || []) {
4834
4824
  if (file === "registry.json") continue;
4835
4825
  if (!includeTests && isTestFile(file)) continue;
4836
4826
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4837
- const localFilePath = path2__default.default.join(targetDir, file);
4838
- if (fs14__default.default.existsSync(localFilePath) && !isOverwrite) {
4827
+ const localFilePath = path26__default.default.join(targetDir, file);
4828
+ if (fs17__default.default.existsSync(localFilePath) && !isOverwrite) {
4839
4829
  p19__namespace.log.warn(
4840
- ` \u21B3 Skipping existing file: ${pc13__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4830
+ ` \u21B3 Skipping existing file: ${pc13__default.default.dim(path26__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4841
4831
  );
4842
4832
  continue;
4843
4833
  }
4844
4834
  let content = await fetchRegistryFile(registryBase, remoteFilePath);
4845
4835
  content = rewriteImports(content, globalAliasMap);
4846
4836
  if (!flags.dryRun) {
4847
- fs14__default.default.mkdirSync(path2__default.default.dirname(localFilePath), { recursive: true });
4848
- fs14__default.default.writeFileSync(localFilePath, content, "utf-8");
4837
+ fs17__default.default.mkdirSync(path26__default.default.dirname(localFilePath), { recursive: true });
4838
+ fs17__default.default.writeFileSync(localFilePath, content, "utf-8");
4849
4839
  }
4850
- const displayPath = path2__default.default.relative(projectRoot, localFilePath);
4840
+ const displayPath = path26__default.default.relative(projectRoot, localFilePath);
4851
4841
  totalWrittenFiles.push(displayPath);
4852
4842
  p19__namespace.log.message(` ${pc13__default.default.green("+")} ${displayPath}`);
4853
4843
  }
@@ -4873,7 +4863,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4873
4863
  } else {
4874
4864
  const rootRes = resolutions.get(rootKey);
4875
4865
  const baseDir = getModuleBaseDir(projectRoot, type);
4876
- const displayTarget = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, rootRes.targetName));
4866
+ const displayTarget = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, rootRes.targetName));
4877
4867
  p19__namespace.log.success(
4878
4868
  pc13__default.default.green(
4879
4869
  `Successfully imported ${type} '${name}' (${totalWrittenFiles.length} file${totalWrittenFiles.length === 1 ? "" : "s"} placed in ${displayTarget})`
@@ -4892,19 +4882,19 @@ var DependencyRuleError = class extends Error {
4892
4882
  }
4893
4883
  };
4894
4884
  function isTestFile2(filePath, projectRoot) {
4895
- const norm = (projectRoot ? path2__default.default.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4896
- const base = path2__default.default.basename(norm);
4885
+ const norm = (projectRoot ? path26__default.default.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4886
+ const base = path26__default.default.basename(norm);
4897
4887
  return base.endsWith(".test.ts") || base.endsWith(".test.js") || base.endsWith(".spec.ts") || base.endsWith(".spec.js") || base.endsWith(".d.ts") || norm.includes("/__tests__/") || norm.startsWith("__tests__/") || /(?:^|\/)tests?\//.test(norm);
4898
4888
  }
4899
4889
  function scanDirFiles(dir, projectRoot) {
4900
- if (!fs14__default.default.existsSync(dir)) return [];
4901
- const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
4890
+ if (!fs17__default.default.existsSync(dir)) return [];
4891
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
4902
4892
  const files = [];
4903
4893
  for (const entry of entries) {
4904
4894
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "__tests__" || entry.name.startsWith(".")) {
4905
4895
  continue;
4906
4896
  }
4907
- const fullPath = path2__default.default.join(dir, entry.name);
4897
+ const fullPath = path26__default.default.join(dir, entry.name);
4908
4898
  if (entry.isDirectory()) {
4909
4899
  files.push(...scanDirFiles(fullPath, projectRoot));
4910
4900
  } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !isTestFile2(fullPath, projectRoot)) {
@@ -4913,42 +4903,43 @@ function scanDirFiles(dir, projectRoot) {
4913
4903
  }
4914
4904
  return files;
4915
4905
  }
4916
- function classifyFile(fullPath, projectRoot) {
4917
- const rel = path2__default.default.relative(projectRoot, fullPath).replace(/\\/g, "/");
4918
- const featureMatch = rel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/.*)?$/);
4919
- if (featureMatch && featureMatch[1] && featureMatch[2]) {
4920
- const feature = featureMatch[1];
4921
- const subfolder = featureMatch[2];
4922
- let layer;
4923
- if (subfolder === "domain" || subfolder === "errors") {
4924
- layer = "domain";
4925
- } else if (subfolder === "useCases" || subfolder === "usecases") {
4926
- layer = "useCases";
4927
- } else if (subfolder === "services") {
4928
- layer = "services";
4929
- } else if (subfolder === "infrastructure") {
4930
- layer = "infrastructure";
4931
- } else if (subfolder === "pxExpress" || subfolder === "presentation" || subfolder === "handlers" || subfolder.startsWith("px")) {
4932
- layer = "presentation";
4933
- }
4934
- return { moduleType: "feature", moduleName: feature, feature, layer };
4935
- }
4936
- const sharedMatch = rel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
4937
- if (sharedMatch && sharedMatch[1]) {
4938
- const moduleName = sharedMatch[1];
4939
- const rest = sharedMatch[2] || "";
4940
- let layer = "root";
4941
- if (rest.startsWith("domain/") || rest === "domain" || rest.startsWith("errors/") || rest === "errors") {
4942
- layer = "domain";
4943
- } else if (rest.startsWith("ports/") || rest === "ports") {
4944
- layer = "ports";
4945
- } else if (rest.startsWith("infrastructure/") || rest === "infrastructure") {
4946
- layer = "infrastructure";
4947
- }
4948
- return { moduleType: "shared", moduleName, feature: moduleName, layer };
4949
- }
4950
- const errorMatch = rel.match(/(?:^|\/)(?:src\/)?errors(?:\/(.*))?$/);
4951
- if (errorMatch) {
4906
+ function resolveLintEnvironment(projectRoot) {
4907
+ const config = loadMasonConfig(projectRoot);
4908
+ const resolveDir = (configured, defaultSrc, defaultRoot) => {
4909
+ if (configured !== void 0) {
4910
+ return path26__default.default.resolve(projectRoot, configured);
4911
+ }
4912
+ const srcPath = path26__default.default.join(projectRoot, defaultSrc);
4913
+ if (fs17__default.default.existsSync(srcPath)) return srcPath;
4914
+ const rootPath = path26__default.default.join(projectRoot, defaultRoot);
4915
+ if (fs17__default.default.existsSync(rootPath)) return rootPath;
4916
+ return srcPath;
4917
+ };
4918
+ const featuresBase = resolveDir(config?.paths?.features, "src/features", "features");
4919
+ const sharedBase = resolveDir(config?.paths?.shared, "src/shared", "shared");
4920
+ const errorsBase = resolveDir(config?.paths?.errors, "src/errors", "errors");
4921
+ const defaultBaseErrorRelative = config?.paths?.errors ? path26__default.default.join(config.paths.errors, "AppError.ts") : fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/errors")) ? "src/errors/AppError.ts" : fs17__default.default.existsSync(path26__default.default.join(projectRoot, "errors")) ? "errors/AppError.ts" : "src/errors/AppError.ts";
4922
+ const baseErrorAbs = path26__default.default.resolve(
4923
+ projectRoot,
4924
+ config?.paths?.baseError || defaultBaseErrorRelative
4925
+ );
4926
+ return { featuresBase, sharedBase, errorsBase, baseErrorAbs };
4927
+ }
4928
+ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4929
+ if (!sharedBaseAbs || !errorsBaseAbs) {
4930
+ const env = resolveLintEnvironment(featuresBaseAbs);
4931
+ featuresBaseAbs = env.featuresBase;
4932
+ sharedBaseAbs = env.sharedBase;
4933
+ errorsBaseAbs = env.errorsBase;
4934
+ }
4935
+ const normFullPath = path26__default.default.resolve(fullPathAbs);
4936
+ const normErrorsBase = path26__default.default.resolve(errorsBaseAbs);
4937
+ const normSharedBase = path26__default.default.resolve(sharedBaseAbs);
4938
+ const normFeaturesBase = path26__default.default.resolve(featuresBaseAbs);
4939
+ const isUnder = (base, target) => {
4940
+ return target === base || target.startsWith(base + path26__default.default.sep);
4941
+ };
4942
+ if (isUnder(normErrorsBase, normFullPath)) {
4952
4943
  return {
4953
4944
  moduleType: "error",
4954
4945
  moduleName: "global-errors",
@@ -4956,46 +4947,154 @@ function classifyFile(fullPath, projectRoot) {
4956
4947
  layer: "domain"
4957
4948
  };
4958
4949
  }
4950
+ if (isUnder(normSharedBase, normFullPath)) {
4951
+ const rel = path26__default.default.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
4952
+ const parts = rel.split("/").filter(Boolean);
4953
+ if (parts.length >= 1) {
4954
+ const moduleName = parts[0];
4955
+ const subfolder = parts[1];
4956
+ let layer = "root";
4957
+ if (subfolder === "domain" || subfolder === "errors") {
4958
+ layer = "domain";
4959
+ } else if (subfolder === "ports") {
4960
+ layer = "ports";
4961
+ } else if (subfolder === "infrastructure") {
4962
+ layer = "infrastructure";
4963
+ }
4964
+ return { moduleType: "shared", moduleName, feature: moduleName, layer };
4965
+ }
4966
+ }
4967
+ if (isUnder(normFeaturesBase, normFullPath)) {
4968
+ const rel = path26__default.default.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
4969
+ const parts = rel.split("/").filter(Boolean);
4970
+ if (parts.length >= 2) {
4971
+ const moduleName = parts[0];
4972
+ const subfolder = parts[1];
4973
+ let layer;
4974
+ if (subfolder === "domain" || subfolder === "errors") {
4975
+ layer = "domain";
4976
+ } else if (subfolder === "useCases" || subfolder === "usecases") {
4977
+ layer = "useCases";
4978
+ } else if (subfolder === "services") {
4979
+ layer = "services";
4980
+ } else if (subfolder === "infrastructure") {
4981
+ layer = "infrastructure";
4982
+ } else if (subfolder.startsWith("px") || subfolder === "presentation" || subfolder === "handlers" || subfolder === "transformers") {
4983
+ layer = "presentation";
4984
+ }
4985
+ return { moduleType: "feature", moduleName, feature: moduleName, layer };
4986
+ }
4987
+ }
4959
4988
  return {};
4960
4989
  }
4961
- function classifyTarget(specifier, sourceFileAbs, projectRoot) {
4990
+ function classifyTarget(specifier, sourceFileAbs, projectRoot, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4962
4991
  if (specifier === "@solid-stack/di" || specifier.startsWith("@solid-stack/di/")) {
4963
4992
  return { isExternal: true, isDiFramework: true };
4964
4993
  }
4965
- if (specifier.startsWith("node:") || ["crypto", "fs", "path", "http", "https", "url", "os", "child_process", "stream", "express", "cors", "dotenv"].includes(specifier)) {
4994
+ if (specifier.startsWith("node:") || [
4995
+ "crypto",
4996
+ "fs",
4997
+ "path",
4998
+ "http",
4999
+ "https",
5000
+ "url",
5001
+ "os",
5002
+ "child_process",
5003
+ "stream",
5004
+ "express",
5005
+ "cors",
5006
+ "dotenv"
5007
+ ].includes(specifier)) {
4966
5008
  return { isExternal: true, isDiFramework: false };
4967
5009
  }
4968
- let resolvedRel = null;
5010
+ if (!featuresBaseAbs || !sharedBaseAbs || !errorsBaseAbs) {
5011
+ const env = resolveLintEnvironment(projectRoot);
5012
+ featuresBaseAbs = featuresBaseAbs || env.featuresBase;
5013
+ sharedBaseAbs = sharedBaseAbs || env.sharedBase;
5014
+ errorsBaseAbs = errorsBaseAbs || env.errorsBase;
5015
+ }
5016
+ const isGlobalConfig = specifier === "@configs" || specifier.startsWith("@configs/") || specifier === "@/configs" || specifier.startsWith("@/configs/") || specifier === "~/configs" || specifier.startsWith("~/configs/") || specifier === "configs" || specifier.startsWith("configs/");
5017
+ let targetAbs = null;
4969
5018
  if (specifier.startsWith(".")) {
4970
- const abs = path2__default.default.resolve(path2__default.default.dirname(sourceFileAbs), specifier);
4971
- resolvedRel = path2__default.default.relative(projectRoot, abs).replace(/\\/g, "/");
4972
- } else if (specifier.startsWith("@/features/") || specifier.startsWith("~/features/")) {
4973
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4974
- } else if (specifier.startsWith("@features/")) {
4975
- resolvedRel = "src/" + specifier.slice(1);
4976
- } else if (specifier.startsWith("@/shared/") || specifier.startsWith("~/shared/")) {
4977
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4978
- } else if (specifier.startsWith("@shared/")) {
4979
- resolvedRel = "src/" + specifier.slice(1);
4980
- } else if (specifier.startsWith("@/configs/") || specifier.startsWith("~/configs/") || specifier === "@/configs" || specifier === "~/configs") {
4981
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4982
- } else if (specifier === "@configs" || specifier.startsWith("@configs/")) {
4983
- resolvedRel = "src/" + specifier.slice(1);
4984
- } else if (specifier.startsWith("@/errors/") || specifier.startsWith("~/errors/") || specifier === "@/errors" || specifier === "~/errors") {
4985
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4986
- } else if (specifier === "@errors" || specifier.startsWith("@errors/")) {
4987
- resolvedRel = "src/" + specifier.slice(1);
4988
- } else if (specifier.startsWith("@/") || specifier.startsWith("~/")) {
4989
- resolvedRel = "src/" + specifier.slice(2);
4990
- } else if (specifier.startsWith("features/") || specifier.startsWith("shared/") || specifier.startsWith("configs/") || specifier === "configs" || specifier.startsWith("errors/") || specifier === "errors") {
4991
- resolvedRel = specifier;
4992
- }
4993
- if (!resolvedRel) {
4994
- return { isExternal: true, isDiFramework: false };
5019
+ targetAbs = path26__default.default.resolve(path26__default.default.dirname(sourceFileAbs), specifier);
5020
+ } else {
5021
+ const featRel = path26__default.default.relative(projectRoot, featuresBaseAbs).replace(/\\/g, "/");
5022
+ const sharedRel = path26__default.default.relative(projectRoot, sharedBaseAbs).replace(/\\/g, "/");
5023
+ const errorsRel = path26__default.default.relative(projectRoot, errorsBaseAbs).replace(/\\/g, "/");
5024
+ const featPrefixes = ["features"];
5025
+ if (featRel && featRel !== "." && !featRel.startsWith("..")) {
5026
+ featPrefixes.push(featRel);
5027
+ const b = path26__default.default.basename(featRel);
5028
+ if (!featPrefixes.includes(b)) featPrefixes.push(b);
5029
+ }
5030
+ const sharedPrefixes = ["shared"];
5031
+ if (sharedRel && sharedRel !== "." && !sharedRel.startsWith("..")) {
5032
+ sharedPrefixes.push(sharedRel);
5033
+ const b = path26__default.default.basename(sharedRel);
5034
+ if (!sharedPrefixes.includes(b)) sharedPrefixes.push(b);
5035
+ }
5036
+ const errorsPrefixes = ["errors"];
5037
+ if (errorsRel && errorsRel !== "." && !errorsRel.startsWith("..")) {
5038
+ errorsPrefixes.push(errorsRel);
5039
+ const b = path26__default.default.basename(errorsRel);
5040
+ if (!errorsPrefixes.includes(b)) errorsPrefixes.push(b);
5041
+ }
5042
+ for (const prefix of featPrefixes) {
5043
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5044
+ const m = specifier.match(aliasRegex);
5045
+ if (m && m[2]) {
5046
+ targetAbs = path26__default.default.resolve(featuresBaseAbs, m[2]);
5047
+ break;
5048
+ }
5049
+ }
5050
+ if (!targetAbs) {
5051
+ for (const prefix of sharedPrefixes) {
5052
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5053
+ const m = specifier.match(aliasRegex);
5054
+ if (m && m[2]) {
5055
+ targetAbs = path26__default.default.resolve(sharedBaseAbs, m[2]);
5056
+ break;
5057
+ }
5058
+ }
5059
+ }
5060
+ if (!targetAbs) {
5061
+ for (const prefix of errorsPrefixes) {
5062
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}(?:\\/(.*))?$`);
5063
+ const m = specifier.match(aliasRegex);
5064
+ if (m) {
5065
+ targetAbs = path26__default.default.resolve(errorsBaseAbs, m[2] || "");
5066
+ break;
5067
+ }
5068
+ }
5069
+ }
5070
+ if (!targetAbs && (specifier.startsWith("@/") || specifier.startsWith("~/"))) {
5071
+ const sub = specifier.slice(2);
5072
+ const srcCandidate = path26__default.default.resolve(projectRoot, "src", sub);
5073
+ const rootCandidate = path26__default.default.resolve(projectRoot, sub);
5074
+ if (fs17__default.default.existsSync(srcCandidate)) {
5075
+ targetAbs = srcCandidate;
5076
+ } else if (fs17__default.default.existsSync(rootCandidate)) {
5077
+ targetAbs = rootCandidate;
5078
+ } else {
5079
+ targetAbs = srcCandidate;
5080
+ }
5081
+ }
5082
+ if (!targetAbs) {
5083
+ const featCandidate = path26__default.default.resolve(featuresBaseAbs, specifier);
5084
+ if (fs17__default.default.existsSync(featCandidate) || fs17__default.default.existsSync(featCandidate + ".ts") || fs17__default.default.existsSync(featCandidate + ".js")) {
5085
+ targetAbs = featCandidate;
5086
+ }
5087
+ }
4995
5088
  }
4996
- const isGlobalConfig = resolvedRel.startsWith("src/configs/") || resolvedRel === "src/configs" || resolvedRel.startsWith("configs/") || resolvedRel === "configs";
4997
- const isGlobalError = resolvedRel.startsWith("src/errors/") || resolvedRel === "src/errors" || resolvedRel.startsWith("errors/") || resolvedRel === "errors";
4998
- if (isGlobalError) {
5089
+ if (!targetAbs) {
5090
+ return { isExternal: true, isDiFramework: false, isGlobalConfig };
5091
+ }
5092
+ const normTarget = path26__default.default.resolve(targetAbs);
5093
+ const srcConfig = path26__default.default.resolve(projectRoot, "src/configs");
5094
+ const rootConfig = path26__default.default.resolve(projectRoot, "configs");
5095
+ const isTargetConfig = isGlobalConfig || normTarget === srcConfig || normTarget.startsWith(srcConfig + path26__default.default.sep) || normTarget === rootConfig || normTarget.startsWith(rootConfig + path26__default.default.sep);
5096
+ const classification = classifyFile(targetAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs);
5097
+ if (classification.moduleType === "error") {
4999
5098
  return {
5000
5099
  isExternal: false,
5001
5100
  isDiFramework: false,
@@ -5003,33 +5102,19 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5003
5102
  isTargetError: true
5004
5103
  };
5005
5104
  }
5006
- const featMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/(.*))?$/);
5007
- if (featMatch && featMatch[1] && featMatch[2]) {
5008
- const targetFeature = featMatch[1];
5009
- const targetSubfolder = featMatch[2];
5010
- const rest = featMatch[3] || "";
5011
- let targetLayer;
5012
- if (targetSubfolder === "domain" || targetSubfolder === "errors") {
5013
- targetLayer = "domain";
5014
- } else if (targetSubfolder === "useCases" || targetSubfolder === "usecases") {
5015
- targetLayer = "useCases";
5016
- } else if (targetSubfolder === "services") {
5017
- targetLayer = "services";
5018
- } else if (targetSubfolder === "infrastructure") {
5019
- targetLayer = "infrastructure";
5020
- } else if (targetSubfolder === "pxExpress" || targetSubfolder === "presentation" || targetSubfolder === "handlers" || targetSubfolder.startsWith("px")) {
5021
- targetLayer = "presentation";
5022
- }
5023
- const basePart = rest ? path2__default.default.basename(rest) : targetSubfolder;
5024
- const targetFileName = basePart.replace(/\.(js|ts|mjs|cjs)$/, "");
5105
+ if (classification.moduleType === "feature") {
5106
+ const rel = path26__default.default.relative(featuresBaseAbs, targetAbs).replace(/\\/g, "/");
5107
+ const parts = rel.split("/").filter(Boolean);
5108
+ const targetSubfolder = parts[1];
5109
+ const targetFileName = path26__default.default.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5025
5110
  const isTargetPort = /^I[A-Z]/.test(targetFileName);
5026
5111
  const isTargetRepo = isTargetPort && targetFileName.includes("Repo");
5027
- const isTargetError = targetSubfolder === "errors" || rest.startsWith("errors/") || rest.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5112
+ const isTargetError = targetSubfolder === "errors" || rel.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5028
5113
  return {
5029
5114
  isExternal: false,
5030
5115
  isDiFramework: false,
5031
- targetFeature,
5032
- targetLayer,
5116
+ targetFeature: classification.moduleName,
5117
+ targetLayer: classification.layer,
5033
5118
  targetSubfolder,
5034
5119
  targetFileName,
5035
5120
  isTargetPort,
@@ -5037,25 +5122,21 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5037
5122
  isTargetError
5038
5123
  };
5039
5124
  }
5040
- const sharedMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
5041
- if (sharedMatch) {
5042
- const targetSharedModule = sharedMatch[1];
5043
- const sharedRest = sharedMatch[2] || "";
5044
- const isSharedRoot = !sharedRest.includes("/");
5045
- const isSharedPorts = sharedRest.startsWith("ports/") || sharedRest === "ports";
5046
- const isSharedInfra = sharedRest.startsWith("infrastructure/") || sharedRest === "infrastructure";
5047
- const isSharedDomain = sharedRest.startsWith("domain/") || sharedRest === "domain";
5125
+ if (classification.moduleType === "shared") {
5126
+ const targetFileName = path26__default.default.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5127
+ const isTargetError = classification.layer === "domain" && (targetFileName.endsWith("Error") || targetFileName.endsWith("Errors") || targetAbs.includes("/errors/"));
5048
5128
  return {
5049
5129
  isExternal: false,
5050
5130
  isDiFramework: false,
5051
- targetSharedModule,
5052
- isSharedRoot,
5053
- isSharedPorts,
5054
- isSharedInfra,
5055
- isSharedDomain
5131
+ targetSharedModule: classification.moduleName,
5132
+ isSharedRoot: classification.layer === "root",
5133
+ isSharedPorts: classification.layer === "ports",
5134
+ isSharedInfra: classification.layer === "infrastructure",
5135
+ isSharedDomain: classification.layer === "domain",
5136
+ isTargetError
5056
5137
  };
5057
5138
  }
5058
- return { isExternal: true, isDiFramework: false, isGlobalConfig };
5139
+ return { isExternal: true, isDiFramework: false, isGlobalConfig: isTargetConfig };
5059
5140
  }
5060
5141
  function extractImportStatements(content) {
5061
5142
  const statements = [];
@@ -5177,22 +5258,50 @@ var FeatureDependencyGraph = class {
5177
5258
  return dfs(start);
5178
5259
  }
5179
5260
  };
5180
- function discoverAllFeatures(projectRoot) {
5181
- const featuresBase = resolveFeaturesDir(projectRoot);
5182
- if (!fs14__default.default.existsSync(featuresBase)) return [];
5183
- const entries = fs14__default.default.readdirSync(featuresBase, { withFileTypes: true });
5184
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5261
+ function discoverAllFeatures(featuresBaseAbs, excludeDirs = []) {
5262
+ const base = featuresBaseAbs;
5263
+ if (!fs17__default.default.existsSync(base)) return [];
5264
+ const excludeSet = new Set(excludeDirs.map((d) => path26__default.default.resolve(d)));
5265
+ const entries = fs17__default.default.readdirSync(base, { withFileTypes: true });
5266
+ return entries.filter((e) => {
5267
+ if (!e.isDirectory()) return false;
5268
+ if (e.name.startsWith(".")) return false;
5269
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5270
+ return false;
5271
+ }
5272
+ const resolved = path26__default.default.resolve(base, e.name);
5273
+ for (const ex of excludeSet) {
5274
+ if (ex === resolved || ex.startsWith(resolved + path26__default.default.sep) || resolved.startsWith(ex + path26__default.default.sep)) {
5275
+ return false;
5276
+ }
5277
+ }
5278
+ return true;
5279
+ }).map((e) => ({
5185
5280
  name: e.name,
5186
- dir: path2__default.default.join(featuresBase, e.name)
5281
+ dir: path26__default.default.join(base, e.name)
5187
5282
  })).sort((a, b) => a.name.localeCompare(b.name));
5188
5283
  }
5189
- function discoverAllShared(projectRoot) {
5190
- const sharedBase = resolveSharedDir(projectRoot);
5191
- if (!fs14__default.default.existsSync(sharedBase)) return [];
5192
- const entries = fs14__default.default.readdirSync(sharedBase, { withFileTypes: true });
5193
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5284
+ function discoverAllShared(sharedBaseAbs, excludeDirs = []) {
5285
+ const base = sharedBaseAbs;
5286
+ if (!fs17__default.default.existsSync(base)) return [];
5287
+ const excludeSet = new Set(excludeDirs.map((d) => path26__default.default.resolve(d)));
5288
+ const entries = fs17__default.default.readdirSync(base, { withFileTypes: true });
5289
+ return entries.filter((e) => {
5290
+ if (!e.isDirectory()) return false;
5291
+ if (e.name.startsWith(".")) return false;
5292
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5293
+ return false;
5294
+ }
5295
+ const resolved = path26__default.default.resolve(base, e.name);
5296
+ for (const ex of excludeSet) {
5297
+ if (ex === resolved || ex.startsWith(resolved + path26__default.default.sep) || resolved.startsWith(ex + path26__default.default.sep)) {
5298
+ return false;
5299
+ }
5300
+ }
5301
+ return true;
5302
+ }).map((e) => ({
5194
5303
  name: e.name,
5195
- dir: path2__default.default.join(sharedBase, e.name)
5304
+ dir: path26__default.default.join(base, e.name)
5196
5305
  })).sort((a, b) => a.name.localeCompare(b.name));
5197
5306
  }
5198
5307
  function extractClassMethods(content, className) {
@@ -5348,7 +5457,7 @@ function extractClassMethods(content, className) {
5348
5457
  return methods;
5349
5458
  }
5350
5459
  function checkUseCaseShape(featureName, filePath, relativePath, content, addViolation) {
5351
- const fileName = path2__default.default.basename(filePath);
5460
+ const fileName = path26__default.default.basename(filePath);
5352
5461
  const lines = content.split(/\r?\n/);
5353
5462
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5354
5463
  if (!classMatch) {
@@ -5444,7 +5553,7 @@ private ${m.name}(...) { ... }`
5444
5553
  }
5445
5554
  }
5446
5555
  function checkServiceShape(featureName, filePath, relativePath, content, addViolation) {
5447
- const fileName = path2__default.default.basename(filePath);
5556
+ const fileName = path26__default.default.basename(filePath);
5448
5557
  const lines = content.split(/\r?\n/);
5449
5558
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5450
5559
  if (!classMatch) {
@@ -5543,40 +5652,32 @@ function lintCodebase(options = {}) {
5543
5652
  const startTime = Date.now();
5544
5653
  const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
5545
5654
  const failFast = !options.complete;
5546
- const lintConfig = loadLintConfig(projectRoot);
5547
- const baseErrorRelative = lintConfig.baseErrorPath || "src/errors/AppError.ts";
5548
- const baseErrorAbs = path2__default.default.resolve(projectRoot, baseErrorRelative);
5549
- const featuresBase = resolveFeaturesDir(projectRoot);
5550
- const sharedBase = resolveSharedDir(projectRoot);
5551
- let errorsBase = path2__default.default.join(projectRoot, "src/errors");
5552
- if (!fs14__default.default.existsSync(errorsBase) && fs14__default.default.existsSync(path2__default.default.join(projectRoot, "errors"))) {
5553
- errorsBase = path2__default.default.join(projectRoot, "errors");
5554
- }
5655
+ const { featuresBase, sharedBase, errorsBase, baseErrorAbs } = resolveLintEnvironment(projectRoot);
5555
5656
  const missingFoundations = [];
5556
- if (!fs14__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5557
- if (!fs14__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5558
- if (!fs14__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5657
+ if (!fs17__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5658
+ if (!fs17__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5659
+ if (!fs17__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5559
5660
  if (missingFoundations.length > 0) {
5560
5661
  throw new DependencyRuleError(
5561
- `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every project must contain 'features/', 'shared/', and 'errors/'.`,
5662
+ `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
5562
5663
  [],
5563
5664
  true
5564
5665
  );
5565
5666
  }
5566
- if (!fs14__default.default.existsSync(baseErrorAbs)) {
5667
+ if (!fs17__default.default.existsSync(baseErrorAbs)) {
5567
5668
  throw new DependencyRuleError(
5568
- `Project Structure Violation: Base error class not found at '${baseErrorRelative}'. Create this file or update 'baseErrorPath' in mason-lint.config.json.`,
5669
+ `Project Structure Violation: Base error class not found at '${path26__default.default.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
5569
5670
  [],
5570
5671
  true
5571
5672
  );
5572
5673
  }
5573
- const baseErrorContent = fs14__default.default.readFileSync(baseErrorAbs, "utf-8");
5674
+ const baseErrorContent = fs17__default.default.readFileSync(baseErrorAbs, "utf-8");
5574
5675
  const baseClassMatch = baseErrorContent.match(
5575
5676
  /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)/
5576
5677
  );
5577
5678
  const baseErrorClassName = baseClassMatch ? baseClassMatch[1] : "AppError";
5578
- const features = discoverAllFeatures(projectRoot);
5579
- const sharedModules = discoverAllShared(projectRoot);
5679
+ const features = discoverAllFeatures(featuresBase, [sharedBase, errorsBase]);
5680
+ const sharedModules = discoverAllShared(sharedBase, [featuresBase, errorsBase]);
5580
5681
  const errorModule = { name: "global-errors", dir: errorsBase, type: "error" };
5581
5682
  const allModules = [
5582
5683
  ...features.map((f) => ({ ...f, type: "feature" })),
@@ -5619,12 +5720,12 @@ Code: ${v.code}`;
5619
5720
  const allFiles = scanDirFiles(mod.dir, projectRoot);
5620
5721
  modResult.scannedFilesCount = allFiles.length;
5621
5722
  for (const file of allFiles) {
5622
- const relPath = path2__default.default.relative(projectRoot, file).replace(/\\/g, "/");
5623
- const { moduleType, moduleName, layer } = classifyFile(file, projectRoot);
5723
+ const relPath = path26__default.default.relative(projectRoot, file).replace(/\\/g, "/");
5724
+ const { moduleType, moduleName, layer } = classifyFile(file, featuresBase, sharedBase, errorsBase);
5624
5725
  if (!layer || !moduleType || !moduleName) continue;
5625
- const content = fs14__default.default.readFileSync(file, "utf-8");
5726
+ const content = fs17__default.default.readFileSync(file, "utf-8");
5626
5727
  const statements = extractImportStatements(content);
5627
- const baseName = path2__default.default.basename(file);
5728
+ const baseName = path26__default.default.basename(file);
5628
5729
  const isBarrel = baseName === "index.ts" || baseName === "index.js";
5629
5730
  const throwErrorRegex = /\bthrow\s+(?:new\s+)?Error\s*\(/g;
5630
5731
  let throwMatch;
@@ -5643,7 +5744,7 @@ Code: ${v.code}`;
5643
5744
  code: lineCode,
5644
5745
  ruleId: "E3_PLAIN_ERROR_THROW",
5645
5746
  severity: "error",
5646
- advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a domain-specific error class that inherits from it.`,
5747
+ advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a custom error class that inherits from it.`,
5647
5748
  fixExample: {
5648
5749
  bad: lineCode,
5649
5750
  good: `throw new ${baseErrorClassName}("Something went wrong");`
@@ -5651,7 +5752,7 @@ Code: ${v.code}`;
5651
5752
  });
5652
5753
  }
5653
5754
  const isErrorFile = relPath.includes("/errors/") || relPath.startsWith("errors/") || relPath.startsWith("src/errors/") || moduleType === "error" || baseName.endsWith("Error.ts") || baseName.endsWith("Errors.ts") || baseName.endsWith("Error.js") || baseName.endsWith("Errors.js");
5654
- const isBaseErrorFile = path2__default.default.resolve(file) === path2__default.default.resolve(baseErrorAbs);
5755
+ const isBaseErrorFile = path26__default.default.resolve(file) === path26__default.default.resolve(baseErrorAbs);
5655
5756
  if (isErrorFile && !isBaseErrorFile) {
5656
5757
  const classRegex = /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)(?:<[^>]+>)?(?:\s+extends\s+([A-Za-z0-9_]+))?/g;
5657
5758
  let classMatch;
@@ -5673,7 +5774,7 @@ Code: ${v.code}`;
5673
5774
  code: lineCode,
5674
5775
  ruleId: "E4_MISSING_INHERITANCE",
5675
5776
  severity: "error",
5676
- advice: `Error class '${className}' must extend '${baseErrorClassName}' (or another class that derives from it).`,
5777
+ advice: `Error class '${className}' must extend '${baseErrorClassName}'.`,
5677
5778
  fixExample: {
5678
5779
  bad: lineCode,
5679
5780
  good: `export class ${className} extends ${baseErrorClassName} { ... }`
@@ -5690,7 +5791,7 @@ Code: ${v.code}`;
5690
5791
  code: lineCode,
5691
5792
  ruleId: "E5_NATIVE_ERROR_INHERITANCE",
5692
5793
  severity: "error",
5693
- advice: `Error class '${className}' extends the native 'Error'. It must extend your base error class ('${baseErrorClassName}').`,
5794
+ advice: `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${baseErrorClassName}').`,
5694
5795
  fixExample: {
5695
5796
  bad: lineCode,
5696
5797
  good: `export class ${className} extends ${baseErrorClassName} { ... }`
@@ -5701,7 +5802,7 @@ Code: ${v.code}`;
5701
5802
  }
5702
5803
  if (moduleType === "error") {
5703
5804
  for (const stmt of statements) {
5704
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5805
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5705
5806
  if (target.targetFeature) {
5706
5807
  addViolation({
5707
5808
  feature: "global-errors",
@@ -5767,7 +5868,7 @@ Code: ${v.code}`;
5767
5868
  }
5768
5869
  }
5769
5870
  for (const stmt of statements) {
5770
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5871
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5771
5872
  if (target.targetFeature) {
5772
5873
  addViolation({
5773
5874
  feature: moduleName,
@@ -5897,7 +5998,7 @@ Code: ${v.code}`;
5897
5998
  }
5898
5999
  }
5899
6000
  for (const stmt of statements) {
5900
- const target = classifyTarget(stmt.specifier, file, projectRoot);
6001
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5901
6002
  if (target.targetFeature && target.targetFeature !== feat.name) {
5902
6003
  const evidence = {
5903
6004
  fromFeature: feat.name,