dependency-cruiser 16.3.0 → 16.3.2
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 +12 -8
- package/src/config-utl/extract-depcruise-config/index.mjs +1 -1
- package/src/config-utl/extract-depcruise-config/read-config.mjs +5 -0
- package/src/config-utl/extract-depcruise-options.mjs +28 -0
- package/src/extract/helpers.mjs +8 -13
- package/src/extract/resolve/module-classifiers.mjs +2 -2
- package/src/extract/transpile/try-import-available.mjs +4 -5
- package/src/graph-utl/rule-set.mjs +3 -2
- package/src/main/options/assert-validity.mjs +1 -1
- package/src/main/rule-set/normalize.mjs +2 -4
- package/src/meta.cjs +1 -1
- package/src/report/anon/anonymize-path.mjs +1 -1
- package/src/report/utl/index.mjs +1 -1
- package/src/utl/get-extension.mjs +1 -1
- package/types/config-utl/extract-depcruise-config.d.mts +8 -6
- package/types/config-utl/extract-depcruise-options.d.mts +18 -0
- package/types/dependency-cruiser.d.mts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "16.3.
|
|
3
|
+
"version": "16.3.2",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -95,6 +95,10 @@
|
|
|
95
95
|
"types": "./types/config-utl/extract-depcruise-config.d.mts",
|
|
96
96
|
"import": "./src/config-utl/extract-depcruise-config/index.mjs"
|
|
97
97
|
},
|
|
98
|
+
"./config-utl/extract-depcruise-options": {
|
|
99
|
+
"types": "./types/config-utl/extract-depcruise-options.d.mts",
|
|
100
|
+
"import": "./src/config-utl/extract-depcruise-options.mjs"
|
|
101
|
+
},
|
|
98
102
|
"./config-utl/extract-ts-config": {
|
|
99
103
|
"types": "./types/config-utl/extract-ts-config.d.mts",
|
|
100
104
|
"import": "./src/config-utl/extract-ts-config.mjs"
|
|
@@ -136,10 +140,10 @@
|
|
|
136
140
|
"acorn-jsx-walk": "2.0.0",
|
|
137
141
|
"acorn-loose": "8.4.0",
|
|
138
142
|
"acorn-walk": "8.3.2",
|
|
139
|
-
"ajv": "8.
|
|
143
|
+
"ajv": "8.13.0",
|
|
140
144
|
"chalk": "5.3.0",
|
|
141
145
|
"commander": "12.0.0",
|
|
142
|
-
"enhanced-resolve": "5.16.
|
|
146
|
+
"enhanced-resolve": "5.16.1",
|
|
143
147
|
"figures": "6.1.0",
|
|
144
148
|
"ignore": "5.3.1",
|
|
145
149
|
"indent-string": "5.0.0",
|
|
@@ -152,19 +156,19 @@
|
|
|
152
156
|
"prompts": "2.4.2",
|
|
153
157
|
"rechoir": "^0.8.0",
|
|
154
158
|
"safe-regex": "2.1.1",
|
|
155
|
-
"semver": "^7.6.
|
|
156
|
-
"semver-try-require": "
|
|
159
|
+
"semver": "^7.6.1",
|
|
160
|
+
"semver-try-require": "7.0.0",
|
|
157
161
|
"teamcity-service-messages": "0.1.14",
|
|
158
162
|
"tsconfig-paths-webpack-plugin": "4.1.0",
|
|
159
|
-
"watskeburt": "4.0.
|
|
163
|
+
"watskeburt": "4.0.2",
|
|
160
164
|
"wrap-ansi": "9.0.0"
|
|
161
165
|
},
|
|
162
166
|
"overrides": {
|
|
163
|
-
"semver": "^7.6.
|
|
167
|
+
"semver": "^7.6.1",
|
|
164
168
|
"postcss": "^8.4.31"
|
|
165
169
|
},
|
|
166
170
|
"resolutions": {
|
|
167
|
-
"semver": "^7.6.
|
|
171
|
+
"semver": "^7.6.1",
|
|
168
172
|
"postcss": "^8.4.31"
|
|
169
173
|
},
|
|
170
174
|
"engines": {
|
|
@@ -47,7 +47,7 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
|
47
47
|
* @param {string} pConfigFileName
|
|
48
48
|
* @param {Set?} pAlreadyVisited
|
|
49
49
|
* @param {string?} pBaseDirectory
|
|
50
|
-
* @return {import('../../../types/
|
|
50
|
+
* @return {import('../../../types/configuration.mjs').IConfiguration} dependency-cruiser options
|
|
51
51
|
* @throws {Error} when the config is not valid (/ does not exist/ isn't readable)
|
|
52
52
|
*/
|
|
53
53
|
export default async function extractDepcruiseConfig(
|
|
@@ -2,6 +2,11 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { extname } from "node:path";
|
|
3
3
|
import json5 from "json5";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} pAbsolutePathToConfigFile
|
|
8
|
+
* @returns {Promise<import('../../../types/configuration.mjs').IConfiguration>}
|
|
9
|
+
*/
|
|
5
10
|
export default async function readConfig(pAbsolutePathToConfigFile) {
|
|
6
11
|
if (
|
|
7
12
|
[".js", ".cjs", ".mjs", ""].includes(extname(pAbsolutePathToConfigFile))
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import extractDepcruiseConfig from "./extract-depcruise-config/index.mjs";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {import('../../../types/configuration.mjs').IConfiguration}} pConfiguration
|
|
6
|
+
* @returns {import('../../../types/configuration.mjs').ICruiseOptions}
|
|
7
|
+
*/
|
|
8
|
+
function configuration2options(pConfiguration) {
|
|
9
|
+
/* c8 ignore next 1 */
|
|
10
|
+
const lConfiguration = structuredClone(pConfiguration || {});
|
|
11
|
+
const lReturnValue = structuredClone(lConfiguration?.options ?? {});
|
|
12
|
+
|
|
13
|
+
delete lConfiguration.options;
|
|
14
|
+
lReturnValue.ruleSet = structuredClone(lConfiguration);
|
|
15
|
+
lReturnValue.validate = Object.keys(lReturnValue.ruleSet).length > 0;
|
|
16
|
+
|
|
17
|
+
return lReturnValue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param {string} pConfigFileName
|
|
23
|
+
* @returns {Promise<import('../../../types/configuration.mjs').ICruiseOptions>}
|
|
24
|
+
*/
|
|
25
|
+
export default async function extractDepcruiseOptions(pConfigFileName) {
|
|
26
|
+
const lReturnValue = await extractDepcruiseConfig(pConfigFileName);
|
|
27
|
+
return configuration2options(lReturnValue);
|
|
28
|
+
}
|
package/src/extract/helpers.mjs
CHANGED
|
@@ -28,8 +28,6 @@ export function detectPreCompilationNess(pTSDependencies, pJSDependencies) {
|
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
/* eslint-disable security/detect-object-injection */
|
|
32
|
-
|
|
33
31
|
/**
|
|
34
32
|
* Given a module string returns in an object
|
|
35
33
|
* - the module name
|
|
@@ -42,25 +40,22 @@ export function detectPreCompilationNess(pTSDependencies, pJSDependencies) {
|
|
|
42
40
|
* (if there's a default node API that does this I'm all ears)
|
|
43
41
|
*
|
|
44
42
|
* @param {string} pString
|
|
45
|
-
* @returns {
|
|
43
|
+
* @returns {{module:string; protocol?:string; mimeType?:string}}
|
|
46
44
|
*/
|
|
47
45
|
export function extractModuleAttributes(pString) {
|
|
48
46
|
let lReturnValue = { module: pString };
|
|
49
47
|
const lModuleAttributes = pString.match(
|
|
50
48
|
// eslint-disable-next-line security/detect-unsafe-regex
|
|
51
|
-
/^((node:|file:|data:)(([^,]+),)?)(
|
|
49
|
+
/^(?:(?<protocol>node:|file:|data:)(?:(?<mimeType>[^,]+),)?)(?<module>.+)$/,
|
|
52
50
|
);
|
|
53
|
-
const lProtocolPosition = 2;
|
|
54
|
-
const lMimeTypePosition = 4;
|
|
55
|
-
const lModulePosition = 5;
|
|
56
51
|
|
|
57
|
-
if (lModuleAttributes) {
|
|
58
|
-
lReturnValue.module = lModuleAttributes
|
|
59
|
-
if (lModuleAttributes
|
|
60
|
-
lReturnValue.protocol = lModuleAttributes
|
|
52
|
+
if (lModuleAttributes?.groups) {
|
|
53
|
+
lReturnValue.module = lModuleAttributes?.groups.module;
|
|
54
|
+
if (lModuleAttributes?.groups?.protocol) {
|
|
55
|
+
lReturnValue.protocol = lModuleAttributes.groups.protocol;
|
|
61
56
|
}
|
|
62
|
-
if (lModuleAttributes
|
|
63
|
-
lReturnValue.mimeType = lModuleAttributes
|
|
57
|
+
if (lModuleAttributes?.groups?.mimeType) {
|
|
58
|
+
lReturnValue.mimeType = lModuleAttributes.groups.mimeType;
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
61
|
|
|
@@ -106,7 +106,7 @@ function isSubpathImport(pModuleName, pManifest) {
|
|
|
106
106
|
const lMatchREasString = pImportLHS.replace(/\*/g, ".+");
|
|
107
107
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
108
108
|
const lMatchRE = new RegExp(`^${lMatchREasString}$`);
|
|
109
|
-
return
|
|
109
|
+
return lMatchRE.test(pModuleName);
|
|
110
110
|
})
|
|
111
111
|
);
|
|
112
112
|
}
|
|
@@ -217,7 +217,7 @@ function matchesTSConfigPaths(pModuleName, pPaths) {
|
|
|
217
217
|
return Object.keys(pPaths).some((pPathLHS) => {
|
|
218
218
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
219
219
|
const lMatchRE = new RegExp(`^${pPathLHS.replace(/\*/g, ".+")}$`);
|
|
220
|
-
return
|
|
220
|
+
return lMatchRE.test(pModuleName);
|
|
221
221
|
});
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -5,7 +5,7 @@ import { coerce, satisfies } from "semver";
|
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
|
|
7
7
|
const PACKAGE_RE = "[^/]+";
|
|
8
|
-
const SCOPED_PACKAGE_RE = "@[^/]+(
|
|
8
|
+
const SCOPED_PACKAGE_RE = "@[^/]+(?:/[^/]+)";
|
|
9
9
|
const ROOT_MODULE_RE = new RegExp(`^(${SCOPED_PACKAGE_RE}|${PACKAGE_RE})`, "g");
|
|
10
10
|
|
|
11
11
|
function extractRootModuleName(pModuleName) {
|
|
@@ -17,10 +17,9 @@ function getVersion(pModuleName) {
|
|
|
17
17
|
// (yo, you're import-ing 'json'!), but that's _experimental_, printing scary
|
|
18
18
|
// messages to stderr so: ¯\_(ツ)_/¯
|
|
19
19
|
// eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require
|
|
20
|
-
const lManifest = require(
|
|
21
|
-
extractRootModuleName(pModuleName),
|
|
22
|
-
|
|
23
|
-
));
|
|
20
|
+
const lManifest = require(
|
|
21
|
+
path.join(extractRootModuleName(pModuleName), "package.json"),
|
|
22
|
+
);
|
|
24
23
|
return lManifest.version;
|
|
25
24
|
}
|
|
26
25
|
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* @return {import("../../types/rule-set").IForbiddenRuleType|undefined} - a rule (or 'undefined' if nothing found)
|
|
11
11
|
*/
|
|
12
12
|
export function findRuleByName(pRuleSet, pName) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const lNamedRules = (pRuleSet?.forbidden ?? []).concat(
|
|
14
|
+
pRuleSet?.required ?? [],
|
|
15
15
|
);
|
|
16
|
+
return lNamedRules.find((pRule) => pRule.name === pName);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
function ruleHasALicenseLikeAttribute(pRule) {
|
|
@@ -2,7 +2,7 @@ import merge from "lodash/merge.js";
|
|
|
2
2
|
import safeRegex from "safe-regex";
|
|
3
3
|
import report from "#report/index.mjs";
|
|
4
4
|
|
|
5
|
-
const MODULE_SYSTEM_LIST_RE = /^((cjs|amd|es6|tsd)(
|
|
5
|
+
const MODULE_SYSTEM_LIST_RE = /^(?:(?:cjs|amd|es6|tsd)(?:,|$)){1,4}/gi;
|
|
6
6
|
const VALID_DEPTH_RE = /^\d{1,2}$/g;
|
|
7
7
|
|
|
8
8
|
function assertModuleSystemsValid(pModuleSystems) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { normalizeREProperties, normalizeToREAsString } from "../helpers.mjs";
|
|
2
2
|
|
|
3
|
-
const VALID_SEVERITIES = /^(error|warn|info|ignore)$/;
|
|
3
|
+
const VALID_SEVERITIES = /^(?:error|warn|info|ignore)$/;
|
|
4
4
|
const DEFAULT_SEVERITY = "warn";
|
|
5
5
|
const DEFAULT_RULE = "unnamed";
|
|
6
6
|
const DEFAULT_SCOPE = "module";
|
|
@@ -8,9 +8,7 @@ const DEFAULT_SCOPE = "module";
|
|
|
8
8
|
function normalizeSeverity(pSeverity) {
|
|
9
9
|
const lSeverity = pSeverity ? pSeverity : DEFAULT_SEVERITY;
|
|
10
10
|
|
|
11
|
-
return
|
|
12
|
-
? lSeverity
|
|
13
|
-
: DEFAULT_SEVERITY;
|
|
11
|
+
return VALID_SEVERITIES.test(lSeverity) ? lSeverity : DEFAULT_SEVERITY;
|
|
14
12
|
}
|
|
15
13
|
/**
|
|
16
14
|
*
|
package/src/meta.cjs
CHANGED
|
@@ -2,7 +2,7 @@ import { anonymizePathElement } from "./anonymize-path-element.mjs";
|
|
|
2
2
|
|
|
3
3
|
export const WHITELIST_RE =
|
|
4
4
|
// eslint-disable-next-line security/detect-unsafe-regex
|
|
5
|
-
/^(
|
|
5
|
+
/^(?:|[.]+|~|bin|apps?|cli|src|libs?|configs?|components?|fixtures?|helpers?|i18n|index\.(?:jsx?|[mc]js|d\.ts|tsx?|vue|coffee|ls)|_?_?mocks?_?_?|node_modules|packages?|package\.json|scripts?|services?|sources?|specs?|_?_?tests?_?_?|types?|uti?ls?|tools)$/;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Kind of smartly anonymizes paths, by
|
package/src/report/utl/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ export function formatViolation(
|
|
|
33
33
|
* @return {string} prefix and filename concatenated
|
|
34
34
|
*/
|
|
35
35
|
function smartURIConcat(pPrefix, pSource) {
|
|
36
|
-
if (
|
|
36
|
+
if (PROTOCOL_PREFIX_RE.test(pPrefix)) {
|
|
37
37
|
return `${pPrefix}${pSource}`;
|
|
38
38
|
} else {
|
|
39
39
|
return join(pPrefix, pSource);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { extname } from "node:path";
|
|
3
3
|
|
|
4
|
-
const EXTENSION_RE = /(?<extension>((
|
|
4
|
+
const EXTENSION_RE = /(?<extension>(?:(?:\.d\.(?:c|m)?ts)|\.coffee\.md)$)/;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Returns the extension of the given file name path.
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IConfiguration } from "../configuration.mjs";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Reads the file with name `pConfigFileName` returns the parsed cruise
|
|
5
|
-
*
|
|
5
|
+
* configuration. If you're looking for the function to read a
|
|
6
|
+
* dependency-cruiser configuration file and put the result into the `cruise`
|
|
7
|
+
* function use `extractDepcruiseOptions` instead.s
|
|
6
8
|
*
|
|
7
9
|
* You can safely ignore the optional parameters. This should work (given
|
|
8
10
|
* `.dependency-cruiser.js` exists and contains a valid dependency-cruiser
|
|
9
11
|
* config)
|
|
10
12
|
*
|
|
11
13
|
* ```javascript
|
|
12
|
-
* const depcruiseConfig = extractDepcruiseConfig("./.dependency-cruiser.js")
|
|
14
|
+
* const depcruiseConfig = await extractDepcruiseConfig("./.dependency-cruiser.js")
|
|
13
15
|
* ```
|
|
14
16
|
*
|
|
15
17
|
* @param pConfigFileName
|
|
16
18
|
* @param pAlreadyVisited
|
|
17
19
|
* @param pBaseDirectory
|
|
18
|
-
* @return dependency-cruiser
|
|
20
|
+
* @return dependency-cruiser configuration
|
|
19
21
|
* @throws when the config is not valid (/ does not exist/ isn't readable)
|
|
20
22
|
*/
|
|
21
23
|
export default function extractDepcruiseConfig(
|
|
22
24
|
pConfigFileName: string,
|
|
23
25
|
pAlreadyVisited?: Set<string>,
|
|
24
|
-
pBaseDirectory?: string
|
|
25
|
-
): Promise<
|
|
26
|
+
pBaseDirectory?: string,
|
|
27
|
+
): Promise<IConfiguration>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ICruiseOptions } from "../options.mjs";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Reads the file with name `pConfigFileName` returns the parsed cruise
|
|
5
|
+
* options you can use as
|
|
6
|
+
*
|
|
7
|
+
* ```javascript
|
|
8
|
+
* const depcruiseOptions = await extractDepcruiseOptions("./.dependency-cruiser.js")
|
|
9
|
+
* const cruiseResult = await cruise(["./src"], depcruiseOptions);
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* @param pConfigFileName
|
|
13
|
+
* @return dependency-cruiser options
|
|
14
|
+
* @throws when the config is not valid (/ does not exist/ isn't readable)
|
|
15
|
+
*/
|
|
16
|
+
export default function extractDepcruiseOptions(
|
|
17
|
+
pConfigFileName: string,
|
|
18
|
+
): Promise<ICruiseOptions>;
|
|
@@ -90,7 +90,7 @@ export interface ITranspileOptions {
|
|
|
90
90
|
export function cruise(
|
|
91
91
|
pFileAndDirectoryArray: string[],
|
|
92
92
|
pCruiseOptions?: ICruiseOptions,
|
|
93
|
-
pResolveOptions?: IResolveOptions
|
|
93
|
+
pResolveOptions?: Partial<IResolveOptions>,
|
|
94
94
|
pTranspileOptions?: ITranspileOptions,
|
|
95
95
|
): Promise<IReporterOutput>;
|
|
96
96
|
|