dependency-cruiser 17.3.2 → 17.3.3-beta-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/bin/depcruise-baseline.mjs +43 -43
- package/bin/depcruise-fmt.mjs +89 -89
- package/bin/dependency-cruise.mjs +171 -171
- package/configs/plugins/3d-reporter-plugin.mjs +36 -36
- package/configs/plugins/stats-reporter-plugin.mjs +51 -51
- package/configs/recommended-strict.cjs +5 -5
- package/configs/recommended-warn-only.cjs +5 -5
- package/configs/recommended.cjs +22 -22
- package/configs/rules/no-circular.cjs +10 -10
- package/configs/rules/no-deprecated-core.cjs +10 -10
- package/configs/rules/no-duplicate-dependency-types.cjs +17 -17
- package/configs/rules/no-non-package-json.cjs +11 -11
- package/configs/rules/no-orphans.cjs +18 -18
- package/configs/rules/not-to-deprecated.cjs +10 -10
- package/configs/rules/not-to-unresolvable.cjs +10 -10
- package/package.json +170 -170
- package/src/cache/cache.mjs +139 -139
- package/src/cache/content-strategy.mjs +88 -88
- package/src/cache/find-content-changes.mjs +58 -58
- package/src/cache/helpers.mjs +52 -52
- package/src/cache/metadata-strategy.mjs +83 -83
- package/src/cache/options-compatible.mjs +56 -109
- package/src/cli/assert-node-environment-suitable.mjs +7 -7
- package/src/cli/defaults.mjs +5 -5
- package/src/cli/format-meta-info.mjs +22 -22
- package/src/cli/format.mjs +28 -28
- package/src/cli/index.mjs +145 -145
- package/src/cli/init-config/build-config.mjs +94 -94
- package/src/cli/init-config/environment-helpers.mjs +77 -77
- package/src/cli/init-config/find-extensions.mjs +27 -27
- package/src/cli/init-config/get-user-input.mjs +151 -151
- package/src/cli/init-config/index.mjs +88 -88
- package/src/cli/init-config/normalize-init-options.mjs +47 -47
- package/src/cli/init-config/utl.mjs +4 -4
- package/src/cli/init-config/validators.mjs +10 -10
- package/src/cli/init-config/write-config.mjs +21 -21
- package/src/cli/init-config/write-run-scripts-to-manifest.mjs +103 -107
- package/src/cli/listeners/cli-feedback.mjs +49 -49
- package/src/cli/listeners/ndjson.mjs +66 -66
- package/src/cli/listeners/performance-log/format-helpers.mjs +63 -63
- package/src/cli/listeners/performance-log/handlers.mjs +56 -56
- package/src/cli/listeners/performance-log/index.mjs +37 -37
- package/src/cli/normalize-cli-options.mjs +182 -182
- package/src/cli/tools/wrap-stream-in-html.mjs +37 -37
- package/src/cli/utl/assert-file-existence.mjs +7 -7
- package/src/cli/utl/io.mjs +28 -31
- package/src/config-utl/extract-babel-config.mjs +69 -69
- package/src/config-utl/extract-depcruise-config/index.mjs +54 -54
- package/src/config-utl/extract-depcruise-config/merge-configs.mjs +63 -63
- package/src/config-utl/extract-depcruise-config/read-config.mjs +9 -9
- package/src/config-utl/extract-depcruise-options.mjs +9 -9
- package/src/config-utl/extract-known-violations.mjs +49 -49
- package/src/config-utl/extract-ts-config.mjs +46 -48
- package/src/config-utl/extract-webpack-resolve-config.mjs +88 -88
- package/src/config-utl/make-absolute.mjs +5 -5
- package/src/enrich/add-validations.mjs +13 -13
- package/src/enrich/derive/circular.mjs +49 -49
- package/src/enrich/derive/dependents.mjs +27 -27
- package/src/enrich/derive/folders/aggregate-to-folders.mjs +104 -104
- package/src/enrich/derive/folders/index.mjs +19 -19
- package/src/enrich/derive/folders/utl.mjs +18 -18
- package/src/enrich/derive/metrics/get-module-metrics.mjs +27 -27
- package/src/enrich/derive/metrics/index.mjs +8 -8
- package/src/enrich/derive/module-utl.mjs +18 -18
- package/src/enrich/derive/orphan/index.mjs +18 -18
- package/src/enrich/derive/orphan/is-orphan.mjs +9 -9
- package/src/enrich/derive/reachable.mjs +165 -168
- package/src/enrich/enrich-modules.mjs +25 -25
- package/src/enrich/index.mjs +15 -15
- package/src/enrich/soften-known-violations.mjs +90 -90
- package/src/enrich/summarize/add-rule-set-used.mjs +13 -13
- package/src/enrich/summarize/get-stats.mjs +17 -17
- package/src/enrich/summarize/index.mjs +18 -18
- package/src/enrich/summarize/is-same-violation.mjs +30 -30
- package/src/enrich/summarize/summarize-folders.mjs +35 -35
- package/src/enrich/summarize/summarize-modules.mjs +97 -97
- package/src/enrich/summarize/summarize-options.mjs +71 -71
- package/src/extract/acorn/estree-helpers.mjs +66 -66
- package/src/extract/acorn/extract-amd-deps.mjs +63 -64
- package/src/extract/acorn/extract-cjs-deps.mjs +83 -83
- package/src/extract/acorn/extract-es6-deps.mjs +54 -54
- package/src/extract/acorn/extract-stats.mjs +4 -4
- package/src/extract/acorn/extract.mjs +28 -28
- package/src/extract/acorn/parse.mjs +37 -37
- package/src/extract/clear-caches.mjs +7 -7
- package/src/extract/extract-dependencies.mjs +109 -109
- package/src/extract/extract-stats.mjs +21 -21
- package/src/extract/gather-initial-sources.mjs +64 -64
- package/src/extract/helpers.mjs +73 -71
- package/src/extract/index.mjs +120 -120
- package/src/extract/resolve/determine-dependency-types.mjs +166 -169
- package/src/extract/resolve/external-module-helpers.mjs +76 -76
- package/src/extract/resolve/get-manifest.mjs +79 -79
- package/src/extract/resolve/index.mjs +175 -164
- package/src/extract/resolve/is-built-in.mjs +22 -24
- package/src/extract/resolve/merge-manifests.mjs +43 -43
- package/src/extract/resolve/module-classifiers.mjs +229 -229
- package/src/extract/resolve/resolve-amd.mjs +44 -44
- package/src/extract/resolve/resolve-cjs.mjs +40 -40
- package/src/extract/resolve/resolve-helpers.mjs +20 -20
- package/src/extract/resolve/resolve.mjs +26 -26
- package/src/extract/swc/dependency-visitor.mjs +211 -211
- package/src/extract/swc/extract-swc-deps.mjs +4 -4
- package/src/extract/swc/extract.mjs +7 -7
- package/src/extract/swc/parse.mjs +12 -12
- package/src/extract/transpile/babel-wrap.mjs +9 -9
- package/src/extract/transpile/coffeescript-wrap.mjs +21 -21
- package/src/extract/transpile/index.mjs +47 -47
- package/src/extract/transpile/javascript-wrap.mjs +6 -6
- package/src/extract/transpile/livescript-wrap.mjs +5 -5
- package/src/extract/transpile/meta.mjs +80 -80
- package/src/extract/transpile/svelte-preprocess.mjs +73 -73
- package/src/extract/transpile/svelte-wrap.mjs +19 -19
- package/src/extract/transpile/try-import-available.mjs +26 -27
- package/src/extract/transpile/typescript-wrap.mjs +39 -39
- package/src/extract/transpile/vue-template-wrap.cjs +43 -43
- package/src/extract/tsc/extract-stats.mjs +4 -4
- package/src/extract/tsc/extract-typescript-deps.mjs +429 -398
- package/src/extract/tsc/extract.mjs +22 -22
- package/src/extract/tsc/parse.mjs +21 -21
- package/src/graph-utl/add-focus.mjs +35 -35
- package/src/graph-utl/compare.mjs +24 -24
- package/src/graph-utl/consolidate-module-dependencies.mjs +35 -35
- package/src/graph-utl/consolidate-modules.mjs +33 -33
- package/src/graph-utl/consolidate-to-folder.mjs +13 -13
- package/src/graph-utl/consolidate-to-pattern.mjs +34 -34
- package/src/graph-utl/filter-bank.mjs +74 -69
- package/src/graph-utl/indexed-module-graph.mjs +227 -225
- package/src/graph-utl/match-facade.mjs +3 -3
- package/src/graph-utl/rule-set.mjs +20 -20
- package/src/graph-utl/strip-self-transitions.mjs +6 -6
- package/src/main/cruise.mjs +81 -81
- package/src/main/files-and-dirs/normalize.mjs +7 -7
- package/src/main/format.mjs +11 -14
- package/src/main/helpers.mjs +25 -25
- package/src/main/index.mjs +8 -8
- package/src/main/options/assert-validity.mjs +100 -100
- package/src/main/options/defaults.mjs +11 -11
- package/src/main/options/normalize.mjs +158 -160
- package/src/main/report-wrap.mjs +37 -37
- package/src/main/resolve-options/normalize.mjs +127 -128
- package/src/main/rule-set/assert-validity.mjs +67 -73
- package/src/main/rule-set/normalize.mjs +81 -79
- package/src/meta.cjs +15 -16
- package/src/report/anon/anonymize-path-element.mjs +20 -34
- package/src/report/anon/anonymize-path.mjs +11 -11
- package/src/report/anon/index.mjs +119 -119
- package/src/report/anon/random-string.mjs +23 -23
- package/src/report/azure-devops.mjs +75 -99
- package/src/report/baseline.mjs +9 -9
- package/src/report/csv.mjs +13 -13
- package/src/report/d2.mjs +105 -105
- package/src/report/dot/default-theme.mjs +152 -152
- package/src/report/dot/index.mjs +146 -146
- package/src/report/dot/module-utl.mjs +72 -72
- package/src/report/dot/prepare-custom-level.mjs +20 -20
- package/src/report/dot/prepare-flat-level.mjs +11 -11
- package/src/report/dot/prepare-folder-level.mjs +12 -13
- package/src/report/dot/theming.mjs +73 -73
- package/src/report/dot-webpage/dot-module.mjs +36 -36
- package/src/report/dot-webpage/svg-in-html-snippets/script.cjs +208 -210
- package/src/report/dot-webpage/svg-in-html-snippets/style.css +51 -51
- package/src/report/dot-webpage/wrap-in-html.mjs +7 -7
- package/src/report/error-html/index.mjs +49 -49
- package/src/report/error-html/utl.mjs +99 -99
- package/src/report/error-long.mjs +1 -1
- package/src/report/error.mjs +93 -93
- package/src/report/html/index.mjs +48 -48
- package/src/report/identity.mjs +4 -4
- package/src/report/index.mjs +33 -33
- package/src/report/json.mjs +4 -4
- package/src/report/markdown.mjs +120 -120
- package/src/report/mermaid.mjs +111 -111
- package/src/report/metrics.mjs +185 -185
- package/src/report/null.mjs +4 -4
- package/src/report/plugins.mjs +41 -41
- package/src/report/teamcity.mjs +150 -150
- package/src/report/text.mjs +42 -42
- package/src/report/utl/dependency-to-incidence-transformer.mjs +32 -32
- package/src/report/utl/index.mjs +53 -53
- package/src/schema/configuration.validate.mjs +1 -0
- package/src/schema/cruise-result.validate.mjs +1 -0
- package/src/schema/utl.mjs +6 -0
- package/src/utl/array-util.mjs +25 -25
- package/src/utl/bus.mjs +12 -12
- package/src/utl/extract-root-module-name.cjs +8 -8
- package/src/utl/find-all-files.mjs +54 -54
- package/src/utl/get-extension.mjs +2 -2
- package/src/utl/object-util.mjs +21 -22
- package/src/utl/path-to-posix.mjs +5 -5
- package/src/utl/regex-util.mjs +20 -20
- package/src/utl/try-import.mjs +42 -41
- package/src/utl/try-require.cjs +23 -23
- package/src/utl/wrap-and-indent.mjs +33 -33
- package/src/validate/index.mjs +65 -65
- package/src/validate/match-dependency-rule.mjs +47 -47
- package/src/validate/match-folder-dependency-rule.mjs +27 -27
- package/src/validate/match-module-rule-helpers.mjs +76 -76
- package/src/validate/match-module-rule.mjs +12 -12
- package/src/validate/matchers.mjs +162 -162
- package/src/validate/rule-classifiers.mjs +9 -9
- package/src/validate/violates-required-rule.mjs +23 -23
- package/types/cache-options.d.mts +27 -27
- package/types/config-utl/extract-babel-config.d.mts +1 -1
- package/types/config-utl/extract-depcruise-config.d.mts +3 -3
- package/types/config-utl/extract-depcruise-options.d.mts +1 -1
- package/types/config-utl/extract-ts-config.d.mts +1 -1
- package/types/config-utl/extract-webpack-resolve-config.d.mts +3 -3
- package/types/configuration.d.mts +10 -10
- package/types/cruise-result.d.mts +414 -414
- package/types/dependency-cruiser.d.mts +52 -52
- package/types/filter-types.d.mts +45 -45
- package/types/options.d.mts +430 -430
- package/types/plugins/3d-reporter-plugin.d.mts +9 -9
- package/types/plugins/mermaid-reporter-plugin.d.mts +10 -10
- package/types/plugins/stats-reporter-plugin.d.mts +9 -9
- package/types/reporter-options.d.mts +196 -196
- package/types/resolve-options.d.mts +23 -23
- package/types/restrictions.d.mts +174 -174
- package/types/rule-set.d.mts +132 -132
- package/types/rule-summary.d.mts +14 -14
- package/types/shared-types.d.mts +89 -89
- package/types/strict-filter-types.d.mts +52 -52
- package/types/strict-options.d.mts +34 -34
- package/types/strict-restrictions.d.mts +25 -25
- package/types/strict-rule-set.d.mts +36 -36
- package/types/violations.d.mts +40 -40
- package/src/schema/README.md +0 -5
- package/src/schema/baseline-violations.schema.mjs +0 -1
- package/src/schema/configuration.schema.mjs +0 -1
- package/src/schema/cruise-result.schema.mjs +0 -1
- package/types/README.md +0 -1
package/src/main/report-wrap.mjs
CHANGED
|
@@ -17,34 +17,34 @@ import stripSelfTransitions from "#graph-utl/strip-self-transitions.mjs";
|
|
|
17
17
|
* @returns {ICruiseResult}
|
|
18
18
|
*/
|
|
19
19
|
function reSummarizeResults(pResult, pFormatOptions) {
|
|
20
|
-
|
|
20
|
+
let lModules = applyFilters(pResult.modules, pFormatOptions);
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
22
|
+
if (Object.hasOwn(pFormatOptions, "collapse")) {
|
|
23
|
+
lModules = consolidateToPattern(lModules, pFormatOptions.collapse)
|
|
24
|
+
.sort(compareModules)
|
|
25
|
+
.map(stripSelfTransitions);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...pResult,
|
|
29
|
+
summary: {
|
|
30
|
+
...pResult.summary,
|
|
31
|
+
...summarize(
|
|
32
|
+
lModules,
|
|
33
|
+
{
|
|
34
|
+
...pResult.summary.optionsUsed,
|
|
35
|
+
...pFormatOptions,
|
|
36
|
+
},
|
|
37
|
+
(pResult.summary.optionsUsed.args || "").split(" "),
|
|
38
|
+
// TODO: apply filters to the folders too
|
|
39
|
+
pResult.folders,
|
|
40
|
+
),
|
|
41
|
+
},
|
|
42
|
+
modules: lModules,
|
|
43
|
+
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function getReporterSection(pOutputType) {
|
|
47
|
-
|
|
47
|
+
return pOutputType === "x-dot-webpage" ? "dot" : pOutputType;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -54,18 +54,18 @@ function getReporterSection(pOutputType) {
|
|
|
54
54
|
* @returns {IReporterOutput}
|
|
55
55
|
*/
|
|
56
56
|
export default async function reportWrap(pResult, pFormatOptions) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
const lReportFunction = await getReporter(pFormatOptions.outputType);
|
|
58
|
+
const lReportOptions =
|
|
59
|
+
pResult.summary.optionsUsed?.reporterOptions?.[
|
|
60
|
+
getReporterSection(pFormatOptions.outputType)
|
|
61
|
+
] ?? {};
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
return lReportFunction(
|
|
64
|
+
reSummarizeResults(pResult, pFormatOptions),
|
|
65
|
+
// passing format options here so reporters that read collapse patterns
|
|
66
|
+
// from the result take the one passed in the format options instead
|
|
67
|
+
Object.hasOwn(pFormatOptions, "collapse")
|
|
68
|
+
? { ...lReportOptions, collapsePattern: pFormatOptions.collapse }
|
|
69
|
+
: lReportOptions,
|
|
70
|
+
);
|
|
71
71
|
}
|
|
@@ -2,8 +2,8 @@ import fs from "node:fs";
|
|
|
2
2
|
import enhancedResolve from "enhanced-resolve";
|
|
3
3
|
import { scannableExtensions } from "#extract/transpile/meta.mjs";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
ruleSetHasDeprecationRule,
|
|
6
|
+
ruleSetHasLicenseRule,
|
|
7
7
|
} from "#graph-utl/rule-set.mjs";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -14,33 +14,32 @@ import {
|
|
|
14
14
|
const DEFAULT_CACHE_DURATION = 4000;
|
|
15
15
|
/** @type {Partial<IResolveOptions>} */
|
|
16
16
|
const DEFAULT_RESOLVE_OPTIONS = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
exportsFields: [],
|
|
17
|
+
symlinks: true,
|
|
18
|
+
// if a webpack config overrides extensions, there's probably
|
|
19
|
+
// good cause. The scannableExtensions are an educated guess
|
|
20
|
+
// anyway.Note: if extract/transpile/index gets an unknown extension
|
|
21
|
+
// it'll fall back to the javascript parser
|
|
22
|
+
extensions: scannableExtensions,
|
|
23
|
+
// for typescript projects that import stuff that's only in
|
|
24
|
+
// node_modules/@types we need:
|
|
25
|
+
// - the inclusion of .d.ts to the extensions (see above)
|
|
26
|
+
// - an explicit inclusion of node_modules/@types to the spots
|
|
27
|
+
// to look for modules (in addition to "node_modules" which
|
|
28
|
+
// is the default for enhanced-resolve)
|
|
29
|
+
modules: ["node_modules", "node_modules/@types"],
|
|
30
|
+
// this overrides the default exports fields enhanced-resolve uses
|
|
31
|
+
// (being ["exports"]) to keep backwards compatibility between enhanced-resolve
|
|
32
|
+
// 4 and 5 (4 didn't heed them at all and the empty array has the same
|
|
33
|
+
// effect).
|
|
34
|
+
// Also see https://github.com/sverweij/dependency-cruiser/issues/338
|
|
35
|
+
exportsFields: [],
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
function omit(pObject, pProperty) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
const lObject = structuredClone(pObject);
|
|
40
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
41
|
+
delete lObject[pProperty];
|
|
42
|
+
return lObject;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
/**
|
|
@@ -49,89 +48,89 @@ function omit(pObject, pProperty) {
|
|
|
49
48
|
* @returns {Partial<IResolveOptions>}
|
|
50
49
|
*/
|
|
51
50
|
function getNonOverridableResolveOptions(pCacheDuration) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
return {
|
|
52
|
+
// This should cover most of the bases of dependency-cruiser's
|
|
53
|
+
// uses. Not overridable for now because for other
|
|
54
|
+
// file systems it's not sure we can use sync system calls
|
|
55
|
+
// Also: passing a non-cached filesystem makes performance
|
|
56
|
+
// worse.
|
|
57
|
+
fileSystem: new enhancedResolve.CachedInputFileSystem(fs, pCacheDuration),
|
|
58
|
+
// our code depends on sync behavior, so having this
|
|
59
|
+
// overridden is not an option
|
|
60
|
+
useSyncFileSystemCalls: true,
|
|
61
|
+
};
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
function pushPlugin(pPlugins, pPluginToPush) {
|
|
66
|
-
|
|
65
|
+
return (pPlugins || []).concat(pPluginToPush);
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
// eslint-disable-next-line max-lines-per-function
|
|
70
69
|
async function compileResolveOptions(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
pResolveOptions,
|
|
71
|
+
pTSConfig,
|
|
72
|
+
pResolveOptionsFromDCConfig,
|
|
74
73
|
) {
|
|
75
|
-
|
|
74
|
+
let lResolveOptions = {};
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
76
|
+
// There's a performance impact of ~1 ms per resolve even when there
|
|
77
|
+
// are 0 paths in the tsconfig, so not loading it when not necessary
|
|
78
|
+
// will be a win.
|
|
79
|
+
// Also: requiring the plugin only when it's necessary will save some
|
|
80
|
+
// startup time (especially on a cold require cache)
|
|
81
|
+
if (pResolveOptions.tsConfig) {
|
|
82
|
+
const { default: TsConfigPathsPlugin } =
|
|
83
|
+
await import("tsconfig-paths-webpack-plugin");
|
|
84
|
+
lResolveOptions.plugins = pushPlugin(
|
|
85
|
+
lResolveOptions.plugins,
|
|
86
|
+
// @ts-expect-error TS2351 "TsConfPathsPlugin is not constructable" - is unjustified
|
|
87
|
+
new TsConfigPathsPlugin({
|
|
88
|
+
configFile: pResolveOptions.tsConfig,
|
|
89
|
+
// TsConfigPathsPlugin requires a baseUrl to be present in the tsconfig,
|
|
90
|
+
// otherwise it prints scary messages that it didn't and read the tsConfig
|
|
91
|
+
// (potentially making users think it's dependency-cruiser disregarding the
|
|
92
|
+
// tsconfig). Hence up till version 13.0.4 dependency-cruiser only loaded
|
|
93
|
+
// TsConfigPathsPlugin when an options.baseUrl existed. However, this
|
|
94
|
+
// isn't necessary anymore:
|
|
95
|
+
// - [tsconfig#baseUrl documentation](https://www.typescriptlang.org/tsconfig#baseUrl)
|
|
96
|
+
// UNrecommends the use of the baseUrl for non-AMD projects
|
|
97
|
+
// - [tsconfig-paths PR #207](https://github.com/dividab/tsconfig-paths/pull/208)
|
|
98
|
+
// 'tolerates' undefined baseUrls
|
|
99
|
+
//
|
|
100
|
+
// Hence, until
|
|
101
|
+
// [tpwp issue #99](https://github.com/dividab/tsconfig-paths-webpack-plugin/issues/99)
|
|
102
|
+
// lands:
|
|
103
|
+
// - pass a default baseUrl to TsConfigPathsPlugin if the baseUrl isn't available
|
|
104
|
+
// - pass undefined in all other cases; TsConfigPathsPlugin will read
|
|
105
|
+
// it from the tsconfig.json in that case. Passing the processed baseUrl
|
|
106
|
+
// (pTSConfig?.options?.baseUrl) instead would've been more obvious, but
|
|
107
|
+
// doesn't work, as that is an absolute path and tsconfig-paths(-wpp)
|
|
108
|
+
// seems to process that again resulting in invalid paths and unresolved
|
|
109
|
+
// or erroneous dependencies
|
|
110
|
+
// eslint-disable-next-line no-undefined
|
|
111
|
+
baseUrl: pTSConfig?.options?.baseUrl ? undefined : "./",
|
|
112
|
+
// TsConfigPathsPlugin doesn't (can't) read enhanced-resolve's
|
|
113
|
+
// list of extensions, and the default it uses for extensions
|
|
114
|
+
// so we do it ourselves - either with the extensions passed
|
|
115
|
+
// or with the supported ones.
|
|
116
|
+
extensions:
|
|
117
|
+
pResolveOptionsFromDCConfig.extensions ||
|
|
118
|
+
pResolveOptions.extensions ||
|
|
119
|
+
DEFAULT_RESOLVE_OPTIONS.extensions,
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
return {
|
|
125
|
+
...DEFAULT_RESOLVE_OPTIONS,
|
|
126
|
+
...lResolveOptions,
|
|
127
|
+
...omit(pResolveOptionsFromDCConfig, "cachedInputFileSystem"),
|
|
128
|
+
...pResolveOptions,
|
|
129
|
+
...getNonOverridableResolveOptions(
|
|
130
|
+
pResolveOptionsFromDCConfig?.cachedInputFileSystem?.cacheDuration ??
|
|
131
|
+
DEFAULT_CACHE_DURATION,
|
|
132
|
+
),
|
|
133
|
+
};
|
|
135
134
|
}
|
|
136
135
|
|
|
137
136
|
/**
|
|
@@ -142,40 +141,40 @@ async function compileResolveOptions(
|
|
|
142
141
|
*/
|
|
143
142
|
// eslint-disable-next-line complexity
|
|
144
143
|
export default async function normalizeResolveOptions(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
pResolveOptions,
|
|
145
|
+
pOptions,
|
|
146
|
+
pTSConfig,
|
|
148
147
|
) {
|
|
149
|
-
|
|
148
|
+
const lRuleSet = pOptions?.ruleSet ?? {};
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
return await compileResolveOptions(
|
|
151
|
+
{
|
|
152
|
+
// EnhancedResolve's symlinks:
|
|
153
|
+
// - true => symlinks are followed (vv)
|
|
154
|
+
// node's --preserve-symlinks:
|
|
155
|
+
// - true => symlinks are NOT followed (vv)
|
|
156
|
+
// => symlinks = !preserveSymlinks
|
|
157
|
+
symlinks: !pOptions?.preserveSymlinks,
|
|
158
|
+
tsConfig:
|
|
159
|
+
pOptions?.tsConfig?.fileName ??
|
|
160
|
+
pOptions?.ruleSet?.options?.tsConfig?.fileName ??
|
|
161
|
+
null,
|
|
163
162
|
|
|
164
|
-
|
|
163
|
+
/* squirrel the externalModuleResolutionStrategy and combinedDependencies
|
|
165
164
|
thing into the resolve options
|
|
166
165
|
- they're not for enhanced resolve, but they are for what we consider
|
|
167
166
|
resolve options ...
|
|
168
167
|
*/
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
168
|
+
combinedDependencies: pOptions?.combinedDependencies ?? false,
|
|
169
|
+
/* Same for the builtInModules override/ add option ...*/
|
|
170
|
+
...(pOptions?.builtInModules?.override || pOptions?.builtInModules?.add
|
|
171
|
+
? { builtInModules: pOptions?.builtInModules }
|
|
172
|
+
: {}),
|
|
173
|
+
resolveLicenses: ruleSetHasLicenseRule(lRuleSet),
|
|
174
|
+
resolveDeprecations: ruleSetHasDeprecationRule(lRuleSet),
|
|
175
|
+
...pResolveOptions,
|
|
176
|
+
},
|
|
177
|
+
pTSConfig || {},
|
|
178
|
+
pOptions?.enhancedResolveOptions ?? {},
|
|
179
|
+
);
|
|
181
180
|
}
|
|
@@ -1,105 +1,99 @@
|
|
|
1
|
-
import Ajv from "ajv";
|
|
2
1
|
import safeRegex from "safe-regex";
|
|
3
2
|
import { assertCruiseOptionsValid } from "../options/assert-validity.mjs";
|
|
4
3
|
import { normalizeToREAsString } from "../helpers.mjs";
|
|
5
|
-
import
|
|
4
|
+
import { bus } from "#utl/bus.mjs";
|
|
6
5
|
import { has, get } from "#utl/object-util.mjs";
|
|
6
|
+
import validateConfigurationSchema from "#schema/configuration.validate.mjs";
|
|
7
|
+
import { validateErrorsToString } from "#schema/utl.mjs";
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* @import { IConfiguration } from "../../../types/configuration.mjs";
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
// the repeat limit is not the best of heuristics for indicating exponential time
|
|
14
|
-
// regular expressions - and it leads to false positives. E.g. if you use rules
|
|
15
|
-
// 'generated' from rules it could be the generated 'from' or 'to' have a list
|
|
16
|
-
// of file patterns that's easily > 25 of length. It's currently not possible
|
|
17
|
-
// to disable this check in safe-regex (e.g. by setting it to an odd value like
|
|
18
|
-
// 0 or -1, or by passing a 'switch this thing off please' option), so the only
|
|
19
|
-
// option is to increase the repeat limit to something fairly high.
|
|
20
|
-
//
|
|
21
|
-
// This does _not_ influence the star height algorithm, which is the main value
|
|
22
|
-
// of the safe-regex package.
|
|
13
|
+
// Bump safe-regex repeat limit to 10000 to avoid false positives
|
|
14
|
+
// for long pattern lists. This does not affect the star-height safety check.
|
|
23
15
|
const MAX_SAFE_REGEX_STAR_REPEAT_LIMIT = 10000;
|
|
24
16
|
|
|
25
|
-
function assertSchemaCompliance(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
function assertSchemaCompliance(pConfiguration) {
|
|
18
|
+
if (!validateConfigurationSchema(pConfiguration)) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`The supplied configuration is not valid: ${validateErrorsToString(validateConfigurationSchema.errors)}.\n`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
31
23
|
}
|
|
32
24
|
|
|
33
25
|
function hasPath(pObject, pSection, pCondition) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
// pCondition can be nested properties, so we use a bespoke
|
|
27
|
+
// 'has' function instead of simple elvis operators
|
|
28
|
+
return has(pObject, pSection) && has(pObject[pSection], pCondition);
|
|
37
29
|
}
|
|
38
30
|
|
|
39
31
|
function safeRule(pRule, pSection, pCondition) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
if (hasPath(pRule, pSection, pCondition)) {
|
|
33
|
+
return safeRegex(normalizeToREAsString(get(pRule[pSection], pCondition)), {
|
|
34
|
+
limit: MAX_SAFE_REGEX_STAR_REPEAT_LIMIT,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
46
38
|
}
|
|
47
39
|
|
|
48
40
|
function assertRuleSafety(pRule) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
const lRegexConditions = [
|
|
42
|
+
{ section: "from", condition: "path" },
|
|
43
|
+
{ section: "to", condition: "path" },
|
|
44
|
+
{ section: "from", condition: "pathNot" },
|
|
45
|
+
{ section: "to", condition: "pathNot" },
|
|
46
|
+
{ section: "to", condition: "license" },
|
|
47
|
+
{ section: "to", condition: "licenseNot" },
|
|
48
|
+
{ section: "to", condition: "via" },
|
|
49
|
+
{ section: "to", condition: "via.path" },
|
|
50
|
+
{ section: "to", condition: "viaNot" },
|
|
51
|
+
{ section: "to", condition: "viaNot.path" },
|
|
52
|
+
{ section: "to", condition: "viaOnly" },
|
|
53
|
+
{ section: "to", condition: "viaOnly.path" },
|
|
54
|
+
{ section: "to", condition: "viaSomeNot" },
|
|
55
|
+
{ section: "to", condition: "viaSomeNot.path" },
|
|
56
|
+
];
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
58
|
+
if (
|
|
59
|
+
lRegexConditions.some(
|
|
60
|
+
(pCondition) =>
|
|
61
|
+
!safeRule(pRule, pCondition.section, pCondition.condition),
|
|
62
|
+
)
|
|
63
|
+
) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`rule ${JSON.stringify(
|
|
66
|
+
pRule,
|
|
67
|
+
null,
|
|
68
|
+
"",
|
|
69
|
+
)} has an unsafe regular expression. Bailing out.\n`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
80
72
|
}
|
|
81
73
|
|
|
82
74
|
/**
|
|
83
75
|
* Returns the passed configuration pConfiguration when it is valid.
|
|
84
76
|
* Throws an Error in all other cases.
|
|
85
77
|
*
|
|
86
|
-
* Validations:
|
|
87
|
-
* - the rule set adheres to the [config json schema](../../schema/configuration.schema.json)
|
|
88
|
-
* - any regular expression in the rule set is 'safe' (~= won't be too slow)
|
|
89
|
-
*
|
|
90
78
|
* @param {IConfiguration} pConfiguration The configuration to validate
|
|
91
|
-
* @return {IConfiguration}
|
|
92
|
-
* @throws {Error}
|
|
93
|
-
* a message
|
|
79
|
+
* @return {IConfiguration} The configuration as passed
|
|
80
|
+
* @throws {Error} An error with the reason for the error as a message
|
|
94
81
|
*/
|
|
95
82
|
export default function assertRuleSetValid(pConfiguration) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
bus.info("parse rule set: validate");
|
|
84
|
+
|
|
85
|
+
bus.debug("parse rule set: validate: schema compliance");
|
|
86
|
+
assertSchemaCompliance(pConfiguration);
|
|
87
|
+
|
|
88
|
+
bus.debug("parse rule set: validate: rule safety");
|
|
89
|
+
(pConfiguration.allowed || []).forEach(assertRuleSafety);
|
|
90
|
+
(pConfiguration.forbidden || []).forEach(assertRuleSafety);
|
|
91
|
+
|
|
92
|
+
bus.debug("parse rule set: validate: cruise options validity");
|
|
93
|
+
if (pConfiguration?.options) {
|
|
94
|
+
assertCruiseOptionsValid(pConfiguration.options);
|
|
95
|
+
}
|
|
96
|
+
return pConfiguration;
|
|
103
97
|
}
|
|
104
98
|
|
|
105
99
|
/* think we can ignore object injection here because it's not a public function */
|