@solid-stack/mason 1.0.33 → 1.0.34

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.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var fs4 = require('fs');
4
- var path2 = require('path');
3
+ var fs17 = require('fs');
4
+ var path26 = require('path');
5
5
  var p19 = require('@clack/prompts');
6
6
  var pc14 = require('picocolors');
7
7
  var url = require('url');
@@ -31,8 +31,8 @@ function _interopNamespace(e) {
31
31
  return Object.freeze(n);
32
32
  }
33
33
 
34
- var fs4__default = /*#__PURE__*/_interopDefault(fs4);
35
- var path2__default = /*#__PURE__*/_interopDefault(path2);
34
+ var fs17__default = /*#__PURE__*/_interopDefault(fs17);
35
+ var path26__default = /*#__PURE__*/_interopDefault(path26);
36
36
  var p19__namespace = /*#__PURE__*/_interopNamespace(p19);
37
37
  var pc14__default = /*#__PURE__*/_interopDefault(pc14);
38
38
  var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
@@ -105,8 +105,8 @@ function isValidIdentifier(str) {
105
105
  }
106
106
  function writeFileSafely(absolutePath, content, options = {}) {
107
107
  const projectRoot = options.projectRoot || process.cwd();
108
- const relPath = path2__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
109
- const existedBefore = fs4__default.default.existsSync(absolutePath);
108
+ const relPath = path26__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
109
+ const existedBefore = fs17__default.default.existsSync(absolutePath);
110
110
  if (options.dryRun) {
111
111
  return {
112
112
  relativePath: relPath,
@@ -125,11 +125,11 @@ function writeFileSafely(absolutePath, content, options = {}) {
125
125
  existedBefore: true
126
126
  };
127
127
  }
128
- const dir = path2__default.default.dirname(absolutePath);
129
- if (!fs4__default.default.existsSync(dir)) {
130
- fs4__default.default.mkdirSync(dir, { recursive: true });
128
+ const dir = path26__default.default.dirname(absolutePath);
129
+ if (!fs17__default.default.existsSync(dir)) {
130
+ fs17__default.default.mkdirSync(dir, { recursive: true });
131
131
  }
132
- fs4__default.default.writeFileSync(absolutePath, content, "utf-8");
132
+ fs17__default.default.writeFileSync(absolutePath, content, "utf-8");
133
133
  return {
134
134
  relativePath: relPath,
135
135
  absolutePath,
@@ -156,17 +156,17 @@ function printGeneratedFiles(files, isDryRun = false) {
156
156
  }
157
157
  }
158
158
  function loadMasonConfig(startDir = process.cwd()) {
159
- let current = path2__default.default.resolve(startDir);
159
+ let current = path26__default.default.resolve(startDir);
160
160
  while (true) {
161
- const configPath = path2__default.default.join(current, "mason.config.json");
162
- if (fs4__default.default.existsSync(configPath)) {
161
+ const configPath = path26__default.default.join(current, "mason.config.json");
162
+ if (fs17__default.default.existsSync(configPath)) {
163
163
  try {
164
- return JSON.parse(fs4__default.default.readFileSync(configPath, "utf-8"));
164
+ return JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
165
165
  } catch {
166
166
  return null;
167
167
  }
168
168
  }
169
- const parent = path2__default.default.dirname(current);
169
+ const parent = path26__default.default.dirname(current);
170
170
  if (parent === current) break;
171
171
  current = parent;
172
172
  }
@@ -176,70 +176,91 @@ function getEffectiveMode(projectRoot, flags) {
176
176
  if (flags?.registry) return "registry";
177
177
  const config = loadMasonConfig(projectRoot);
178
178
  if (config?.mode) return config.mode;
179
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "index.json")) && (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "features")) || fs4__default.default.existsSync(path2__default.default.join(projectRoot, "shared")) || fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/features")) || fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared")))) {
179
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "index.json")) && (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "features")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "shared")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared")))) {
180
180
  return "registry";
181
181
  }
182
182
  return "app";
183
183
  }
184
184
  function getConfiguredFeaturesDir(projectRoot, flags) {
185
- if (flags?.target) return path2__default.default.resolve(projectRoot, flags.target);
186
- if (flags?.dest) return path2__default.default.resolve(projectRoot, flags.dest);
185
+ if (flags?.target) return path26__default.default.resolve(projectRoot, flags.target);
186
+ if (flags?.dest) return path26__default.default.resolve(projectRoot, flags.dest);
187
187
  const config = loadMasonConfig(projectRoot);
188
188
  if (config?.paths?.features) {
189
- return path2__default.default.resolve(projectRoot, config.paths.features);
189
+ return path26__default.default.resolve(projectRoot, config.paths.features);
190
190
  }
191
191
  const mode = getEffectiveMode(projectRoot, flags);
192
192
  if (mode === "registry") {
193
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
194
- return path2__default.default.join(projectRoot, "src/features");
193
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features"))) {
194
+ return path26__default.default.join(projectRoot, "src/features");
195
195
  }
196
- return path2__default.default.join(projectRoot, "features");
196
+ return path26__default.default.join(projectRoot, "features");
197
197
  }
198
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
199
- return path2__default.default.join(projectRoot, "src/features");
198
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/features"))) {
199
+ return path26__default.default.join(projectRoot, "src/features");
200
200
  }
201
- return path2__default.default.join(projectRoot, "features");
201
+ return path26__default.default.join(projectRoot, "features");
202
202
  }
203
203
  function getConfiguredSharedDir(projectRoot, flags) {
204
- if (flags?.target) return path2__default.default.resolve(projectRoot, flags.target);
205
- if (flags?.dest) return path2__default.default.resolve(projectRoot, flags.dest);
204
+ if (flags?.target) return path26__default.default.resolve(projectRoot, flags.target);
205
+ if (flags?.dest) return path26__default.default.resolve(projectRoot, flags.dest);
206
206
  const config = loadMasonConfig(projectRoot);
207
207
  if (config?.paths?.shared) {
208
- return path2__default.default.resolve(projectRoot, config.paths.shared);
208
+ return path26__default.default.resolve(projectRoot, config.paths.shared);
209
209
  }
210
210
  const mode = getEffectiveMode(projectRoot, flags);
211
211
  if (mode === "registry") {
212
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
213
- return path2__default.default.join(projectRoot, "src/shared");
212
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared"))) {
213
+ return path26__default.default.join(projectRoot, "src/shared");
214
214
  }
215
- return path2__default.default.join(projectRoot, "shared");
215
+ return path26__default.default.join(projectRoot, "shared");
216
216
  }
217
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
218
- return path2__default.default.join(projectRoot, "src/shared");
217
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/shared"))) {
218
+ return path26__default.default.join(projectRoot, "src/shared");
219
219
  }
220
- return path2__default.default.join(projectRoot, "shared");
220
+ return path26__default.default.join(projectRoot, "shared");
221
221
  }
