dependency-cruiser 16.4.1 → 16.5.0
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/package.json +5 -5
- package/src/cli/format-meta-info.mjs +23 -11
- package/src/enrich/add-validations.mjs +3 -3
- package/src/enrich/derive/folders/index.mjs +2 -2
- package/src/enrich/derive/reachable.mjs +6 -3
- package/src/enrich/summarize/index.mjs +2 -2
- package/src/enrich/summarize/summarize-modules.mjs +2 -2
- package/src/extract/acorn/extract.mjs +3 -3
- package/src/extract/acorn/parse.mjs +0 -6
- package/src/extract/clear-caches.mjs +6 -6
- package/src/extract/swc/extract.mjs +3 -5
- package/src/extract/swc/parse.mjs +16 -22
- package/src/extract/transpile/babel-wrap.mjs +3 -0
- package/src/extract/transpile/coffeescript-wrap.mjs +3 -0
- package/src/extract/transpile/javascript-wrap.mjs +8 -0
- package/src/extract/transpile/livescript-wrap.mjs +2 -0
- package/src/extract/transpile/meta.mjs +45 -5
- package/src/extract/transpile/svelte-wrap.mjs +2 -1
- package/src/extract/transpile/typescript-wrap.mjs +2 -0
- package/src/extract/transpile/vue-template-wrap.cjs +4 -0
- package/src/extract/tsc/extract.mjs +4 -4
- package/src/extract/tsc/parse.mjs +14 -22
- package/src/graph-utl/compare.mjs +10 -14
- package/src/graph-utl/consolidate-module-dependencies.mjs +2 -2
- package/src/graph-utl/consolidate-modules.mjs +2 -2
- package/src/main/options/assert-validity.mjs +2 -2
- package/src/main/report-wrap.mjs +4 -4
- package/src/meta.cjs +1 -1
- package/src/report/dot/index.mjs +6 -12
- package/src/report/dot/module-utl.mjs +5 -35
- package/src/report/dot/prepare-custom-level.mjs +8 -7
- package/src/report/dot/prepare-flat-level.mjs +8 -7
- package/src/report/dot/prepare-folder-level.mjs +9 -7
- package/src/report/dot/theming.mjs +20 -6
- package/src/report/error-html/utl.mjs +2 -11
- package/src/report/index.mjs +2 -7
- package/src/report/markdown.mjs +5 -3
- package/src/utl/regex-util.mjs +2 -7
- package/src/validate/index.mjs +14 -17
- package/src/validate/match-dependency-rule.mjs +34 -25
- package/src/validate/match-folder-dependency-rule.mjs +3 -3
- package/src/validate/match-module-rule-helpers.mjs +132 -0
- package/src/validate/match-module-rule.mjs +6 -130
- package/src/validate/matchers.mjs +22 -38
- package/src/validate/rule-classifiers.mjs +0 -2
- package/src/validate/violates-required-rule.mjs +8 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.5.0",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -139,20 +139,20 @@
|
|
|
139
139
|
"README.md"
|
|
140
140
|
],
|
|
141
141
|
"dependencies": {
|
|
142
|
-
"acorn": "^8.
|
|
142
|
+
"acorn": "^8.13.0",
|
|
143
143
|
"acorn-jsx": "^5.3.2",
|
|
144
144
|
"acorn-jsx-walk": "^2.0.0",
|
|
145
145
|
"acorn-loose": "^8.4.0",
|
|
146
|
-
"acorn-walk": "^8.3.
|
|
146
|
+
"acorn-walk": "^8.3.4",
|
|
147
147
|
"ajv": "^8.17.1",
|
|
148
148
|
"commander": "^12.1.0",
|
|
149
149
|
"enhanced-resolve": "^5.17.1",
|
|
150
|
-
"ignore": "^
|
|
150
|
+
"ignore": "^6.0.2",
|
|
151
151
|
"interpret": "^3.1.1",
|
|
152
152
|
"is-installed-globally": "^1.0.0",
|
|
153
153
|
"json5": "^2.2.3",
|
|
154
154
|
"memoize": "^10.0.0",
|
|
155
|
-
"picocolors": "^1.
|
|
155
|
+
"picocolors": "^1.1.1",
|
|
156
156
|
"picomatch": "^4.0.2",
|
|
157
157
|
"prompts": "^2.4.2",
|
|
158
158
|
"rechoir": "^0.8.0",
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
+
import { release, platform, arch } from "node:os";
|
|
1
2
|
import pc from "picocolors";
|
|
2
3
|
|
|
3
4
|
import { getAvailableTranspilers, allExtensions } from "#main/index.mjs";
|
|
5
|
+
import meta from "#meta.cjs";
|
|
4
6
|
|
|
5
7
|
function bool2Symbol(pBool) {
|
|
6
8
|
return pBool ? pc.green("✔") : pc.red("x");
|
|
7
9
|
}
|
|
8
10
|
|
|
11
|
+
const MAX_VERSION_RANGE_STRING_LENGTH = 19;
|
|
12
|
+
const MAX_TRANSPILER_NAME_LENGTH = 22;
|
|
13
|
+
const MAX_VERSION_STRING_LENGTH = 24;
|
|
14
|
+
|
|
9
15
|
function formatTranspilers() {
|
|
10
|
-
|
|
11
|
-
(
|
|
12
|
-
`${pAll} ${bool2Symbol(pThis.available)} ${pThis.name} (${
|
|
13
|
-
pThis.version
|
|
14
|
-
})\n`,
|
|
15
|
-
` ${bool2Symbol(true)} javascript (>es1)\n`,
|
|
16
|
+
let lTranspilerTableHeader = pc.bold(
|
|
17
|
+
` ✔ ${"transpiler".padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${"versions supported".padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} version found`,
|
|
16
18
|
);
|
|
19
|
+
let lTranspilerTableDivider = ` - ${"-".repeat(MAX_TRANSPILER_NAME_LENGTH)} ${"-".repeat(MAX_VERSION_RANGE_STRING_LENGTH)} ${"-".repeat(MAX_VERSION_STRING_LENGTH)}`;
|
|
20
|
+
let lTranspilerTable = getAvailableTranspilers()
|
|
21
|
+
.map(
|
|
22
|
+
(pTranspiler) =>
|
|
23
|
+
` ${bool2Symbol(pTranspiler.available)} ${pTranspiler.name.padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${pTranspiler.version.padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} ${pTranspiler.currentVersion}`,
|
|
24
|
+
)
|
|
25
|
+
.join("\n");
|
|
26
|
+
return `${lTranspilerTableHeader}\n${lTranspilerTableDivider}\n${lTranspilerTable}\n`;
|
|
17
27
|
}
|
|
18
28
|
|
|
19
29
|
function formatExtensions(pExtensions) {
|
|
@@ -26,7 +36,11 @@ function formatExtensions(pExtensions) {
|
|
|
26
36
|
|
|
27
37
|
export default function formatMetaInfo() {
|
|
28
38
|
return `
|
|
29
|
-
|
|
39
|
+
${pc.bold("dependency-cruiser")}@${meta.version}
|
|
40
|
+
|
|
41
|
+
node version supported : ${meta.engines.node}
|
|
42
|
+
node version found : ${process.version}
|
|
43
|
+
os version found : ${arch()} ${platform()}@${release()}
|
|
30
44
|
|
|
31
45
|
If you need a supported, but not enabled transpiler ('${pc.red(
|
|
32
46
|
"x",
|
|
@@ -34,11 +48,9 @@ export default function formatMetaInfo() {
|
|
|
34
48
|
it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
|
|
35
49
|
will enable livescript support if it's installed in your project folder.
|
|
36
50
|
|
|
37
|
-
Transpilers:
|
|
38
|
-
|
|
39
51
|
${formatTranspilers()}
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
${pc.bold("✔ extension")}
|
|
53
|
+
- ---------
|
|
42
54
|
${formatExtensions(allExtensions)}
|
|
43
55
|
`;
|
|
44
56
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { validateDependency, validateModule } from "#validate/index.mjs";
|
|
2
2
|
|
|
3
3
|
function addDependencyViolations(pModule, pDependency, pRuleSet, pValidate) {
|
|
4
4
|
return {
|
|
5
5
|
...pDependency,
|
|
6
6
|
...(pValidate
|
|
7
|
-
?
|
|
7
|
+
? validateDependency(pRuleSet, pModule, pDependency)
|
|
8
8
|
: { valid: true }),
|
|
9
9
|
};
|
|
10
10
|
}
|
|
@@ -24,7 +24,7 @@ function addDependencyViolations(pModule, pDependency, pRuleSet, pValidate) {
|
|
|
24
24
|
export default function addValidations(pModules, pRuleSet, pValidate) {
|
|
25
25
|
return pModules.map((pModule) => ({
|
|
26
26
|
...pModule,
|
|
27
|
-
...(pValidate ?
|
|
27
|
+
...(pValidate ? validateModule(pRuleSet, pModule) : { valid: true }),
|
|
28
28
|
dependencies: pModule.dependencies.map((pDependency) =>
|
|
29
29
|
addDependencyViolations(pModule, pDependency, pRuleSet, pValidate),
|
|
30
30
|
),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import aggregateToFolders from "./aggregate-to-folders.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { validateFolder } from "#validate/index.mjs";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @param {import("../../../../types/dependency-cruiser.js").IFolder} pFolder
|
|
@@ -9,7 +9,7 @@ import validate from "#validate/index.mjs";
|
|
|
9
9
|
function validateFolderDependency(pFolder, pOptions) {
|
|
10
10
|
return (pDependency) => ({
|
|
11
11
|
...pDependency,
|
|
12
|
-
...
|
|
12
|
+
...validateFolder(pOptions.ruleSet || {}, pFolder, pDependency),
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/* eslint-disable security/detect-object-injection, no-inline-comments */
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
matchToModulePath,
|
|
4
|
+
matchToModulePathNot,
|
|
5
|
+
} from "#validate/matchers.mjs";
|
|
3
6
|
import IndexedModuleGraph from "#graph-utl/indexed-module-graph.mjs";
|
|
4
7
|
import { extractGroups } from "#utl/regex-util.mjs";
|
|
5
8
|
|
|
@@ -25,8 +28,8 @@ function isModuleInRuleTo(pRule, pModuleTo, pModuleFrom) {
|
|
|
25
28
|
: [];
|
|
26
29
|
|
|
27
30
|
return (
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
matchToModulePath(pRule, pModuleTo, lGroups) &&
|
|
32
|
+
matchToModulePathNot(pRule, pModuleTo, lGroups)
|
|
30
33
|
);
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getModulesCruised,
|
|
8
8
|
getDependenciesCruised,
|
|
9
9
|
} from "./get-stats.mjs";
|
|
10
|
-
import
|
|
10
|
+
import { compareViolations } from "#graph-utl/compare.mjs";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
*
|
|
@@ -31,7 +31,7 @@ export default function summarize(
|
|
|
31
31
|
) {
|
|
32
32
|
const lViolations = summarizeModules(pModules, pOptions.ruleSet)
|
|
33
33
|
.concat(summarizeFolders(pFolders || [], pOptions.ruleSet))
|
|
34
|
-
.sort(
|
|
34
|
+
.sort(compareViolations);
|
|
35
35
|
|
|
36
36
|
return {
|
|
37
37
|
violations: lViolations,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import isSameViolation from "./is-same-violation.mjs";
|
|
2
2
|
import { findRuleByName } from "#graph-utl/rule-set.mjs";
|
|
3
|
-
import
|
|
3
|
+
import { compareViolations } from "#graph-utl/compare.mjs";
|
|
4
4
|
import { uniqWith } from "#utl/array-util.mjs";
|
|
5
5
|
|
|
6
6
|
function cutNonTransgressions(pModule) {
|
|
@@ -135,7 +135,7 @@ export default function summarizeModules(pModules, pRuleSet) {
|
|
|
135
135
|
return uniqWith(
|
|
136
136
|
extractDependencyViolations(pModules, pRuleSet)
|
|
137
137
|
.concat(extractModuleViolations(pModules, pRuleSet))
|
|
138
|
-
.sort(
|
|
138
|
+
.sort(compareViolations),
|
|
139
139
|
isSameViolation,
|
|
140
140
|
);
|
|
141
141
|
}
|
|
@@ -2,7 +2,7 @@ import { join } from "node:path";
|
|
|
2
2
|
import extractES6Deps from "./extract-es6-deps.mjs";
|
|
3
3
|
import extractCommonJSDeps from "./extract-cjs-deps.mjs";
|
|
4
4
|
import extractAMDDeps from "./extract-amd-deps.mjs";
|
|
5
|
-
import
|
|
5
|
+
import { getASTCached } from "./parse.mjs";
|
|
6
6
|
import extractStats from "./extract-stats.mjs";
|
|
7
7
|
|
|
8
8
|
export function extract(
|
|
@@ -11,7 +11,7 @@ export function extract(
|
|
|
11
11
|
pTranspileOptions,
|
|
12
12
|
) {
|
|
13
13
|
let lDependencies = [];
|
|
14
|
-
const lAST =
|
|
14
|
+
const lAST = getASTCached(join(baseDir, pFileName), pTranspileOptions);
|
|
15
15
|
|
|
16
16
|
if (moduleSystems.includes("cjs")) {
|
|
17
17
|
extractCommonJSDeps(lAST, lDependencies, "cjs", exoticRequireStrings);
|
|
@@ -27,6 +27,6 @@ export function extract(
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function getStats({ baseDir }, pFileName, pTranspileOptions) {
|
|
30
|
-
const lAST =
|
|
30
|
+
const lAST = getASTCached(join(baseDir, pFileName), pTranspileOptions);
|
|
31
31
|
return extractStats(lAST);
|
|
32
32
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { clearCache as tscClearCache } from "./tsc/parse.mjs";
|
|
2
|
+
import { clearCache as acornClearCache } from "./acorn/parse.mjs";
|
|
3
|
+
import { clearCache as swcClearCache } from "./swc/parse.mjs";
|
|
4
4
|
import { clearCache as externalModuleHelpers_clearCache } from "./resolve/external-module-helpers.mjs";
|
|
5
5
|
import { clearCache as getManifest_clearCache } from "./resolve/get-manifest.mjs";
|
|
6
6
|
import { clearCache as resolveAMD_clearCache } from "./resolve/resolve-amd.mjs";
|
|
7
7
|
import { clearCache as resolve_clearCache } from "./resolve/resolve.mjs";
|
|
8
8
|
|
|
9
9
|
export default function clearCaches() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
tscClearCache();
|
|
11
|
+
acornClearCache();
|
|
12
|
+
swcClearCache();
|
|
13
13
|
externalModuleHelpers_clearCache();
|
|
14
14
|
getManifest_clearCache();
|
|
15
15
|
resolveAMD_clearCache();
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { join } from "node:path/posix";
|
|
2
2
|
import { isTypeScriptCompatible } from "../helpers.mjs";
|
|
3
3
|
import extractSwcDeps from "./extract-swc-deps.mjs";
|
|
4
|
-
import
|
|
4
|
+
import { getASTCached, isAvailable } from "./parse.mjs";
|
|
5
5
|
|
|
6
6
|
export function shouldUse({ parser }, pFileName) {
|
|
7
|
-
return (
|
|
8
|
-
parser === "swc" && parse.isAvailable() && isTypeScriptCompatible(pFileName)
|
|
9
|
-
);
|
|
7
|
+
return parser === "swc" && isAvailable() && isTypeScriptCompatible(pFileName);
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
export function extract(
|
|
@@ -14,7 +12,7 @@ export function extract(
|
|
|
14
12
|
pFileName,
|
|
15
13
|
) {
|
|
16
14
|
return extractSwcDeps(
|
|
17
|
-
|
|
15
|
+
getASTCached(join(baseDir, pFileName)),
|
|
18
16
|
exoticRequireStrings,
|
|
19
17
|
).filter(({ moduleSystem }) => moduleSystems.includes(moduleSystem));
|
|
20
18
|
}
|
|
@@ -26,31 +26,25 @@ function getAST(pFileName) {
|
|
|
26
26
|
return swc.parseFileSync(pFileName, SWC_PARSE_OPTIONS);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Compiles the file identified by pFileName into an (swc)
|
|
31
|
+
* AST and returns it. Subsequent calls for the same file name will
|
|
32
|
+
* return the result from a cache
|
|
33
|
+
*
|
|
34
|
+
* @param {string} pFileName - the name of the file to compile
|
|
35
|
+
* @return {import('@swc/core').ModuleItem[]} - an (swc) AST
|
|
36
|
+
*/
|
|
29
37
|
export const getASTCached = memoize(getAST);
|
|
30
38
|
|
|
31
39
|
export function clearCache() {
|
|
32
40
|
memoizeClear(getASTCached);
|
|
33
41
|
}
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
isAvailable: () => swc !== false,
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Compiles the file identified by pFileName into an (swc)
|
|
47
|
-
* AST and returns it. Subsequent calls for the same file name will
|
|
48
|
-
* return the result from a cache
|
|
49
|
-
*
|
|
50
|
-
* @param {string} pFileName - the name of the file to compile
|
|
51
|
-
* @return {import('@swc/core').ModuleItem[]} - an (swc) AST
|
|
52
|
-
*/
|
|
53
|
-
getASTCached,
|
|
54
|
-
|
|
55
|
-
clearCache,
|
|
56
|
-
};
|
|
43
|
+
/**
|
|
44
|
+
* @return {boolean} - true if the swc compiler is available,
|
|
45
|
+
* false in all other cases
|
|
46
|
+
*/
|
|
47
|
+
// @ts-expect-error dfdfd
|
|
48
|
+
export const isAvailable = () => swc !== false;
|
|
49
|
+
|
|
50
|
+
export const version = () => `@swc/core@${swc.version}`;
|
|
@@ -5,6 +5,9 @@ const babel = await tryImport("@babel/core", meta.supportedTranspilers.babel);
|
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
isAvailable: () => babel !== false,
|
|
8
|
+
|
|
9
|
+
version: () => `@babel/core@${babel.version}`,
|
|
10
|
+
|
|
8
11
|
transpile: (pSource, pFileName, pTranspileOptions = {}) =>
|
|
9
12
|
babel.transformSync(pSource, {
|
|
10
13
|
...(pTranspileOptions.babelConfig || {}),
|
|
@@ -28,6 +28,9 @@ const coffeeScript = await getCoffeeScriptModule();
|
|
|
28
28
|
export default function coffeeScriptWrap(pLiterate) {
|
|
29
29
|
return {
|
|
30
30
|
isAvailable: () => coffeeScript !== false,
|
|
31
|
+
|
|
32
|
+
version: () => `coffeescript@${coffeeScript.VERSION}`,
|
|
33
|
+
|
|
31
34
|
transpile: (pSource) => {
|
|
32
35
|
const lOptions = pLiterate ? { literate: true } : {};
|
|
33
36
|
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
isAvailable: () => true,
|
|
5
|
+
|
|
6
|
+
version: () => {
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
return `acorn@${require("acorn").version}`;
|
|
9
|
+
},
|
|
10
|
+
|
|
3
11
|
transpile: (pSource) => pSource,
|
|
4
12
|
};
|
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
/* eslint security/detect-object-injection : 0*/
|
|
2
|
+
import {
|
|
3
|
+
isAvailable as swcIsAvailable,
|
|
4
|
+
version as swcVersion,
|
|
5
|
+
} from "../swc/parse.mjs";
|
|
2
6
|
import tryAvailable from "./try-import-available.mjs";
|
|
7
|
+
import javascriptWrap from "./javascript-wrap.mjs";
|
|
8
|
+
import babelWrap from "./babel-wrap.mjs";
|
|
9
|
+
import coffeeScriptWrapFunction from "./coffeescript-wrap.mjs";
|
|
10
|
+
import livescriptWrap from "./livescript-wrap.mjs";
|
|
11
|
+
import svelteWrapFunction from "./svelte-wrap.mjs";
|
|
12
|
+
import typescriptWrapFunction from "./typescript-wrap.mjs";
|
|
13
|
+
import vueTemplateWrap from "./vue-template-wrap.cjs";
|
|
3
14
|
import meta from "#meta.cjs";
|
|
4
15
|
|
|
16
|
+
const swcWrap = {
|
|
17
|
+
isAvailable: () => swcIsAvailable(),
|
|
18
|
+
version: () => swcVersion(),
|
|
19
|
+
};
|
|
20
|
+
const coffeeScriptWrap = coffeeScriptWrapFunction(false);
|
|
21
|
+
const svelteWrap = svelteWrapFunction(javascriptWrap);
|
|
22
|
+
const typescriptWrap = typescriptWrapFunction("esm");
|
|
23
|
+
|
|
5
24
|
function gotCoffee() {
|
|
6
25
|
return (
|
|
7
26
|
tryAvailable("coffeescript", meta.supportedTranspilers.coffeescript) ||
|
|
@@ -28,6 +47,19 @@ const TRANSPILER2AVAILABLE = {
|
|
|
28
47
|
),
|
|
29
48
|
};
|
|
30
49
|
|
|
50
|
+
const TRANSPILER2WRAPPER = {
|
|
51
|
+
babel: babelWrap,
|
|
52
|
+
javascript: javascriptWrap,
|
|
53
|
+
"coffee-script": coffeeScriptWrap,
|
|
54
|
+
coffeescript: coffeeScriptWrap,
|
|
55
|
+
livescript: livescriptWrap,
|
|
56
|
+
svelte: svelteWrap,
|
|
57
|
+
swc: swcWrap,
|
|
58
|
+
typescript: typescriptWrap,
|
|
59
|
+
"vue-template-compiler": vueTemplateWrap,
|
|
60
|
+
"@vue/compiler-sfc": vueTemplateWrap,
|
|
61
|
+
};
|
|
62
|
+
|
|
31
63
|
export const EXTENSION2AVAILABLE = new Map([
|
|
32
64
|
[".js", TRANSPILER2AVAILABLE.javascript],
|
|
33
65
|
[".cjs", TRANSPILER2AVAILABLE.javascript],
|
|
@@ -81,6 +113,11 @@ export const allExtensions = Array.from(EXTENSION2AVAILABLE.keys()).map(
|
|
|
81
113
|
}),
|
|
82
114
|
);
|
|
83
115
|
|
|
116
|
+
function getCurrentVersion(pTranspiler) {
|
|
117
|
+
const lTranspiler = TRANSPILER2WRAPPER[pTranspiler];
|
|
118
|
+
return lTranspiler.isAvailable() ? lTranspiler.version() : "-";
|
|
119
|
+
}
|
|
120
|
+
|
|
84
121
|
/**
|
|
85
122
|
* an array of extensions that are 'scannable' (have a valid transpiler
|
|
86
123
|
* available for) in the current environment.
|
|
@@ -99,9 +136,12 @@ export const scannableExtensions = Array.from(
|
|
|
99
136
|
* @return {IAvailableTranspiler[]} an array of supported transpilers
|
|
100
137
|
*/
|
|
101
138
|
export function getAvailableTranspilers() {
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
139
|
+
return ["javascript"]
|
|
140
|
+
.concat(Object.keys(meta.supportedTranspilers))
|
|
141
|
+
.map((pTranspiler) => ({
|
|
142
|
+
name: pTranspiler,
|
|
143
|
+
version: meta.supportedTranspilers[pTranspiler] || "*",
|
|
144
|
+
available: TRANSPILER2AVAILABLE[pTranspiler],
|
|
145
|
+
currentVersion: getCurrentVersion(pTranspiler),
|
|
146
|
+
}));
|
|
107
147
|
}
|
|
@@ -2,7 +2,7 @@ import preProcess from "./svelte-preprocess.mjs";
|
|
|
2
2
|
import tryImport from "#utl/try-import.mjs";
|
|
3
3
|
import meta from "#meta.cjs";
|
|
4
4
|
|
|
5
|
-
const { compile } = await tryImport(
|
|
5
|
+
const { compile, VERSION } = await tryImport(
|
|
6
6
|
"svelte/compiler",
|
|
7
7
|
meta.supportedTranspilers.svelte,
|
|
8
8
|
);
|
|
@@ -21,6 +21,7 @@ function getTranspiler(pTranspilerWrapper) {
|
|
|
21
21
|
export default function svelteWrap(pTranspilerWrapper) {
|
|
22
22
|
return {
|
|
23
23
|
isAvailable: () => Boolean(compile),
|
|
24
|
+
version: () => `svelte/compiler@${VERSION}`,
|
|
24
25
|
transpile: getTranspiler(pTranspilerWrapper),
|
|
25
26
|
};
|
|
26
27
|
}
|
|
@@ -36,6 +36,8 @@ export default function typescriptWrap(pFlavor) {
|
|
|
36
36
|
return {
|
|
37
37
|
isAvailable: () => typescript !== false,
|
|
38
38
|
|
|
39
|
+
version: () => `typescript@${typescript.version}`,
|
|
40
|
+
|
|
39
41
|
transpile: (pSource, _pFileName, pTranspileOptions = {}) =>
|
|
40
42
|
typescript.transpileModule(pSource, {
|
|
41
43
|
...(pTranspileOptions.tsConfig || {}),
|
|
@@ -71,6 +71,10 @@ function vue2Transpile(pSource) {
|
|
|
71
71
|
|
|
72
72
|
module.exports = {
|
|
73
73
|
isAvailable: () => vueTemplateCompiler !== false,
|
|
74
|
+
version: () =>
|
|
75
|
+
vueTemplateCompiler.version
|
|
76
|
+
? `@vue/compiler-sfc@${vueTemplateCompiler.version}`
|
|
77
|
+
: "vue-template-compiler",
|
|
74
78
|
transpile: (pSource) =>
|
|
75
79
|
isVue3 ? vue3Transpile(pSource) : vue2Transpile(pSource),
|
|
76
80
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { isTypeScriptCompatible } from "../helpers.mjs";
|
|
3
3
|
import extractTypeScriptDeps from "./extract-typescript-deps.mjs";
|
|
4
|
-
import
|
|
4
|
+
import { getASTCached, isAvailable } from "./parse.mjs";
|
|
5
5
|
import extractStats from "./extract-stats.mjs";
|
|
6
6
|
|
|
7
7
|
export function shouldUse({ tsPreCompilationDeps, parser }, pFileName) {
|
|
8
8
|
return (
|
|
9
9
|
(tsPreCompilationDeps || parser === "tsc") &&
|
|
10
|
-
|
|
10
|
+
isAvailable() &&
|
|
11
11
|
isTypeScriptCompatible(pFileName)
|
|
12
12
|
);
|
|
13
13
|
}
|
|
@@ -18,12 +18,12 @@ export function extract(
|
|
|
18
18
|
pTranspileOptions,
|
|
19
19
|
) {
|
|
20
20
|
return extractTypeScriptDeps(
|
|
21
|
-
|
|
21
|
+
getASTCached(join(baseDir, pFileName), pTranspileOptions),
|
|
22
22
|
exoticRequireStrings,
|
|
23
23
|
).filter(({ moduleSystem }) => moduleSystems.includes(moduleSystem));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function getStats({ baseDir }, pFileName, pTranspileOptions) {
|
|
27
|
-
const lAST =
|
|
27
|
+
const lAST = getASTCached(join(baseDir, pFileName), pTranspileOptions);
|
|
28
28
|
return extractStats(lAST);
|
|
29
29
|
}
|
|
@@ -53,30 +53,22 @@ function getAST(pFileName, pTranspileOptions) {
|
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Compiles the file identified by pFileName into a (typescript)
|
|
58
|
+
* AST and returns it. Subsequent calls for the same file name will
|
|
59
|
+
* return the result from a cache
|
|
60
|
+
*
|
|
61
|
+
* @param {string} pFileName - the name of the file to compile
|
|
62
|
+
* @return {object} - a (typescript) AST
|
|
63
|
+
*/
|
|
56
64
|
export const getASTCached = memoize(getAST);
|
|
57
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @return {boolean} - true if the typescript compiler is available,
|
|
68
|
+
* false in all other cases
|
|
69
|
+
*/
|
|
70
|
+
export const isAvailable = () => typescript !== false;
|
|
71
|
+
|
|
58
72
|
export function clearCache() {
|
|
59
73
|
memoizeClear(getASTCached);
|
|
60
74
|
}
|
|
61
|
-
|
|
62
|
-
export default {
|
|
63
|
-
getASTFromSource,
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @return {boolean} - true if the typescript compiler is available,
|
|
67
|
-
* false in all other cases
|
|
68
|
-
*/
|
|
69
|
-
isAvailable: () => typescript !== false,
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Compiles the file identified by pFileName into a (typescript)
|
|
73
|
-
* AST and returns it. Subsequent calls for the same file name will
|
|
74
|
-
* return the result from a cache
|
|
75
|
-
*
|
|
76
|
-
* @param {string} pFileName - the name of the file to compile
|
|
77
|
-
* @return {object} - a (typescript) AST
|
|
78
|
-
*/
|
|
79
|
-
getASTCached,
|
|
80
|
-
|
|
81
|
-
clearCache,
|
|
82
|
-
};
|
|
@@ -10,35 +10,31 @@ function severity2number(pSeverity) {
|
|
|
10
10
|
return lSeverity2Number.get(pSeverity) || -1;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function
|
|
13
|
+
export function compareSeverities(pFirstSeverity, pSecondSeverity) {
|
|
14
14
|
return Math.sign(
|
|
15
|
-
severity2number(pFirstSeverity) - severity2number(pSecondSeverity)
|
|
15
|
+
severity2number(pFirstSeverity) - severity2number(pSecondSeverity),
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export function
|
|
19
|
+
export function compareViolations(pFirstViolation, pSecondViolation) {
|
|
20
20
|
return (
|
|
21
|
-
|
|
21
|
+
compareSeverities(
|
|
22
|
+
pFirstViolation.rule.severity,
|
|
23
|
+
pSecondViolation.rule.severity,
|
|
24
|
+
) ||
|
|
22
25
|
pFirstViolation.rule.name.localeCompare(pSecondViolation.rule.name) ||
|
|
23
26
|
pFirstViolation.from.localeCompare(pSecondViolation.from) ||
|
|
24
27
|
pFirstViolation.to.localeCompare(pSecondViolation.to)
|
|
25
28
|
);
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
export function
|
|
31
|
+
export function compareRules(pLeftRule, pRightRule) {
|
|
29
32
|
return (
|
|
30
|
-
|
|
33
|
+
compareSeverities(pLeftRule.severity, pRightRule.severity) ||
|
|
31
34
|
pLeftRule.name.localeCompare(pRightRule.name)
|
|
32
35
|
);
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
export function
|
|
38
|
+
export function compareModules(pLeftModule, pRightModule) {
|
|
36
39
|
return pLeftModule.source > pRightModule.source ? 1 : -1;
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
export default {
|
|
40
|
-
modules,
|
|
41
|
-
rules,
|
|
42
|
-
severities,
|
|
43
|
-
violations,
|
|
44
|
-
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { compareRules } from "./compare.mjs";
|
|
2
2
|
import { uniq } from "#utl/array-util.mjs";
|
|
3
3
|
|
|
4
4
|
function mergeDependency(pLeftDependency, pRightDependency) {
|
|
@@ -10,7 +10,7 @@ function mergeDependency(pLeftDependency, pRightDependency) {
|
|
|
10
10
|
),
|
|
11
11
|
rules: pLeftDependency.rules
|
|
12
12
|
.concat(pRightDependency?.rules ?? [])
|
|
13
|
-
.sort(
|
|
13
|
+
.sort(compareRules),
|
|
14
14
|
valid: pLeftDependency.valid && pRightDependency.valid,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { compareRules } from "./compare.mjs";
|
|
2
2
|
import { uniqBy } from "#utl/array-util.mjs";
|
|
3
3
|
|
|
4
4
|
function mergeModule(pLeftModule, pRightModule) {
|
|
@@ -11,7 +11,7 @@ function mergeModule(pLeftModule, pRightModule) {
|
|
|
11
11
|
),
|
|
12
12
|
rules: pLeftModule.rules
|
|
13
13
|
.concat(pRightModule?.rules ?? [])
|
|
14
|
-
.sort(
|
|
14
|
+
.sort(compareRules),
|
|
15
15
|
valid: pLeftModule.valid && pRightModule.valid,
|
|
16
16
|
consolidated:
|
|
17
17
|
Boolean(pLeftModule.consolidated) || Boolean(pRightModule.consolidated),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable security/detect-object-injection */
|
|
2
2
|
import safeRegex from "safe-regex";
|
|
3
|
-
import
|
|
3
|
+
import { getAvailableReporters } from "#report/index.mjs";
|
|
4
4
|
|
|
5
5
|
const MODULE_SYSTEM_LIST_RE = /^(?:(?:cjs|amd|es6|tsd)(?:,|$)){1,4}/gi;
|
|
6
6
|
const VALID_DEPTH_RE = /^\d{1,2}$/g;
|
|
@@ -53,7 +53,7 @@ function assertRegExpSafety(pPattern) {
|
|
|
53
53
|
function assertOutputTypeValid(pOutputType) {
|
|
54
54
|
if (
|
|
55
55
|
Boolean(pOutputType) &&
|
|
56
|
-
!
|
|
56
|
+
!getAvailableReporters().includes(pOutputType) &&
|
|
57
57
|
!pOutputType.startsWith("plugin:")
|
|
58
58
|
) {
|
|
59
59
|
throw new Error(`'${pOutputType}' is not a valid output type.\n`);
|