@solid-stack/mason 1.0.34 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +51 -61
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +51 -61
- package/dist/bin.js.map +1 -1
- package/dist/core/lintEngine.d.ts +6 -0
- package/dist/core/lintEngine.d.ts.map +1 -1
- package/dist/index.cjs +60 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -39
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lint.d.ts +6 -5
- package/dist/types/lint.d.ts.map +1 -1
- package/dist/utils/config.d.ts +9 -7
- package/dist/utils/config.d.ts.map +1 -1
- package/package.json +1 -1
- package/schema.json +7 -13
package/dist/bin.js
CHANGED
|
@@ -189,37 +189,6 @@ function getConfiguredSharedDir(projectRoot, flags) {
|
|
|
189
189
|
}
|
|
190
190
|
return path26.join(projectRoot, "shared");
|
|
191
191
|
}
|
|
192
|
-
function loadLintConfig(projectRoot) {
|
|
193
|
-
const configPath = path26.join(projectRoot, "mason-lint.config.json");
|
|
194
|
-
if (fs17.existsSync(configPath)) {
|
|
195
|
-
try {
|
|
196
|
-
return JSON.parse(fs17.readFileSync(configPath, "utf-8"));
|
|
197
|
-
} catch {
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return {};
|
|
201
|
-
}
|
|
202
|
-
function getResolvedLintPaths(projectRoot, config) {
|
|
203
|
-
const masonConfig = loadMasonConfig(projectRoot);
|
|
204
|
-
const configuredFeatures = config.paths?.features ?? masonConfig?.paths?.features;
|
|
205
|
-
const configuredShared = config.paths?.shared ?? masonConfig?.paths?.shared;
|
|
206
|
-
const configuredErrors = config.paths?.errors;
|
|
207
|
-
const resolveBase = (configuredPath, defaultSrc, defaultRoot) => {
|
|
208
|
-
if (configuredPath !== void 0) {
|
|
209
|
-
return path26.resolve(projectRoot, configuredPath);
|
|
210
|
-
}
|
|
211
|
-
const srcPath = path26.join(projectRoot, defaultSrc);
|
|
212
|
-
if (fs17.existsSync(srcPath)) return srcPath;
|
|
213
|
-
const rootPath = path26.join(projectRoot, defaultRoot);
|
|
214
|
-
if (fs17.existsSync(rootPath)) return rootPath;
|
|
215
|
-
return srcPath;
|
|
216
|
-
};
|
|
217
|
-
return {
|
|
218
|
-
featuresBase: resolveBase(configuredFeatures, "src/features", "features"),
|
|
219
|
-
sharedBase: resolveBase(configuredShared, "src/shared", "shared"),
|
|
220
|
-
errorsBase: resolveBase(configuredErrors, "src/errors", "errors")
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
192
|
|
|
224
193
|
// src/utils/project.ts
|
|
225
194
|
function findProjectRoot(startDir = process.cwd()) {
|
|
@@ -4905,19 +4874,43 @@ function scanDirFiles(dir, projectRoot) {
|
|
|
4905
4874
|
}
|
|
4906
4875
|
return files;
|
|
4907
4876
|
}
|
|
4877
|
+
function resolveLintEnvironment(projectRoot) {
|
|
4878
|
+
const config = loadMasonConfig(projectRoot);
|
|
4879
|
+
const resolveDir = (configured, defaultSrc, defaultRoot) => {
|
|
4880
|
+
if (configured !== void 0) {
|
|
4881
|
+
return path26.resolve(projectRoot, configured);
|
|
4882
|
+
}
|
|
4883
|
+
const srcPath = path26.join(projectRoot, defaultSrc);
|
|
4884
|
+
if (fs17.existsSync(srcPath)) return srcPath;
|
|
4885
|
+
const rootPath = path26.join(projectRoot, defaultRoot);
|
|
4886
|
+
if (fs17.existsSync(rootPath)) return rootPath;
|
|
4887
|
+
return srcPath;
|
|
4888
|
+
};
|
|
4889
|
+
const featuresBase = resolveDir(config?.paths?.features, "src/features", "features");
|
|
4890
|
+
const sharedBase = resolveDir(config?.paths?.shared, "src/shared", "shared");
|
|
4891
|
+
const errorsBase = resolveDir(config?.paths?.errors, "src/errors", "errors");
|
|
4892
|
+
const defaultBaseErrorRelative = config?.paths?.errors ? path26.join(config.paths.errors, "AppError.ts") : fs17.existsSync(path26.join(projectRoot, "src/errors")) ? "src/errors/AppError.ts" : fs17.existsSync(path26.join(projectRoot, "errors")) ? "errors/AppError.ts" : "src/errors/AppError.ts";
|
|
4893
|
+
const baseErrorAbs = path26.resolve(
|
|
4894
|
+
projectRoot,
|
|
4895
|
+
config?.paths?.baseError || defaultBaseErrorRelative
|
|
4896
|
+
);
|
|
4897
|
+
return { featuresBase, sharedBase, errorsBase, baseErrorAbs };
|
|
4898
|
+
}
|
|
4908
4899
|
function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
|
|
4909
4900
|
if (!sharedBaseAbs || !errorsBaseAbs) {
|
|
4910
|
-
const
|
|
4911
|
-
featuresBaseAbs =
|
|
4912
|
-
sharedBaseAbs =
|
|
4913
|
-
errorsBaseAbs =
|
|
4901
|
+
const env = resolveLintEnvironment(featuresBaseAbs);
|
|
4902
|
+
featuresBaseAbs = env.featuresBase;
|
|
4903
|
+
sharedBaseAbs = env.sharedBase;
|
|
4904
|
+
errorsBaseAbs = env.errorsBase;
|
|
4914
4905
|
}
|
|
4915
4906
|
const normFullPath = path26.resolve(fullPathAbs);
|
|
4916
4907
|
const normErrorsBase = path26.resolve(errorsBaseAbs);
|
|
4917
4908
|
const normSharedBase = path26.resolve(sharedBaseAbs);
|
|
4918
4909
|
const normFeaturesBase = path26.resolve(featuresBaseAbs);
|
|
4919
|
-
const
|
|
4920
|
-
|
|
4910
|
+
const isUnder = (base, target) => {
|
|
4911
|
+
return target === base || target.startsWith(base + path26.sep);
|
|
4912
|
+
};
|
|
4913
|
+
if (isUnder(normErrorsBase, normFullPath)) {
|
|
4921
4914
|
return {
|
|
4922
4915
|
moduleType: "error",
|
|
4923
4916
|
moduleName: "global-errors",
|
|
@@ -4925,26 +4918,26 @@ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs
|
|
|
4925
4918
|
layer: "domain"
|
|
4926
4919
|
};
|
|
4927
4920
|
}
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
const parts =
|
|
4921
|
+
if (isUnder(normSharedBase, normFullPath)) {
|
|
4922
|
+
const rel = path26.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
|
|
4923
|
+
const parts = rel.split("/").filter(Boolean);
|
|
4931
4924
|
if (parts.length >= 1) {
|
|
4932
4925
|
const moduleName = parts[0];
|
|
4933
|
-
const
|
|
4926
|
+
const subfolder = parts[1];
|
|
4934
4927
|
let layer = "root";
|
|
4935
|
-
if (
|
|
4928
|
+
if (subfolder === "domain" || subfolder === "errors") {
|
|
4936
4929
|
layer = "domain";
|
|
4937
|
-
} else if (
|
|
4930
|
+
} else if (subfolder === "ports") {
|
|
4938
4931
|
layer = "ports";
|
|
4939
|
-
} else if (
|
|
4932
|
+
} else if (subfolder === "infrastructure") {
|
|
4940
4933
|
layer = "infrastructure";
|
|
4941
4934
|
}
|
|
4942
4935
|
return { moduleType: "shared", moduleName, feature: moduleName, layer };
|
|
4943
4936
|
}
|
|
4944
4937
|
}
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
const parts =
|
|
4938
|
+
if (isUnder(normFeaturesBase, normFullPath)) {
|
|
4939
|
+
const rel = path26.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
|
|
4940
|
+
const parts = rel.split("/").filter(Boolean);
|
|
4948
4941
|
if (parts.length >= 2) {
|
|
4949
4942
|
const moduleName = parts[0];
|
|
4950
4943
|
const subfolder = parts[1];
|
|
@@ -4957,7 +4950,7 @@ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs
|
|
|
4957
4950
|
layer = "services";
|
|
4958
4951
|
} else if (subfolder === "infrastructure") {
|
|
4959
4952
|
layer = "infrastructure";
|
|
4960
|
-
} else if (subfolder
|
|
4953
|
+
} else if (subfolder.startsWith("px") || subfolder === "presentation" || subfolder === "handlers" || subfolder === "transformers") {
|
|
4961
4954
|
layer = "presentation";
|
|
4962
4955
|
}
|
|
4963
4956
|
return { moduleType: "feature", moduleName, feature: moduleName, layer };
|
|
@@ -4986,10 +4979,10 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot, featuresBaseAbs,
|
|
|
4986
4979
|
return { isExternal: true, isDiFramework: false };
|
|
4987
4980
|
}
|
|
4988
4981
|
if (!featuresBaseAbs || !sharedBaseAbs || !errorsBaseAbs) {
|
|
4989
|
-
const
|
|
4990
|
-
featuresBaseAbs = featuresBaseAbs ||
|
|
4991
|
-
sharedBaseAbs = sharedBaseAbs ||
|
|
4992
|
-
errorsBaseAbs = errorsBaseAbs ||
|
|
4982
|
+
const env = resolveLintEnvironment(projectRoot);
|
|
4983
|
+
featuresBaseAbs = featuresBaseAbs || env.featuresBase;
|
|
4984
|
+
sharedBaseAbs = sharedBaseAbs || env.sharedBase;
|
|
4985
|
+
errorsBaseAbs = errorsBaseAbs || env.errorsBase;
|
|
4993
4986
|
}
|
|
4994
4987
|
const isGlobalConfig = specifier === "@configs" || specifier.startsWith("@configs/") || specifier === "@/configs" || specifier.startsWith("@/configs/") || specifier === "~/configs" || specifier.startsWith("~/configs/") || specifier === "configs" || specifier.startsWith("configs/");
|
|
4995
4988
|
let targetAbs = null;
|
|
@@ -5630,24 +5623,21 @@ function lintCodebase(options = {}) {
|
|
|
5630
5623
|
const startTime = Date.now();
|
|
5631
5624
|
const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
|
|
5632
5625
|
const failFast = !options.complete;
|
|
5633
|
-
const
|
|
5634
|
-
const { featuresBase, sharedBase, errorsBase } = getResolvedLintPaths(projectRoot, lintConfig);
|
|
5626
|
+
const { featuresBase, sharedBase, errorsBase, baseErrorAbs } = resolveLintEnvironment(projectRoot);
|
|
5635
5627
|
const missingFoundations = [];
|
|
5636
5628
|
if (!fs17.existsSync(featuresBase)) missingFoundations.push("features/");
|
|
5637
5629
|
if (!fs17.existsSync(sharedBase)) missingFoundations.push("shared/");
|
|
5638
5630
|
if (!fs17.existsSync(errorsBase)) missingFoundations.push("errors/");
|
|
5639
5631
|
if (missingFoundations.length > 0) {
|
|
5640
5632
|
throw new DependencyRuleError(
|
|
5641
|
-
`Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every
|
|
5633
|
+
`Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
|
|
5642
5634
|
[],
|
|
5643
5635
|
true
|
|
5644
5636
|
);
|
|
5645
5637
|
}
|
|
5646
|
-
const baseErrorRelative = lintConfig.baseErrorPath || path26.relative(projectRoot, path26.join(errorsBase, "AppError.ts")).replace(/\\/g, "/");
|
|
5647
|
-
const baseErrorAbs = path26.resolve(projectRoot, baseErrorRelative);
|
|
5648
5638
|
if (!fs17.existsSync(baseErrorAbs)) {
|
|
5649
5639
|
throw new DependencyRuleError(
|
|
5650
|
-
`Project Structure Violation: Base error class not found at '${
|
|
5640
|
+
`Project Structure Violation: Base error class not found at '${path26.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
|
|
5651
5641
|
[],
|
|
5652
5642
|
true
|
|
5653
5643
|
);
|
|
@@ -5725,7 +5715,7 @@ Code: ${v.code}`;
|
|
|
5725
5715
|
code: lineCode,
|
|
5726
5716
|
ruleId: "E3_PLAIN_ERROR_THROW",
|
|
5727
5717
|
severity: "error",
|
|
5728
|
-
advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a
|
|
5718
|
+
advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a custom error class that inherits from it.`,
|
|
5729
5719
|
fixExample: {
|
|
5730
5720
|
bad: lineCode,
|
|
5731
5721
|
good: `throw new ${baseErrorClassName}("Something went wrong");`
|
|
@@ -5755,7 +5745,7 @@ Code: ${v.code}`;
|
|
|
5755
5745
|
code: lineCode,
|
|
5756
5746
|
ruleId: "E4_MISSING_INHERITANCE",
|
|
5757
5747
|
severity: "error",
|
|
5758
|
-
advice: `Error class '${className}' must extend '${baseErrorClassName}'
|
|
5748
|
+
advice: `Error class '${className}' must extend '${baseErrorClassName}'.`,
|
|
5759
5749
|
fixExample: {
|
|
5760
5750
|
bad: lineCode,
|
|
5761
5751
|
good: `export class ${className} extends ${baseErrorClassName} { ... }`
|
|
@@ -5772,7 +5762,7 @@ Code: ${v.code}`;
|
|
|
5772
5762
|
code: lineCode,
|
|
5773
5763
|
ruleId: "E5_NATIVE_ERROR_INHERITANCE",
|
|
5774
5764
|
severity: "error",
|
|
5775
|
-
advice: `Error class '${className}' extends
|
|
5765
|
+
advice: `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${baseErrorClassName}').`,
|
|
5776
5766
|
fixExample: {
|
|
5777
5767
|
bad: lineCode,
|
|
5778
5768
|
good: `export class ${className} extends ${baseErrorClassName} { ... }`
|