222
222
  function loadLintConfig(projectRoot) {
223
- const configPath = path2__default.default.join(projectRoot, "mason-lint.config.json");
224
- if (fs4__default.default.existsSync(configPath)) {
223
+ const configPath = path26__default.default.join(projectRoot, "mason-lint.config.json");
224
+ if (fs17__default.default.existsSync(configPath)) {
225
225
  try {
226
- return JSON.parse(fs4__default.default.readFileSync(configPath, "utf-8"));
226
+ return JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
227
227
  } catch {
228
228
  }
229
229
  }
230
- return { baseErrorPath: "src/errors/AppError.ts" };
230
+ return {};
231
+ }
232
+ function getResolvedLintPaths(projectRoot, config) {
233
+ const masonConfig = loadMasonConfig(projectRoot);
234
+ const configuredFeatures = config.paths?.features ?? masonConfig?.paths?.features;
235
+ const configuredShared = config.paths?.shared ?? masonConfig?.paths?.shared;
236
+ const configuredErrors = config.paths?.errors;
237
+ const resolveBase = (configuredPath, defaultSrc, defaultRoot) => {
238
+ if (configuredPath !== void 0) {
239
+ return path26__default.default.resolve(projectRoot, configuredPath);
240
+ }
241
+ const srcPath = path26__default.default.join(projectRoot, defaultSrc);
242
+ if (fs17__default.default.existsSync(srcPath)) return srcPath;
243
+ const rootPath = path26__default.default.join(projectRoot, defaultRoot);
244
+ if (fs17__default.default.existsSync(rootPath)) return rootPath;
245
+ return srcPath;
246
+ };
247
+ return {
248
+ featuresBase: resolveBase(configuredFeatures, "src/features", "features"),
249
+ sharedBase: resolveBase(configuredShared, "src/shared", "shared"),
250
+ errorsBase: resolveBase(configuredErrors, "src/errors", "errors")
251
+ };
231
252
  }
232
253
 
233
254
  // src/utils/project.ts
234
255
  function findProjectRoot(startDir = process.cwd()) {
235
- let current = path2__default.default.resolve(startDir);
256
+ let current = path26__default.default.resolve(startDir);
236
257
  while (true) {
237
- if (fs4__default.default.existsSync(path2__default.default.join(current, "package.json"))) {
258
+ if (fs17__default.default.existsSync(path26__default.default.join(current, "package.json"))) {
238
259
  return current;
239
260
  }
240
- const parent = path2__default.default.dirname(current);
261
+ const parent = path26__default.default.dirname(current);
241
262
  if (parent === current) {
242
- return path2__default.default.resolve(startDir);
263
+ return path26__default.default.resolve(startDir);
243
264
  }
244
265
  current = parent;
245
266
  }
@@ -252,9 +273,9 @@ function resolveSharedDir(projectRoot, flags) {
252
273
  }
253
274
  function listExistingShared(projectRoot) {
254
275
  const sharedDir = resolveSharedDir(projectRoot);
255
- if (!fs4__default.default.existsSync(sharedDir)) return [];
276
+ if (!fs17__default.default.existsSync(sharedDir)) return [];
256
277
  try {
257
- const entries = fs4__default.default.readdirSync(sharedDir, { withFileTypes: true });
278
+ const entries = fs17__default.default.readdirSync(sharedDir, { withFileTypes: true });
258
279
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
259
280
  } catch {
260
281
  return [];
@@ -262,9 +283,9 @@ function listExistingShared(projectRoot) {
262
283
  }
263
284
  function listExistingFeatures(projectRoot) {
264
285
  const featuresDir = resolveFeaturesDir(projectRoot);
265
- if (!fs4__default.default.existsSync(featuresDir)) return [];
286
+ if (!fs17__default.default.existsSync(featuresDir)) return [];
266
287
  try {
267
- const entries = fs4__default.default.readdirSync(featuresDir, { withFileTypes: true });
288
+ const entries = fs17__default.default.readdirSync(featuresDir, { withFileTypes: true });
268
289
  return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
269
290
  } catch {
270
291
  return [];
@@ -274,14 +295,14 @@ function listDomainInterfaces(projectRoot, featureName) {
274
295
  const results = [];
275
296
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
276
297
  for (const feat of features) {
277
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
278
- if (!fs4__default.default.existsSync(domainDir)) continue;
298
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
299
+ if (!fs17__default.default.existsSync(domainDir)) continue;
279
300
  try {
280
- const files = fs4__default.default.readdirSync(domainDir);
301
+ const files = fs17__default.default.readdirSync(domainDir);
281
302
  for (const file of files) {
282
303
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
283
304
  const name = file.replace(/\.ts$/, "");
284
- const fullPath = path2__default.default.join(domainDir, file);
305
+ const fullPath = path26__default.default.join(domainDir, file);
285
306
  if (/^I[A-Z]/.test(name)) {
286
307
  results.push({
287
308
  name,
@@ -290,7 +311,7 @@ function listDomainInterfaces(projectRoot, featureName) {
290
311
  });
291
312
  } else {
292
313
  try {
293
- const content = fs4__default.default.readFileSync(fullPath, "utf-8");
314
+ const content = fs17__default.default.readFileSync(fullPath, "utf-8");
294
315
  if (/export\s+(?:abstract\s+class|interface)\s+(\w+)/.test(content)) {
295
316
  results.push({
296
317
  name,
@@ -312,17 +333,17 @@ function listDomainEntities(projectRoot, featureName) {
312
333
  const results = [];
313
334
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
314
335
  for (const feat of features) {
315
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
316
- if (!fs4__default.default.existsSync(domainDir)) continue;
336
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
337
+ if (!fs17__default.default.existsSync(domainDir)) continue;
317
338
  try {
318
- const files = fs4__default.default.readdirSync(domainDir);
339
+ const files = fs17__default.default.readdirSync(domainDir);
319
340
  for (const file of files) {
320
341
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
321
342
  const name = file.replace(/\.ts$/, "");
322
343
  if (!/^I[A-Z]/.test(name)) {
323
344
  results.push({
324
345
  name,
325
- fullPath: path2__default.default.join(domainDir, file),
346
+ fullPath: path26__default.default.join(domainDir, file),
326
347
  feature: feat
327
348
  });
328
349
  }
@@ -337,16 +358,16 @@ function listUseCases(projectRoot, featureName) {
337
358
  const results = [];
338
359
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
339
360
  for (const feat of features) {
340
- const useCasesDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
341
- if (!fs4__default.default.existsSync(useCasesDir)) continue;
361
+ const useCasesDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
362
+ if (!fs17__default.default.existsSync(useCasesDir)) continue;
342
363
  try {
343
- const files = fs4__default.default.readdirSync(useCasesDir);
364
+ const files = fs17__default.default.readdirSync(useCasesDir);
344
365
  for (const file of files) {
345
366
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
346
367
  const name = file.replace(/\.ts$/, "");
347
368
  results.push({
348
369
  name,
349
- fullPath: path2__default.default.join(useCasesDir, file),
370
+ fullPath: path26__default.default.join(useCasesDir, file),
350
371
  feature: feat
351
372
  });
352
373
  }
@@ -458,25 +479,25 @@ function normalizeRegistryUrl(urlOrPath, baseDir) {
458
479
  return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`;
459
480
  }
460
481
  if (baseDir && (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed === "." || trimmed === "..")) {
461
- return path2__default.default.resolve(baseDir, trimmed);
482
+ return path26__default.default.resolve(baseDir, trimmed);
462
483
  }
463
484
  return trimmed;
464
485
  }
465
486
  function findLocalRegistry(startDir = process.cwd()) {
466
- let current = path2__default.default.resolve(startDir);
487
+ let current = path26__default.default.resolve(startDir);
467
488
  while (true) {
468
- const candidate = path2__default.default.join(current, "mason-registry");
469
- if (fs4__default.default.existsSync(candidate) && fs4__default.default.existsSync(path2__default.default.join(candidate, "index.json"))) {
489
+ const candidate = path26__default.default.join(current, "mason-registry");
490
+ if (fs17__default.default.existsSync(candidate) && fs17__default.default.existsSync(path26__default.default.join(candidate, "index.json"))) {
470
491
  return candidate;
471
492
  }
472
- const parent = path2__default.default.dirname(current);
493
+ const parent = path26__default.default.dirname(current);
473
494
  if (parent === current) break;
474
495
  current = parent;
475
496
  }
476
497
  return null;
477
498
  }
478
499
  function getRegistryBase(projectRoot, override) {
479
- const rootDir = projectRoot ? path2__default.default.resolve(projectRoot) : process.cwd();
500
+ const rootDir = projectRoot ? path26__default.default.resolve(projectRoot) : process.cwd();
480
501
  if (override && override.trim()) {
481
502
  return normalizeRegistryUrl(override.trim(), rootDir);
482
503
  }
@@ -484,30 +505,30 @@ function getRegistryBase(projectRoot, override) {
484
505
  return normalizeRegistryUrl(process.env.MASON_REGISTRY_URL.trim(), rootDir);
485
506
  }
486
507
  const configLocations = [
487
- path2__default.default.join(rootDir, "mason.config.json"),
488
- path2__default.default.join(process.cwd(), "mason.config.json")
508
+ path26__default.default.join(rootDir, "mason.config.json"),
509
+ path26__default.default.join(process.cwd(), "mason.config.json")
489
510
  ];
490
511
  for (const configPath of configLocations) {
491
- if (fs4__default.default.existsSync(configPath)) {
512
+ if (fs17__default.default.existsSync(configPath)) {
492
513
  try {
493
- const config = JSON.parse(fs4__default.default.readFileSync(configPath, "utf-8"));
514
+ const config = JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
494
515
  if (config.registry && typeof config.registry === "string") {
495
- return normalizeRegistryUrl(config.registry.trim(), path2__default.default.dirname(configPath));
516
+ return normalizeRegistryUrl(config.registry.trim(), path26__default.default.dirname(configPath));
496
517
  }
497
518
  } catch {
498
519
  }
499
520
  }
500
521
  }
501
522
  const pkgLocations = [
502
- path2__default.default.join(rootDir, "package.json"),
503
- path2__default.default.join(process.cwd(), "package.json")
523
+ path26__default.default.join(rootDir, "package.json"),
524
+ path26__default.default.join(process.cwd(), "package.json")
504
525
  ];
505
526
  for (const pkgPath of pkgLocations) {
506
- if (fs4__default.default.existsSync(pkgPath)) {
527
+ if (fs17__default.default.existsSync(pkgPath)) {
507
528
  try {
508
- const pkg = JSON.parse(fs4__default.default.readFileSync(pkgPath, "utf-8"));
529
+ const pkg = JSON.parse(fs17__default.default.readFileSync(pkgPath, "utf-8"));
509
530
  if (pkg.mason?.registry && typeof pkg.mason.registry === "string") {
510
- return normalizeRegistryUrl(pkg.mason.registry.trim(), path2__default.default.dirname(pkgPath));
531
+ return normalizeRegistryUrl(pkg.mason.registry.trim(), path26__default.default.dirname(pkgPath));
511
532
  }
512
533
  } catch {
513
534
  }
@@ -555,16 +576,16 @@ async function fetchRegistryFile(registryBase, relPath) {
555
576
  if (baseDir.startsWith("file://")) {
556
577
  baseDir = url.fileURLToPath(baseDir);
557
578
  }
558
- let filePath = path2__default.default.resolve(baseDir, cleanRelPath);
559
- if (!fs4__default.default.existsSync(filePath)) {
560
- const inSrcPath = path2__default.default.resolve(baseDir, "src", cleanRelPath);
561
- if (fs4__default.default.existsSync(inSrcPath)) {
579
+ let filePath = path26__default.default.resolve(baseDir, cleanRelPath);
580
+ if (!fs17__default.default.existsSync(filePath)) {
581
+ const inSrcPath = path26__default.default.resolve(baseDir, "src", cleanRelPath);
582
+ if (fs17__default.default.existsSync(inSrcPath)) {
562
583
  filePath = inSrcPath;
563
584
  } else {
564
585
  throw new Error(`Registry file not found at ${filePath}`);
565
586
  }
566
587
  }
567
- return fs4__default.default.promises.readFile(filePath, "utf-8");
588
+ return fs17__default.default.promises.readFile(filePath, "utf-8");
568
589
  }
569
590
  async function fetchRegistryIndex(registryBase) {
570
591
  const content = await fetchRegistryFile(registryBase, "index.json");
@@ -626,19 +647,19 @@ function findClosestMatch(target, candidates) {
626
647
  return null;
627
648
  }
628
649
  function detectPackageManager(projectRoot) {
629
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
630
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
631
- if (fs4__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lockb")) || fs4__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lock"))) return "bun";
650
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
651
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
652
+ if (fs17__default.default.existsSync(path26__default.default.join(projectRoot, "bun.lockb")) || fs17__default.default.existsSync(path26__default.default.join(projectRoot, "bun.lock"))) return "bun";
632
653
  return "npm";
633
654
  }
634
655
  function getMissingNpmPackages(projectRoot, requiredPackages) {
635
656
  if (!requiredPackages || requiredPackages.length === 0) return [];
636
- const pkgJsonPath = path2__default.default.join(projectRoot, "package.json");
637
- if (!fs4__default.default.existsSync(pkgJsonPath)) {
657
+ const pkgJsonPath = path26__default.default.join(projectRoot, "package.json");
658
+ if (!fs17__default.default.existsSync(pkgJsonPath)) {
638
659
  return requiredPackages;
639
660
  }
640
661
  try {
641
- const pkg = JSON.parse(fs4__default.default.readFileSync(pkgJsonPath, "utf-8"));
662
+ const pkg = JSON.parse(fs17__default.default.readFileSync(pkgJsonPath, "utf-8"));
642
663
  const installed = /* @__PURE__ */ new Set([
643
664
  ...Object.keys(pkg.dependencies || {}),
644
665
  ...Object.keys(pkg.devDependencies || {}),
@@ -677,12 +698,12 @@ function installNpmPackages(projectRoot, packages, pm) {
677
698
  });
678
699
  }
679
700
  function getAllFiles(dir, baseDir = dir) {
680
- if (!fs4__default.default.existsSync(dir)) return [];
681
- const entries = fs4__default.default.readdirSync(dir, { withFileTypes: true });
701
+ if (!fs17__default.default.existsSync(dir)) return [];
702
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
682
703
  const files = [];
683
704
  for (const entry of entries) {
684
- const fullPath = path2__default.default.join(dir, entry.name);
685
- const relPath = path2__default.default.relative(baseDir, fullPath).replace(/\\/g, "/");
705
+ const fullPath = path26__default.default.join(dir, entry.name);
706
+ const relPath = path26__default.default.relative(baseDir, fullPath).replace(/\\/g, "/");
686
707
  if (entry.isDirectory()) {
687
708
  if (entry.name === "__tests__" || entry.name.startsWith(".")) {
688
709
  continue;
@@ -698,13 +719,13 @@ function getAllFiles(dir, baseDir = dir) {
698
719
  return files.sort();
699
720
  }
700
721
  function computeDirectoryHash(dirPath, files) {
701
- if (!fs4__default.default.existsSync(dirPath)) return "";
722
+ if (!fs17__default.default.existsSync(dirPath)) return "";
702
723
  const hash = crypto.createHash("sha256");
703
724
  const fileList = (files ?? getAllFiles(dirPath)).sort();
704
725
  for (const relativePath of fileList) {
705
- const absolutePath = path2__default.default.join(dirPath, relativePath);
706
- if (!fs4__default.default.existsSync(absolutePath)) continue;
707
- const content = fs4__default.default.readFileSync(absolutePath, "utf8");
726
+ const absolutePath = path26__default.default.join(dirPath, relativePath);
727
+ if (!fs17__default.default.existsSync(absolutePath)) continue;
728
+ const content = fs17__default.default.readFileSync(absolutePath, "utf8");
708
729
  const normalizedContent = content.replace(/\r\n/g, "\n");
709
730
  hash.update(relativePath);
710
731
  hash.update(normalizedContent);
@@ -727,33 +748,33 @@ hbs.registerHelper("join", (arr, sep) => {
727
748
  });
728
749
  var cachedTemplatesDir = null;
729
750
  function getTemplatesDir() {
730
- if (cachedTemplatesDir && fs4__default.default.existsSync(cachedTemplatesDir)) {
751
+ if (cachedTemplatesDir && fs17__default.default.existsSync(cachedTemplatesDir)) {
731
752
  return cachedTemplatesDir;
732
753
  }
733
- const currentDir = typeof __dirname !== "undefined" ? __dirname : path2__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
734
- const cand1 = path2__default.default.resolve(currentDir, "../../templates");
735
- if (fs4__default.default.existsSync(cand1)) {
754
+ const currentDir = typeof __dirname !== "undefined" ? __dirname : path26__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
755
+ const cand1 = path26__default.default.resolve(currentDir, "../../templates");
756
+ if (fs17__default.default.existsSync(cand1)) {
736
757
  cachedTemplatesDir = cand1;
737
758
  return cand1;
738
759
  }
739
- const cand2 = path2__default.default.resolve(currentDir, "../templates");
740
- if (fs4__default.default.existsSync(cand2)) {
760
+ const cand2 = path26__default.default.resolve(currentDir, "../templates");
761
+ if (fs17__default.default.existsSync(cand2)) {
741
762
  cachedTemplatesDir = cand2;
742
763
  return cand2;
743
764
  }
744
- const cand3 = path2__default.default.resolve(currentDir, "templates");
745
- if (fs4__default.default.existsSync(cand3)) {
765
+ const cand3 = path26__default.default.resolve(currentDir, "templates");
766
+ if (fs17__default.default.existsSync(cand3)) {
746
767
  cachedTemplatesDir = cand3;
747
768
  return cand3;
748
769
  }
749
770
  let curr = currentDir;
750
771
  while (true) {
751
- const candTemplates = path2__default.default.join(curr, "templates");
752
- if (fs4__default.default.existsSync(candTemplates)) {
772
+ const candTemplates = path26__default.default.join(curr, "templates");
773
+ if (fs17__default.default.existsSync(candTemplates)) {
753
774
  cachedTemplatesDir = candTemplates;
754
775
  return candTemplates;
755
776
  }
756
- const parent = path2__default.default.dirname(curr);
777
+ const parent = path26__default.default.dirname(curr);
757
778
  if (parent === curr) break;
758
779
  curr = parent;
759
780
  }
@@ -761,8 +782,8 @@ function getTemplatesDir() {
761
782
  }
762
783
  var templateCache = /* @__PURE__ */ new Map();
763
784
  function loadTemplate(relativePath) {
764
- const fullPath = path2__default.default.isAbsolute(relativePath) ? relativePath : path2__default.default.join(getTemplatesDir(), relativePath);
765
- return fs4__default.default.readFileSync(fullPath, "utf-8");
785
+ const fullPath = path26__default.default.isAbsolute(relativePath) ? relativePath : path26__default.default.join(getTemplatesDir(), relativePath);
786
+ return fs17__default.default.readFileSync(fullPath, "utf-8");
766
787
  }
767
788
  function renderTemplateFile(relativePath, context) {
768
789
  let compiled = templateCache.get(relativePath);
@@ -847,8 +868,8 @@ function generateDomainEntityCode(name, kind = "interface", properties = []) {
847
868
  function generateDomain(options) {
848
869
  const projectRoot = options.projectRoot || findProjectRoot();
849
870
  const entityName = toPascalCase(options.name);
850
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
851
- const filePath = path2__default.default.join(targetDir, `${entityName}.ts`);
871
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
872
+ const filePath = path26__default.default.join(targetDir, `${entityName}.ts`);
852
873
  const code = generateDomainEntityCode(
853
874
  entityName,
854
875
  options.kind || "interface",
@@ -897,8 +918,8 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
897
918
  function generateInterface(options) {
898
919
  const projectRoot = options.projectRoot || findProjectRoot();
899
920
  const ifaceName = ensureInterfacePrefix(options.name);
900
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
901
- const filePath = path2__default.default.join(targetDir, `${ifaceName}.ts`);
921
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
922
+ const filePath = path26__default.default.join(targetDir, `${ifaceName}.ts`);
902
923
  const code = generateInterfaceCode(
903
924
  ifaceName,
904
925
  options.kind || "abstractClass",
@@ -1133,7 +1154,7 @@ function parseInterfaceMethodsAndImports(content, targetIfaceName) {
1133
1154
  };
1134
1155
  }
1135
1156
  function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
1136
- if (customPath && fs4__default.default.existsSync(customPath)) {
1157
+ if (customPath && fs17__default.default.existsSync(customPath)) {
1137
1158
  return { filePath: customPath, ifaceName };
1138
1159
  }
1139
1160
  const candidateNames = [
@@ -1143,22 +1164,22 @@ function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
1143
1164
  ];
1144
1165
  const features = featureName ? [featureName, ...listExistingFeatures(projectRoot).filter((f) => f !== featureName)] : listExistingFeatures(projectRoot);
1145
1166
  for (const feat of features) {
1146
- const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
1147
- if (!fs4__default.default.existsSync(domainDir)) continue;
1167
+ const domainDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
1168
+ if (!fs17__default.default.existsSync(domainDir)) continue;
1148
1169
  for (const cand of candidateNames) {
1149
- const p1 = path2__default.default.join(domainDir, `${cand}.ts`);
1150
- if (fs4__default.default.existsSync(p1)) {
1170
+ const p1 = path26__default.default.join(domainDir, `${cand}.ts`);
1171
+ if (fs17__default.default.existsSync(p1)) {
1151
1172
  return { filePath: p1, ifaceName: cand, feature: feat };
1152
1173
  }
1153
1174
  }
1154
1175
  }
1155
1176
  for (const cand of candidateNames) {
1156
- const p1 = path2__default.default.join(projectRoot, "domain", `${cand}.ts`);
1157
- if (fs4__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
1158
- const p22 = path2__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
1159
- if (fs4__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
1160
- const p32 = path2__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
1161
- if (fs4__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
1177
+ const p1 = path26__default.default.join(projectRoot, "domain", `${cand}.ts`);
1178
+ if (fs17__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
1179
+ const p22 = path26__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
1180
+ if (fs17__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
1181
+ const p32 = path26__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
1182
+ if (fs17__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
1162
1183
  }
1163
1184
  return null;
1164
1185
  }
@@ -1181,7 +1202,7 @@ function loadInterfaceHierarchy(projectRoot, initialIfaceName, featureName, cust
1181
1202
  while (currentFile && !visited.has(currentFile)) {
1182
1203
  visited.add(currentFile);
1183
1204
  try {
1184
- const content = fs4__default.default.readFileSync(currentFile, "utf-8");
1205
+ const content = fs17__default.default.readFileSync(currentFile, "utf-8");
1185
1206
  const parsed = parseInterfaceMethodsAndImports(content, currentName);
1186
1207
  for (const m of parsed.methods) {
1187
1208
  if (!allMethods.some((existing) => existing.name === m.name)) {
@@ -1257,7 +1278,7 @@ function generateStubCode(stubClassName, ifaceName, entityName, featureName, met
1257
1278
  const entitiesVar = `${entityVar}s`;
1258
1279
  const idKey = `${entityVar}Id`;
1259
1280
  const impPath = ifaceImportPath || `../domain/${ifaceName}.js`;
1260
- const entityImportPath = ifaceImportPath ? `${path2__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1281
+ const entityImportPath = ifaceImportPath ? `${path26__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1261
1282
  const importsByFrom = /* @__PURE__ */ new Map();
1262
1283
  for (const imp of domainImports) {
1263
1284
  if (imp.name === ifaceName || imp.name === baseEntity) continue;
@@ -1306,7 +1327,7 @@ function generateConcreteInfraCode(className, ifaceName, dependencies = [], meth
1306
1327
  if (baseEntity) {
1307
1328
  finalMethods = synthesizeCrudMethods(baseEntity);
1308
1329
  if (!finalDomainImports.some((imp) => imp.name === baseEntity)) {
1309
- const importPath = ifaceImportPath ? `${path2__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1330
+ const importPath = ifaceImportPath ? `${path26__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
1310
1331
  finalDomainImports.push({
1311
1332
  name: baseEntity,
1312
1333
  from: importPath,
@@ -1351,8 +1372,8 @@ function generateInfrastructure(options) {
1351
1372
  const projectRoot = options.projectRoot || findProjectRoot();
1352
1373
  const className = toPascalCase(options.name);
1353
1374
  const isFeatureScope = options.scope !== "global" && Boolean(options.feature);
1354
- const targetDir = options.targetDir || (isFeatureScope ? path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path2__default.default.join(projectRoot, "infrastructure"));
1355
- const filePath = path2__default.default.join(targetDir, `${className}.ts`);
1375
+ const targetDir = options.targetDir || (isFeatureScope ? path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path26__default.default.join(projectRoot, "infrastructure"));
1376
+ const filePath = path26__default.default.join(targetDir, `${className}.ts`);
1356
1377
  let code;
1357
1378
  if (options.implementsInterface) {
1358
1379
  const rawIfaceName = options.implementsInterface;
@@ -1366,7 +1387,7 @@ function generateInfrastructure(options) {
1366
1387
  const ifaceFilePath = hierarchy.ifaceFilePath;
1367
1388
  let ifaceImportPath;
1368
1389
  if (ifaceFilePath) {
1369
- let rel = path2__default.default.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
1390
+ let rel = path26__default.default.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
1370
1391
  if (!rel.startsWith(".")) rel = "./" + rel;
1371
1392
  ifaceImportPath = rel;
1372
1393
  } else if (isFeatureScope) {
@@ -1379,8 +1400,8 @@ function generateInfrastructure(options) {
1379
1400
  if (new RegExp(`\\b${item.name}\\b`).test(allSignatures)) {
1380
1401
  let fromPath;
1381
1402
  if (imp.specifier.startsWith(".") && ifaceFilePath) {
1382
- const absTarget = path2__default.default.resolve(path2__default.default.dirname(ifaceFilePath), imp.specifier);
1383
- let rel = path2__default.default.relative(targetDir, absTarget).replace(/\\/g, "/");
1403
+ const absTarget = path26__default.default.resolve(path26__default.default.dirname(ifaceFilePath), imp.specifier);
1404
+ let rel = path26__default.default.relative(targetDir, absTarget).replace(/\\/g, "/");
1384
1405
  if (!rel.startsWith(".")) rel = "./" + rel;
1385
1406
  fromPath = rel;
1386
1407
  } else {
@@ -1567,8 +1588,8 @@ function generateUseCase(options) {
1567
1588
  const files = [];
1568
1589
  const projectRoot = options.projectRoot || findProjectRoot();
1569
1590
  const ucName = toPascalCase(options.name);
1570
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1571
- const filePath = path2__default.default.join(targetDir, `${ucName}.ts`);
1591
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
1592
+ const filePath = path26__default.default.join(targetDir, `${ucName}.ts`);
1572
1593
  const code = generateUseCaseCode(
1573
1594
  ucName,
1574
1595
  options.dependencies || [],
@@ -1584,7 +1605,7 @@ function generateUseCase(options) {
1584
1605
  })
1585
1606
  );
1586
1607
  if (options.includeTest) {
1587
- const testPath = path2__default.default.join(targetDir, `${ucName}.test.ts`);
1608
+ const testPath = path26__default.default.join(targetDir, `${ucName}.test.ts`);
1588
1609
  const testCode = generateUseCaseTestCode(ucName, options.dependencies || []);
1589
1610
  files.push(
1590
1611
  writeFileSafely(testPath, testCode, {
@@ -1652,10 +1673,10 @@ function generateHttpHandler(options) {
1652
1673
  const files = [];
1653
1674
  const projectRoot = options.projectRoot || findProjectRoot();
1654
1675
  const className = toPascalCase(options.name);
1655
- const pxDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1656
- const handlersDir = path2__default.default.join(pxDir, "handlers");
1657
- const pxIndexPath = path2__default.default.join(pxDir, "index.ts");
1658
- if (!fs4__default.default.existsSync(pxIndexPath)) {
1676
+ const pxDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1677
+ const handlersDir = path26__default.default.join(pxDir, "handlers");
1678
+ const pxIndexPath = path26__default.default.join(pxDir, "index.ts");
1679
+ if (!fs17__default.default.existsSync(pxIndexPath)) {
1659
1680
  const featurePath = options.routePrefix || `/${options.feature.toLowerCase()}`;
1660
1681
  const pxIndexContent = renderTemplate(expressIndexTemplate, {
1661
1682
  routePath: featurePath
@@ -1668,7 +1689,7 @@ function generateHttpHandler(options) {
1668
1689
  })
1669
1690
  );
1670
1691
  }
1671
- const handlerFilePath = path2__default.default.join(handlersDir, `${className}.ts`);
1692
+ const handlerFilePath = path26__default.default.join(handlersDir, `${className}.ts`);
1672
1693
  const code = generateHttpHandlerCode(
1673
1694
  className,
1674
1695
  options.method || "get",
@@ -1689,11 +1710,11 @@ function generateHttpHandler(options) {
1689
1710
  return files;
1690
1711
  }
1691
1712
  function updateOrGenerateDiProvider(featureDir, featureName, bindings = [], options = {}) {
1692
- const providerPath = path2__default.default.join(featureDir, "diProvider.ts");
1713
+ const providerPath = path26__default.default.join(featureDir, "diProvider.ts");
1693
1714
  const pascalFeature = toPascalCase(featureName);
1694
1715
  const providerModuleName = `${pascalFeature}Provider`;
1695
- if (fs4__default.default.existsSync(providerPath) && !options.overwrite) {
1696
- let content = fs4__default.default.readFileSync(providerPath, "utf-8");
1716
+ if (fs17__default.default.existsSync(providerPath) && !options.overwrite) {
1717
+ let content = fs17__default.default.readFileSync(providerPath, "utf-8");
1697
1718
  content = content.replace(/\n*export\s+const\s+ScaffoldProvider\s*=[^;]+;?/g, "");
1698
1719
  for (const b of bindings) {
1699
1720
  const ifaceImp = b.ifaceImportPath || `./domain/${b.ifaceName}.js`;
@@ -1752,7 +1773,7 @@ function generateFeature(options) {
1752
1773
  const projectRoot = options.projectRoot || findProjectRoot();
1753
1774
  const rawName = options.name.trim();
1754
1775
  const featureName = toCamelCase(rawName);
1755
- const targetDir = options.targetDir || path2__default.default.join(resolveFeaturesDir(projectRoot), featureName);
1776
+ const targetDir = options.targetDir || path26__default.default.join(resolveFeaturesDir(projectRoot), featureName);
1756
1777
  const routePath = options.routePath || `/${featureName}`;
1757
1778
  const rawEntities = [];
1758
1779
  if (options.entityNames && options.entityNames.length > 0) {
@@ -1773,7 +1794,7 @@ function generateFeature(options) {
1773
1794
  const domainFile = generateDomain({
1774
1795
  name: ent,
1775
1796
  feature: featureName,
1776
- targetDir: path2__default.default.join(targetDir, "domain"),
1797
+ targetDir: path26__default.default.join(targetDir, "domain"),
1777
1798
  projectRoot,
1778
1799
  dryRun: options.dryRun,
1779
1800
  overwrite: options.overwrite,
@@ -1793,7 +1814,7 @@ function generateFeature(options) {
1793
1814
  const ifaceFile = generateInterface({
1794
1815
  name: ifaceName,
1795
1816
  feature: featureName,
1796
- targetDir: path2__default.default.join(targetDir, "domain"),
1817
+ targetDir: path26__default.default.join(targetDir, "domain"),
1797
1818
  entityName: ent,
1798
1819
  projectRoot,
1799
1820
  dryRun: options.dryRun,
@@ -1810,7 +1831,7 @@ function generateFeature(options) {
1810
1831
  const stubFile = generateInfrastructure({
1811
1832
  name: stubName,
1812
1833
  feature: featureName,
1813
- targetDir: path2__default.default.join(targetDir, "infrastructure"),
1834
+ targetDir: path26__default.default.join(targetDir, "infrastructure"),
1814
1835
  kind: "stub",
1815
1836
  implementsInterface: ifaceName,
1816
1837
  entityName: ent,
@@ -1852,7 +1873,7 @@ function generateFeature(options) {
1852
1873
  const ucFiles = generateUseCase({
1853
1874
  name: ucName,
1854
1875
  feature: featureName,
1855
- targetDir: path2__default.default.join(targetDir, "useCases"),
1876
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1856
1877
  dependencies: options.includeInterface !== false ? [ifaceName] : [],
1857
1878
  inputProperties: [{ name: idParam, type: "string" }],
1858
1879
  outputProperties: [{ name: entVar, type: primaryEntity }],
@@ -1897,7 +1918,7 @@ function generateFeature(options) {
1897
1918
  const ucFiles = generateUseCase({
1898
1919
  name: ucName,
1899
1920
  feature: featureName,
1900
- targetDir: path2__default.default.join(targetDir, "useCases"),
1921
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1901
1922
  dependencies: deps,
1902
1923
  inputProperties: [{ name: entVar, type: ent }],
1903
1924
  outputProperties: [{ name: entVar, type: ent }],
@@ -1930,7 +1951,7 @@ function generateFeature(options) {
1930
1951
  const ucFiles = generateUseCase({
1931
1952
  name: ucName,
1932
1953
  feature: featureName,
1933
- targetDir: path2__default.default.join(targetDir, "useCases"),
1954
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1934
1955
  dependencies: deps,
1935
1956
  inputProperties: [{ name: idParam, type: "string" }],
1936
1957
  outputProperties: [{ name: entVar, type: ent }],
@@ -1963,7 +1984,7 @@ function generateFeature(options) {
1963
1984
  const ucFiles = generateUseCase({
1964
1985
  name: ucName,
1965
1986
  feature: featureName,
1966
- targetDir: path2__default.default.join(targetDir, "useCases"),
1987
+ targetDir: path26__default.default.join(targetDir, "useCases"),
1967
1988
  dependencies: deps,
1968
1989
  inputProperties: [
1969
1990
  { name: "page", type: "number", optional: true },
@@ -2007,7 +2028,7 @@ function generateFeature(options) {
2007
2028
  const ucFiles = generateUseCase({
2008
2029
  name: ucName,
2009
2030
  feature: featureName,
2010
- targetDir: path2__default.default.join(targetDir, "useCases"),
2031
+ targetDir: path26__default.default.join(targetDir, "useCases"),
2011
2032
  dependencies: deps,
2012
2033
  inputProperties: [{ name: entVar, type: ent }],
2013
2034
  outputProperties: [{ name: entVar, type: ent }],
@@ -2040,7 +2061,7 @@ function generateFeature(options) {
2040
2061
  const ucFiles = generateUseCase({
2041
2062
  name: ucName,
2042
2063
  feature: featureName,
2043
- targetDir: path2__default.default.join(targetDir, "useCases"),
2064
+ targetDir: path26__default.default.join(targetDir, "useCases"),
2044
2065
  dependencies: deps,
2045
2066
  inputProperties: [{ name: idParam, type: "string" }],
2046
2067
  outputProperties: [{ name: "success", type: "boolean" }],
@@ -2077,7 +2098,7 @@ function generateFeature(options) {
2077
2098
  const ucFiles = generateUseCase({
2078
2099
  name: ucName,
2079
2100
  feature: featureName,
2080
- targetDir: path2__default.default.join(targetDir, "useCases"),
2101
+ targetDir: path26__default.default.join(targetDir, "useCases"),
2081
2102
  dependencies: customUc.dependencies || [],
2082
2103
  inputProperties: customUc.inputProperties || [],
2083
2104
  outputProperties: customUc.outputProperties || [],
@@ -2109,8 +2130,8 @@ function generateFeature(options) {
2109
2130
  }
2110
2131
  }
2111
2132
  if (options.includeExpress !== false) {
2112
- const pxDir = path2__default.default.join(targetDir, "pxExpress");
2113
- const pxIndexPath = path2__default.default.join(pxDir, "index.ts");
2133
+ const pxDir = path26__default.default.join(targetDir, "pxExpress");
2134
+ const pxIndexPath = path26__default.default.join(pxDir, "index.ts");
2114
2135
  if (!files.some((f) => f.absolutePath === pxIndexPath)) {
2115
2136
  const pxIndexContent = renderTemplate(expressIndexTemplate, { routePath });
2116
2137
  files.push(
@@ -2155,7 +2176,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2155
2176
  }
2156
2177
  const normalizedName = toCamelCase(name);
2157
2178
  const baseFeaturesDir = resolveFeaturesDir(projectRoot, flags);
2158
- const defaultDir = path2__default.default.relative(projectRoot, path2__default.default.join(baseFeaturesDir, normalizedName));
2179
+ const defaultDir = path26__default.default.relative(projectRoot, path26__default.default.join(baseFeaturesDir, normalizedName));
2159
2180
  let targetDirRel = defaultDir;
2160
2181
  if (!flags.yes && !flags.target && !flags.dest) {
2161
2182
  targetDirRel = handleCancel(
@@ -2166,7 +2187,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2166
2187
  })
2167
2188
  ).trim();
2168
2189
  }
2169
- const targetDir = flags.dest ? path2__default.default.resolve(projectRoot, flags.dest) : flags.target ? path2__default.default.resolve(projectRoot, flags.target) : path2__default.default.resolve(projectRoot, targetDirRel);
2190
+ const targetDir = flags.dest ? path26__default.default.resolve(projectRoot, flags.dest) : flags.target ? path26__default.default.resolve(projectRoot, flags.target) : path26__default.default.resolve(projectRoot, targetDirRel);
2170
2191
  let includeExpress = flags.express !== void 0 ? Boolean(flags.express) : true;
2171
2192
  let routePath = `/${normalizedName}`;
2172
2193
  let includeDomain = true;
@@ -2408,8 +2429,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2408
2429
  };
2409
2430
  const files = generateFeature(options);
2410
2431
  if (isRegistry) {
2411
- const registryPath = path2__default.default.join(targetDir, "registry.json");
2412
- if (!fs4__default.default.existsSync(registryPath)) {
2432
+ const registryPath = path26__default.default.join(targetDir, "registry.json");
2433
+ if (!fs17__default.default.existsSync(registryPath)) {
2413
2434
  const manifest = {
2414
2435
  name: toKebabCase(normalizedName),
2415
2436
  type: "feature",
@@ -2435,7 +2456,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2435
2456
  printGeneratedFiles(files, options.dryRun);
2436
2457
  p19__namespace.outro(
2437
2458
  pc14__default.default.green(
2438
- `\u2713 Feature '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2459
+ `\u2713 Feature '${normalizedName}' initialized in ${path26__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2439
2460
  )
2440
2461
  );
2441
2462
  }
@@ -2446,7 +2467,7 @@ function generateShared(options) {
2446
2467
  const pascalName = toPascalCase(rawName);
2447
2468
  const camelName = toCamelCase(rawName);
2448
2469
  const kebabName = toKebabCase(rawName);
2449
- const targetDir = options.targetDir || path2__default.default.join(resolveSharedDir(projectRoot), kebabName);
2470
+ const targetDir = options.targetDir || path26__default.default.join(resolveSharedDir(projectRoot), kebabName);
2450
2471
  const fileDefs = [];
2451
2472
  const facadeContent = `import { MakeInjectable, type DepsType } from "@solid-stack/di";
2452
2473
  import { I${pascalName}Engine } from "./ports/I${pascalName}Engine.js";
@@ -2458,7 +2479,7 @@ export class ${pascalName} {
2458
2479
  }
2459
2480
  `;
2460
2481
  fileDefs.push({
2461
- absolutePath: path2__default.default.join(targetDir, `${pascalName}.ts`),
2482
+ absolutePath: path26__default.default.join(targetDir, `${pascalName}.ts`),
2462
2483
  content: facadeContent
2463
2484
  });
2464
2485
  const portContent = `export abstract class I${pascalName}Engine {
@@ -2466,7 +2487,7 @@ export class ${pascalName} {
2466
2487
  }
2467
2488
  `;
2468
2489
  fileDefs.push({
2469
- absolutePath: path2__default.default.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2490
+ absolutePath: path26__default.default.join(targetDir, "ports", `I${pascalName}Engine.ts`),
2470
2491
  content: portContent
2471
2492
  });
2472
2493
  const concreteContent = `import { MakeInjectable } from "@solid-stack/di";
@@ -2478,7 +2499,7 @@ export class Default${pascalName}Engine implements I${pascalName}Engine {
2478
2499
  }
2479
2500
  `;
2480
2501
  fileDefs.push({
2481
- absolutePath: path2__default.default.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2502
+ absolutePath: path26__default.default.join(targetDir, "infrastructure", `Default${pascalName}Engine.ts`),
2482
2503
  content: concreteContent
2483
2504
  });
2484
2505
  if (options.includeStub !== false) {
@@ -2491,7 +2512,7 @@ export class Stub${pascalName}Engine implements I${pascalName}Engine {
2491
2512
  }
2492
2513
  `;
2493
2514
  fileDefs.push({
2494
- absolutePath: path2__default.default.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2515
+ absolutePath: path26__default.default.join(targetDir, "infrastructure", `Stub${pascalName}Engine.ts`),
2495
2516
  content: stubContent
2496
2517
  });
2497
2518
  }
@@ -2506,7 +2527,7 @@ export const diProvider = (c: Container): void => {
2506
2527
  export default diProvider;
2507
2528
  `;
2508
2529
  fileDefs.push({
2509
- absolutePath: path2__default.default.join(targetDir, "diProvider.ts"),
2530
+ absolutePath: path26__default.default.join(targetDir, "diProvider.ts"),
2510
2531
  content: providerContent
2511
2532
  });
2512
2533
  if (options.isRegistry) {
@@ -2523,7 +2544,7 @@ export default diProvider;
2523
2544
  files: []
2524
2545
  };
2525
2546
  fileDefs.push({
2526
- absolutePath: path2__default.default.join(targetDir, "registry.json"),
2547
+ absolutePath: path26__default.default.join(targetDir, "registry.json"),
2527
2548
  content: JSON.stringify(registryManifest, null, 2) + "\n"
2528
2549
  });
2529
2550
  }
@@ -2560,7 +2581,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2560
2581
  }
2561
2582
  const normalizedName = toKebabCase(name);
2562
2583
  const baseSharedDir = resolveSharedDir(projectRoot, flags);
2563
- const defaultDir = path2__default.default.relative(projectRoot, path2__default.default.join(baseSharedDir, normalizedName));
2584
+ const defaultDir = path26__default.default.relative(projectRoot, path26__default.default.join(baseSharedDir, normalizedName));
2564
2585
  let targetDirRel = defaultDir;
2565
2586
  if (!flags.yes && !flags.target && !flags.dest) {
2566
2587
  targetDirRel = handleCancel(
@@ -2571,7 +2592,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2571
2592
  })
2572
2593
  ).trim();
2573
2594
  }
2574
- const targetDir = flags.dest ? path2__default.default.resolve(projectRoot, flags.dest) : flags.target ? path2__default.default.resolve(projectRoot, flags.target) : path2__default.default.resolve(projectRoot, targetDirRel);
2595
+ const targetDir = flags.dest ? path26__default.default.resolve(projectRoot, flags.dest) : flags.target ? path26__default.default.resolve(projectRoot, flags.target) : path26__default.default.resolve(projectRoot, targetDirRel);
2575
2596
  let description = flags.description || "";
2576
2597
  let includeStub = true;
2577
2598
  if (!flags.yes) {
@@ -2605,7 +2626,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2605
2626
  printGeneratedFiles(files, Boolean(flags.dryRun));
2606
2627
  p19__namespace.outro(
2607
2628
  pc14__default.default.green(
2608
- `\u2713 Shared module '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2629
+ `\u2713 Shared module '${normalizedName}' initialized in ${path26__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2609
2630
  )
2610
2631
  );
2611
2632
  }
@@ -3032,7 +3053,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
3032
3053
  const infraFile = generateInfrastructure(options);
3033
3054
  files.push(infraFile);
3034
3055
  if (registerInProvider && scope === "feature" && feature && implementsInterface) {
3035
- const featureDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feature);
3056
+ const featureDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feature);
3036
3057
  const providerFile = updateOrGenerateDiProvider(
3037
3058
  featureDir,
3038
3059
  feature,
@@ -3194,7 +3215,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3194
3215
  files.push(stubFile);
3195
3216
  }
3196
3217
  if (registerInProvider && generateStub) {
3197
- const featureDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feature);
3218
+ const featureDir = path26__default.default.join(resolveFeaturesDir(projectRoot), feature);
3198
3219
  const providerFile = updateOrGenerateDiProvider(
3199
3220
  featureDir,
3200
3221
  feature,
@@ -3382,21 +3403,21 @@ function generateInjectable(options) {
3382
3403
  const className = toPascalCase(options.name);
3383
3404
  let targetDir = "";
3384
3405
  if (options.customPath) {
3385
- targetDir = path2__default.default.isAbsolute(options.customPath) ? options.customPath : path2__default.default.join(projectRoot, options.customPath);
3406
+ targetDir = path26__default.default.isAbsolute(options.customPath) ? options.customPath : path26__default.default.join(projectRoot, options.customPath);
3386
3407
  } else if (options.location === "feature-service" && options.feature) {
3387
- targetDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3408
+ targetDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services");
3388
3409
  } else if (options.location === "feature-transformer" && options.feature) {
3389
- targetDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3410
+ targetDir = path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
3390
3411
  } else if (options.location === "module") {
3391
- targetDir = path2__default.default.join(projectRoot, "modules", className);
3412
+ targetDir = path26__default.default.join(projectRoot, "modules", className);
3392
3413
  } else {
3393
- targetDir = options.feature ? path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path2__default.default.join(projectRoot, "shared", className.toLowerCase());
3414
+ targetDir = options.feature ? path26__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path26__default.default.join(projectRoot, "shared", className.toLowerCase());
3394
3415
  }
3395
- const filePath = path2__default.default.join(targetDir, `${className}.ts`);
3416
+ const filePath = path26__default.default.join(targetDir, `${className}.ts`);
3396
3417
  let ifaceName;
3397
3418
  if (options.generateInterface) {
3398
3419
  ifaceName = `I${className}`;
3399
- const ifacePath = path2__default.default.join(targetDir, `${ifaceName}.ts`);
3420
+ const ifacePath = path26__default.default.join(targetDir, `${ifaceName}.ts`);
3400
3421
  const ifaceContent = renderTemplate(injectableInterfaceTemplate, { ifaceName });
3401
3422
  files.push(
3402
3423
  writeFileSafely(ifacePath, ifaceContent, {
@@ -3525,7 +3546,7 @@ async function runEnvInit(flags = {}) {
3525
3546
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3526
3547
  const s = p19__namespace.spinner();
3527
3548
  s.start("Scanning for .example environment files...");
3528
- const files = fs4__default.default.readdirSync(projectRoot);
3549
+ const files = fs17__default.default.readdirSync(projectRoot);
3529
3550
  const exampleFiles = files.filter((file) => file.startsWith(".env") && file.endsWith(".example")).sort();
3530
3551
  if (exampleFiles.length === 0) {
3531
3552
  s.stop("No .example files found.");
@@ -3535,11 +3556,11 @@ async function runEnvInit(flags = {}) {
3535
3556
  s.message(`Found ${exampleFiles.length} template(s). Generating...`);
3536
3557
  const generatedFiles = [];
3537
3558
  for (const exampleFile of exampleFiles) {
3538
- const sourcePath = path2__default.default.join(projectRoot, exampleFile);
3559
+ const sourcePath = path26__default.default.join(projectRoot, exampleFile);
3539
3560
  const targetFile = exampleFile.replace(/\.example$/, "");
3540
- const targetPath = path2__default.default.join(projectRoot, targetFile);
3561
+ const targetPath = path26__default.default.join(projectRoot, targetFile);
3541
3562
  let overwrite = flags.overwrite;
3542
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4__default.default.existsSync(targetPath)) {
3563
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17__default.default.existsSync(targetPath)) {
3543
3564
  overwrite = await p19__namespace.confirm({
3544
3565
  message: `${targetFile} already exists. Overwrite?`,
3545
3566
  initialValue: false
@@ -3549,7 +3570,7 @@ async function runEnvInit(flags = {}) {
3549
3570
  process.exit(0);
3550
3571
  }
3551
3572
  }
3552
- const content = fs4__default.default.readFileSync(sourcePath, "utf-8");
3573
+ const content = fs17__default.default.readFileSync(sourcePath, "utf-8");
3553
3574
  const genFile = writeFileSafely(targetPath, content, {
3554
3575
  projectRoot,
3555
3576
  dryRun: Boolean(flags.dryRun),
@@ -3568,7 +3589,7 @@ var EnvEditor = class {
3568
3589
  filePath;
3569
3590
  constructor(filePath) {
3570
3591
  this.filePath = filePath;
3571
- this.lines = fs4__default.default.existsSync(filePath) ? fs4__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3592
+ this.lines = fs17__default.default.existsSync(filePath) ? fs17__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3572
3593
  }
3573
3594
  getLines() {
3574
3595
  return [...this.lines];
@@ -3632,18 +3653,18 @@ var EnvEditor = class {
3632
3653
  });
3633
3654
  }
3634
3655
  save() {
3635
- const dir = path2__default.default.dirname(this.filePath);
3636
- if (!fs4__default.default.existsSync(dir)) {
3637
- fs4__default.default.mkdirSync(dir, { recursive: true });
3656
+ const dir = path26__default.default.dirname(this.filePath);
3657
+ if (!fs17__default.default.existsSync(dir)) {
3658
+ fs17__default.default.mkdirSync(dir, { recursive: true });
3638
3659
  }
3639
- fs4__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3660
+ fs17__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3640
3661
  }
3641
3662
  };
3642
3663
  function discoverEnvironments(projectRoot) {
3643
- if (!fs4__default.default.existsSync(projectRoot)) {
3664
+ if (!fs17__default.default.existsSync(projectRoot)) {
3644
3665
  return ["local", "dev", "prod"];
3645
3666
  }
3646
- const files = fs4__default.default.readdirSync(projectRoot);
3667
+ const files = fs17__default.default.readdirSync(projectRoot);
3647
3668
  const envs = /* @__PURE__ */ new Set();
3648
3669
  for (const file of files) {
3649
3670
  if (file.startsWith(".env")) {
@@ -3668,7 +3689,7 @@ async function runEnvInitExamples(flags = {}) {
3668
3689
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3669
3690
  const s = p19__namespace.spinner();
3670
3691
  s.start("Scanning for local environment files...");
3671
- const files = fs4__default.default.readdirSync(projectRoot, { withFileTypes: true });
3692
+ const files = fs17__default.default.readdirSync(projectRoot, { withFileTypes: true });
3672
3693
  const envFiles = files.filter((dirent) => dirent.isFile() && dirent.name.startsWith(".env") && !dirent.name.endsWith(".example")).map((dirent) => dirent.name).sort();
3673
3694
  if (envFiles.length === 0) {
3674
3695
  s.stop("No local .env files found.");
@@ -3678,11 +3699,11 @@ async function runEnvInitExamples(flags = {}) {
3678
3699
  s.message(`Found ${envFiles.length} local .env file(s). Generating templates...`);
3679
3700
  const generatedFiles = [];
3680
3701
  for (const envFile of envFiles) {
3681
- const sourcePath = path2__default.default.join(projectRoot, envFile);
3702
+ const sourcePath = path26__default.default.join(projectRoot, envFile);
3682
3703
  const targetFile = `${envFile}.example`;
3683
- const targetPath = path2__default.default.join(projectRoot, targetFile);
3704
+ const targetPath = path26__default.default.join(projectRoot, targetFile);
3684
3705
  let overwrite = flags.overwrite;
3685
- if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4__default.default.existsSync(targetPath)) {
3706
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs17__default.default.existsSync(targetPath)) {
3686
3707
  overwrite = await p19__namespace.confirm({
3687
3708
  message: `${targetFile} already exists. Overwrite with redacted values?`,
3688
3709
  initialValue: true
@@ -3716,12 +3737,12 @@ function isInteractive(flags) {
3716
3737
  function getAllExistingKeys(projectRoot, envs) {
3717
3738
  const keys = /* @__PURE__ */ new Set();
3718
3739
  for (const env of envs) {
3719
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3720
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3721
- if (fs4__default.default.existsSync(localPath)) {
3740
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3741
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3742
+ if (fs17__default.default.existsSync(localPath)) {
3722
3743
  new EnvEditor(localPath).getKeys().forEach((k) => keys.add(k));
3723
3744
  }
3724
- if (fs4__default.default.existsSync(examplePath)) {
3745
+ if (fs17__default.default.existsSync(examplePath)) {
3725
3746
  new EnvEditor(examplePath).getKeys().forEach((k) => keys.add(k));
3726
3747
  }
3727
3748
  }
@@ -3793,8 +3814,8 @@ async function runEnvAdd(key, value, flags = {}) {
3793
3814
  })
3794
3815
  );
3795
3816
  }
3796
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3797
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3817
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3818
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3798
3819
  if (flags.dryRun) {
3799
3820
  p19__namespace.log.info(
3800
3821
  pc14__default.default.cyan(`[DRY RUN] Would set ${targetKey}=${envVal} in ${resolveEnvFilename(env, false)}`)
@@ -3841,8 +3862,8 @@ async function runEnvUpdate(key, value, flags = {}) {
3841
3862
  );
3842
3863
  }
3843
3864
  const envsWithKey = allEnvs.filter((env) => {
3844
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3845
- return fs4__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3865
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3866
+ return fs17__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3846
3867
  });
3847
3868
  let targetEnvs = [];
3848
3869
  if (flags.env) {
@@ -3868,7 +3889,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3868
3889
  return { key: targetKey, environments: [] };
3869
3890
  }
3870
3891
  for (const env of targetEnvs) {
3871
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3892
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3872
3893
  const localEditor = new EnvEditor(localPath);
3873
3894
  const currentVal = localEditor.getValue(targetKey);
3874
3895
  let newVal = value;
@@ -3898,7 +3919,7 @@ async function runEnvUpdate(key, value, flags = {}) {
3898
3919
  } else {
3899
3920
  localEditor.set(targetKey, newVal);
3900
3921
  localEditor.save();
3901
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3922
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3902
3923
  const exampleEditor = new EnvEditor(examplePath);
3903
3924
  if (!exampleEditor.has(targetKey)) {
3904
3925
  exampleEditor.set(targetKey, "");
@@ -3934,9 +3955,9 @@ async function runEnvDelete(key, flags = {}) {
3934
3955
  );
3935
3956
  }
3936
3957
  const envsWithKey = allEnvs.filter((env) => {
3937
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3938
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3939
- return fs4__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs4__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3958
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3959
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3960
+ return fs17__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs17__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3940
3961
  });
3941
3962
  let targetEnvs = [];
3942
3963
  if (flags.env) {
@@ -3974,19 +3995,19 @@ async function runEnvDelete(key, flags = {}) {
3974
3995
  }
3975
3996
  }
3976
3997
  for (const env of targetEnvs) {
3977
- const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3978
- const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3998
+ const localPath = path26__default.default.join(projectRoot, resolveEnvFilename(env, false));
3999
+ const examplePath = path26__default.default.join(projectRoot, resolveEnvFilename(env, true));
3979
4000
  if (flags.dryRun) {
3980
4001
  p19__namespace.log.info(
3981
4002
  pc14__default.default.cyan(`[DRY RUN] Would delete ${targetKey} from ${resolveEnvFilename(env, false)} and ${resolveEnvFilename(env, true)}`)
3982
4003
  );
3983
4004
  } else {
3984
- if (fs4__default.default.existsSync(localPath)) {
4005
+ if (fs17__default.default.existsSync(localPath)) {
3985
4006
  const localEditor = new EnvEditor(localPath);
3986
4007
  localEditor.delete(targetKey);
3987
4008
  localEditor.save();
3988
4009
  }
3989
- if (fs4__default.default.existsSync(examplePath)) {
4010
+ if (fs17__default.default.existsSync(examplePath)) {
3990
4011
  const exampleEditor = new EnvEditor(examplePath);
3991
4012
  exampleEditor.delete(targetKey);
3992
4013
  exampleEditor.save();
@@ -4011,10 +4032,10 @@ async function runEnvAudit(flags = {}) {
4011
4032
  for (const env of envs) {
4012
4033
  const localFile = resolveEnvFilename(env, false);
4013
4034
  const exampleFile = resolveEnvFilename(env, true);
4014
- const localPath = path2__default.default.join(projectRoot, localFile);
4015
- const examplePath = path2__default.default.join(projectRoot, exampleFile);
4016
- const localExists = fs4__default.default.existsSync(localPath);
4017
- const exampleExists = fs4__default.default.existsSync(examplePath);
4035
+ const localPath = path26__default.default.join(projectRoot, localFile);
4036
+ const examplePath = path26__default.default.join(projectRoot, exampleFile);
4037
+ const localExists = fs17__default.default.existsSync(localPath);
4038
+ const exampleExists = fs17__default.default.existsSync(examplePath);
4018
4039
  const localEditor = new EnvEditor(localPath);
4019
4040
  const exampleEditor = new EnvEditor(examplePath);
4020
4041
  const localKeys = localExists ? localEditor.getKeys() : [];
@@ -4353,17 +4374,17 @@ function getModuleBaseDir(projectRoot, modType) {
4353
4374
  return modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4354
4375
  }
4355
4376
  const folder = modType === "shared" ? "shared" : "features";
4356
- return path2__default.default.join(projectRoot, "src", folder);
4377
+ return path26__default.default.join(projectRoot, "src", folder);
4357
4378
  }
4358
4379
  function getExistingModuleDir(projectRoot, modType, modName) {
4359
4380
  const folder = modType === "shared" ? "shared" : "features";
4360
4381
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4361
- const inConfigured = path2__default.default.join(configuredDir, modName);
4362
- if (fs4__default.default.existsSync(inConfigured)) return inConfigured;
4363
- const inSrc = path2__default.default.join(projectRoot, "src", folder, modName);
4364
- if (fs4__default.default.existsSync(inSrc)) return inSrc;
4365
- const inRoot = path2__default.default.join(projectRoot, folder, modName);
4366
- if (fs4__default.default.existsSync(inRoot)) return inRoot;
4382
+ const inConfigured = path26__default.default.join(configuredDir, modName);
4383
+ if (fs17__default.default.existsSync(inConfigured)) return inConfigured;
4384
+ const inSrc = path26__default.default.join(projectRoot, "src", folder, modName);
4385
+ if (fs17__default.default.existsSync(inSrc)) return inSrc;
4386
+ const inRoot = path26__default.default.join(projectRoot, folder, modName);
4387
+ if (fs17__default.default.existsSync(inRoot)) return inRoot;
4367
4388
  return null;
4368
4389
  }
4369
4390
  function checkModuleExists(projectRoot, modType, modName) {
@@ -4374,14 +4395,14 @@ function getAvailableLocalModules(projectRoot, modType) {
4374
4395
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
4375
4396
  const dirs = [
4376
4397
  configuredDir,
4377
- path2__default.default.join(projectRoot, "src", folder),
4378
- path2__default.default.join(projectRoot, folder)
4398
+ path26__default.default.join(projectRoot, "src", folder),
4399
+ path26__default.default.join(projectRoot, folder)
4379
4400
  ];
4380
4401
  const set = /* @__PURE__ */ new Set();
4381
4402
  for (const dir of dirs) {
4382
- if (fs4__default.default.existsSync(dir)) {
4403
+ if (fs17__default.default.existsSync(dir)) {
4383
4404
  try {
4384
- const entries = fs4__default.default.readdirSync(dir, { withFileTypes: true });
4405
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
4385
4406
  for (const e of entries) {
4386
4407
  if (e.isDirectory() && !e.name.startsWith(".")) {
4387
4408
  set.add(e.name);
@@ -4583,7 +4604,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4583
4604
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticAlias}/`);
4584
4605
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
4585
4606
  const baseDir = getModuleBaseDir(projectRoot, modType);
4586
- const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, programmaticAlias));
4607
+ const displayDest = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, programmaticAlias));
4587
4608
  p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4588
4609
  resolutions.set(key, {
4589
4610
  type: modType,
@@ -4771,7 +4792,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4771
4792
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${newName}/`);
4772
4793
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${newName}`);
4773
4794
  const baseDir = getModuleBaseDir(projectRoot, modType);
4774
- const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, newName));
4795
+ const displayDest = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, newName));
4775
4796
  p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4776
4797
  resolutions.set(key, {
4777
4798
  type: modType,
@@ -4823,7 +4844,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4823
4844
  continue;
4824
4845
  }
4825
4846
  const folder = res.type === "shared" ? "shared" : "features";
4826
- const targetDir = path2__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4847
+ const targetDir = path26__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4827
4848
  const isOverwrite = Boolean(flags.overwrite || res.action === "overwrite");
4828
4849
  if (key !== rootKey) {
4829
4850
  p19__namespace.log.step(
@@ -4833,30 +4854,30 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4833
4854
  if (res.action === "overwrite" && !flags.dryRun) {
4834
4855
  const existingDir = getExistingModuleDir(projectRoot, res.type, res.targetName);
4835
4856
  if (existingDir && existingDir !== targetDir) {
4836
- fs4__default.default.rmSync(existingDir, { recursive: true, force: true });
4857
+ fs17__default.default.rmSync(existingDir, { recursive: true, force: true });
4837
4858
  }
4838
- if (fs4__default.default.existsSync(targetDir)) {
4839
- fs4__default.default.rmSync(targetDir, { recursive: true, force: true });
4859
+ if (fs17__default.default.existsSync(targetDir)) {
4860
+ fs17__default.default.rmSync(targetDir, { recursive: true, force: true });
4840
4861
  }
4841
4862
  }
4842
4863
  for (const file of res.manifest.files || []) {
4843
4864
  if (file === "registry.json") continue;
4844
4865
  if (!includeTests && isTestFile(file)) continue;
4845
4866
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4846
- const localFilePath = path2__default.default.join(targetDir, file);
4847
- if (fs4__default.default.existsSync(localFilePath) && !isOverwrite) {
4867
+ const localFilePath = path26__default.default.join(targetDir, file);
4868
+ if (fs17__default.default.existsSync(localFilePath) && !isOverwrite) {
4848
4869
  p19__namespace.log.warn(
4849
- ` \u21B3 Skipping existing file: ${pc14__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4870
+ ` \u21B3 Skipping existing file: ${pc14__default.default.dim(path26__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4850
4871
  );
4851
4872
  continue;
4852
4873
  }
4853
4874
  let content = await fetchRegistryFile(registryBase, remoteFilePath);
4854
4875
  content = rewriteImports(content, globalAliasMap);
4855
4876
  if (!flags.dryRun) {
4856
- fs4__default.default.mkdirSync(path2__default.default.dirname(localFilePath), { recursive: true });
4857
- fs4__default.default.writeFileSync(localFilePath, content, "utf-8");
4877
+ fs17__default.default.mkdirSync(path26__default.default.dirname(localFilePath), { recursive: true });
4878
+ fs17__default.default.writeFileSync(localFilePath, content, "utf-8");
4858
4879
  }
4859
- const displayPath = path2__default.default.relative(projectRoot, localFilePath);
4880
+ const displayPath = path26__default.default.relative(projectRoot, localFilePath);
4860
4881
  totalWrittenFiles.push(displayPath);
4861
4882
  p19__namespace.log.message(` ${pc14__default.default.green("+")} ${displayPath}`);
4862
4883
  }
@@ -4882,7 +4903,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4882
4903
  } else {
4883
4904
  const rootRes = resolutions.get(rootKey);
4884
4905
  const baseDir = getModuleBaseDir(projectRoot, type);
4885
- const displayTarget = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, rootRes.targetName));
4906
+ const displayTarget = path26__default.default.relative(projectRoot, path26__default.default.join(baseDir, rootRes.targetName));
4886
4907
  p19__namespace.log.success(
4887
4908
  pc14__default.default.green(
4888
4909
  `Successfully imported ${type} '${name}' (${totalWrittenFiles.length} file${totalWrittenFiles.length === 1 ? "" : "s"} placed in ${displayTarget})`
@@ -4901,19 +4922,19 @@ var DependencyRuleError = class extends Error {
4901
4922
  }
4902
4923
  };
4903
4924
  function isTestFile2(filePath, projectRoot) {
4904
- const norm = (projectRoot ? path2__default.default.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4905
- const base = path2__default.default.basename(norm);
4925
+ const norm = (projectRoot ? path26__default.default.relative(projectRoot, filePath) : filePath).replace(/\\/g, "/");
4926
+ const base = path26__default.default.basename(norm);
4906
4927
  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);
4907
4928
  }
4908
4929
  function scanDirFiles(dir, projectRoot) {
4909
- if (!fs4__default.default.existsSync(dir)) return [];
4910
- const entries = fs4__default.default.readdirSync(dir, { withFileTypes: true });
4930
+ if (!fs17__default.default.existsSync(dir)) return [];
4931
+ const entries = fs17__default.default.readdirSync(dir, { withFileTypes: true });
4911
4932
  const files = [];
4912
4933
  for (const entry of entries) {
4913
4934
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "__tests__" || entry.name.startsWith(".")) {
4914
4935
  continue;
4915
4936
  }
4916
- const fullPath = path2__default.default.join(dir, entry.name);
4937
+ const fullPath = path26__default.default.join(dir, entry.name);
4917
4938
  if (entry.isDirectory()) {
4918
4939
  files.push(...scanDirFiles(fullPath, projectRoot));
4919
4940
  } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !isTestFile2(fullPath, projectRoot)) {
@@ -4922,42 +4943,19 @@ function scanDirFiles(dir, projectRoot) {
4922
4943
  }
4923
4944
  return files;
4924
4945
  }
4925
- function classifyFile(fullPath, projectRoot) {
4926
- const rel = path2__default.default.relative(projectRoot, fullPath).replace(/\\/g, "/");
4927
- const featureMatch = rel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/.*)?$/);
4928
- if (featureMatch && featureMatch[1] && featureMatch[2]) {
4929
- const feature = featureMatch[1];
4930
- const subfolder = featureMatch[2];
4931
- let layer;
4932
- if (subfolder === "domain" || subfolder === "errors") {
4933
- layer = "domain";
4934
- } else if (subfolder === "useCases" || subfolder === "usecases") {
4935
- layer = "useCases";
4936
- } else if (subfolder === "services") {
4937
- layer = "services";
4938
- } else if (subfolder === "infrastructure") {
4939
- layer = "infrastructure";
4940
- } else if (subfolder === "pxExpress" || subfolder === "presentation" || subfolder === "handlers" || subfolder.startsWith("px")) {
4941
- layer = "presentation";
4942
- }
4943
- return { moduleType: "feature", moduleName: feature, feature, layer };
4944
- }
4945
- const sharedMatch = rel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
4946
- if (sharedMatch && sharedMatch[1]) {
4947
- const moduleName = sharedMatch[1];
4948
- const rest = sharedMatch[2] || "";
4949
- let layer = "root";
4950
- if (rest.startsWith("domain/") || rest === "domain" || rest.startsWith("errors/") || rest === "errors") {
4951
- layer = "domain";
4952
- } else if (rest.startsWith("ports/") || rest === "ports") {
4953
- layer = "ports";
4954
- } else if (rest.startsWith("infrastructure/") || rest === "infrastructure") {
4955
- layer = "infrastructure";
4956
- }
4957
- return { moduleType: "shared", moduleName, feature: moduleName, layer };
4958
- }
4959
- const errorMatch = rel.match(/(?:^|\/)(?:src\/)?errors(?:\/(.*))?$/);
4960
- if (errorMatch) {
4946
+ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4947
+ if (!sharedBaseAbs || !errorsBaseAbs) {
4948
+ const paths = getResolvedLintPaths(featuresBaseAbs, loadLintConfig(featuresBaseAbs));
4949
+ featuresBaseAbs = paths.featuresBase;
4950
+ sharedBaseAbs = paths.sharedBase;
4951
+ errorsBaseAbs = paths.errorsBase;
4952
+ }
4953
+ const normFullPath = path26__default.default.resolve(fullPathAbs);
4954
+ const normErrorsBase = path26__default.default.resolve(errorsBaseAbs);
4955
+ const normSharedBase = path26__default.default.resolve(sharedBaseAbs);
4956
+ const normFeaturesBase = path26__default.default.resolve(featuresBaseAbs);
4957
+ const relErrors = path26__default.default.relative(normErrorsBase, normFullPath).replace(/\\/g, "/");
4958
+ if (!relErrors.startsWith("..") && !path26__default.default.isAbsolute(relErrors)) {
4961
4959
  return {
4962
4960
  moduleType: "error",
4963
4961
  moduleName: "global-errors",
@@ -4965,46 +4963,154 @@ function classifyFile(fullPath, projectRoot) {
4965
4963
  layer: "domain"
4966
4964
  };
4967
4965
  }
4966
+ const relShared = path26__default.default.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
4967
+ if (!relShared.startsWith("..") && !path26__default.default.isAbsolute(relShared)) {
4968
+ const parts = relShared.split("/").filter(Boolean);
4969
+ if (parts.length >= 1) {
4970
+ const moduleName = parts[0];
4971
+ const rest = parts.slice(1).join("/");
4972
+ let layer = "root";
4973
+ if (rest.startsWith("domain/") || rest === "domain" || rest.startsWith("errors/") || rest === "errors") {
4974
+ layer = "domain";
4975
+ } else if (rest.startsWith("ports/") || rest === "ports") {
4976
+ layer = "ports";
4977
+ } else if (rest.startsWith("infrastructure/") || rest === "infrastructure") {
4978
+ layer = "infrastructure";
4979
+ }
4980
+ return { moduleType: "shared", moduleName, feature: moduleName, layer };
4981
+ }
4982
+ }
4983
+ const relFeatures = path26__default.default.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
4984
+ if (!relFeatures.startsWith("..") && !path26__default.default.isAbsolute(relFeatures)) {
4985
+ const parts = relFeatures.split("/").filter(Boolean);
4986
+ if (parts.length >= 2) {
4987
+ const moduleName = parts[0];
4988
+ const subfolder = parts[1];
4989
+ let layer;
4990
+ if (subfolder === "domain" || subfolder === "errors") {
4991
+ layer = "domain";
4992
+ } else if (subfolder === "useCases" || subfolder === "usecases") {
4993
+ layer = "useCases";
4994
+ } else if (subfolder === "services") {
4995
+ layer = "services";
4996
+ } else if (subfolder === "infrastructure") {
4997
+ layer = "infrastructure";
4998
+ } else if (subfolder === "pxExpress" || subfolder === "presentation" || subfolder === "handlers" || subfolder.startsWith("px")) {
4999
+ layer = "presentation";
5000
+ }
5001
+ return { moduleType: "feature", moduleName, feature: moduleName, layer };
5002
+ }
5003
+ }
4968
5004
  return {};
4969
5005
  }
4970
- function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5006
+ function classifyTarget(specifier, sourceFileAbs, projectRoot, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4971
5007
  if (specifier === "@solid-stack/di" || specifier.startsWith("@solid-stack/di/")) {
4972
5008
  return { isExternal: true, isDiFramework: true };
4973
5009
  }
4974
- if (specifier.startsWith("node:") || ["crypto", "fs", "path", "http", "https", "url", "os", "child_process", "stream", "express", "cors", "dotenv"].includes(specifier)) {
5010
+ if (specifier.startsWith("node:") || [
5011
+ "crypto",
5012
+ "fs",
5013
+ "path",
5014
+ "http",
5015
+ "https",
5016
+ "url",
5017
+ "os",
5018
+ "child_process",
5019
+ "stream",
5020
+ "express",
5021
+ "cors",
5022
+ "dotenv"
5023
+ ].includes(specifier)) {
4975
5024
  return { isExternal: true, isDiFramework: false };
4976
5025
  }
4977
- let resolvedRel = null;
5026
+ if (!featuresBaseAbs || !sharedBaseAbs || !errorsBaseAbs) {
5027
+ const paths = getResolvedLintPaths(projectRoot, loadLintConfig(projectRoot));
5028
+ featuresBaseAbs = featuresBaseAbs || paths.featuresBase;
5029
+ sharedBaseAbs = sharedBaseAbs || paths.sharedBase;
5030
+ errorsBaseAbs = errorsBaseAbs || paths.errorsBase;
5031
+ }
5032
+ const isGlobalConfig = specifier === "@configs" || specifier.startsWith("@configs/") || specifier === "@/configs" || specifier.startsWith("@/configs/") || specifier === "~/configs" || specifier.startsWith("~/configs/") || specifier === "configs" || specifier.startsWith("configs/");
5033
+ let targetAbs = null;
4978
5034
  if (specifier.startsWith(".")) {
4979
- const abs = path2__default.default.resolve(path2__default.default.dirname(sourceFileAbs), specifier);
4980
- resolvedRel = path2__default.default.relative(projectRoot, abs).replace(/\\/g, "/");
4981
- } else if (specifier.startsWith("@/features/") || specifier.startsWith("~/features/")) {
4982
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4983
- } else if (specifier.startsWith("@features/")) {
4984
- resolvedRel = "src/" + specifier.slice(1);
4985
- } else if (specifier.startsWith("@/shared/") || specifier.startsWith("~/shared/")) {
4986
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4987
- } else if (specifier.startsWith("@shared/")) {
4988
- resolvedRel = "src/" + specifier.slice(1);
4989
- } else if (specifier.startsWith("@/configs/") || specifier.startsWith("~/configs/") || specifier === "@/configs" || specifier === "~/configs") {
4990
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4991
- } else if (specifier === "@configs" || specifier.startsWith("@configs/")) {
4992
- resolvedRel = "src/" + specifier.slice(1);
4993
- } else if (specifier.startsWith("@/errors/") || specifier.startsWith("~/errors/") || specifier === "@/errors" || specifier === "~/errors") {
4994
- resolvedRel = specifier.replace(/^[@~]\//, "src/");
4995
- } else if (specifier === "@errors" || specifier.startsWith("@errors/")) {
4996
- resolvedRel = "src/" + specifier.slice(1);
4997
- } else if (specifier.startsWith("@/") || specifier.startsWith("~/")) {
4998
- resolvedRel = "src/" + specifier.slice(2);
4999
- } else if (specifier.startsWith("features/") || specifier.startsWith("shared/") || specifier.startsWith("configs/") || specifier === "configs" || specifier.startsWith("errors/") || specifier === "errors") {
5000
- resolvedRel = specifier;
5001
- }
5002
- if (!resolvedRel) {
5003
- return { isExternal: true, isDiFramework: false };
5035
+ targetAbs = path26__default.default.resolve(path26__default.default.dirname(sourceFileAbs), specifier);
5036
+ } else {
5037
+ const featRel = path26__default.default.relative(projectRoot, featuresBaseAbs).replace(/\\/g, "/");
5038
+ const sharedRel = path26__default.default.relative(projectRoot, sharedBaseAbs).replace(/\\/g, "/");
5039
+ const errorsRel = path26__default.default.relative(projectRoot, errorsBaseAbs).replace(/\\/g, "/");
5040
+ const featPrefixes = ["features"];
5041
+ if (featRel && featRel !== "." && !featRel.startsWith("..")) {
5042
+ featPrefixes.push(featRel);
5043
+ const b = path26__default.default.basename(featRel);
5044
+ if (!featPrefixes.includes(b)) featPrefixes.push(b);
5045
+ }
5046
+ const sharedPrefixes = ["shared"];
5047
+ if (sharedRel && sharedRel !== "." && !sharedRel.startsWith("..")) {
5048
+ sharedPrefixes.push(sharedRel);
5049
+ const b = path26__default.default.basename(sharedRel);
5050
+ if (!sharedPrefixes.includes(b)) sharedPrefixes.push(b);
5051
+ }
5052
+ const errorsPrefixes = ["errors"];
5053
+ if (errorsRel && errorsRel !== "." && !errorsRel.startsWith("..")) {
5054
+ errorsPrefixes.push(errorsRel);
5055
+ const b = path26__default.default.basename(errorsRel);
5056
+ if (!errorsPrefixes.includes(b)) errorsPrefixes.push(b);
5057
+ }
5058
+ for (const prefix of featPrefixes) {
5059
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5060
+ const m = specifier.match(aliasRegex);
5061
+ if (m && m[2]) {
5062
+ targetAbs = path26__default.default.resolve(featuresBaseAbs, m[2]);
5063
+ break;
5064
+ }
5065
+ }
5066
+ if (!targetAbs) {
5067
+ for (const prefix of sharedPrefixes) {
5068
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}\\/(.*)$`);
5069
+ const m = specifier.match(aliasRegex);
5070
+ if (m && m[2]) {
5071
+ targetAbs = path26__default.default.resolve(sharedBaseAbs, m[2]);
5072
+ break;
5073
+ }
5074
+ }
5075
+ }
5076
+ if (!targetAbs) {
5077
+ for (const prefix of errorsPrefixes) {
5078
+ const aliasRegex = new RegExp(`^([@~]\\/|@)?${prefix}(?:\\/(.*))?$`);
5079
+ const m = specifier.match(aliasRegex);
5080
+ if (m) {
5081
+ targetAbs = path26__default.default.resolve(errorsBaseAbs, m[2] || "");
5082
+ break;
5083
+ }
5084
+ }
5085
+ }
5086
+ if (!targetAbs && (specifier.startsWith("@/") || specifier.startsWith("~/"))) {
5087
+ const sub = specifier.slice(2);
5088
+ const srcCandidate = path26__default.default.resolve(projectRoot, "src", sub);
5089
+ const rootCandidate = path26__default.default.resolve(projectRoot, sub);
5090
+ if (fs17__default.default.existsSync(srcCandidate)) {
5091
+ targetAbs = srcCandidate;
5092
+ } else if (fs17__default.default.existsSync(rootCandidate)) {
5093
+ targetAbs = rootCandidate;
5094
+ } else {
5095
+ targetAbs = srcCandidate;
5096
+ }
5097
+ }
5098
+ if (!targetAbs) {
5099
+ const featCandidate = path26__default.default.resolve(featuresBaseAbs, specifier);
5100
+ if (fs17__default.default.existsSync(featCandidate) || fs17__default.default.existsSync(featCandidate + ".ts") || fs17__default.default.existsSync(featCandidate + ".js")) {
5101
+ targetAbs = featCandidate;
5102
+ }
5103
+ }
5104
+ }
5105
+ if (!targetAbs) {
5106
+ return { isExternal: true, isDiFramework: false, isGlobalConfig };
5004
5107
  }
5005
- const isGlobalConfig = resolvedRel.startsWith("src/configs/") || resolvedRel === "src/configs" || resolvedRel.startsWith("configs/") || resolvedRel === "configs";
5006
- const isGlobalError = resolvedRel.startsWith("src/errors/") || resolvedRel === "src/errors" || resolvedRel.startsWith("errors/") || resolvedRel === "errors";
5007
- if (isGlobalError) {
5108
+ const normTarget = path26__default.default.resolve(targetAbs);
5109
+ const srcConfig = path26__default.default.resolve(projectRoot, "src/configs");
5110
+ const rootConfig = path26__default.default.resolve(projectRoot, "configs");
5111
+ const isTargetConfig = isGlobalConfig || normTarget === srcConfig || normTarget.startsWith(srcConfig + path26__default.default.sep) || normTarget === rootConfig || normTarget.startsWith(rootConfig + path26__default.default.sep);
5112
+ const classification = classifyFile(targetAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs);
5113
+ if (classification.moduleType === "error") {
5008
5114
  return {
5009
5115
  isExternal: false,
5010
5116
  isDiFramework: false,
@@ -5012,33 +5118,19 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5012
5118
  isTargetError: true
5013
5119
  };
5014
5120
  }
5015
- const featMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?features\/([^/]+)\/([^/]+)(?:\/(.*))?$/);
5016
- if (featMatch && featMatch[1] && featMatch[2]) {
5017
- const targetFeature = featMatch[1];
5018
- const targetSubfolder = featMatch[2];
5019
- const rest = featMatch[3] || "";
5020
- let targetLayer;
5021
- if (targetSubfolder === "domain" || targetSubfolder === "errors") {
5022
- targetLayer = "domain";
5023
- } else if (targetSubfolder === "useCases" || targetSubfolder === "usecases") {
5024
- targetLayer = "useCases";
5025
- } else if (targetSubfolder === "services") {
5026
- targetLayer = "services";
5027
- } else if (targetSubfolder === "infrastructure") {
5028
- targetLayer = "infrastructure";
5029
- } else if (targetSubfolder === "pxExpress" || targetSubfolder === "presentation" || targetSubfolder === "handlers" || targetSubfolder.startsWith("px")) {
5030
- targetLayer = "presentation";
5031
- }
5032
- const basePart = rest ? path2__default.default.basename(rest) : targetSubfolder;
5033
- const targetFileName = basePart.replace(/\.(js|ts|mjs|cjs)$/, "");
5121
+ if (classification.moduleType === "feature") {
5122
+ const rel = path26__default.default.relative(featuresBaseAbs, targetAbs).replace(/\\/g, "/");
5123
+ const parts = rel.split("/").filter(Boolean);
5124
+ const targetSubfolder = parts[1];
5125
+ const targetFileName = path26__default.default.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5034
5126
  const isTargetPort = /^I[A-Z]/.test(targetFileName);
5035
5127
  const isTargetRepo = isTargetPort && targetFileName.includes("Repo");
5036
- const isTargetError = targetSubfolder === "errors" || rest.startsWith("errors/") || rest.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5128
+ const isTargetError = targetSubfolder === "errors" || rel.includes("/errors/") || targetFileName.endsWith("Error") || targetFileName.endsWith("Errors");
5037
5129
  return {
5038
5130
  isExternal: false,
5039
5131
  isDiFramework: false,
5040
- targetFeature,
5041
- targetLayer,
5132
+ targetFeature: classification.moduleName,
5133
+ targetLayer: classification.layer,
5042
5134
  targetSubfolder,
5043
5135
  targetFileName,
5044
5136
  isTargetPort,
@@ -5046,25 +5138,21 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot) {
5046
5138
  isTargetError
5047
5139
  };
5048
5140
  }
5049
- const sharedMatch = resolvedRel.match(/(?:^|\/)(?:src\/)?shared\/([^/]+)(?:\/(.*))?$/);
5050
- if (sharedMatch) {
5051
- const targetSharedModule = sharedMatch[1];
5052
- const sharedRest = sharedMatch[2] || "";
5053
- const isSharedRoot = !sharedRest.includes("/");
5054
- const isSharedPorts = sharedRest.startsWith("ports/") || sharedRest === "ports";
5055
- const isSharedInfra = sharedRest.startsWith("infrastructure/") || sharedRest === "infrastructure";
5056
- const isSharedDomain = sharedRest.startsWith("domain/") || sharedRest === "domain";
5141
+ if (classification.moduleType === "shared") {
5142
+ const targetFileName = path26__default.default.basename(targetAbs).replace(/\.(js|ts|mjs|cjs)$/, "");
5143
+ const isTargetError = classification.layer === "domain" && (targetFileName.endsWith("Error") || targetFileName.endsWith("Errors") || targetAbs.includes("/errors/"));
5057
5144
  return {
5058
5145
  isExternal: false,
5059
5146
  isDiFramework: false,
5060
- targetSharedModule,
5061
- isSharedRoot,
5062
- isSharedPorts,
5063
- isSharedInfra,
5064
- isSharedDomain
5147
+ targetSharedModule: classification.moduleName,
5148
+ isSharedRoot: classification.layer === "root",
5149
+ isSharedPorts: classification.layer === "ports",
5150
+ isSharedInfra: classification.layer === "infrastructure",
5151
+ isSharedDomain: classification.layer === "domain",
5152
+ isTargetError
5065
5153
  };
5066
5154
  }
5067
- return { isExternal: true, isDiFramework: false, isGlobalConfig };
5155
+ return { isExternal: true, isDiFramework: false, isGlobalConfig: isTargetConfig };
5068
5156
  }
5069
5157
  function extractImportStatements(content) {
5070
5158
  const statements = [];
@@ -5186,22 +5274,50 @@ var FeatureDependencyGraph = class {
5186
5274
  return dfs(start);
5187
5275
  }
5188
5276
  };
5189
- function discoverAllFeatures(projectRoot) {
5190
- const featuresBase = resolveFeaturesDir(projectRoot);
5191
- if (!fs4__default.default.existsSync(featuresBase)) return [];
5192
- const entries = fs4__default.default.readdirSync(featuresBase, { withFileTypes: true });
5193
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5277
+ function discoverAllFeatures(featuresBaseAbs, excludeDirs = []) {
5278
+ const base = featuresBaseAbs;
5279
+ if (!fs17__default.default.existsSync(base)) return [];
5280
+ const excludeSet = new Set(excludeDirs.map((d) => path26__default.default.resolve(d)));
5281
+ const entries = fs17__default.default.readdirSync(base, { withFileTypes: true });
5282
+ return entries.filter((e) => {
5283
+ if (!e.isDirectory()) return false;
5284
+ if (e.name.startsWith(".")) return false;
5285
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5286
+ return false;
5287
+ }
5288
+ const resolved = path26__default.default.resolve(base, e.name);
5289
+ for (const ex of excludeSet) {
5290
+ if (ex === resolved || ex.startsWith(resolved + path26__default.default.sep) || resolved.startsWith(ex + path26__default.default.sep)) {
5291
+ return false;
5292
+ }
5293
+ }
5294
+ return true;
5295
+ }).map((e) => ({
5194
5296
  name: e.name,
5195
- dir: path2__default.default.join(featuresBase, e.name)
5297
+ dir: path26__default.default.join(base, e.name)
5196
5298
  })).sort((a, b) => a.name.localeCompare(b.name));
5197
5299
  }
5198
- function discoverAllShared(projectRoot) {
5199
- const sharedBase = resolveSharedDir(projectRoot);
5200
- if (!fs4__default.default.existsSync(sharedBase)) return [];
5201
- const entries = fs4__default.default.readdirSync(sharedBase, { withFileTypes: true });
5202
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
5300
+ function discoverAllShared(sharedBaseAbs, excludeDirs = []) {
5301
+ const base = sharedBaseAbs;
5302
+ if (!fs17__default.default.existsSync(base)) return [];
5303
+ const excludeSet = new Set(excludeDirs.map((d) => path26__default.default.resolve(d)));
5304
+ const entries = fs17__default.default.readdirSync(base, { withFileTypes: true });
5305
+ return entries.filter((e) => {
5306
+ if (!e.isDirectory()) return false;
5307
+ if (e.name.startsWith(".")) return false;
5308
+ if (["__tests__", "tests", "node_modules", "dist", "coverage", "scratch"].includes(e.name)) {
5309
+ return false;
5310
+ }
5311
+ const resolved = path26__default.default.resolve(base, e.name);
5312
+ for (const ex of excludeSet) {
5313
+ if (ex === resolved || ex.startsWith(resolved + path26__default.default.sep) || resolved.startsWith(ex + path26__default.default.sep)) {
5314
+ return false;
5315
+ }
5316
+ }
5317
+ return true;
5318
+ }).map((e) => ({
5203
5319
  name: e.name,
5204
- dir: path2__default.default.join(sharedBase, e.name)
5320
+ dir: path26__default.default.join(base, e.name)
5205
5321
  })).sort((a, b) => a.name.localeCompare(b.name));
5206
5322
  }
5207
5323
  function extractClassMethods(content, className) {
@@ -5357,7 +5473,7 @@ function extractClassMethods(content, className) {
5357
5473
  return methods;
5358
5474
  }
5359
5475
  function checkUseCaseShape(featureName, filePath, relativePath, content, addViolation) {
5360
- const fileName = path2__default.default.basename(filePath);
5476
+ const fileName = path26__default.default.basename(filePath);
5361
5477
  const lines = content.split(/\r?\n/);
5362
5478
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5363
5479
  if (!classMatch) {
@@ -5453,7 +5569,7 @@ private ${m.name}(...) { ... }`
5453
5569
  }
5454
5570
  }
5455
5571
  function checkServiceShape(featureName, filePath, relativePath, content, addViolation) {
5456
- const fileName = path2__default.default.basename(filePath);
5572
+ const fileName = path26__default.default.basename(filePath);
5457
5573
  const lines = content.split(/\r?\n/);
5458
5574
  const classMatch = content.match(/(?:export\s+(?:default\s+)?)?class\s+([A-Za-z0-9_]+)/);
5459
5575
  if (!classMatch) {
@@ -5553,18 +5669,11 @@ function lintCodebase(options = {}) {
5553
5669
  const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
5554
5670
  const failFast = !options.complete;
5555
5671
  const lintConfig = loadLintConfig(projectRoot);
5556
- const baseErrorRelative = lintConfig.baseErrorPath || "src/errors/AppError.ts";
5557
- const baseErrorAbs = path2__default.default.resolve(projectRoot, baseErrorRelative);
5558
- const featuresBase = resolveFeaturesDir(projectRoot);
5559
- const sharedBase = resolveSharedDir(projectRoot);
5560
- let errorsBase = path2__default.default.join(projectRoot, "src/errors");
5561
- if (!fs4__default.default.existsSync(errorsBase) && fs4__default.default.existsSync(path2__default.default.join(projectRoot, "errors"))) {
5562
- errorsBase = path2__default.default.join(projectRoot, "errors");
5563
- }
5672
+ const { featuresBase, sharedBase, errorsBase } = getResolvedLintPaths(projectRoot, lintConfig);
5564
5673
  const missingFoundations = [];
5565
- if (!fs4__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5566
- if (!fs4__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5567
- if (!fs4__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5674
+ if (!fs17__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5675
+ if (!fs17__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5676
+ if (!fs17__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5568
5677
  if (missingFoundations.length > 0) {
5569
5678
  throw new DependencyRuleError(
5570
5679
  `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every project must contain 'features/', 'shared/', and 'errors/'.`,
@@ -5572,20 +5681,22 @@ function lintCodebase(options = {}) {
5572
5681
  true
5573
5682
  );
5574
5683
  }
5575
- if (!fs4__default.default.existsSync(baseErrorAbs)) {
5684
+ const baseErrorRelative = lintConfig.baseErrorPath || path26__default.default.relative(projectRoot, path26__default.default.join(errorsBase, "AppError.ts")).replace(/\\/g, "/");
5685
+ const baseErrorAbs = path26__default.default.resolve(projectRoot, baseErrorRelative);
5686
+ if (!fs17__default.default.existsSync(baseErrorAbs)) {
5576
5687
  throw new DependencyRuleError(
5577
5688
  `Project Structure Violation: Base error class not found at '${baseErrorRelative}'. Create this file or update 'baseErrorPath' in mason-lint.config.json.`,
5578
5689
  [],
5579
5690
  true
5580
5691
  );
5581
5692
  }
5582
- const baseErrorContent = fs4__default.default.readFileSync(baseErrorAbs, "utf-8");
5693
+ const baseErrorContent = fs17__default.default.readFileSync(baseErrorAbs, "utf-8");
5583
5694
  const baseClassMatch = baseErrorContent.match(
5584
5695
  /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)/
5585
5696
  );
5586
5697
  const baseErrorClassName = baseClassMatch ? baseClassMatch[1] : "AppError";
5587
- const features = discoverAllFeatures(projectRoot);
5588
- const sharedModules = discoverAllShared(projectRoot);
5698
+ const features = discoverAllFeatures(featuresBase, [sharedBase, errorsBase]);
5699
+ const sharedModules = discoverAllShared(sharedBase, [featuresBase, errorsBase]);
5589
5700
  const errorModule = { name: "global-errors", dir: errorsBase, type: "error" };
5590
5701
  const allModules = [
5591
5702
  ...features.map((f) => ({ ...f, type: "feature" })),
@@ -5628,12 +5739,12 @@ Code: ${v.code}`;
5628
5739
  const allFiles = scanDirFiles(mod.dir, projectRoot);
5629
5740
  modResult.scannedFilesCount = allFiles.length;
5630
5741
  for (const file of allFiles) {
5631
- const relPath = path2__default.default.relative(projectRoot, file).replace(/\\/g, "/");
5632
- const { moduleType, moduleName, layer } = classifyFile(file, projectRoot);
5742
+ const relPath = path26__default.default.relative(projectRoot, file).replace(/\\/g, "/");
5743
+ const { moduleType, moduleName, layer } = classifyFile(file, featuresBase, sharedBase, errorsBase);
5633
5744
  if (!layer || !moduleType || !moduleName) continue;
5634
- const content = fs4__default.default.readFileSync(file, "utf-8");
5745
+ const content = fs17__default.default.readFileSync(file, "utf-8");
5635
5746
  const statements = extractImportStatements(content);
5636
- const baseName = path2__default.default.basename(file);
5747
+ const baseName = path26__default.default.basename(file);
5637
5748
  const isBarrel = baseName === "index.ts" || baseName === "index.js";
5638
5749
  const throwErrorRegex = /\bthrow\s+(?:new\s+)?Error\s*\(/g;
5639
5750
  let throwMatch;
@@ -5660,7 +5771,7 @@ Code: ${v.code}`;
5660
5771
  });
5661
5772
  }
5662
5773
  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");
5663
- const isBaseErrorFile = path2__default.default.resolve(file) === path2__default.default.resolve(baseErrorAbs);
5774
+ const isBaseErrorFile = path26__default.default.resolve(file) === path26__default.default.resolve(baseErrorAbs);
5664
5775
  if (isErrorFile && !isBaseErrorFile) {
5665
5776
  const classRegex = /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)(?:<[^>]+>)?(?:\s+extends\s+([A-Za-z0-9_]+))?/g;
5666
5777
  let classMatch;
@@ -5710,7 +5821,7 @@ Code: ${v.code}`;
5710
5821
  }
5711
5822
  if (moduleType === "error") {
5712
5823
  for (const stmt of statements) {
5713
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5824
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5714
5825
  if (target.targetFeature) {
5715
5826
  addViolation({
5716
5827
  feature: "global-errors",
@@ -5776,7 +5887,7 @@ Code: ${v.code}`;
5776
5887
  }
5777
5888
  }
5778
5889
  for (const stmt of statements) {
5779
- const target = classifyTarget(stmt.specifier, file, projectRoot);
5890
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5780
5891
  if (target.targetFeature) {
5781
5892
  addViolation({
5782
5893
  feature: moduleName,
@@ -5906,7 +6017,7 @@ Code: ${v.code}`;
5906
6017
  }
5907
6018
  }
5908
6019
  for (const stmt of statements) {
5909
- const target = classifyTarget(stmt.specifier, file, projectRoot);
6020
+ const target = classifyTarget(stmt.specifier, file, projectRoot, featuresBase, sharedBase, errorsBase);
5910
6021
  if (target.targetFeature && target.targetFeature !== feat.name) {
5911
6022
  const evidence = {
5912
6023
  fromFeature: feat.name,
@@ -6817,6 +6928,7 @@ exports.getConfiguredSharedDir = getConfiguredSharedDir;
6817
6928
  exports.getEffectiveMode = getEffectiveMode;
6818
6929
  exports.getMissingNpmPackages = getMissingNpmPackages;
6819
6930
  exports.getRegistryBase = getRegistryBase;
6931
+ exports.getResolvedLintPaths = getResolvedLintPaths;
6820
6932
  exports.getTemplatesDir = getTemplatesDir;
6821
6933
  exports.handleCancel = handleCancel;
6822
6934
  exports.handleCreate = handleCreate;