@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/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import fs4 from 'fs';
2
- import path2 from 'path';
1
+ import fs17 from 'fs';
2
+ import path26 from 'path';
3
3
  import * as p19 from '@clack/prompts';
4
4
  import pc14 from 'picocolors';
5
5
  import { fileURLToPath } from 'url';
@@ -76,8 +76,8 @@ function isValidIdentifier(str) {
76
76
  }
77
77
  function writeFileSafely(absolutePath, content, options = {}) {
78
78
  const projectRoot = options.projectRoot || process.cwd();
79
- const relPath = path2.relative(projectRoot, absolutePath).replace(/\\/g, "/");
80
- const existedBefore = fs4.existsSync(absolutePath);
79
+ const relPath = path26.relative(projectRoot, absolutePath).replace(/\\/g, "/");
80
+ const existedBefore = fs17.existsSync(absolutePath);
81
81
  if (options.dryRun) {
82
82
  return {
83
83
  relativePath: relPath,
@@ -96,11 +96,11 @@ function writeFileSafely(absolutePath, content, options = {}) {
96
96
  existedBefore: true
97
97
  };
98
98
  }
99
- const dir = path2.dirname(absolutePath);
100
- if (!fs4.existsSync(dir)) {
101
- fs4.mkdirSync(dir, { recursive: true });
99
+ const dir = path26.dirname(absolutePath);
100
+ if (!fs17.existsSync(dir)) {
101
+ fs17.mkdirSync(dir, { recursive: true });
102
102
  }
103
- fs4.writeFileSync(absolutePath, content, "utf-8");
103
+ fs17.writeFileSync(absolutePath, content, "utf-8");
104
104
  return {
105
105
  relativePath: relPath,
106
106
  absolutePath,
@@ -127,17 +127,17 @@ function printGeneratedFiles(files, isDryRun = false) {
127
127
  }
128
128
  }
129
129
  function loadMasonConfig(startDir = process.cwd()) {
130
- let current = path2.resolve(startDir);
130
+ let current = path26.resolve(startDir);
131
131
  while (true) {
132
- const configPath = path2.join(current, "mason.config.json");
133
- if (fs4.existsSync(configPath)) {
132
+ const configPath = path26.join(current, "mason.config.json");
133
+ if (fs17.existsSync(configPath)) {
134
134
  try {
135
- return JSON.parse(fs4.readFileSync(configPath, "utf-8"));
135
+ return JSON.parse(fs17.readFileSync(configPath, "utf-8"));
136
136
  } catch {
137
137
  return null;
138
138
  }
139
139
  }
140
- const parent = path2.dirname(current);
140
+ const parent = path26.dirname(current);
141
141
  if (parent === current) break;
142
142
  current = parent;
143
143
  }
@@ -147,70 +147,91 @@ function getEffectiveMode(projectRoot, flags) {
147
147
  if (flags?.registry) return "registry";
148
148
  const config = loadMasonConfig(projectRoot);
149
149
  if (config?.mode) return config.mode;
150
- if (fs4.existsSync(path2.join(projectRoot, "index.json")) && (fs4.existsSync(path2.join(projectRoot, "features")) || fs4.existsSync(path2.join(projectRoot, "shared")) || fs4.existsSync(path2.join(projectRoot, "src/features")) || fs4.existsSync(path2.join(projectRoot, "src/shared")))) {
150
+ if (fs17.existsSync(path26.join(projectRoot, "index.json")) && (fs17.existsSync(path26.join(projectRoot, "features")) || fs17.existsSync(path26.join(projectRoot, "shared")) || fs17.existsSync(path26.join(projectRoot, "src/features")) || fs17.existsSync(path26.join(projectRoot, "src/shared")))) {
151
151
  return "registry";
152
152
  }
153
153
  return "app";
154
154
  }
155
155
  function getConfiguredFeaturesDir(projectRoot, flags) {
156
- if (flags?.target) return path2.resolve(projectRoot, flags.target);
157
- if (flags?.dest) return path2.resolve(projectRoot, flags.dest);
156
+ if (flags?.target) return path26.resolve(projectRoot, flags.target);
157
+ if (flags?.dest) return path26.resolve(projectRoot, flags.dest);
158
158
  const config = loadMasonConfig(projectRoot);
159
159
  if (config?.paths?.features) {
160
- return path2.resolve(projectRoot, config.paths.features);
160
+ return path26.resolve(projectRoot, config.paths.features);
161
161
  }
162
162
  const mode = getEffectiveMode(projectRoot, flags);
163
163
  if (mode === "registry") {
164
- if (fs4.existsSync(path2.join(projectRoot, "src/features"))) {
165
- return path2.join(projectRoot, "src/features");
164
+ if (fs17.existsSync(path26.join(projectRoot, "src/features"))) {
165
+ return path26.join(projectRoot, "src/features");
166
166
  }
167
- return path2.join(projectRoot, "features");
167
+ return path26.join(projectRoot, "features");
168
168
  }
169
- if (fs4.existsSync(path2.join(projectRoot, "src/features"))) {
170
- return path2.join(projectRoot, "src/features");
169
+ if (fs17.existsSync(path26.join(projectRoot, "src/features"))) {
170
+ return path26.join(projectRoot, "src/features");
171
171
  }
172
- return path2.join(projectRoot, "features");
172
+ return path26.join(projectRoot, "features");
173
173
  }
174
174
  function getConfiguredSharedDir(projectRoot, flags) {
175
- if (flags?.target) return path2.resolve(projectRoot, flags.target);
176
- if (flags?.dest) return path2.resolve(projectRoot, flags.dest);
175
+ if (flags?.target) return path26.resolve(projectRoot, flags.target);
176
+ if (flags?.dest) return path26.resolve(projectRoot, flags.dest);
177
177
  const config = loadMasonConfig(projectRoot);
178
178
  if (config?.paths?.shared) {
179
- return path2.resolve(projectRoot, config.paths.shared);
179
+ return path26.resolve(projectRoot, config.paths.shared);
180
180
  }
181
181
  const mode = getEffectiveMode(projectRoot, flags);
182
182
  if (mode === "registry") {
183
- if (fs4.existsSync(path2.join(projectRoot, "src/shared"))) {
184
- return path2.join(projectRoot, "src/shared");
183
+ if (fs17.existsSync(path26.join(projectRoot, "src/shared"))) {
184
+ return path26.join(projectRoot, "src/shared");
185
185
  }
186
- return path2.join(projectRoot, "shared");
186
+ return path26.join(projectRoot, "shared");
187
187
  }
188
- if (fs4.existsSync(path2.join(projectRoot, "src/shared"))) {
189
- return path2.join(projectRoot, "src/shared");
188
+ if (fs17.existsSync(path26.join(projectRoot, "src/shared"))) {
189
+ return path26.join(projectRoot, "src/shared");
190
190
  }
191
- return path2.join(projectRoot, "shared");
191
+ return path26.join(projectRoot, "shared");
192
192
  }
193
193
  function loadLintConfig(projectRoot) {
194
- const configPath = path2.join(projectRoot, "mason-lint.config.json");
195
- if (fs4.existsSync(configPath)) {
196
- try {
197
- return JSON.parse(fs4.readFileSync(configPath, "utf-8"));
198
- } catch {
199
- }
194
+ const masonConfig = loadMasonConfig(projectRoot);
195
+ if (masonConfig) {
196
+ return {
197
+ baseErrorPath: masonConfig.paths?.baseError,
198
+ paths: masonConfig.paths
199
+ };
200
200
  }
201
- return { baseErrorPath: "src/errors/AppError.ts" };
201
+ return {};
202
+ }
203
+ function getResolvedLintPaths(projectRoot, config) {
204
+ const masonConfig = loadMasonConfig(projectRoot);
205
+ const configuredFeatures = config?.paths?.features ?? masonConfig?.paths?.features;
206
+ const configuredShared = config?.paths?.shared ?? masonConfig?.paths?.shared;
207
+ const configuredErrors = config?.paths?.errors ?? masonConfig?.paths?.errors;
208
+ const resolveBase = (configuredPath, defaultSrc, defaultRoot) => {
209
+ if (configuredPath !== void 0) {
210
+ return path26.resolve(projectRoot, configuredPath);
211
+ }
212
+ const srcPath = path26.join(projectRoot, defaultSrc);
213
+ if (fs17.existsSync(srcPath)) return srcPath;
214
+ const rootPath = path26.join(projectRoot, defaultRoot);
215
+ if (fs17.existsSync(rootPath)) return rootPath;
216
+ return srcPath;
217
+ };
218
+ return {
219
+ featuresBase: resolveBase(configuredFeatures, "src/features", "features"),
220
+ sharedBase: resolveBase(configuredShared, "src/shared", "shared"),
221
+ errorsBase: resolveBase(configuredErrors, "src/errors", "errors")
222
+ };
202
223
  }
203
224
 
204
225
  // src/utils/project.ts
205
226
  function findProjectRoot(startDir = process.cwd()) {
206
- let current = path2.resolve(startDir);
227
+ let current = path26.resolve(startDir);
207
228
  while (true) {
208
- if (fs4.existsSync(path2.join(current, "package.json"))) {
229
+ if (fs17.existsSync(path26.join(current, "package.json"))) {
209
230
  return current;
210
231
  }
211
- const parent = path2.dirname(current);
232
+ const parent = path26.dirname(current);
212
233
  if (parent === current) {
213
- return path2.resolve(startDir);
234
+ return path26.resolve(startDir);
214
235
  }
215
236
  current = parent;
216
237
  }
@@ -223,9 +244,9 @@ function resolveSharedDir(projectRoot, flags) {
223
244
  }
224
245
  function listExistingShared(projectRoot) {
225
246
  const sharedDir = resolveSharedDir(projectRoot);
226
- if (!fs4.existsSync(sharedDir)) return [];
247
+ if (!fs17.existsSync(sharedDir)) return [];
227
248
  try {
228
- const entries = fs4.readdirSync(sharedDir, { withFileTypes: true });
249
+ const entries = fs17.readdirSync(sharedDir, { withFileTypes: true });
229
250
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
230
251
  } catch {
231
252
  return [];
@@ -233,9 +254,9 @@ function listExistingShared(projectRoot) {
233
254
  }
234
255
  function listExistingFeatures(projectRoot) {
235
256
  const featuresDir = resolveFeaturesDir(projectRoot);
236
- if (!fs4.existsSync(featuresDir)) return [];
257
+ if (!fs17.existsSync(featuresDir)) return [];
237
258
  try {
238
- const entries = fs4.readdirSync(featuresDir, { withFileTypes: true });
259
+ const entries = fs17.readdirSync(featuresDir, { withFileTypes: true });
239
260
  return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
240
261
  } catch {
241
262
  return [];
@@ -245,14 +266,14 @@ function listDomainInterfaces(projectRoot, featureName) {
245
266
  const results = [];
246
267
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
247
268
  for (const feat of features) {
248
- const domainDir = path2.join(resolveFeaturesDir(projectRoot), feat, "domain");
249
- if (!fs4.existsSync(domainDir)) continue;
269
+ const domainDir = path26.join(resolveFeaturesDir(projectRoot), feat, "domain");
270
+ if (!fs17.existsSync(domainDir)) continue;
250
271
  try {
251
- const files = fs4.readdirSync(domainDir);
272
+ const files = fs17.readdirSync(domainDir);
252
273
  for (const file of files) {
253
274
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
254
275
  const name = file.replace(/\.ts$/, "");
255
- const fullPath = path2.join(domainDir, file);
276
+ const fullPath = path26.join(domainDir, file);
256
277
  if (/^I[A-Z]/.test(name)) {
257
278
  results.push({
258
279
  name,
@@ -261,7 +282,7 @@ function listDomainInterfaces(projectRoot, featureName) {
261
282
  });
262
283
  } else {
263
284
  try {
264
- const content = fs4.readFileSync(fullPath, "utf-8");
285
+ const content = fs17.readFileSync(fullPath, "utf-8");
265
286
  if (/export\s+(?:abstract\s+class|interface)\s+(\w+)/.test(content)) {
266
287
  results.push({
267
288
  name,
@@ -283,17 +304,17 @@ function listDomainEntities(projectRoot, featureName) {
283
304
  const results = [];
284
305
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
285
306
  for (const feat of features) {
286
- const domainDir = path2.join(resolveFeaturesDir(projectRoot), feat, "domain");
287
- if (!fs4.existsSync(domainDir)) continue;
307
+ const domainDir = path26.join(resolveFeaturesDir(projectRoot), feat, "domain");
308
+ if (!fs17.existsSync(domainDir)) continue;
288
309
  try {
289
- const files = fs4.readdirSync(domainDir);
310
+ const files = fs17.readdirSync(domainDir);
290
311
  for (const file of files) {
291
312
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
292
313
  const name = file.replace(/\.ts$/, "");
293
314
  if (!/^I[A-Z]/.test(name)) {
294
315
  results.push({
295
316
  name,
296
- fullPath: path2.join(domainDir, file),
317
+ fullPath: path26.join(domainDir, file),
297
318
  feature: feat
298
319
  });
299
320
  }
@@ -308,16 +329,16 @@ function listUseCases(projectRoot, featureName) {
308
329
  const results = [];
309
330
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
310
331
  for (const feat of features) {
311
- const useCasesDir = path2.join(resolveFeaturesDir(projectRoot), feat, "useCases");
312
- if (!fs4.existsSync(useCasesDir)) continue;
332
+ const useCasesDir = path26.join(resolveFeaturesDir(projectRoot), feat, "useCases");
333
+ if (!fs17.existsSync(useCasesDir)) continue;
313
334
  try {
314
- const files = fs4.readdirSync(useCasesDir);
335
+ const files = fs17.readdirSync(useCasesDir);
315
336
  for (const file of files) {
316
337
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
317
338
  const name = file.replace(/\.ts$/, "");
318
339
  results.push({
319
340
  name,
320
- fullPath: path2.join(useCasesDir, file),
341
+ fullPath: path26.join(useCasesDir, file),
321
342
  feature: feat
322
343
  });
323
344
  }
@@ -429,25 +450,25 @@ function normalizeRegistryUrl(urlOrPath, baseDir) {
429
450
  return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`;
430
451
  }
431
452
  if (baseDir && (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed === "." || trimmed === "..")) {
432
- return path2.resolve(baseDir, trimmed);
453
+ return path26.resolve(baseDir, trimmed);
433
454
  }
434
455
  return trimmed;
435
456
  }
436
457
  function findLocalRegistry(startDir = process.cwd()) {
437
- let current = path2.resolve(startDir);
458
+ let current = path26.resolve(startDir);
438
459
  while (true) {
439
- const candidate = path2.join(current, "mason-registry");
440
- if (fs4.existsSync(candidate) && fs4.existsSync(path2.join(candidate, "index.json"))) {
460
+ const candidate = path26.join(current, "mason-registry");
461
+ if (fs17.existsSync(candidate) && fs17.existsSync(path26.join(candidate, "index.json"))) {
441
462
  return candidate;
442
463
  }
443
- const parent = path2.dirname(current);
464
+ const parent = path26.dirname(current);
444
465
  if (parent === current) break;
445
466
  current = parent;
446
467
  }
447
468
  return null;
448
469
  }
449
470
  function getRegistryBase(projectRoot, override) {
450
- const rootDir = projectRoot ? path2.resolve(projectRoot) : process.cwd();
471
+ const rootDir = projectRoot ? path26.resolve(projectRoot) : process.cwd();
451
472
  if (override && override.trim()) {
452
473
  return normalizeRegistryUrl(override.trim(), rootDir);
453
474
  }
@@ -455,30 +476,30 @@ function getRegistryBase(projectRoot, override) {
455
476
  return normalizeRegistryUrl(process.env.MASON_REGISTRY_URL.trim(), rootDir);
456
477
  }
457
478
  const configLocations = [
458
- path2.join(rootDir, "mason.config.json"),
459
- path2.join(process.cwd(), "mason.config.json")
479
+ path26.join(rootDir, "mason.config.json"),
480
+ path26.join(process.cwd(), "mason.config.json")
460
481
  ];
461
482
  for (const configPath of configLocations) {
462
- if (fs4.existsSync(configPath)) {
483
+ if (fs17.existsSync(configPath)) {
463
484
  try {
464
- const config = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
485
+ const config = JSON.parse(fs17.readFileSync(configPath, "utf-8"));
465
486
  if (config.registry && typeof config.registry === "string") {
466
- return normalizeRegistryUrl(config.registry.trim(), path2.dirname(configPath));
487
+ return normalizeRegistryUrl(config.registry.trim(), path26.dirname(configPath));
467
488
  }
468
489
  } catch {
469
490
  }
470
491
  }
471
492
  }
472
493
  const pkgLocations = [
473
- path2.join(rootDir, "package.json"),
474
- path2.join(process.cwd(), "package.json")
494
+ path26.join(rootDir, "package.json"),
495
+ path26.join(process.cwd(), "package.json")
475
496
  ];
476
497
  for (const pkgPath of pkgLocations) {
477
- if (fs4.existsSync(pkgPath)) {
498
+ if (fs17.existsSync(pkgPath)) {
478
499
  try {
479
- const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
500
+ const pkg = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
480
501
  if (pkg.mason?.registry && typeof pkg.mason.registry === "string") {
481
- return normalizeRegistryUrl(pkg.mason.registry.trim(), path2.dirname(pkgPath));
502
+ return normalizeRegistryUrl(pkg.mason.registry.trim(), path26.dirname(pkgPath));
482
503
  }
483
504
  } catch {
484
505
  }
@@ -526,16 +547,16 @@ async function fetchRegistryFile(registryBase, relPath) {
526
547
  if (baseDir.startsWith("file://")) {
527
548
  baseDir = fileURLToPath(baseDir);
528
549
  }
529
- let filePath = path2.resolve(baseDir, cleanRelPath);
530
- if (!fs4.existsSync(filePath)) {
531
- const inSrcPath = path2.resolve(baseDir, "src", cleanRelPath);
532
- if (fs4.existsSync(inSrcPath)) {
550
+ let filePath = path26.resolve(baseDir, cleanRelPath);
551
+ if (!fs17.existsSync(filePath)) {
552
+ const inSrcPath = path26.resolve(baseDir, "src", cleanRelPath);
553
+ if (fs17.existsSync(inSrcPath)) {
533
554
  filePath = inSrcPath;
534
555
  } else {
535
556
  throw new Error(`Registry file not found at ${filePath}`);
536
557
  }
537
558
  }
538
- return fs4.promises.readFile(filePath, "utf-8");
559
+ return fs17.promises.readFile(filePath, "utf-8");
539
560
  }
540
561
  async function fetchRegistryIndex(registryBase) {
541
562
  const content = await fetchRegistryFile(registryBase, "index.json");
@@ -597,19 +618,19 @@ function findClosestMatch(target, candidates) {
597
618
  return null;
598
619
  }
599
620
  function detectPackageManager(projectRoot) {
600
- if (fs4.existsSync(path2.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
601
- if (fs4.existsSync(path2.join(projectRoot, "yarn.lock"))) return "yarn";
602
- if (fs4.existsSync(path2.join(projectRoot, "bun.lockb")) || fs4.existsSync(path2.join(projectRoot, "bun.lock"))) return "bun";
621
+ if (fs17.existsSync(path26.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
622
+ if (fs17.existsSync(path26.join(projectRoot, "yarn.lock"))) return "yarn";
623
+ if (fs17.existsSync(path26.join(projectRoot, "bun.lockb")) || fs17.existsSync(path26.join(projectRoot, "bun.lock"))) return "bun";
603
624
  return "npm";
604
625
  }
605
626
  function getMissingNpmPackages(projectRoot, requiredPackages) {
606
627
  if (!requiredPackages || requiredPackages.length === 0) return [];
607
- const pkgJsonPath = path2.join(projectRoot, "package.json");
608
- if (!fs4.existsSync(pkgJsonPath)) {
628
+ const pkgJsonPath = path26.join(projectRoot, "package.json");
629
+ if (!fs17.existsSync(pkgJsonPath)) {
609
630
  return requiredPackages;
610
631
  }
611
632
  try {
612
- const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
633
+ const pkg = JSON.parse(fs17.readFileSync(pkgJsonPath, "utf-8"));
613
634
  const installed = /* @__PURE__ */ new Set([
614
635
  ...Object.keys(pkg.dependencies || {}),
615
636
  ...Object.keys(pkg.devDependencies || {}),
@@ -648,12 +669,12 @@ function installNpmPackages(projectRoot, packages, pm) {
648
669
  });
649
670
  }
650
671
  function getAllFiles(dir, baseDir = dir) {
651
- if (!fs4.existsSync(dir)) return [];
652
- const entries = fs4.readdirSync(dir, { withFileTypes: true });
672
+ if (!fs17.existsSync(dir)) return [];
673
+ const entries = fs17.readdirSync(dir, { withFileTypes: true });
653
674
  const files = [];
654
675
  for (const entry of entries) {
655
- const fullPath = path2.join(dir, entry.name);
656
- const relPath = path2.relative(baseDir, fullPath).replace(/\\/g, "/");
676
+ const fullPath = path26.join(dir, entry.name);
677
+ const relPath = path26.relative(baseDir, fullPath).replace(/\\/g, "/");
657
678
  if (entry.isDirectory()) {
658
679
  if (entry.name === "__tests__" || entry.name.startsWith(".")) {
659
680
  continue;
@@ -669,13 +690,13 @@ function getAllFiles(dir, baseDir = dir) {
669
690
  return files.sort();
670
691
  }
671
692
  function computeDirectoryHash(dirPath, files) {
672
- if (!fs4.existsSync(dirPath)) return "";
693
+ if (!fs17.existsSync(dirPath)) return "";
673
694
  const hash = createHash("sha256");
674
695
  const fileList = (files ?? getAllFiles(dirPath)).sort();
675
696
  for (const relativePath of fileList) {
676
- const absolutePath = path2.join(dirPath, relativePath);
677
- if (!fs4.existsSync(absolutePath)) continue;
678
- const content = fs4.readFileSync(absolutePath, "utf8");
697
+ const absolutePath = path26.join(dirPath, relativePath);
698
+ if (!fs17.existsSync(absolutePath)) continue;
699
+ const content = fs17.readFileSync(absolutePath, "utf8");
679
700
  const normalizedContent = content.replace(/\r\n/g, "\n");
680
701
  hash.update(relativePath);
681
702
  hash.update(normalizedContent);
@@ -698,33 +719,33 @@ hbs.registerHelper("join", (arr, sep) => {
698
719
  });
699
720
  var cachedTemplatesDir = null;
700
721
  function getTemplatesDir() {
701
- if (cachedTemplatesDir && fs4.existsSync(cachedTemplatesDir)) {
722
+ if (cachedTemplatesDir && fs17.existsSync(cachedTemplatesDir)) {
702
723
  return cachedTemplatesDir;
703
724
  }
704
- const currentDir = typeof __dirname !== "undefined" ? __dirname : path2.dirname(fileURLToPath(import.meta.url));
705
- const cand1 = path2.resolve(currentDir, "../../templates");
706
- if (fs4.existsSync(cand1)) {
725
+ const currentDir = typeof __dirname !== "undefined" ? __dirname : path26.dirname(fileURLToPath(import.meta.url));
726
+ const cand1 = path26.resolve(currentDir, "../../templates");
727
+ if (fs17.existsSync(cand1)) {
707
728
  cachedTemplatesDir = cand1;
708
729
  return cand1;
709
730
  }
710
- const cand2 = path2.resolve(currentDir, "../templates");
711
- if (fs4.existsSync(cand2)) {
731
+ const cand2 = path26.resolve(currentDir, "../templates");
732
+ if (fs17.existsSync(cand2)) {
712
733
  cachedTemplatesDir = cand2;
713
734
  return cand2;
714
735
  }
715
- const cand3 = path2.resolve(currentDir, "templates");
716
- if (fs4.existsSync(cand3)) {
736
+ const cand3 = path26.resolve(currentDir, "templates");
737
+ if (fs17.existsSync(cand3)) {
717
738
  cachedTemplatesDir = cand3;
718
739
  return cand3;
719
740
  }
720
741
  let curr = currentDir;
721
742
  while (true) {
722
- const candTemplates = path2.join(curr, "templates");
723
- if (fs4.existsSync(candTemplates)) {
743
+ const candTemplates = path26.join(curr, "templates");
744
+ if (fs17.existsSync(candTemplates)) {
724
745
  cachedTemplatesDir = candTemplates;
725
746
  return candTemplates;
726
747
  }
727
- const parent = path2.dirname(curr);
748
+ const parent = path26.dirname(curr);
728
749
  if (parent === curr) break;
729
750
  curr = parent;
730
751
  }
@@ -732,8 +753,8 @@ function getTemplatesDir() {
732
753
  }
733
754
  var templateCache = /* @__PURE__ */ new Map();
734
755
  function loadTemplate(relativePath) {
735
- const fullPath = path2.isAbsolute(relativePath) ? relativePath : path2.join(getTemplatesDir(), relativePath);
736
- return fs4.readFileSync(fullPath, "utf-8");
756
+ const fullPath = path26.isAbsolute(relativePath) ? relativePath : path26.join(getTemplatesDir(), relativePath);
757
+ return fs17.readFileSync(fullPath, "utf-8");
737
758
  }
738
759
  function renderTemplateFile(relativePath, context) {
739
760
  let compiled = templateCache.get(relativePath);
@@ -818,8 +839,8 @@ function generateDomainEntityCode(name, kind = "interface", properties = []) {
818
839
  function generateDomain(options) {
819
840
  const projectRoot = options.projectRoot || findProjectRoot();
820
841
  const entityName = toPascalCase(options.name);
821
- const targetDir = options.targetDir || path2.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
822
- const filePath = path2.join(targetDir, `${entityName}.ts`);
842
+ const targetDir = options.targetDir || path26.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
843
+ const filePath = path26.join(targetDir, `${entityName}.ts`);
823
844
  const code = generateDomainEntityCode(
824
845
  entityName,
825
846
  options.kind || "interface",
@@ -868,8 +889,8 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
868
889
  function generateInterface(options) {
869
890
  const projectRoot = options.projectRoot || findProjectRoot();
870
891
  const ifaceName = ensureInterfacePrefix(options.name);
871
- const targetDir = options.targetDir || path2.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
872
- const filePath = path2.join(targetDir, `${ifaceName}.ts`);
892
+ const targetDir = options.targetDir || path26.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
893
+ const filePath = path26.join(targetDir, `${ifaceName}.ts`);
873
894
  const code = generateInterfaceCode(
874
895
  ifaceName,
875
896
  options.kind || "abstractClass",
@@ -1104,7 +1125,7 @@ function parseInterfaceMethodsAndImports(content, targetIfaceName) {
1104
1125
  };
1105
1126
  }
1106
1127
  function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
1107
- if (customPath && fs4.existsSync(customPath)) {
1128
+ if (customPath && fs17.existsSync(customPath)) {
1108
1129
  return { filePath: customPath, ifaceName };
1109
1130
  }
1110
1131
  const candidateNames = [
@@ -1114,22 +1135,22 @@ function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
1114
1135
  ];
1115
1136
  const features = featureName ? [featureName, ...listExistingFeatures(projectRoot).filter((f) => f !== featureName)] : listExistingFeatures(projectRoot);
1116
1137
  for (const feat of features) {
1117
- const domainDir = path2.join(resolveFeaturesDir(projectRoot), feat, "domain");
1118
- if (!fs4.existsSync(domainDir)) continue;
1138
+ const domainDir = path26.join(resolveFeaturesDir(projectRoot), feat, "domain");
1139
+ if (!fs17.existsSync(domainDir)) continue;
1119
1140
  for (const cand of candidateNames) {
1120
- const p1 = path2.join(domainDir, `${cand}.ts`);
1121
- if (fs4.existsSync(p1)) {
1141
+ const p1 = path26.join(domainDir, `${cand}.ts`);
1142
+ if (fs17.existsSync(p1)) {
1122
1143
  return { filePath: p1, ifaceName: cand, feature: feat };
1123
1144
  }
1124
1145
  }
1125
1146
  }
1126
1147
  for (const cand of candidateNames) {
1127
- const p1 = path2.join(projectRoot, "domain", `${cand}.ts`);
1128
- if (fs4.existsSync(p1)) return { filePath: p1, ifaceName: cand };
1129
- const p22 = path2.join(projectRoot, "src", "domain", `${cand}.ts`);
1130
- if (fs4.existsSync(p22)) return { filePath: p22, ifaceName: cand };
1131
- const p32 = path2.join(projectRoot, "interfaces", `${cand}.ts`);
1132
- if (fs4.existsSync(p32)) return { filePath: p32, ifaceName: cand };
1148
+ const p1 = path26.join(projectRoot, "domain", `${cand}.ts`);
1149
+ if (fs17.existsSync(p1)) return { filePath: p1, ifaceName: cand };
1150
+ const p22 = path26.join(projectRoot, "src", "domain", `${cand}.ts`);
1151
+ if (fs17.existsSync(p22)) return { filePath: p22, ifaceName: cand };
1152
+ const p32 = path26.join(projectRoot, "interfaces", `${cand}.ts`);
1153
+ if (fs17.existsSync(p32)) return { filePath: p32, ifaceName: cand };
1133
1154
  }
1134
1155
  return null;
1135
1156
  }
@@ -1152,7 +1173,7 @@ function loadInterfaceHierarchy(projectRoot, initialIfaceName, featureName, cust
1152
1173
  while (currentFile && !visited.has(currentFile)) {
1153
1174
  visited.add(currentFile);
1154
1175
  try {
1155
- const content = fs4.readFileSync(currentFile, "utf-8");
1176
+ const content = fs17.readFileSync(currentFile, "utf-8");
1156
1177
  const parsed = parseInterfaceMethodsAndImports(content, currentName);
1157
1178
  for (const m of parsed.methods) {
1158
1179
  if (!allMethods.some((existing) => existing.name === m.name)) {
@@ -1228,7 +1249,7 @@ function generateStubCode(stubClassName, ifaceName, entityName, featureName, met
1228
1249
  const entitiesVar = `${entityVar}s`;
1229
1250
  const idKey = `${entityVar}Id`;
1230
1251
  const impPath = ifaceImportPath || `../domain/${ifaceName}.js`;
1231
- const entityImportPath = ifaceImportPath ? `${path2.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1252
+ const entityImportPath = ifaceImportPath ? `${path26.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1232
1253
  const importsByFrom = /* @__PURE__ */ new Map();
1233
1254
  for (const imp of domainImports) {
1234
1255
  if (imp.name === ifaceName || imp.name === baseEntity) continue;
@@ -1277,7 +1298,7 @@ function generateConcreteInfraCode(className, ifaceName, dependencies = [], meth
1277
1298
  if (baseEntity) {
1278
1299
  finalMethods = synthesizeCrudMethods(baseEntity);
1279
1300
  if (!finalDomainImports.some((imp) => imp.name === baseEntity)) {
1280
- const importPath = ifaceImportPath ? `${path2.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1301
+ const importPath = ifaceImportPath ? `${path26.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1281
1302
  finalDomainImports.push({
1282
1303
  name: baseEntity,
1283
1304
  from: importPath,
@@ -1322,8 +1343,8 @@ function generateInfrastructure(options) {
1322
1343
  const projectRoot = options.projectRoot || findProjectRoot();
1323
1344
  const className = toPascalCase(options.name);
1324
1345
  const isFeatureScope = options.scope !== "global" && Boolean(options.feature);
1325
- const targetDir = options.targetDir || (isFeatureScope ? path2.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path2.join(projectRoot, "infrastructure"));
1326
- const filePath = path2.join(targetDir, `${className}.ts`);
1346
+ const targetDir = options.targetDir || (isFeatureScope ? path26.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path26.join(projectRoot, "infrastructure"));
1347
+ const filePath = path26.join(targetDir, `${className}.ts`);
1327
1348
  let code;
1328
1349
  if (options.implementsInterface) {
1329
1350
  const rawIfaceName = options.implementsInterface;
@@ -1337,7 +1358,7 @@ function generateInfrastructure(options) {
1337
1358
  const ifaceFilePath = hierarchy.ifaceFilePath;
1338
1359
  let ifaceImportPath;
1339
1360
  if (ifaceFilePath) {
1340
- let rel = path2.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
1361
+ let rel = path26.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
1341
1362
  if (!rel.startsWith(".")) rel = "./" + rel;
1342
1363
  ifaceImportPath = rel;
1343
1364
  } else if (isFeatureScope) {
@@ -1350,8 +1371,8 @@ function generateInfrastructure(options) {
1350
1371
  if (new RegExp(`\\b${item.name}\\b`).test(allSignatures)) {
1351
1372
  let fromPath;
1352
1373
  if (imp.specifier.startsWith(".") && ifaceFilePath) {
1353
- const absTarget = path2.resolve(path2.dirname(ifaceFilePath), imp.specifier);
1354
- let rel = path2.relative(targetDir, absTarget).replace(/\\/g, "/");
1374
+ const absTarget = path26.resolve(path26.dirname(ifaceFilePath), imp.specifier);
1375
+ let rel = path26.relative(targetDir, absTarget).replace(/\\/g, "/");
1355
1376
  if (!rel.startsWith(".")) rel = "./" + rel;
1356
1377
  fromPath = rel;
1357
1378
  } else {
@@ -1538,8 +1559,8 @@ function generateUseCase(options) {
1538
1559
  const files = [];
1539
1560
  const projectRoot = options.projectRoot || findProjectRoot();
1540
1561
  const ucName = toPascalCase(options.name);
1541
- const targetDir = options.targetDir || path2.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1542
- const filePath = path2.join(targetDir, `${ucName}.ts`);
1562
+ const targetDir = options.targetDir || path26.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1563
+ const filePath = path26.join(targetDir, `${ucName}.ts`);
1543
1564
  const code = generateUseCaseCode(
1544
1565
  ucName,
1545
1566
  options.dependencies || [],
@@ -1555,7 +1576,7 @@ function generateUseCase(options) {
1555
1576
  })
1556
1577
  );
1557
1578
  if (options.includeTest) {
1558
- const testPath = path2.join(targetDir, `${ucName}.test.ts`);
1579
+ const testPath = path26.join(targetDir, `${ucName}.test.ts`);
1559
1580
  const testCode = generateUseCaseTestCode(ucName, options.dependencies || []);
1560
1581
  files.push(
1561
1582
  writeFileSafely(testPath, testCode, {
@@ -1623,10 +1644,10 @@ function generateHttpHandler(options) {
1623
1644
  const files = [];
1624
1645
  const projectRoot = options.projectRoot || findProjectRoot();
1625
1646
  const className = toPascalCase(options.name);
1626
- const pxDir = path2.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1627
- const handlersDir = path2.join(pxDir, "handlers");
1628
- const pxIndexPath = path2.join(pxDir, "index.ts");
1629
- if (!fs4.existsSync(pxIndexPath)) {
1647
+ const pxDir = path26.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1648
+ const handlersDir = path26.join(pxDir, "handlers");
1649
+ const pxIndexPath = path26.join(pxDir, "index.ts");
1650
+ if (!fs17.existsSync(pxIndexPath)) {
1630
1651
  const featurePath = options.routePrefix || `/${options.feature.toLowerCase()}`;
1631
1652
  const pxIndexContent = renderTemplate(expressIndexTemplate, {
1632
1653
  routePath: featurePath
@@ -1639,7 +1660,7 @@ function generateHttpHandler(options) {
1639
1660
  })
1640
1661
  );
1641
1662
  }
1642
- const handlerFilePath = path2.join(handlersDir, `${className}.ts`);
1663
+ const handlerFilePath = path26.join(handlersDir, `${className}.ts`);
1643
1664
  const code = generateHttpHandlerCode(
1644
1665
  className,
1645
1666
  options.method || "get",
@@ -1660,11 +1681,11 @@ function generateHttpHandler(options) {
1660
1681
  return files;
1661
1682
  }
1662
1683
  function updateOrGenerateDiProvider(featureDir, featureName, bindings = [], options = {}) {
1663
- const providerPath = path2.join(featureDir, "diProvider.ts");
1684
+ const providerPath = path26.join(featureDir, "diProvider.ts");
1664
1685
  const pascalFeature = toPascalCase(featureName);
1665
1686
  const providerModuleName = `${pascalFeature}Provider`;
1666
- if (fs4.existsSync(providerPath) && !options.overwrite) {
1667
- let content = fs4.readFileSync(providerPath, "utf-8");
1687
+ if (fs17.existsSync(providerPath) && !options.overwrite) {
1688
+ let content = fs17.readFileSync(providerPath, "utf-8");
1668
1689
  content = content.replace(/\n*export\s+const\s+ScaffoldProvider\s*=[^;]+;?/g, "");
1669
1690
  for (const b of bindings) {
1670
1691
  const ifaceImp = b.ifaceImportPath || `./domain/${b.ifaceName}.js`;
@@ -1723,7 +1744,7 @@ function generateFeature(options) {
1723
1744
  const projectRoot = options.projectRoot || findProjectRoot();
1724
1745
  const rawName = options.name.trim();
1725
1746
  const featureName = toCamelCase(rawName);
1726
- const targetDir = options.targetDir || path2.join(resolveFeaturesDir(projectRoot), featureName);
1747
+ const targetDir = options.targetDir || path26.join(resolveFeaturesDir(projectRoot), featureName);
1727
1748
  const routePath = options.routePath || `/${featureName}`;
1728
1749
  const rawEntities = [];
1729
1750
  if (options.entityNames && options.entityNames.length > 0) {
@@ -1744,7 +1765,7 @@ function generateFeature(options) {
1744
1765
  const domainFile = generateDomain({
1745
1766
  name: ent,
1746
1767
  feature: featureName,
1747
- targetDir: path2.join(targetDir, "domain"),
1768
+ targetDir: path26.join(targetDir, "domain"),
1748
1769
  projectRoot,
1749
1770
  dryRun: options.dryRun,
1750
1771
  overwrite: options.overwrite,
@@ -1764,7 +1785,7 @@ function generateFeature(options) {
1764
1785
  const ifaceFile = generateInterface({
1765
1786
  name: ifaceName,
1766
1787
  feature: featureName,
1767
- targetDir: path2.join(targetDir, "domain"),
1788
+ targetDir: path26.join(targetDir, "domain"),
1768
1789
  entityName: ent,
1769
1790
  projectRoot,
1770
1791
  dryRun: options.dryRun,
@@ -1781,7 +1802,7 @@ function generateFeature(options) {
1781
1802
  const stubFile = generateInfrastructure({
1782
1803
  name: stubName,
1783
1804
  feature: featureName,
1784
- targetDir: path2.join(targetDir, "infrastructure"),
1805
+ targetDir: path26.join(targetDir, "infrastructure"),
1785
1806
  kind: "stub",
1786
1807
  implementsInterface: ifaceName,
1787
1808
  entityName: ent,
@@ -1823,7 +1844,7 @@ function generateFeature(options) {
1823
1844
  const ucFiles = generateUseCase({
1824
1845
  name: ucName,
1825
1846
  feature: featureName,
1826
- targetDir: path2.join(targetDir, "useCases"),
1847
+ targetDir: path26.join(targetDir, "useCases"),
1827
1848
  dependencies: options.includeInterface !== false ? [ifaceName] : [],
1828
1849
  inputProperties: [{ name: idParam, type: "string" }],
1829
1850
  outputProperties: [{ name: entVar, type: primaryEntity }],
@@ -1868,7 +1889,7 @@ function generateFeature(options) {
1868
1889
  const ucFiles = generateUseCase({
1869
1890
  name: ucName,
1870
1891
  feature: featureName,
1871
- targetDir: path2.join(targetDir, "useCases"),
1892
+ targetDir: path26.join(targetDir, "useCases"),
1872
1893
  dependencies: deps,
1873
1894
  inputProperties: [{ name: entVar, type: ent }],
1874
1895
  outputProperties: [{ name: entVar, type: ent }],
@@ -1901,7 +1922,7 @@ function generateFeature(options) {
1901
1922
  const ucFiles = generateUseCase({
1902
1923
  name: ucName,
1903
1924
  feature: featureName,
1904
- targetDir: path2.join(targetDir, "useCases"),
1925
+ targetDir: path26.join(targetDir, "useCases"),
1905
1926
  dependencies: deps,
1906
1927
  inputProperties: [{ name: idParam, type: "string" }],
1907
1928
  outputProperties: [{ name: entVar, type: ent }],
@@ -1934,7 +1955,7 @@ function generateFeature(options) {
1934
1955
  const ucFiles = generateUseCase({
1935
1956
  name: ucName,
1936
1957
  feature: featureName,
1937
- targetDir: path2.join(targetDir, "useCases"),
1958
+ targetDir: path26.join(targetDir, "useCases"),
1938
1959
  dependencies: deps,
1939
1960
  inputProperties: [
1940
1961
  { name: "page", type: "number", optional: true },
@@ -1978,7 +1999,7 @@ function generateFeature(options) {
1978
1999
  const ucFiles = generateUseCase({
1979
2000
  name: ucName,
1980
2001
  feature: featureName,
1981
- targetDir: path2.join(targetDir, "useCases"),
2002
+ targetDir: path26.join(targetDir, "useCases"),
1982
2003
  dependencies: deps,
1983
2004
  inputProperties: [{ name: entVar, type: ent }],
1984
2005
  outputProperties: [{ name: entVar, type: ent }],
@@ -2011,7 +2032,7 @@ function generateFeature(options) {
2011
2032
  const ucFiles = generateUseCase({
2012
2033
  name: ucName,
2013
2034
  feature: featureName,
2014
- targetDir: path2.join(targetDir, "useCases"),
2035
+ targetDir: path26.join(targetDir, "useCases"),
2015
2036
  dependencies: deps,
2016
2037
  inputProperties: [{ name: idParam, type: "string" }],
2017
2038
  outputProperties: [{ name: "success", type: "boolean" }],
@@ -2048,7 +2069,7 @@ function generateFeature(options) {
2048
2069
  const ucFiles = generateUseCase({
2049
2070
  name: ucName,
2050
2071
  feature: featureName,
2051
- targetDir: path2.join(targetDir, "useCases"),
2072
+ targetDir: path26.join(targetDir, "useCases"),
2052
2073
  dependencies: customUc.dependencies || [],
2053
2074
  inputProperties: customUc.inputProperties || [],
2054
2075
  outputProperties: customUc.outputProperties || [],
@@ -2080,8 +2101,8 @@ function generateFeature(options) {
2080
2101
  }
2081
2102
  }
2082
2103
  if (options.includeExpress !== false) {
2083
- const pxDir = path2.join(targetDir, "pxExpress");
2084
- const pxIndexPath = path2.join(pxDir, "index.ts");
2104
+ const pxDir = path26.join(targetDir, "pxExpress");
2105
+ const pxIndexPath = path26.join(pxDir, "index.ts");
2085
2106
  if (!files.some((f) => f.absolutePath === pxIndexPath)) {
2086
2107
  const pxIndexContent = renderTemplate(expressIndexTemplate, { routePath });
2087
2108
  files.push(
@@ -2126,7 +2147,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2126
2147
  }
2127
2148
  const normalizedName = toCamelCase(name);
2128
2149
  const baseFeaturesDir = resolveFeaturesDir(projectRoot, flags);
2129
- const defaultDir = path2.relative(projectRoot, path2.join(baseFeaturesDir, normalizedName));
2150
+ const defaultDir = path26.relative(projectRoot, path26.join(baseFeaturesDir, normalizedName));
2130
2151
  let targetDirRel = defaultDir;
2131
2152
  if (!flags.yes && !flags.target && !flags.dest) {
2132
2153
  targetDirRel = handleCancel(
@@ -2137,7 +2158,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2137
2158
  })
2138
2159
  ).trim();
2139
2160
  }
2140
- const targetDir = flags.dest ? path2.resolve(projectRoot, flags.dest) : flags.target ? path2.resolve(projectRoot, flags.target) : path2.resolve(projectRoot, targetDirRel);
2161
+ const targetDir = flags.dest ? path26.resolve(projectRoot, flags.dest) : flags.target ? path26.resolve(projectRoot, flags.target) : path26.resolve(projectRoot, targetDirRel);
2141
2162
  let includeExpress = flags.express !== void 0 ? Boolean(flags.express) : true;
2142
2163
  let routePath = `/${normalizedName}`;
2143
2164
  let includeDomain = true;
@@ -2379,8 +2400,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2379
2400
  };
2380
2401
  const files = generateFeature(options);
2381
2402
  if (isRegistry) {
2382
- const registryPath = path2.join(targetDir, "registry.json");
2383
- if (!fs4.existsSync(registryPath)) {
2403
+ const registryPath = path26.join(targetDir, "registry.json");
2404
+ if (!fs17.existsSync(registryPath)) {
2384
2405
  const manifest = {
2385
2406
  name: toKebabCase(normalizedName),
2386
2407
  type: "feature",
@@ -2406,7 +2427,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2406
2427
  printGeneratedFiles(files, options.dryRun);
2407
2428
  p19.outro(
2408
2429
  pc14.green(
2409
- `\u2713 Feature '${normalizedName}' initialized in ${path2.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2430
+ `\u2713 Feature '${normalizedName}' initialized in ${path26.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2410
2431
  )
2411
2432
  );
2412
2433
  }
@@ -2417,7 +2438,7 @@ function generateShared(options) {
2417
2438
  const pascalName = toPascalCase(rawName);
2418
2439
  const camelName = toCamelCase(rawName);
2419
2440
  const kebabName = toKebabCase(rawName);
2420
- const targetDir = options.targetDir || path2.join(resolveSharedDir(projectRoot), kebabName);
2441
+ const targetDir = options.targetDir || path26.join(resolveSharedDir(projectRoot), kebabName);
2421
2442
  const fileDefs = [];
2422
2443
  const facadeContent = `import { MakeInjectable, type DepsType } from "@solid-stack/di";
2423
2444
  import { I${pascalName}Engine } from "./ports/I${pascalName}Engine.js";
@@ -2429,7 +2450,7 @@ export class ${pascalName} {
2429
2450
  }
2430
2451
  `;
2431
2452
  fileDefs.push({
2432
- absolutePath: path2.join(targetDir, `${pascalName}.ts`),
2453
+ absolutePath: path26.join(targetDir, `${pascalName}.ts`),
2433
2454
  content: facadeContent
2434
2455
  });
2435
2456
  const portContent = `export abstract class I${pascalName}Engine {
@@ -2437,7 +2458,7 @@ export class ${pascalName} {
2437
2458
  }
2438
2459
  `;
2439
2460
  fileDefs.push({
2440
- absolutePath: path2.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2461
+ absolutePath: path26.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2441
2462
  content: portContent
2442
2463
  });
2443
2464
  const concreteContent = `import { MakeInjectable } from "@solid-stack/di";
@@ -2449,7 +2470,7 @@ export class Default${pascalName}Engine implements I${pascalName}Engine {
2449
2470
  }
2450
2471
  `;
2451
2472
  fileDefs.push({
2452
- absolutePath: path2.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2473
+ absolutePath: path26.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2453
2474
  content: concreteContent
2454
2475
  });
2455
2476
  if (options.includeStub !== false) {
@@ -2462,7 +2483,7 @@ export class Stub${pascalName}Engine implements I${pascalName}Engine {
2462
2483
  }
2463
2484
  `;
2464
2485
  fileDefs.push({
2465
- absolutePath: path2.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2486
+ absolutePath: path26.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2466
2487
  content: stubContent
2467
2488
  });
2468
2489
  }
@@ -2477,7 +2498,7 @@ export const diProvider = (c: Container): void => {
2477
2498
  export default diProvider;
2478
2499
  `;
2479
2500
  fileDefs.push({
2480
- absolutePath: path2.join(targetDir, "diProvider.ts"),
2501
+ absolutePath: path26.join(targetDir, "diProvider.ts"),
2481
2502
  content: providerContent
2482
2503
  });
2483
2504
  if (options.isRegistry) {
@@ -2494,7 +2515,7 @@ export default diProvider;
2494
2515
  files: []
2495
2516
  };
2496
2517
  fileDefs.push({
2497
- absolutePath: path2.join(targetDir, "registry.json"),
2518
+ absolutePath: path26.join(targetDir, "registry.json"),
2498
2519
  content: JSON.stringify(registryManifest, null, 2) + "\n"
2499
2520
  });
2500
2521
  }
@@ -2531,7 +2552,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2531
2552
  }
2532
2553
  const normalizedName = toKebabCase(name);
2533
2554
  const baseSharedDir = resolveSharedDir(projectRoot, flags);
2534
- const defaultDir = path2.relative(projectRoot, path2.join(baseSharedDir, normalizedName));
2555
+ const defaultDir = path26.relative(projectRoot, path26.join(baseSharedDir, normalizedName));
2535
2556
  let targetDirRel = defaultDir;
2536
2557
  if (!flags.yes && !flags.target && !flags.dest) {
2537
2558
  targetDirRel = handleCancel(
@@ -2542,7 +2563,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2542
2563
  })
2543
2564
  ).trim();
2544
2565
  }
2545
- const targetDir = flags.dest ? path2.resolve(projectRoot, flags.dest) : flags.target ? path2.resolve(projectRoot, flags.target) : path2.resolve(projectRoot, targetDirRel);
2566
+ const targetDir = flags.dest ? path26.resolve(projectRoot, flags.dest) : flags.target ? path26.resolve(projectRoot, flags.target) : path26.resolve(projectRoot, targetDirRel);
2546
2567
  let description = flags.description || "";
2547
2568
  let includeStub = true;
2548
2569
  if (!flags.yes) {
@@ -2576,7 +2597,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2576
2597
  printGeneratedFiles(files, Boolean(flags.dryRun));
2577
2598
  p19.outro(
2578
2599
  pc14.green(
2579
- `\u2713 Shared module '${normalizedName}' initialized in ${path2.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2600
+ `\u2713 Shared module '${normalizedName}' initialized in ${path26.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2580
2601
  )
2581
2602
  );
2582
2603
  }
@@ -3003,7 +3024,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
3003
3024
  const infraFile = generateInfrastructure(options);
3004
3025
  files.push(infraFile);
3005
3026
  if (registerInProvider && scope === "feature" && feature && implementsInterface) {
3006
- const featureDir = path2.join(resolveFeaturesDir(projectRoot), feature);
3027
+ const featureDir = path26.join(resolveFeaturesDir(projectRoot), feature);
3007
3028
  const providerFile = updateOrGenerateDiProvider(
3008
3029
  featureDir,
3009
3030
  feature,
@@ -3165,7 +3186,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3165
3186
  files.push(stubFile);
3166
3187
  }
3167
3188
  if (registerInProvider && generateStub) {
3168
- const featureDir = path2.join(resolveFeaturesDir(projectRoot), feature);
3189
+ const featureDir = path26.join(resolveFeaturesDir(projectRoot), feature);
3169
3190
  const providerFile = updateOrGenerateDiProvider(
3170
3191
  featureDir,
3171
3192
  feature,
@@ -3353,21 +3374,21 @@ function generateInjectable(options) {
3353
3374
  const className = toPascalCase(options.name);
3354
3375
  let targetDir = "";
3355
3376
  if (options.customPath) {
3356
- targetDir = path2.isAbsolute(options.customPath) ? options.customPath : path2.join(projectRoot, options.customPath);
3377
+ targetDir = path26.isAbsolute(options.customPath) ? options.customPath : path26.join(projectRoot, options.customPath);
3357
3378
  } else if (options.location === "feature-service" && options.feature) {
3358
- targetDir = path2.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3379
+ targetDir = path26.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3359
3380
  } else if (options.location === "feature-transformer" && options.feature) {
3360
- targetDir = path2.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3381
+ targetDir = path26.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3361
3382
  } else if (options.location === "module") {
3362
- targetDir = path2.join(projectRoot, "modules", className);
3383
+ targetDir = path26.join(projectRoot, "modules", className);
3363
3384
  } else {
3364
- targetDir = options.feature ? path2.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path2.join(projectRoot, "shared", className.toLowerCase());
3385
+ targetDir = options.feature ? path26.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path26.join(projectRoot, "shared", className.toLowerCase());
3365
3386
  }
3366
- const filePath = path2.join(targetDir, `${className}.ts`);
3387
+ const filePath = path26.join(targetDir, `${className}.ts`);
3367
3388
  let ifaceName;
3368
3389
  if (options.generateInterface) {
3369
3390
  ifaceName = `I${className}`;
3370
- const ifacePath = path2.join(targetDir, `${ifaceName}.ts`);
3391
+ const ifacePath = path26.join(targetDir, `${ifaceName}.ts`);
3371
3392
  const ifaceContent = renderTemplate(injectableInterfaceTemplate, { ifaceName });
3372
3393
  files.push(
3373
3394
  writeFileSafely(ifacePath, ifaceContent, {
@@ -3496,7 +3517,7 @@ async function runEnvInit(flags = {}) {
3496
3517
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3497
3518
  const s = p19.spinner();
3498
3519
  s.start("Scanning for .example environment files...");
3499
- const files = fs4.readdirSync(projectRoot);
3520
+ const files = fs17.readdirSync(projectRoot);
3500
3521
  const exampleFiles = files.filter((file) => file.startsWith(".env") && file.endsWith(".example")).sort();
3501
3522
  if (exampleFiles.length === 0) {
3502
3523
  s.stop("No .example files found.");
@@ -3506,11 +3527,11 @@ async function runEnvInit(flags = {}) {
3506
3527
  s.message(`Found ${exampleFiles.length} template(s). Generating...`);
3507
3528
  const generatedFiles = [];
3508
3529
  for (const exampleFile of exampleFiles) {
3509
- const sourcePath = path2.join(projectRoot, exampleFile);
3530
+ const sourcePath = path26.join(projectRoot, exampleFile);
3510
3531
  const targetFile = exampleFile.replace(/\.example$/, "");
3511
- const targetPath = path2.join(projectRoot, targetFile);
3532
+ const targetPath = path26.join(projectRoot, targetFile);
3512
3533
  let overwrite = flags.overwrite;
3513
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4.existsSync(targetPath)) {
3534
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17.existsSync(targetPath)) {
3514
3535
  overwrite = await p19.confirm({
3515
3536
  message: `${targetFile} already exists. Overwrite?`,
3516
3537
  initialValue: false
@@ -3520,7 +3541,7 @@ async function runEnvInit(flags = {}) {
3520
3541
  process.exit(0);
3521
3542
  }
3522
3543
  }
3523
- const content = fs4.readFileSync(sourcePath, "utf-8");
3544
+ const content = fs17.readFileSync(sourcePath, "utf-8");
3524
3545
  const genFile = writeFileSafely(targetPath, content, {
3525
3546
  projectRoot,
3526
3547
  dryRun: Boolean(flags.dryRun),
@@ -3539,7 +3560,7 @@ var EnvEditor = class {
3539
3560
  filePath;
3540
3561
  constructor(filePath) {
3541
3562
  this.filePath = filePath;
3542
- this.lines = fs4.existsSync(filePath) ? fs4.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3563
+ this.lines = fs17.existsSync(filePath) ? fs17.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3543
3564
  }
3544
3565
  getLines() {
3545
3566
  return [...this.lines];
@@ -3603,18 +3624,18 @@ var EnvEditor = class {
3603
3624
  });
3604
3625
  }
3605
3626
  save() {
3606
- const dir = path2.dirname(this.filePath);
3607
- if (!fs4.existsSync(dir)) {
3608
- fs4.mkdirSync(dir, { recursive: true });
3627
+ const dir = path26.dirname(this.filePath);
3628
+ if (!fs17.existsSync(dir)) {
3629
+ fs17.mkdirSync(dir, { recursive: true });
3609
3630
  }
3610
- fs4.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3631
+ fs17.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3611
3632
  }
3612
3633
  };
3613
3634
  function discoverEnvironments(projectRoot) {
3614
- if (!fs4.existsSync(projectRoot)) {
3635
+ if (!fs17.existsSync(projectRoot)) {
3615
3636
  return ["local", "dev", "prod"];
3616
3637
  }
3617
- const files = fs4.readdirSync(projectRoot);
3638
+ const files = fs17.readdirSync(projectRoot);
3618
3639
  const envs = /* @__PURE__ */ new Set();
3619
3640
  for (const file of files) {
3620
3641
  if (file.startsWith(".env")) {
@@ -3639,7 +3660,7 @@ async function runEnvInitExamples(flags = {}) {
3639
3660
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3640
3661
  const s = p19.spinner();
3641
3662
  s.start("Scanning for local environment files...");
3642
- const files = fs4.readdirSync(projectRoot, { withFileTypes: true });
3663
+ const files = fs17.readdirSync(projectRoot, { withFileTypes: true });
3643
3664
  const envFiles = files.filter((dirent) => dirent.isFile() && dirent.name.startsWith(".env") && !dirent.name.endsWith(".example")).map((dirent) => dirent.name).sort();
3644
3665
  if (envFiles.length === 0) {
3645
3666
  s.stop("No local .env files found.");
@@ -3649,11 +3670,11 @@ async function runEnvInitExamples(flags = {}) {
3649
3670
  s.message(`Found ${envFiles.length} local .env file(s). Generating templates...`);
3650
3671
  const generatedFiles = [];
3651
3672
  for (const envFile of envFiles) {
3652
- const sourcePath = path2.join(projectRoot, envFile);
3673
+ const sourcePath = path26.join(projectRoot, envFile);
3653
3674
  const targetFile = `${envFile}.example`;
3654
- const targetPath = path2.join(projectRoot, targetFile);
3675
+ const targetPath = path26.join(projectRoot, targetFile);
3655
3676
  let overwrite = flags.overwrite;
3656
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4.existsSync(targetPath)) {
3677
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17.existsSync(targetPath)) {
3657
3678
  overwrite = await p19.confirm({
3658
3679
  message: `${targetFile} already exists. Overwrite with redacted values?`,
3659
3680
  initialValue: true
@@ -3687,12 +3708,12 @@ function isInteractive(flags) {
3687
3708
  function getAllExistingKeys(projectRoot, envs) {
3688
3709
  const keys = /* @__PURE__ */ new Set();
3689
3710
  for (const env of envs) {
3690
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3691
- const examplePath = path2.join(projectRoot, resolveEnvFilename(env, true));
3692
- if (fs4.existsSync(localPath)) {
3711
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3712
+ const examplePath = path26.join(projectRoot, resolveEnvFilename(env, true));
3713
+ if (fs17.existsSync(localPath)) {
3693
3714
  new EnvEditor(localPath).getKeys().forEach((k) => keys.add(k));
3694
3715
  }
3695
- if (fs4.existsSync(examplePath)) {
3716
+ if (fs17.existsSync(examplePath)) {
3696
3717
  new EnvEditor(examplePath).getKeys().forEach((k) => keys.add(k));
3697
3718
  }
3698
3719
  }
@@ -3764,8 +3785,8 @@ async function runEnvAdd(key, value, flags = {}) {
3764
3785
  })
3765
3786
  );
3766
3787
  }
3767
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3768
- const examplePath = path2.join(projectRoot, resolveEnvFilename(env, true));
3788
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3789
+ const examplePath = path26.join(projectRoot, resolveEnvFilename(env, true));
3769
3790
  if (flags.dryRun) {
3770
3791
  p19.log.info(
3771
3792
  pc14.cyan(`[DRY RUN] Would set ${targetKey}=${envVal} in ${resolveEnvFilename(env, false)}`)
@@ -3812,8 +3833,8 @@ async function runEnvUpdate(key, value, flags = {}) {
3812
3833
  );
3813
3834
  }
3814
3835
  const envsWithKey = allEnvs.filter((env) => {
3815
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3816
- return fs4.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3836
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3837
+ return fs17.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3817
3838
  });
3818
3839
  let targetEnvs = [];
3819
3840
  if (flags.env) {
@@ -3839,7 +3860,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3839
3860
  return { key: targetKey, environments: [] };
3840
3861
  }
3841
3862
  for (const env of targetEnvs) {
3842
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3863
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3843
3864
  const localEditor = new EnvEditor(localPath);
3844
3865
  const currentVal = localEditor.getValue(targetKey);
3845
3866
  let newVal = value;
@@ -3869,7 +3890,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3869
3890
  } else {
3870
3891
  localEditor.set(targetKey, newVal);
3871
3892
  localEditor.save();
3872
- const examplePath = path2.join(projectRoot, resolveEnvFilename(env, true));
3893
+ const examplePath = path26.join(projectRoot, resolveEnvFilename(env, true));
3873
3894
  const exampleEditor = new EnvEditor(examplePath);
3874
3895
  if (!exampleEditor.has(targetKey)) {
3875
3896
  exampleEditor.set(targetKey, "");
@@ -3905,9 +3926,9 @@ async function runEnvDelete(key, flags = {}) {
3905
3926
  );
3906
3927
  }
3907
3928
  const envsWithKey = allEnvs.filter((env) => {
3908
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3909
- const examplePath = path2.join(projectRoot, resolveEnvFilename(env, true));
3910
- return fs4.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs4.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3929
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3930
+ const examplePath = path26.join(projectRoot, resolveEnvFilename(env, true));
3931
+ return fs17.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs17.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3911
3932
  });
3912
3933
  let targetEnvs = [];
3913
3934
  if (flags.env) {
@@ -3945,19 +3966,19 @@ async function runEnvDelete(key, flags = {}) {
3945
3966
  }
3946
3967
  }
3947
3968
  for (const env of targetEnvs) {
3948
- const localPath = path2.join(projectRoot, resolveEnvFilename(env, false));
3949
- const examplePath = path2.join(projectRoot, resolveEnvFilename(env, true));
3969
+ const localPath = path26.join(projectRoot, resolveEnvFilename(env, false));
3970
+ const examplePath = path26.join(projectRoot, resolveEnvFilename(env, true));
3950
3971
  if (flags.dryRun) {
3951
3972
  p19.log.info(
3952
3973
  pc14.cyan(`[DRY RUN] Would delete ${targetKey} from ${resolveEnvFilename(env, false)} and ${resolveEnvFilename(env, true)}`)
3953
3974
  );
3954
3975
  } else {
3955
- if (fs4.existsSync(localPath)) {
3976
+ if (fs17.existsSync(localPath)) {
3956
3977
  const localEditor = new EnvEditor(localPath);
3957
3978
  localEditor.delete(targetKey);
3958
3979
  localEditor.save();
3959
3980
  }
3960
- if (fs4.existsSync(examplePath)) {
3981
+ if (fs17.existsSync(examplePath)) {
3961
3982
  const exampleEditor = new EnvEditor(examplePath);
3962
3983
  exampleEditor.delete(targetKey);
3963
3984
  exampleEditor.save();
@@ -3982,10 +4003,10 @@ async function runEnvAudit(flags = {}) {
3982
4003
  for (const env of envs) {
3983
4004
  const localFile = resolveEnvFilename(env, false);
3984
4005
  const exampleFile = resolveEnvFilename(env, true);
3985
- const localPath = path2.join(projectRoot, localFile);
3986
- const examplePath = path2.join(projectRoot, exampleFile);
3987
- const localExists = fs4.existsSync(localPath);
3988
- const exampleExists = fs4.existsSync(examplePath);
4006
+ const localPath = path26.join(projectRoot, localFile);
4007
+ const examplePath = path26.join(projectRoot, exampleFile);
4008
+ const localExists = fs17.existsSync(localPath);
4009
+ const exampleExists = fs17.existsSync(examplePath);
3989
4010
  const localEditor = new EnvEditor(localPath);
3990
4011
  const exampleEditor = new EnvEditor(examplePath);
3991
4012
  const localKeys = localExists ? localEditor.getKeys() : [];
@@ -4324,17 +4345,17 @@ function getModuleBaseDir(projectRoot, modType) {
4324
4345
  return modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4325
4346
  }
4326
4347
  const folder = modType === "shared" ? "shared" : "features";
4327
- return path2.join(projectRoot, "src", folder);
4348
+ return path26.join(projectRoot, "src", folder);
4328
4349
  }
4329
4350
  function getExistingModuleDir(projectRoot, modType, modName) {
4330
4351
  const folder = modType === "shared" ? "shared" : "features";
4331
4352
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4332
- const inConfigured = path2.join(configuredDir, modName);
4333
- if (fs4.existsSync(inConfigured)) return inConfigured;
4334
- const inSrc = path2.join(projectRoot, "src", folder, modName);
4335
- if (fs4.existsSync(inSrc)) return inSrc;
4336
- const inRoot = path2.join(projectRoot, folder, modName);
4337
- if (fs4.existsSync(inRoot)) return inRoot;
4353
+ const inConfigured = path26.join(configuredDir, modName);
4354
+ if (fs17.existsSync(inConfigured)) return inConfigured;
4355
+ const inSrc = path26.join(projectRoot, "src", folder, modName);
4356
+ if (fs17.existsSync(inSrc)) return inSrc;
4357
+ const inRoot = path26.join(projectRoot, folder, modName);
4358
+ if (fs17.existsSync(inRoot)) return inRoot;
4338
4359
  return null;
4339
4360
  }
4340
4361
  function checkModuleExists(projectRoot, modType, modName) {
@@ -4345,14 +4366,14 @@ function getAvailableLocalModules(projectRoot, modType) {
4345
4366
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4346
4367
  const dirs = [
4347
4368
  configuredDir,
4348
- path2.join(projectRoot, "src", folder),
4349
- path2.join(projectRoot, folder)
4369
+ path26.join(projectRoot, "src", folder),
4370
+ path26.join(projectRoot, folder)
4350
4371
  ];
4351
4372
  const set = /* @__PURE__ */ new Set();
4352
4373
  for (const dir of dirs) {
4353
- if (fs4.existsSync(dir)) {
4374
+ if (fs17.existsSync(dir)) {
4354
4375
  try {
4355
- const entries = fs4.readdirSync(dir, { withFileTypes: true });
4376
+ const entries = fs17.readdirSync(dir, { withFileTypes: true });
4356
4377
  for (const e of entries) {
4357
4378
  if (e.isDirectory() && !e.name.startsWith(".")) {
4358
4379
  set.add(e.name);
@@ -4554,7 +4575,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4554
4575
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticAlias}/`);
4555
4576
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
4556
4577
  const baseDir = getModuleBaseDir(projectRoot, modType);
4557
- const displayDest = path2.relative(projectRoot, path2.join(baseDir, programmaticAlias));
4578
+ const displayDest = path26.relative(projectRoot, path26.join(baseDir, programmaticAlias));
4558
4579
  p19.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4559
4580
  resolutions.set(key, {
4560
4581
  type: modType,
@@ -4742,7 +4763,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4742
4763
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${newName}/`);
4743
4764
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${newName}`);
4744
4765
  const baseDir = getModuleBaseDir(projectRoot, modType);
4745
- const displayDest = path2.relative(projectRoot, path2.join(baseDir, newName));
4766
+ const displayDest = path26.relative(projectRoot, path26.join(baseDir, newName));
4746
4767
  p19.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4747
4768
  resolutions.set(key, {
4748
4769
  type: modType,
@@ -4794,7 +4815,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4794
4815
  continue;
4795
4816
  }
4796
4817
  const folder = res.type === "shared" ? "shared" : "features";
4797
- const targetDir = path2.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4818
+ const targetDir = path26.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4798
4819
  const isOverwrite = Boolean(flags.overwrite || res.action === "overwrite");
4799
4820
  if (key !== rootKey) {
4800
4821
  p19.log.step(
@@ -4804,30 +4825,30 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4804
4825
  if (res.action === "overwrite" && !flags.dryRun) {
4805
4826
  const existingDir = getExistingModuleDir(projectRoot, res.type, res.targetName);
4806
4827
  if (existingDir && existingDir !== targetDir) {
4807
- fs4.rmSync(existingDir, { recursive: true, force: true });
4828
+ fs17.rmSync(existingDir, { recursive: true, force: true });
4808
4829
  }
4809
- if (fs4.existsSync(targetDir)) {
4810
- fs4.rmSync(targetDir, { recursive: true, force: true });
4830
+ if (fs17.existsSync(targetDir)) {
4831
+ fs17.rmSync(targetDir, { recursive: true, force: true });
4811
4832
  }
4812
4833
  }
4813
4834
  for (const file of res.manifest.files || []) {
4814
4835
  if (file === "registry.json") continue;
4815
4836
  if (!includeTests && isTestFile(file)) continue;
4816
4837
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4817
- const localFilePath = path2.join(targetDir, file);
4818
- if (fs4.existsSync(localFilePath) && !isOverwrite) {
4838
+ const localFilePath = path26.join(targetDir, file);
4839
+ if (fs17.existsSync(localFilePath) && !isOverwrite) {
4819
4840
  p19.log.warn(
4820
- ` \u21B3 Skipping existing file: ${pc14.dim(path2.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4841
+ ` \u21B3 Skipping existing file: ${pc14.dim(path26.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4821
4842
  );
4822
4843
  continue;
4823
4844
  }
4824
4845
  let content = await fetchRegistryFile(registryBase, remoteFilePath);
4825
4846
  content = rewriteImports(content, globalAliasMap);
4826
4847
  if (!flags.dryRun) {
4827
- fs4.mkdirSync(path2.dirname(localFilePath), { recursive: true });
4828
- fs4.writeFileSync(localFilePath, content, "utf-8");
4848
+ fs17.mkdirSync(path26.dirname(localFilePath), { recursive: true });
4849
+ fs17.writeFileSync(localFilePath, content, "utf-8");
4829
4850
  }
4830
- const displayPath = path2.relative(projectRoot, localFilePath);
4851
+ const displayPath = path26.relative(projectRoot, localFilePath);
4831
4852
  totalWrittenFiles.push(displayPath);
4832
4853
  p19.log.message(` ${pc14.green("+")} ${displayPath}`);
4833
4854
  }
@@ -4853,7 +4874,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4853
4874
  } else {
4854
4875
  const rootRes = resolutions.get(rootKey);
4855
4876
  const baseDir = getModuleBaseDir(projectRoot, type);
4856
- const displayTarget = path2.relative(projectRoot, path2.join(baseDir, rootRes.targetName));
4877
+ const displayTarget = path26.relative(projectRoot, path26.join(baseDir, rootRes.targetName));
4857
4878
  p19.log.success(
4858
4879
  pc14.green(
4859
4880
  `Successfully imported ${type} '${name}' (${totalWrittenFiles.length} file${totalWrittenFiles.length === 1 ? "" : "s"} placed in ${displayTarget})`
@@ -4872,19 +4893,19 @@ var DependencyRuleError = class extends Error {
4872
4893
  }
4873
4894
  };
4874
4895
  function isTestFile2(filePath, projectRoot) {
4875
- const norm = (projectRoot ? path2.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4876
- const base = path2.basename(norm);
4896
+ const norm = (projectRoot ? path26.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4897
+ const base = path26.basename(norm);
4877
4898
  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);
4878
4899
  }
4879
4900
  function scanDirFiles(dir, projectRoot) {
4880
- if (!fs4.existsSync(dir)) return [];
4881
- const entries = fs4.readdirSync(dir, { withFileTypes: true });
4901
+ if (!fs17.existsSync(dir)) return [];
4902
+ const entries = fs17.readdirSync(dir, { withFileTypes: true });
4882
4903
  const files = [];
4883
4904
  for (const entry of entries) {
4884
4905
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "__tests__" || entry.name.startsWith(".")) {
4885
4906
  continue;
4886
4907
  }
4887
- const fullPath = path2.join(dir, entry.name);
4908
+ const fullPath = path26.join(dir, entry.name);
4888
4909
  if (entry.isDirectory()) {
4889
4910
  files.push(...scanDirFiles(fullPath, projectRoot));
4890
4911
  } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !isTestFile2(fullPath, projectRoot)) {
@@ -4893,42 +4914,43 @@ function scanDirFiles(dir, projectRoot) {
4893
4914
  }
4894
4915
  return files;
4895
4916
  }
4896
- function classifyFile(fullPath, projectRoot) {
4897
- const rel = path2.relative(projectRoot, fullPath).replace(/\\/g, "/");
4898
- const featureMatch = rel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/.*)?$/);
4899
- if (featureMatch && featureMatch[1] && featureMatch[2]) {
4900
- const feature = featureMatch[1];
4901
- const subfolder = featureMatch[2];
4902
- let layer;
4903
- if (subfolder === "domain" || subfolder === "errors") {
4904
- layer = "domain";
4905
- } else if (subfolder === "useCases" || subfolder === "usecases") {
4906
- layer = "useCases";
4907
- } else if (subfolder === "services") {
4908
- layer = "services";
4909
- } else if (subfolder === "infrastructure") {
4910
- layer = "infrastructure";
4911
- } else if (subfolder === "pxExpress" || subfolder === "presentation" || subfolder === "handlers" || subfolder.startsWith("px")) {
4912
- layer = "presentation";
4913
- }
4914
- return { moduleType: "feature", moduleName: feature, feature, layer };
4915
- }
4916
- const sharedMatch = rel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
4917
- if (sharedMatch && sharedMatch[1]) {
4918
- const moduleName = sharedMatch[1];
4919
- const rest = sharedMatch[2] || "";
4920
- let layer = "root";
4921
- if (rest.startsWith("domain/") || rest === "domain" || rest.startsWith("errors/") || rest === "errors") {
4922
- layer = "domain";
4923
- } else if (rest.startsWith("ports/") || rest === "ports") {
4924
- layer = "ports";
4925
- } else if (rest.startsWith("infrastructure/") || rest === "infrastructure") {
4926
- layer = "infrastructure";
4927
- }
4928
- return { moduleType: "shared", moduleName, feature: moduleName, layer };
4929
- }
4930
- const errorMatch = rel.match(/(?:^|\/)(?:src\/)?errors(?:\/(.*))?$/);
4931
- if (errorMatch) {
4917
+ function resolveLintEnvironment(projectRoot) {
4918
+ const config = loadMasonConfig(projectRoot);
4919
+ const resolveDir = (configured, defaultSrc, defaultRoot) => {
4920
+ if (configured !== void 0) {
4921
+ return path26.resolve(projectRoot, configured);
4922
+ }
4923
+ const srcPath = path26.join(projectRoot, defaultSrc);
4924
+ if (fs17.existsSync(srcPath)) return srcPath;
4925
+ const rootPath = path26.join(projectRoot, defaultRoot);
4926
+ if (fs17.existsSync(rootPath)) return rootPath;
4927
+ return srcPath;
4928
+ };
4929
+ const featuresBase = resolveDir(config?.paths?.features, "src/features", "features");
4930
+ const sharedBase = resolveDir(config?.paths?.shared, "src/shared", "shared");
4931
+ const errorsBase = resolveDir(config?.paths?.errors, "src/errors", "errors");
4932
+ const defaultBaseErrorRelative = config?.paths?.errors ? path26.join(config.paths.errors, "AppError.ts") : fs17.existsSync(path26.join(projectRoot, "src/errors")) ? "src/errors/AppError.ts" : fs17.existsSync(path26.join(projectRoot, "errors")) ? "errors/AppError.ts" : "src/errors/AppError.ts";
4933
+ const baseErrorAbs = path26.resolve(
4934
+ projectRoot,
4935
+ config?.paths?.baseError || defaultBaseErrorRelative
4936
+ );
4937
+ return { featuresBase, sharedBase, errorsBase, baseErrorAbs };
4938
+ }
4939
+ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4940
+ if (!sharedBaseAbs || !errorsBaseAbs) {
4941
+ const env = resolveLintEnvironment(featuresBaseAbs);
4942
+ featuresBaseAbs = env.featuresBase;
4943
+ sharedBaseAbs = env.sharedBase;
4944
+ errorsBaseAbs = env.errorsBase;
4945
+ }
4946
+ const normFullPath = path26.resolve(fullPathAbs);
4947
+ const normErrorsBase = path26.resolve(errorsBaseAbs);
4948
+ const normSharedBase = path26.resolve(sharedBaseAbs);
4949
+ const normFeaturesBase = path26.resolve(featuresBaseAbs);
4950
+ const isUnder = (base, target) => {
4951
+ return target === base || target.startsWith(base + path26.sep);
4952
+ };
4953
+ if (isUnder(normErrorsBase, normFullPath)) {
4932
4954
  return {
4933
4955
  moduleType: "error",
4934
4956
  moduleName: "global-errors",
@@ -4936,46 +4958,154 @@ function classifyFile(fullPath, projectRoot) {
4936
4958
  layer: "domain"
4937
4959
  };
4938
4960
  }
4961
+ if (isUnder(normSharedBase, normFullPath)) {
4962
+ const rel = path26.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
4963
+ const parts = rel.split("/").filter(Boolean);
4964
+ if (parts.length >= 1) {
4965
+ const moduleName = parts[0];
4966
+ const subfolder = parts[1];
4967
+ let layer = "root";
4968
+ if (subfolder === "domain" || subfolder === "errors") {
4969
+ layer = "domain";
4970
+ } else if (subfolder === "ports") {
4971
+ layer = "ports";
4972
+ } else if (subfolder === "infrastructure") {
4973
+ layer = "infrastructure";
4974
+ }
4975
+ return { moduleType: "shared", moduleName, feature: moduleName, layer };
4976
+ }
4977
+ }
4978
+ if (isUnder(normFeaturesBase, normFullPath)) {
4979
+ const rel = path26.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
4980
+ const parts = rel.split("/").filter(Boolean);
4981
+ if (parts.length >= 2) {
4982
+ const moduleName = parts[0];
4983
+ const subfolder = parts[1];
4984
+ let layer;
4985
+ if (subfolder === "domain" || subfolder === "errors") {
4986
+ layer = "domain";
4987
+ } else if (subfolder === "useCases" || subfolder === "usecases") {
4988
+ layer = "useCases";
4989
+ } else if (subfolder === "services") {
4990
+ layer = "services";
4991
+ } else if (subfolder === "infrastructure") {
4992
+ layer = "infrastructure";
4993
+ } else if (subfolder.startsWith("px") || subfolder === "presentation" || subfolder === "handlers" || subfolder === "transformers") {
4994
+ layer = "presentation";
4995
+ }
4996
+ return { moduleType: "feature", moduleName, feature: moduleName, layer };
4997
+ }
4998
+ }
4939
4999
  return {};
4940
5000
  }
4941
- function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5001
+ function classifyTarget(specifier, sourceFileAbs, projectRoot, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4942
5002
  if (specifier === "@solid-stack/di" || specifier.startsWith("@solid-stack/di/")) {
4943
5003
  return { isExternal: true, isDiFramework: true };
4944
5004
  }
4945
- if (specifier.startsWith("node:") || ["crypto", "fs", "path", "http", "https", "url", "os", "child_process", "stream", "express", "cors", "dotenv"].includes(specifier)) {
5005
+ if (specifier.startsWith("node:") || [
5006
+ "crypto",
5007
+ "fs",
5008
+ "path",
5009
+ "http",
5010
+ "https",
5011
+ "url",
5012
+ "os",
5013
+ "child_process",
5014
+ "stream",
5015
+ "express",
5016
+ "cors",
5017
+ "dotenv"
5018
+ ].includes(specifier)) {
4946
5019
  return { isExternal: true, isDiFramework: false };
4947
5020
  }
4948
- let resolvedRel = null;
5021
+ if (!featuresBaseAbs || !sharedBaseAbs || !errorsBaseAbs) {
5022
+ const env = resolveLintEnvironment(projectRoot);
5023
+ featuresBaseAbs = featuresBaseAbs || env.featuresBase;
5024
+ sharedBaseAbs = sharedBaseAbs || env.sharedBase;
5025
+ errorsBaseAbs = errorsBaseAbs || env.errorsBase;
5026
+ }
5027
+ const isGlobalConfig = specifier === "@configs" || specifier.startsWith("@configs/") || specifier === "@/configs" || specifier.startsWith("@/configs/") || specifier === "~/configs" || specifier.startsWith("~/configs/") || specifier === "configs" || specifier.startsWith("configs/");
5028
+ let targetAbs = null;
4949
5029
  if (specifier.startsWith(".")) {
4950
- const abs = path2.resolve(path2.dirname(sourceFileAbs), specifier);
4951
- resolvedRel = path2.relative(projectRoot, abs).replace(/\\/g, "/");
4952
- } else if (specifier.startsWith("@/features/") || specifier.startsWith("~/features/")) {
4953
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4954
- } else if (specifier.startsWith("@features/")) {
4955
- resolvedRel = "src/" + specifier.slice(1);
4956
- } else if (specifier.startsWith("@/shared/") || specifier.startsWith("~/shared/")) {
4957
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4958
- } else if (specifier.startsWith("@shared/")) {
4959
- resolvedRel = "src/" + specifier.slice(1);
4960
- } else if (specifier.startsWith("@/configs/") || specifier.startsWith("~/configs/") || specifier === "@/configs" || specifier === "~/configs") {
4961
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4962
- } else if (specifier === "@configs" || specifier.startsWith("@configs/")) {
4963
- resolvedRel = "src/" + specifier.slice(1);
4964
- } else if (specifier.startsWith("@/errors/") || specifier.startsWith("~/errors/") || specifier === "@/errors" || specifier === "~/errors") {
4965
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4966
- } else if (specifier === "@errors" || specifier.startsWith("@errors/")) {
4967
- resolvedRel = "src/" + specifier.slice(1);
4968
- } else if (specifier.startsWith("@/") || specifier.startsWith("~/")) {
4969
- resolvedRel = "src/" + specifier.slice(2);
4970
- } else if (specifier.startsWith("features/") || specifier.startsWith("shared/") || specifier.startsWith("configs/") || specifier === "configs" || specifier.startsWith("errors/") || specifier === "errors") {
4971
- resolvedRel = specifier;
4972
- }
4973
- if (!resolvedRel) {
4974
- return { isExternal: true, isDiFramework: false };
5030
+ targetAbs = path26.resolve(path26.dirname(sourceFileAbs), specifier);
5031
+ } else {
5032
+ const featRel = path26.relative(projectRoot, featuresBaseAbs).replace(/\\/g, "/");
5033
+ const sharedRel = path26.relative(projectRoot, sharedBaseAbs).replace(/\\/g, "/");
5034
+ const errorsRel = path26.relative(projectRoot, errorsBaseAbs).replace(/\\/g, "/");
5035
+ const featPrefixes = ["features"];
5036
+ if (featRel && featRel !== "." && !featRel.startsWith("..")) {
5037
+ featPrefixes.push(featRel);
5038
+ const b = path26.basename(featRel);
5039
+ if (!featPrefixes.includes(b)) featPrefixes.push(b);
5040
+ }
5041
+ const sharedPrefixes = ["shared"];
5042
+ if (sharedRel && sharedRel !== "." && !sharedRel.startsWith("..")) {
5043
+ sharedPrefixes.push(sharedRel);
5044
+ const b = path26.basename(sharedRel);
5045
+ if (!sharedPrefixes.includes(b)) sharedPrefixes.push(b);
5046
+ }
5047
+ const errorsPrefixes = ["errors"];
5048
+ if (errorsRel && errorsRel !== "." && !errorsRel.startsWith("..")) {
5049
+ errorsPrefixes.push(errorsRel);
5050
+ const b = path26.basename(errorsRel);
5051
+ if (!errorsPrefixes.includes(b)) errorsPrefixes.push(b);
5052
+ }
5053
+ for (const prefix of featPrefixes) {
5054
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5055
+ const m = specifier.match(aliasRegex);
5056
+ if (m && m[2]) {
5057
+ targetAbs = path26.resolve(featuresBaseAbs, m[2]);
5058
+ break;
5059
+ }
5060
+ }
5061
+ if (!targetAbs) {
5062
+ for (const prefix of sharedPrefixes) {
5063
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5064
+ const m = specifier.match(aliasRegex);
5065
+ if (m && m[2]) {
5066
+ targetAbs = path26.resolve(sharedBaseAbs, m[2]);
5067
+ break;
5068
+ }
5069
+ }
5070
+ }
5071
+ if (!targetAbs) {
5072
+ for (const prefix of errorsPrefixes) {
5073
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}(?:\\/(.*))?$`);
5074
+ const m = specifier.match(aliasRegex);
5075
+ if (m) {
5076
+ targetAbs = path26.resolve(errorsBaseAbs, m[2] || "");
5077
+ break;
5078
+ }
5079
+ }
5080
+ }
5081
+ if (!targetAbs && (specifier.startsWith("@/") || specifier.startsWith("~/"))) {
5082
+ const sub = specifier.slice(2);
5083
+ const srcCandidate = path26.resolve(projectRoot, "src", sub);
5084
+ const rootCandidate = path26.resolve(projectRoot, sub);
5085
+ if (fs17.existsSync(srcCandidate)) {
5086
+ targetAbs = srcCandidate;
5087
+ } else if (fs17.existsSync(rootCandidate)) {
5088
+ targetAbs = rootCandidate;
5089
+ } else {
5090
+ targetAbs = srcCandidate;
5091
+ }
5092
+ }
5093
+ if (!targetAbs) {
5094
+ const featCandidate = path26.resolve(featuresBaseAbs, specifier);
5095
+ if (fs17.existsSync(featCandidate) || fs17.existsSync(featCandidate + ".ts") || fs17.existsSync(featCandidate + ".js")) {
5096
+ targetAbs = featCandidate;
5097
+ }
5098
+ }
5099
+ }
5100
+ if (!targetAbs) {
5101
+ return { isExternal: true, isDiFramework: false, isGlobalConfig };
4975
5102
  }
4976
- const isGlobalConfig = resolvedRel.startsWith("src/configs/") || resolvedRel === "src/configs" || resolvedRel.startsWith("configs/") || resolvedRel === "configs";
4977
- const isGlobalError = resolvedRel.startsWith("src/errors/") || resolvedRel === "src/errors" || resolvedRel.startsWith("errors/") || resolvedRel === "errors";
4978
- if (isGlobalError) {
5103
+ const normTarget = path26.resolve(targetAbs);
5104
+ const srcConfig = path26.resolve(projectRoot, "src/configs");
5105
+ const rootConfig = path26.resolve(projectRoot, "configs");
5106
+ const isTargetConfig = isGlobalConfig || normTarget === srcConfig || normTarget.startsWith(srcConfig + path26.sep) || normTarget === rootConfig || normTarget.startsWith(rootConfig + path26.sep);
5107
+ const classification = classifyFile(targetAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs);
5108
+ if (classification.moduleType === "error") {
4979
5109
  return {
4980
5110
  isExternal: false,
4981
5111
  isDiFramework: false,
@@ -4983,33 +5113,19 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
4983
5113
  isTargetError: true
4984
5114
  };
4985
5115
  }
4986
- const featMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/(.*))?$/);
4987
- if (featMatch && featMatch[1] && featMatch[2]) {
4988
- const targetFeature = featMatch[1];
4989
- const targetSubfolder = featMatch[2];
4990
- const rest = featMatch[3] || "";
4991
- let targetLayer;
4992
- if (targetSubfolder === "domain" || targetSubfolder === "errors") {
4993
- targetLayer = "domain";
4994
- } else if (targetSubfolder === "useCases" || targetSubfolder === "usecases") {
4995
- targetLayer = "useCases";
4996
- } else if (targetSubfolder === "services") {
4997
- targetLayer = "services";
4998
- } else if (targetSubfolder === "infrastructure") {
4999
- targetLayer = "infrastructure";
5000
- } else if (targetSubfolder === "pxExpress" || targetSubfolder === "presentation" || targetSubfolder === "handlers" || targetSubfolder.startsWith("px")) {
5001
- targetLayer = "presentation";
5002
- }
5003
- const basePart = rest ? path2.basename(rest) : targetSubfolder;
5004
- const targetFileName = basePart.replace(/\.(js|ts|mjs|cjs)$/, "");
5116
+ if (classification.moduleType === "feature") {
5117
+ const rel = path26.relative(featuresBaseAbs, targetAbs).replace(/\\/g, "/");
5118
+ const parts = rel.split("/").filter(Boolean);
5119
+ const targetSubfolder = parts[1];
5120
+ const targetFileName = path26.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5005
5121
  const isTargetPort = /^I[A-Z]/.test(targetFileName);
5006
5122
  const isTargetRepo = isTargetPort && targetFileName.includes("Repo");
5007
- const isTargetError = targetSubfolder === "errors" || rest.startsWith("errors/") || rest.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5123
+ const isTargetError = targetSubfolder === "errors" || rel.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5008
5124
  return {
5009
5125
  isExternal: false,
5010
5126
  isDiFramework: false,
5011
- targetFeature,
5012
- targetLayer,
5127
+ targetFeature: classification.moduleName,
5128
+ targetLayer: classification.layer,
5013
5129
  targetSubfolder,
5014
5130
  targetFileName,
5015
5131
  isTargetPort,
@@ -5017,25 +5133,21 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5017
5133
  isTargetError
5018
5134
  };
5019
5135
  }
5020
- const sharedMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
5021
- if (sharedMatch) {
5022
- const targetSharedModule = sharedMatch[1];
5023
- const sharedRest = sharedMatch[2] || "";
5024
- const isSharedRoot = !sharedRest.includes("/");
5025
- const isSharedPorts = sharedRest.startsWith("ports/") || sharedRest === "ports";
5026
- const isSharedInfra = sharedRest.startsWith("infrastructure/") || sharedRest === "infrastructure";
5027
- const isSharedDomain = sharedRest.startsWith("domain/") || sharedRest === "domain";
5136
+ if (classification.moduleType === "shared") {
5137
+ const targetFileName = path26.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5138
+ const isTargetError = classification.layer === "domain" && (targetFileName.endsWith("Error") || targetFileName.endsWith("Errors") || targetAbs.includes("/errors/"));
5028
5139
  return {
5029
5140
  isExternal: false,
5030
5141
  isDiFramework: false,
5031
- targetSharedModule,
5032
- isSharedRoot,
5033
- isSharedPorts,
5034
- isSharedInfra,
5035
- isSharedDomain
5142
+ targetSharedModule: classification.moduleName,
5143
+ isSharedRoot: classification.layer === "root",
5144
+ isSharedPorts: classification.layer === "ports",
5145
+ isSharedInfra: classification.layer === "infrastructure",
5146
+ isSharedDomain: classification.layer === "domain",
5147
+ isTargetError
5036
5148
  };
5037
5149
  }
5038
- return { isExternal: true, isDiFramework: false, isGlobalConfig };
5150
+ return { isExternal: true, isDiFramework: false, isGlobalConfig: isTargetConfig };
5039
5151
  }
5040
5152
  function extractImportStatements(content) {
5041
5153
  const statements = [];
@@ -5157,22 +5269,50 @@ var FeatureDependencyGraph = class {
5157
5269
  return dfs(start);
5158
5270
  }
5159
5271
  };
5160
- function discoverAllFeatures(projectRoot) {
5161
- const featuresBase = resolveFeaturesDir(projectRoot);
5162
- if (!fs4.existsSync(featuresBase)) return [];
5163
- const entries = fs4.readdirSync(featuresBase, { withFileTypes: true });
5164
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5272
+ function discoverAllFeatures(featuresBaseAbs, excludeDirs = []) {
5273
+ const base = featuresBaseAbs;
5274
+ if (!fs17.existsSync(base)) return [];
5275
+ const excludeSet = new Set(excludeDirs.map((d) => path26.resolve(d)));
5276
+ const entries = fs17.readdirSync(base, { withFileTypes: true });
5277
+ return entries.filter((e) => {
5278
+ if (!e.isDirectory()) return false;
5279
+ if (e.name.startsWith(".")) return false;
5280
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5281
+ return false;
5282
+ }
5283
+ const resolved = path26.resolve(base, e.name);
5284
+ for (const ex of excludeSet) {
5285
+ if (ex === resolved || ex.startsWith(resolved + path26.sep) || resolved.startsWith(ex + path26.sep)) {
5286
+ return false;
5287
+ }
5288
+ }
5289
+ return true;
5290
+ }).map((e) => ({
5165
5291
  name: e.name,
5166
- dir: path2.join(featuresBase, e.name)
5292
+ dir: path26.join(base, e.name)
5167
5293
  })).sort((a, b) => a.name.localeCompare(b.name));
5168
5294
  }
5169
- function discoverAllShared(projectRoot) {
5170
- const sharedBase = resolveSharedDir(projectRoot);
5171
- if (!fs4.existsSync(sharedBase)) return [];
5172
- const entries = fs4.readdirSync(sharedBase, { withFileTypes: true });
5173
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5295
+ function discoverAllShared(sharedBaseAbs, excludeDirs = []) {
5296
+ const base = sharedBaseAbs;
5297
+ if (!fs17.existsSync(base)) return [];
5298
+ const excludeSet = new Set(excludeDirs.map((d) => path26.resolve(d)));
5299
+ const entries = fs17.readdirSync(base, { withFileTypes: true });
5300
+ return entries.filter((e) => {
5301
+ if (!e.isDirectory()) return false;
5302
+ if (e.name.startsWith(".")) return false;
5303
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5304
+ return false;
5305
+ }
5306
+ const resolved = path26.resolve(base, e.name);
5307
+ for (const ex of excludeSet) {
5308
+ if (ex === resolved || ex.startsWith(resolved + path26.sep) || resolved.startsWith(ex + path26.sep)) {
5309
+ return false;
5310
+ }
5311
+ }
5312
+ return true;
5313
+ }).map((e) => ({
5174
5314
  name: e.name,
5175
- dir: path2.join(sharedBase, e.name)
5315
+ dir: path26.join(base, e.name)
5176
5316
  })).sort((a, b) => a.name.localeCompare(b.name));
5177
5317
  }
5178
5318
  function extractClassMethods(content, className) {
@@ -5328,7 +5468,7 @@ function extractClassMethods(content, className) {
5328
5468
  return methods;
5329
5469
  }
5330
5470
  function checkUseCaseShape(featureName, filePath, relativePath, content, addViolation) {
5331
- const fileName = path2.basename(filePath);
5471
+ const fileName = path26.basename(filePath);
5332
5472
  const lines = content.split(/\r?\n/);
5333
5473
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5334
5474
  if (!classMatch) {
@@ -5424,7 +5564,7 @@ private ${m.name}(...) { ... }`
5424
5564
  }
5425
5565
  }
5426
5566
  function checkServiceShape(featureName, filePath, relativePath, content, addViolation) {
5427
- const fileName = path2.basename(filePath);
5567
+ const fileName = path26.basename(filePath);
5428
5568
  const lines = content.split(/\r?\n/);
5429
5569
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5430
5570
  if (!classMatch) {
@@ -5523,40 +5663,32 @@ function lintCodebase(options = {}) {
5523
5663
  const startTime = Date.now();
5524
5664
  const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
5525
5665
  const failFast = !options.complete;
5526
- const lintConfig = loadLintConfig(projectRoot);
5527
- const baseErrorRelative = lintConfig.baseErrorPath || "src/errors/AppError.ts";
5528
- const baseErrorAbs = path2.resolve(projectRoot, baseErrorRelative);
5529
- const featuresBase = resolveFeaturesDir(projectRoot);
5530
- const sharedBase = resolveSharedDir(projectRoot);
5531
- let errorsBase = path2.join(projectRoot, "src/errors");
5532
- if (!fs4.existsSync(errorsBase) && fs4.existsSync(path2.join(projectRoot, "errors"))) {
5533
- errorsBase = path2.join(projectRoot, "errors");
5534
- }
5666
+ const { featuresBase, sharedBase, errorsBase, baseErrorAbs } = resolveLintEnvironment(projectRoot);
5535
5667
  const missingFoundations = [];
5536
- if (!fs4.existsSync(featuresBase)) missingFoundations.push("features/");
5537
- if (!fs4.existsSync(sharedBase)) missingFoundations.push("shared/");
5538
- if (!fs4.existsSync(errorsBase)) missingFoundations.push("errors/");
5668
+ if (!fs17.existsSync(featuresBase)) missingFoundations.push("features/");
5669
+ if (!fs17.existsSync(sharedBase)) missingFoundations.push("shared/");
5670
+ if (!fs17.existsSync(errorsBase)) missingFoundations.push("errors/");
5539
5671
  if (missingFoundations.length > 0) {
5540
5672
  throw new DependencyRuleError(
5541
- `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every project must contain 'features/', 'shared/', and 'errors/'.`,
5673
+ `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
5542
5674
  [],
5543
5675
  true
5544
5676
  );
5545
5677
  }
5546
- if (!fs4.existsSync(baseErrorAbs)) {
5678
+ if (!fs17.existsSync(baseErrorAbs)) {
5547
5679
  throw new DependencyRuleError(
5548
- `Project Structure Violation: Base error class not found at '${baseErrorRelative}'. Create this file or update 'baseErrorPath' in mason-lint.config.json.`,
5680
+ `Project Structure Violation: Base error class not found at '${path26.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
5549
5681
  [],
5550
5682
  true
5551
5683
  );
5552
5684
  }
5553
- const baseErrorContent = fs4.readFileSync(baseErrorAbs, "utf-8");
5685
+ const baseErrorContent = fs17.readFileSync(baseErrorAbs, "utf-8");
5554
5686
  const baseClassMatch = baseErrorContent.match(
5555
5687
  /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)/
5556
5688
  );
5557
5689
  const baseErrorClassName = baseClassMatch ? baseClassMatch[1] : "AppError";
5558
- const features = discoverAllFeatures(projectRoot);
5559
- const sharedModules = discoverAllShared(projectRoot);
5690
+ const features = discoverAllFeatures(featuresBase, [sharedBase, errorsBase]);
5691
+ const sharedModules = discoverAllShared(sharedBase, [featuresBase, errorsBase]);
5560
5692
  const errorModule = { name: "global-errors", dir: errorsBase, type: "error" };
5561
5693
  const allModules = [
5562
5694
  ...features.map((f) => ({ ...f, type: "feature" })),
@@ -5599,12 +5731,12 @@ Code: ${v.code}`;
5599
5731
  const allFiles = scanDirFiles(mod.dir, projectRoot);
5600
5732
  modResult.scannedFilesCount = allFiles.length;
5601
5733
  for (const file of allFiles) {
5602
- const relPath = path2.relative(projectRoot, file).replace(/\\/g, "/");
5603
- const { moduleType, moduleName, layer } = classifyFile(file, projectRoot);
5734
+ const relPath = path26.relative(projectRoot, file).replace(/\\/g, "/");
5735
+ const { moduleType, moduleName, layer } = classifyFile(file, featuresBase, sharedBase, errorsBase);
5604
5736
  if (!layer || !moduleType || !moduleName) continue;
5605
- const content = fs4.readFileSync(file, "utf-8");
5737
+ const content = fs17.readFileSync(file, "utf-8");
5606
5738
  const statements = extractImportStatements(content);
5607
- const baseName = path2.basename(file);
5739
+ const baseName = path26.basename(file);
5608
5740
  const isBarrel = baseName === "index.ts" || baseName === "index.js";
5609
5741
  const throwErrorRegex = /\bthrow\s+(?:new\s+)?Error\s*\(/g;
5610
5742
  let throwMatch;
@@ -5623,7 +5755,7 @@ Code: ${v.code}`;
5623
5755
  code: lineCode,
5624
5756
  ruleId: "E3_PLAIN_ERROR_THROW",
5625
5757
  severity: "error",
5626
- advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a domain-specific error class that inherits from it.`,
5758
+ advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a custom error class that inherits from it.`,
5627
5759
  fixExample: {
5628
5760
  bad: lineCode,
5629
5761
  good: `throw new ${baseErrorClassName}("Something went wrong");`
@@ -5631,7 +5763,7 @@ Code: ${v.code}`;
5631
5763
  });
5632
5764
  }
5633
5765
  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");
5634
- const isBaseErrorFile = path2.resolve(file) === path2.resolve(baseErrorAbs);
5766
+ const isBaseErrorFile = path26.resolve(file) === path26.resolve(baseErrorAbs);
5635
5767
  if (isErrorFile && !isBaseErrorFile) {
5636
5768
  const classRegex = /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)(?:<[^>]+>)?(?:\s+extends\s+([A-Za-z0-9_]+))?/g;
5637
5769
  let classMatch;
@@ -5653,7 +5785,7 @@ Code: ${v.code}`;
5653
5785
  code: lineCode,
5654
5786
  ruleId: "E4_MISSING_INHERITANCE",
5655
5787
  severity: "error",
5656
- advice: `Error class '${className}' must extend '${baseErrorClassName}' (or another class that derives from it).`,
5788
+ advice: `Error class '${className}' must extend '${baseErrorClassName}'.`,
5657
5789
  fixExample: {
5658
5790
  bad: lineCode,
5659
5791
  good: `export class ${className} extends ${baseErrorClassName} { ... }`
@@ -5670,7 +5802,7 @@ Code: ${v.code}`;
5670
5802
  code: lineCode,
5671
5803
  ruleId: "E5_NATIVE_ERROR_INHERITANCE",
5672
5804
  severity: "error",
5673
- advice: `Error class '${className}' extends the native 'Error'. It must extend your base error class ('${baseErrorClassName}').`,
5805
+ advice: `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${baseErrorClassName}').`,
5674
5806
  fixExample: {
5675
5807
  bad: lineCode,
5676
5808
  good: `export class ${className} extends ${baseErrorClassName} { ... }`
@@ -5681,7 +5813,7 @@ Code: ${v.code}`;
5681
5813
  }
5682
5814
  if (moduleType === "error") {
5683
5815
  for (const stmt of statements) {
5684
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5816
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5685
5817
  if (target.targetFeature) {
5686
5818
  addViolation({
5687
5819
  feature: "global-errors",
@@ -5747,7 +5879,7 @@ Code: ${v.code}`;
5747
5879
  }
5748
5880
  }
5749
5881
  for (const stmt of statements) {
5750
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5882
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5751
5883
  if (target.targetFeature) {
5752
5884
  addViolation({
5753
5885
  feature: moduleName,
@@ -5877,7 +6009,7 @@ Code: ${v.code}`;
5877
6009
  }
5878
6010
  }
5879
6011
  for (const stmt of statements) {
5880
- const target = classifyTarget(stmt.specifier, file, projectRoot);
6012
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5881
6013
  if (target.targetFeature && target.targetFeature !== feat.name) {
5882
6014
  const evidence = {
5883
6015
  fromFeature: feat.name,
@@ -6743,6 +6875,6 @@ async function runCli(argv = process.argv) {
6743
6875
  cli.parse(argv, { run: true });
6744
6876
  }
6745
6877
 
6746
- export { DEFAULT_REGISTRY_BASE, DependencyRuleError, EnvEditor, FeatureDependencyGraph, PromptCancelledError, computeDirectoryHash, concreteInfraTemplate, createCli, detectPackageManager, diProviderTemplate, discoverEnvironments, domainClassTemplate, domainInterfaceTemplate, domainValueObjectTemplate, ensureInterfacePrefix, expressIndexTemplate, fetchModuleManifest, fetchRegistryFile, fetchRegistryIndex, findClosestMatch, findInterfaceFile, findLocalRegistry, findProjectRoot, generateConcreteInfraCode, generateDomain, generateDomainEntityCode, generateFeature, generateHttpHandler, generateHttpHandlerCode, generateInfrastructure, generateInjectable, generateInjectableCode, generateInterface, generateInterfaceCode, generateShared, generateStubCode, generateUseCase, generateUseCaseCode, generateUseCaseTestCode, getAllFiles, getConfiguredFeaturesDir, getConfiguredSharedDir, getEffectiveMode, getMissingNpmPackages, getRegistryBase, getTemplatesDir, handleCancel, handleCreate, handleEnv, handleImport, handleInit, handleLint, hbs, httpHandlerTemplate, injectableInterfaceTemplate, injectableTemplate, installNpmPackages, interfaceTemplate, isValidIdentifier, levenshteinDistance, lintCodebase, listDomainEntities, listDomainInterfaces, listExistingFeatures, listExistingShared, listUseCases, loadInterfaceHierarchy, loadLintConfig, loadMasonConfig, loadTemplate, normalizeRegistryUrl, parseInterfaceMethodsAndImports, printBanner, printGeneratedFiles, promptProperties, removeInterfacePrefix, renderTemplate, renderTemplateFile, resolveEnvFilename, resolveFeaturesDir, resolveSharedDir, runCli, runEnvAdd, runEnvAudit, runEnvCommand, runEnvDelete, runEnvExamplesCommand, runEnvInit, runEnvInitExamples, runEnvMenu, runEnvUpdate, runSharedCommand, stubInfraTemplate, synthesizeCrudMethods, toCamelCase, toKebabCase, toPascalCase, toPlural, toSingular, toStubName, updateOrGenerateDiProvider, useCaseTemplate, useCaseTestTemplate, writeFileSafely };
6878
+ export { DEFAULT_REGISTRY_BASE, DependencyRuleError, EnvEditor, FeatureDependencyGraph, PromptCancelledError, computeDirectoryHash, concreteInfraTemplate, createCli, detectPackageManager, diProviderTemplate, discoverEnvironments, domainClassTemplate, domainInterfaceTemplate, domainValueObjectTemplate, ensureInterfacePrefix, expressIndexTemplate, fetchModuleManifest, fetchRegistryFile, fetchRegistryIndex, findClosestMatch, findInterfaceFile, findLocalRegistry, findProjectRoot, generateConcreteInfraCode, generateDomain, generateDomainEntityCode, generateFeature, generateHttpHandler, generateHttpHandlerCode, generateInfrastructure, generateInjectable, generateInjectableCode, generateInterface, generateInterfaceCode, generateShared, generateStubCode, generateUseCase, generateUseCaseCode, generateUseCaseTestCode, getAllFiles, getConfiguredFeaturesDir, getConfiguredSharedDir, getEffectiveMode, getMissingNpmPackages, getRegistryBase, getResolvedLintPaths, getTemplatesDir, handleCancel, handleCreate, handleEnv, handleImport, handleInit, handleLint, hbs, httpHandlerTemplate, injectableInterfaceTemplate, injectableTemplate, installNpmPackages, interfaceTemplate, isValidIdentifier, levenshteinDistance, lintCodebase, listDomainEntities, listDomainInterfaces, listExistingFeatures, listExistingShared, listUseCases, loadInterfaceHierarchy, loadLintConfig, loadMasonConfig, loadTemplate, normalizeRegistryUrl, parseInterfaceMethodsAndImports, printBanner, printGeneratedFiles, promptProperties, removeInterfacePrefix, renderTemplate, renderTemplateFile, resolveEnvFilename, resolveFeaturesDir, resolveSharedDir, runCli, runEnvAdd, runEnvAudit, runEnvCommand, runEnvDelete, runEnvExamplesCommand, runEnvInit, runEnvInitExamples, runEnvMenu, runEnvUpdate, runSharedCommand, stubInfraTemplate, synthesizeCrudMethods, toCamelCase, toKebabCase, toPascalCase, toPlural, toSingular, toStubName, updateOrGenerateDiProvider, useCaseTemplate, useCaseTestTemplate, writeFileSafely };
6747
6879
  //# sourceMappingURL=index.js.map
6748
6880
  //# sourceMappingURL=index.js.map