knip 6.23.0 → 6.25.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/LICENSE +1 -1
- package/dist/ConfigurationChief.d.ts +13 -1
- package/dist/ConfigurationChief.js +3 -0
- package/dist/ProjectPrincipal.d.ts +2 -0
- package/dist/ProjectPrincipal.js +7 -6
- package/dist/WorkspaceWorker.d.ts +3 -1
- package/dist/WorkspaceWorker.js +5 -2
- package/dist/binaries/bash-parser.js +55 -83
- package/dist/binaries/index.js +3 -0
- package/dist/binaries/resolvers/yarn.js +4 -3
- package/dist/compilers/compilers.d.ts +2 -0
- package/dist/compilers/compilers.js +15 -4
- package/dist/compilers/index.d.ts +30 -6
- package/dist/compilers/index.js +25 -10
- package/dist/compilers/less.d.ts +7 -0
- package/dist/compilers/less.js +37 -0
- package/dist/compilers/mdx.d.ts +1 -2
- package/dist/compilers/mdx.js +14 -8
- package/dist/compilers/scss.d.ts +3 -2
- package/dist/compilers/scss.js +17 -14
- package/dist/compilers/shared.d.ts +6 -0
- package/dist/compilers/shared.js +9 -0
- package/dist/compilers/style-preprocessors.d.ts +2 -0
- package/dist/compilers/style-preprocessors.js +41 -0
- package/dist/compilers/stylus.d.ts +7 -0
- package/dist/compilers/stylus.js +36 -0
- package/dist/constants.d.ts +5 -1
- package/dist/constants.js +7 -0
- package/dist/graph/analyze.js +37 -2
- package/dist/graph/build.js +23 -1
- package/dist/graph-explorer/explorer.d.ts +1 -0
- package/dist/graph-explorer/explorer.js +2 -0
- package/dist/graph-explorer/operations/find-all-cycles.d.ts +3 -0
- package/dist/graph-explorer/operations/find-all-cycles.js +43 -0
- package/dist/graph-explorer/operations/find-cycles.js +3 -9
- package/dist/graph-explorer/utils.d.ts +10 -1
- package/dist/graph-explorer/utils.js +53 -0
- package/dist/plugins/astro/compiler-mdx.js +11 -2
- package/dist/plugins/astro/compiler.js +8 -4
- package/dist/plugins/bun/index.js +28 -14
- package/dist/plugins/eve/index.d.ts +3 -0
- package/dist/plugins/eve/index.js +22 -0
- package/dist/plugins/execa/visitors/execa.js +10 -18
- package/dist/plugins/fumadocs/index.d.ts +3 -0
- package/dist/plugins/fumadocs/index.js +18 -0
- package/dist/plugins/github-actions/index.js +3 -2
- package/dist/plugins/graphql-codegen/index.js +9 -7
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/jest/index.js +13 -3
- package/dist/plugins/next/index.js +23 -10
- package/dist/plugins/node/index.js +4 -1
- package/dist/plugins/nuxt/index.js +4 -2
- package/dist/plugins/pnpm/index.js +21 -1
- package/dist/plugins/pnpm/types.d.ts +6 -0
- package/dist/plugins/pnpm/types.js +1 -0
- package/dist/plugins/prettier/index.js +19 -3
- package/dist/plugins/prettier/types.d.ts +6 -1
- package/dist/plugins/prisma/compiler.js +3 -0
- package/dist/plugins/rspack/index.js +5 -0
- package/dist/plugins/serverless-framework/index.js +12 -1
- package/dist/plugins/serverless-framework/types.d.ts +5 -2
- package/dist/plugins/stencil/index.js +59 -1
- package/dist/plugins/storybook/index.js +7 -0
- package/dist/plugins/svelte/compiler.d.ts +2 -1
- package/dist/plugins/svelte/compiler.js +8 -1
- package/dist/plugins/tailwind/compiler.js +3 -0
- package/dist/plugins/tailwind/index.js +5 -1
- package/dist/plugins/typedoc/index.js +9 -3
- package/dist/plugins/typedoc/types.d.ts +2 -0
- package/dist/plugins/vite/visitors/importMetaGlob.js +1 -8
- package/dist/plugins/vue/compiler.d.ts +2 -1
- package/dist/plugins/vue/compiler.js +8 -1
- package/dist/plugins/webpack/visitors/requireContext.js +2 -13
- package/dist/plugins/yarn/index.js +13 -4
- package/dist/plugins/yarn/types.d.ts +10 -0
- package/dist/plugins/yarn/types.js +1 -0
- package/dist/plugins/zx/visitors/zx.js +4 -4
- package/dist/reporters/compact.js +1 -2
- package/dist/reporters/cycles.d.ts +3 -0
- package/dist/reporters/cycles.js +79 -0
- package/dist/reporters/index.d.ts +1 -0
- package/dist/reporters/index.js +2 -0
- package/dist/reporters/json.d.ts +3 -0
- package/dist/reporters/json.js +2 -1
- package/dist/reporters/symbols.js +1 -2
- package/dist/reporters/util/util.d.ts +3 -1
- package/dist/reporters/util/util.js +5 -1
- package/dist/schema/configuration.d.ts +40 -6
- package/dist/schema/configuration.js +6 -0
- package/dist/schema/plugins.d.ts +10 -0
- package/dist/schema/plugins.js +2 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +2 -0
- package/dist/types/config.d.ts +10 -0
- package/dist/types/issues.d.ts +3 -0
- package/dist/types/module-graph.d.ts +7 -0
- package/dist/types/package-json.d.ts +4 -1
- package/dist/types.d.ts +1 -1
- package/dist/typescript/SourceFileManager.js +3 -2
- package/dist/typescript/ast-nodes.d.ts +4 -1
- package/dist/typescript/ast-nodes.js +60 -2
- package/dist/typescript/comments.js +22 -3
- package/dist/typescript/get-imports-and-exports.js +10 -0
- package/dist/typescript/glob-imports.d.ts +3 -0
- package/dist/typescript/glob-imports.js +49 -0
- package/dist/typescript/resolve-module-names.d.ts +2 -0
- package/dist/typescript/resolve-module-names.js +35 -1
- package/dist/typescript/visitors/calls.js +4 -6
- package/dist/typescript/visitors/imports.js +8 -8
- package/dist/typescript/visitors/script-visitors.js +4 -4
- package/dist/typescript/visitors/walk.js +6 -1
- package/dist/util/cli-arguments.d.ts +2 -1
- package/dist/util/cli-arguments.js +4 -2
- package/dist/util/create-options.d.ts +32 -5
- package/dist/util/create-options.js +4 -1
- package/dist/util/get-included-issue-types.d.ts +1 -0
- package/dist/util/get-included-issue-types.js +4 -2
- package/dist/util/issue-initializers.js +1 -1
- package/dist/util/load-tsconfig.js +17 -4
- package/dist/util/module-graph.js +1 -0
- package/dist/util/modules.js +25 -4
- package/dist/util/scripts.d.ts +7 -0
- package/dist/util/scripts.js +75 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schema.json +40 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { Visitor } from 'oxc-parser';
|
|
2
|
+
import scss from '../../compilers/scss.js';
|
|
3
|
+
import { IMPORT_FLAGS } from '../../constants.js';
|
|
1
4
|
import { toConfig, toEntry, toProductionEntry } from '../../util/input.js';
|
|
5
|
+
import { dirname, join } from '../../util/path.js';
|
|
2
6
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
|
-
import { collectPropertyValues } from '../../typescript/ast-helpers.js';
|
|
7
|
+
import { collectPropertyValues, getPropertyValues } from '../../typescript/ast-helpers.js';
|
|
4
8
|
import { createCustomElementVisitor } from '../_custom-elements/custom-element-visitor.js';
|
|
5
9
|
const title = 'Stencil';
|
|
6
10
|
const enablers = ['@stencil/core'];
|
|
@@ -9,8 +13,49 @@ const config = ['stencil.config.{ts,js}'];
|
|
|
9
13
|
const production = ['src/**/*.tsx'];
|
|
10
14
|
const entry = ['**/*.spec.{ts,tsx}', '**/*.e2e.{ts,tsx}'];
|
|
11
15
|
const isStencilSpecifier = (specifier) => specifier === '@stencil/core';
|
|
16
|
+
const registerCompilers = ({ hasDependency, registerCompiler }) => {
|
|
17
|
+
if (hasDependency('@stencil/sass'))
|
|
18
|
+
for (const ext of ['.scss', '.sass'])
|
|
19
|
+
registerCompiler({ extension: ext, compiler: scss.compiler });
|
|
20
|
+
};
|
|
12
21
|
const registerVisitors = ({ ctx, registerVisitor }) => {
|
|
13
22
|
registerVisitor(createCustomElementVisitor(ctx, isStencilSpecifier, { decoratorName: 'Component' }));
|
|
23
|
+
const componentNames = new Set();
|
|
24
|
+
registerVisitor({
|
|
25
|
+
Program() {
|
|
26
|
+
componentNames.clear();
|
|
27
|
+
},
|
|
28
|
+
ImportDeclaration(node) {
|
|
29
|
+
if (!isStencilSpecifier(node.source?.value))
|
|
30
|
+
return;
|
|
31
|
+
for (const spec of node.specifiers ?? []) {
|
|
32
|
+
if (spec.type === 'ImportSpecifier' &&
|
|
33
|
+
spec.imported.type === 'Identifier' &&
|
|
34
|
+
spec.imported.name === 'Component')
|
|
35
|
+
componentNames.add(spec.local.name);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
ClassDeclaration(node) {
|
|
39
|
+
resolveStyleUrls(node);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
function resolveStyleUrls(node) {
|
|
43
|
+
const dir = dirname(ctx.filePath);
|
|
44
|
+
for (const decorator of node.decorators ?? []) {
|
|
45
|
+
const expr = decorator.expression;
|
|
46
|
+
if (expr?.type !== 'CallExpression')
|
|
47
|
+
continue;
|
|
48
|
+
if (expr.callee?.type !== 'Identifier' || !componentNames.has(expr.callee.name))
|
|
49
|
+
continue;
|
|
50
|
+
const arg = expr.arguments?.[0];
|
|
51
|
+
if (arg?.type !== 'ObjectExpression')
|
|
52
|
+
continue;
|
|
53
|
+
for (const url of getPropertyValues(arg, 'styleUrl'))
|
|
54
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
55
|
+
for (const url of getPropertyValues(arg, 'styleUrls'))
|
|
56
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
14
59
|
};
|
|
15
60
|
const resolveFromAST = program => {
|
|
16
61
|
const inputs = [];
|
|
@@ -22,6 +67,18 @@ const resolveFromAST = program => {
|
|
|
22
67
|
for (const script of collectPropertyValues(program, 'globalScript')) {
|
|
23
68
|
inputs.push(toProductionEntry(script));
|
|
24
69
|
}
|
|
70
|
+
for (const style of collectPropertyValues(program, 'globalStyle')) {
|
|
71
|
+
inputs.push(toProductionEntry(style));
|
|
72
|
+
}
|
|
73
|
+
new Visitor({
|
|
74
|
+
ObjectExpression(node) {
|
|
75
|
+
const typeValues = getPropertyValues(node, 'type');
|
|
76
|
+
if (!typeValues.has('global-style'))
|
|
77
|
+
return;
|
|
78
|
+
for (const input of getPropertyValues(node, 'input'))
|
|
79
|
+
inputs.push(toProductionEntry(input));
|
|
80
|
+
},
|
|
81
|
+
}).visit(program);
|
|
25
82
|
for (const tsconfig of collectPropertyValues(program, 'tsconfig')) {
|
|
26
83
|
inputs.push(toConfig('typescript', tsconfig));
|
|
27
84
|
}
|
|
@@ -41,6 +98,7 @@ const plugin = {
|
|
|
41
98
|
entry,
|
|
42
99
|
production,
|
|
43
100
|
resolveFromAST,
|
|
101
|
+
registerCompilers,
|
|
44
102
|
registerVisitors,
|
|
45
103
|
};
|
|
46
104
|
export default plugin;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import MDX from '../../compilers/mdx.js';
|
|
1
2
|
import { toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
|
|
2
3
|
import { join, relative } from '../../util/path.js';
|
|
3
4
|
import { hasDependency } from '../../util/plugin.js';
|
|
@@ -54,6 +55,11 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
54
55
|
...configs,
|
|
55
56
|
];
|
|
56
57
|
};
|
|
58
|
+
const registerCompilers = ({ registerCompiler, hasDependency }) => {
|
|
59
|
+
if (hasDependency('@storybook/addon-docs') || hasDependency('@storybook/addon-essentials')) {
|
|
60
|
+
registerCompiler({ extension: '.mdx', compiler: MDX.compiler });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
57
63
|
const plugin = {
|
|
58
64
|
title,
|
|
59
65
|
enablers,
|
|
@@ -62,5 +68,6 @@ const plugin = {
|
|
|
62
68
|
entry,
|
|
63
69
|
project,
|
|
64
70
|
resolveConfig,
|
|
71
|
+
registerCompilers,
|
|
65
72
|
};
|
|
66
73
|
export default plugin;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { importsWithinScripts } from '../../compilers/compilers.js';
|
|
2
|
-
|
|
2
|
+
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
3
|
+
const compiler = (text, path) => {
|
|
4
|
+
const scripts = importsWithinScripts(text, path);
|
|
5
|
+
const styles = stylePreprocessorImports(text, path);
|
|
6
|
+
if (!scripts)
|
|
7
|
+
return styles;
|
|
8
|
+
return styles ? `${scripts};\n${styles}` : scripts;
|
|
9
|
+
};
|
|
3
10
|
export default compiler;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const directiveMatcher = /@(?:import|config|plugin)\s+['"]([^'"]+)['"][^;]*;/g;
|
|
2
2
|
const compiler = (text) => {
|
|
3
|
+
if (!text.includes('@import') && !text.includes('@config') && !text.includes('@plugin'))
|
|
4
|
+
return '';
|
|
3
5
|
const imports = [];
|
|
4
6
|
let match;
|
|
5
7
|
let index = 0;
|
|
8
|
+
directiveMatcher.lastIndex = 0;
|
|
6
9
|
while ((match = directiveMatcher.exec(text)))
|
|
7
10
|
if (match[1])
|
|
8
11
|
imports.push(`import _$${index++} from '${match[1]}';`);
|
|
@@ -5,8 +5,12 @@ const enablers = ['tailwindcss', '@tailwindcss/vite', '@tailwindcss/postcss', '@
|
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
6
|
const entry = ['tailwind.config.{js,cjs,mjs,ts,cts,mts}'];
|
|
7
7
|
const registerCompilers = ({ registerCompiler, hasDependency }) => {
|
|
8
|
-
|
|
8
|
+
for (const enabler of enablers) {
|
|
9
|
+
if (!hasDependency(enabler))
|
|
10
|
+
continue;
|
|
9
11
|
registerCompiler({ extension: '.css', compiler });
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
10
14
|
};
|
|
11
15
|
const plugin = {
|
|
12
16
|
title,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { toDeferResolve } from '../../util/input.js';
|
|
1
|
+
import { toDeferResolve, toEntry } from '../../util/input.js';
|
|
2
|
+
import { join } from '../../util/path.js';
|
|
2
3
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
4
|
const title = 'TypeDoc';
|
|
4
5
|
const enablers = ['typedoc'];
|
|
@@ -12,11 +13,16 @@ const config = [
|
|
|
12
13
|
'package.json',
|
|
13
14
|
'tsconfig.json',
|
|
14
15
|
];
|
|
15
|
-
const resolveConfig = config => {
|
|
16
|
+
const resolveConfig = (config, options) => {
|
|
16
17
|
const cfg = 'typedocOptions' in config ? config.typedocOptions : config;
|
|
17
18
|
const plugins = cfg?.plugin ?? [];
|
|
18
19
|
const themes = cfg?.theme ?? [];
|
|
19
|
-
|
|
20
|
+
const inputs = [...plugins, ...themes].map(id => toDeferResolve(id));
|
|
21
|
+
for (const file of [cfg?.customCss, cfg?.customJs]) {
|
|
22
|
+
if (file)
|
|
23
|
+
inputs.push(toEntry(join(options.configFileDir, file)));
|
|
24
|
+
}
|
|
25
|
+
return inputs;
|
|
20
26
|
};
|
|
21
27
|
const args = {
|
|
22
28
|
resolve: ['plugin', 'theme'],
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { IMPORT_FLAGS } from '../../../constants.js';
|
|
2
|
-
import { _syncGlob } from '../../../util/glob.js';
|
|
3
|
-
import { dirname, isAbsolute, join } from '../../../util/path.js';
|
|
4
1
|
import { getStringValue, isStringLiteral } from '../../../typescript/ast-nodes.js';
|
|
5
2
|
export function createImportMetaGlobVisitor(ctx) {
|
|
6
3
|
return {
|
|
@@ -25,11 +22,7 @@ export function createImportMetaGlobVisitor(ctx) {
|
|
|
25
22
|
}
|
|
26
23
|
if (!patterns?.length)
|
|
27
24
|
return;
|
|
28
|
-
|
|
29
|
-
const files = _syncGlob({ patterns, cwd: dir });
|
|
30
|
-
for (const f of files) {
|
|
31
|
-
ctx.addImport(isAbsolute(f) ? f : join(dir, f), arg.start, IMPORT_FLAGS.ENTRY);
|
|
32
|
-
}
|
|
25
|
+
ctx.addImportGlob(patterns);
|
|
33
26
|
},
|
|
34
27
|
};
|
|
35
28
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { scriptBodies } from '../../compilers/compilers.js';
|
|
2
|
-
|
|
2
|
+
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
3
|
+
const compiler = (text, path) => {
|
|
4
|
+
const scripts = scriptBodies(text, path);
|
|
5
|
+
const styles = stylePreprocessorImports(text, path);
|
|
6
|
+
if (!scripts)
|
|
7
|
+
return styles;
|
|
8
|
+
return styles ? `${scripts};\n${styles}` : scripts;
|
|
9
|
+
};
|
|
3
10
|
export default compiler;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { IMPORT_FLAGS } from '../../../constants.js';
|
|
2
|
-
import { _syncGlob } from '../../../util/glob.js';
|
|
3
|
-
import { dirname, join, toRelative } from '../../../util/path.js';
|
|
4
1
|
import { getStringValue, isStringLiteral } from '../../../typescript/ast-nodes.js';
|
|
5
2
|
export function createRequireContextVisitor(ctx) {
|
|
6
3
|
return {
|
|
@@ -17,16 +14,8 @@ export function createRequireContextVisitor(ctx) {
|
|
|
17
14
|
const arg1 = node.arguments[1];
|
|
18
15
|
const recursive = !(arg1?.type === 'Literal' && 'value' in arg1 && arg1.value === false);
|
|
19
16
|
const regexArg = node.arguments[2];
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const pattern = recursive ? '**/*' : '*';
|
|
23
|
-
const files = _syncGlob({ patterns: [pattern], cwd: baseDir });
|
|
24
|
-
const regex = regexArg && 'regex' in regexArg ? new RegExp(regexArg.regex.pattern, regexArg.regex.flags) : undefined;
|
|
25
|
-
for (const f of files) {
|
|
26
|
-
if (!regex || regex.test(`./${toRelative(f, baseDir)}`)) {
|
|
27
|
-
ctx.addImport(f, node.arguments[0].start, IMPORT_FLAGS.ENTRY);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
17
|
+
const filter = regexArg && 'regex' in regexArg ? new RegExp(regexArg.regex.pattern, regexArg.regex.flags) : undefined;
|
|
18
|
+
ctx.addImportGlob([recursive ? '**/*' : '*'], { base: dirArg, filter });
|
|
30
19
|
},
|
|
31
20
|
};
|
|
32
21
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { isFile } from '../../util/fs.js';
|
|
2
|
-
import { toEntry } from '../../util/input.js';
|
|
2
|
+
import { toDependency, toEntry } from '../../util/input.js';
|
|
3
3
|
const title = 'Yarn';
|
|
4
|
-
const enablers = 'This plugin is enabled when a `yarn.lock` file is found in the root
|
|
5
|
-
const isEnabled = ({ cwd }) => isFile(cwd, 'yarn.lock');
|
|
4
|
+
const enablers = 'This plugin is enabled when a `yarn.lock` file is found in the root directory, or when `yarn@` is specified in the `packageManager` field of `package.json`.';
|
|
5
|
+
const isEnabled = async ({ cwd, manifest }) => manifest.packageManager?.startsWith('yarn@') || isFile(cwd, 'yarn.lock');
|
|
6
6
|
const isRootOnly = true;
|
|
7
7
|
const config = ['.yarnrc.yml'];
|
|
8
8
|
const entry = ['yarn.config.cjs'];
|
|
9
9
|
const resolveConfig = config => {
|
|
10
|
-
const inputs = entry.map(
|
|
10
|
+
const inputs = entry.map(toEntry);
|
|
11
11
|
if (Array.isArray(config.plugins)) {
|
|
12
12
|
for (const plugin of config.plugins) {
|
|
13
13
|
if (typeof plugin === 'string')
|
|
@@ -19,6 +19,15 @@ const resolveConfig = config => {
|
|
|
19
19
|
if (config.yarnPath) {
|
|
20
20
|
inputs.push(toEntry(config.yarnPath));
|
|
21
21
|
}
|
|
22
|
+
if (config.packageExtensions) {
|
|
23
|
+
for (const extension of Object.values(config.packageExtensions)) {
|
|
24
|
+
if (extension.peerDependencies) {
|
|
25
|
+
for (const dep of Object.keys(extension.peerDependencies)) {
|
|
26
|
+
inputs.push(toDependency(dep));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
22
31
|
return inputs;
|
|
23
32
|
};
|
|
24
33
|
const plugin = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { getScriptFromTemplate } from '../../../typescript/ast-nodes.js';
|
|
1
2
|
export function createZxVisitor(ctx) {
|
|
2
3
|
return {
|
|
3
4
|
TaggedTemplateExpression(node) {
|
|
4
5
|
if (!ctx.sourceText.startsWith('#!/usr/bin/env zx'))
|
|
5
6
|
return;
|
|
6
7
|
if (node.tag.type === 'Identifier' && node.tag.name === '$') {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
8
|
+
const script = getScriptFromTemplate(node.quasi);
|
|
9
|
+
if (script)
|
|
10
|
+
ctx.addScript(script);
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
};
|
|
@@ -5,11 +5,10 @@ const logIssueRecord = (issues, cwd) => {
|
|
|
5
5
|
console.log(getIssueLine(issue, cwd));
|
|
6
6
|
};
|
|
7
7
|
export default ({ report, issues, isShowProgress, cwd }) => {
|
|
8
|
-
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
9
8
|
let totalIssues = 0;
|
|
10
9
|
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
11
10
|
if (isReportType) {
|
|
12
|
-
const title =
|
|
11
|
+
const title = getIssueTypeTitle(reportType);
|
|
13
12
|
const issuesForType = reportType === 'duplicates'
|
|
14
13
|
? flattenIssues(issues[reportType])
|
|
15
14
|
: Object.values(issues[reportType])
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import st from '../util/colors.js';
|
|
2
|
+
import { relative } from '../util/path.js';
|
|
3
|
+
import { flattenIssues, getColoredTitle, getIssueTypeTitle } from './util/util.js';
|
|
4
|
+
const kindLabels = {
|
|
5
|
+
import: 'import',
|
|
6
|
+
importAs: 'aliased import',
|
|
7
|
+
importNS: 'namespace import',
|
|
8
|
+
reExport: 're-export',
|
|
9
|
+
reExportAs: 'aliased re-export',
|
|
10
|
+
reExportNS: 'namespace re-export',
|
|
11
|
+
reExportStar: 'star re-export',
|
|
12
|
+
dynamicImport: 'dynamic import',
|
|
13
|
+
sideEffectImport: 'side-effect import',
|
|
14
|
+
};
|
|
15
|
+
const formatEdge = (edge) => {
|
|
16
|
+
const kind = kindLabels[edge.kind ?? 'import'] ?? edge.kind ?? 'import';
|
|
17
|
+
const specifier = edge.specifier ? `${st.dim(' ')}${st.cyanBright(edge.specifier)}` : '';
|
|
18
|
+
return `${st.cyan(kind)}${specifier}${st.dim(' → ')}`;
|
|
19
|
+
};
|
|
20
|
+
const getLocation = (file) => {
|
|
21
|
+
const location = file.line === undefined ? '' : `:${file.line}${file.col === undefined ? '' : `:${file.col}`}`;
|
|
22
|
+
return `${file.symbol}${location}`;
|
|
23
|
+
};
|
|
24
|
+
const formatFile = (file) => st.white(getLocation(file));
|
|
25
|
+
const getIssueRootLocation = (issue, cwd) => {
|
|
26
|
+
const root = issue.symbols?.[0];
|
|
27
|
+
return root ? getLocation(root) : relative(cwd, issue.filePath);
|
|
28
|
+
};
|
|
29
|
+
const sortByFilePath = (cwd) => (a, b) => {
|
|
30
|
+
const aFilePath = relative(cwd, a.filePath);
|
|
31
|
+
const bFilePath = relative(cwd, b.filePath);
|
|
32
|
+
const filePath = aFilePath.localeCompare(bFilePath);
|
|
33
|
+
if (filePath !== 0)
|
|
34
|
+
return filePath;
|
|
35
|
+
const rootLocation = getIssueRootLocation(a, cwd).localeCompare(getIssueRootLocation(b, cwd));
|
|
36
|
+
return rootLocation === 0 ? a.symbol.localeCompare(b.symbol) : rootLocation;
|
|
37
|
+
};
|
|
38
|
+
export default ({ cwd, issues, isShowProgress }) => {
|
|
39
|
+
const cycles = flattenIssues(issues.cycles).sort(sortByFilePath(cwd));
|
|
40
|
+
if (cycles.length === 0) {
|
|
41
|
+
if (isShowProgress)
|
|
42
|
+
console.log('✂️ No circular dependencies found.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
console.log(getColoredTitle(getIssueTypeTitle('cycles'), cycles.length));
|
|
46
|
+
const rootCounts = new Map();
|
|
47
|
+
for (const issue of cycles) {
|
|
48
|
+
const files = issue.symbols ?? issue.symbol.split(' → ').map(symbol => ({ symbol }));
|
|
49
|
+
const root = files[0];
|
|
50
|
+
if (root) {
|
|
51
|
+
const rootLocation = getLocation(root);
|
|
52
|
+
rootCounts.set(rootLocation, (rootCounts.get(rootLocation) ?? 0) + 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let previousRoot = '';
|
|
56
|
+
for (const issue of cycles) {
|
|
57
|
+
const files = issue.symbols ?? issue.symbol.split(' → ').map(symbol => ({ symbol }));
|
|
58
|
+
const root = files[0];
|
|
59
|
+
if (!root)
|
|
60
|
+
continue;
|
|
61
|
+
const rootLocation = getLocation(root);
|
|
62
|
+
if (rootLocation !== previousRoot) {
|
|
63
|
+
const count = rootCounts.get(rootLocation) ?? 0;
|
|
64
|
+
const countLabel = count > 1 ? st.dim(` (${count} cycles)`) : '';
|
|
65
|
+
console.log(`\n${formatFile(root)}${countLabel}`);
|
|
66
|
+
previousRoot = rootLocation;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log('');
|
|
70
|
+
}
|
|
71
|
+
for (let depth = 1; depth <= files.length; depth++) {
|
|
72
|
+
const isClose = depth === files.length;
|
|
73
|
+
const edge = files[depth - 1];
|
|
74
|
+
const file = isClose ? root : files[depth];
|
|
75
|
+
const connector = st.dim(`${' '.repeat(depth - 1)}└── `);
|
|
76
|
+
console.log(`${connector}${formatEdge(edge)}${formatFile(file)}${isClose ? st.dim(' ↩') : ''}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
@@ -2,6 +2,7 @@ declare const _default: {
|
|
|
2
2
|
symbols: (options: import("../types.ts").ReporterOptions) => void;
|
|
3
3
|
compact: ({ report, issues, isShowProgress, cwd }: import("../types.ts").ReporterOptions) => void;
|
|
4
4
|
codeowners: ({ report, issues, isShowProgress, options, cwd }: import("../types.ts").ReporterOptions) => void;
|
|
5
|
+
cycles: ({ cwd, issues, isShowProgress }: import("../types.ts").ReporterOptions) => void;
|
|
5
6
|
disclosure: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
|
|
6
7
|
codeclimate: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
|
|
7
8
|
json: ({ report, issues, options, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
|
package/dist/reporters/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import codeclimate from './codeclimate.js';
|
|
2
2
|
import codeowners from './codeowners.js';
|
|
3
3
|
import compact from './compact.js';
|
|
4
|
+
import cycles from './cycles.js';
|
|
4
5
|
import disclosure from './disclosure.js';
|
|
5
6
|
import githubActions from './github-actions.js';
|
|
6
7
|
import json from './json.js';
|
|
@@ -10,6 +11,7 @@ export default {
|
|
|
10
11
|
symbols,
|
|
11
12
|
compact,
|
|
12
13
|
codeowners,
|
|
14
|
+
cycles,
|
|
13
15
|
disclosure,
|
|
14
16
|
codeclimate,
|
|
15
17
|
json,
|
package/dist/reporters/json.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface JSONReportNamedItem {
|
|
|
4
4
|
}
|
|
5
5
|
export interface JSONReportItem extends JSONReportNamedItem {
|
|
6
6
|
namespace?: string;
|
|
7
|
+
kind?: string;
|
|
8
|
+
specifier?: string;
|
|
7
9
|
pos?: number;
|
|
8
10
|
line?: number;
|
|
9
11
|
col?: number;
|
|
@@ -13,6 +15,7 @@ export type JSONReportEntry = {
|
|
|
13
15
|
owners?: Array<JSONReportNamedItem>;
|
|
14
16
|
binaries?: Array<JSONReportNamedItem>;
|
|
15
17
|
catalog?: Array<JSONReportItem>;
|
|
18
|
+
cycles?: Array<Array<JSONReportItem>>;
|
|
16
19
|
dependencies?: Array<JSONReportItem>;
|
|
17
20
|
devDependencies?: Array<JSONReportItem>;
|
|
18
21
|
duplicates?: Array<Array<JSONReportItem>>;
|
package/dist/reporters/json.js
CHANGED
|
@@ -20,6 +20,7 @@ export default async ({ report, issues, options, cwd }) => {
|
|
|
20
20
|
...(findOwners && { owners: findOwners(file).map(name => ({ name })) }),
|
|
21
21
|
...(report.binaries && { binaries: [] }),
|
|
22
22
|
...(report.catalog && { catalog: [] }),
|
|
23
|
+
...(report.cycles && { cycles: [] }),
|
|
23
24
|
...(report.dependencies && { dependencies: [] }),
|
|
24
25
|
...(report.devDependencies && { devDependencies: [] }),
|
|
25
26
|
...(report.duplicates && { duplicates: [] }),
|
|
@@ -41,7 +42,7 @@ export default async ({ report, issues, options, cwd }) => {
|
|
|
41
42
|
for (const issue of flattenIssues(issues[type])) {
|
|
42
43
|
const { filePath, symbol, symbols } = issue;
|
|
43
44
|
json[filePath] = json[filePath] ?? initRow(filePath);
|
|
44
|
-
if (type === 'duplicates') {
|
|
45
|
+
if (type === 'duplicates' || type === 'cycles') {
|
|
45
46
|
symbols && json[filePath][type]?.push(symbols.map(convert));
|
|
46
47
|
}
|
|
47
48
|
else if (type === 'binaries') {
|
|
@@ -2,11 +2,10 @@ import { printConfigurationHints, printTagHints } from './util/configuration-hin
|
|
|
2
2
|
import { dim, flattenIssues, getColoredTitle, getIssueTypeTitle, getTableForType } from './util/util.js';
|
|
3
3
|
export default (options) => {
|
|
4
4
|
const { report, issues, isDisableConfigHints, isDisableTagHints, isShowProgress } = options;
|
|
5
|
-
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
6
5
|
let totalIssues = 0;
|
|
7
6
|
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
8
7
|
if (isReportType) {
|
|
9
|
-
const title =
|
|
8
|
+
const title = getIssueTypeTitle(reportType);
|
|
10
9
|
const issuesForType = flattenIssues(issues[reportType]);
|
|
11
10
|
if (issuesForType.length > 0) {
|
|
12
11
|
title && console.log(getColoredTitle(title, issuesForType.length));
|
|
@@ -3,7 +3,7 @@ import type { Issue, IssueRecords, IssueSeverity, IssueSymbol, IssueType } from
|
|
|
3
3
|
import { Table } from '../../util/table.ts';
|
|
4
4
|
export declare const dim: (text: string | number | null | undefined) => string;
|
|
5
5
|
export declare const bright: (text: string | number | null | undefined) => string;
|
|
6
|
-
export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => "Duplicate exports" | "Exported types in used namespace" | "Exports in used namespace" | "Referenced optional peerDependencies" | "Unlisted binaries" | "Unlisted dependencies" | "Unresolved imports" | "Unused catalog entries" | "Unused dependencies" | "Unused devDependencies" | "Unused exported enum members" | "Unused exported namespace members" | "Unused exported types" | "Unused exports" | "Unused files";
|
|
6
|
+
export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => "Circular dependencies" | "Duplicate exports" | "Exported types in used namespace" | "Exports in used namespace" | "Referenced optional peerDependencies" | "Unlisted binaries" | "Unlisted dependencies" | "Unresolved imports" | "Unused catalog entries" | "Unused dependencies" | "Unused devDependencies" | "Unused exported enum members" | "Unused exported namespace members" | "Unused exported types" | "Unused exports" | "Unused files";
|
|
7
7
|
export declare const getColoredTitle: (title: string, count: number) => string;
|
|
8
8
|
export declare const getDimmedTitle: (title: string, count: number) => string;
|
|
9
9
|
type LogIssueLine = {
|
|
@@ -17,6 +17,8 @@ export declare const getIssueLine: ({ owner, filePath, symbols, parentSymbol, se
|
|
|
17
17
|
export declare const convert: (issue: Issue | IssueSymbol) => {
|
|
18
18
|
namespace: string | undefined;
|
|
19
19
|
name: string;
|
|
20
|
+
kind: string | undefined;
|
|
21
|
+
specifier: string | undefined;
|
|
20
22
|
line: number | undefined;
|
|
21
23
|
col: number | undefined;
|
|
22
24
|
pos: number | undefined;
|
|
@@ -17,6 +17,8 @@ export const getIssueLine = ({ owner, filePath, symbols, parentSymbol, severity
|
|
|
17
17
|
export const convert = (issue) => ({
|
|
18
18
|
namespace: 'parentSymbol' in issue ? issue.parentSymbol : undefined,
|
|
19
19
|
name: issue.symbol,
|
|
20
|
+
kind: 'kind' in issue ? issue.kind : undefined,
|
|
21
|
+
specifier: 'kind' in issue ? issue.specifier : undefined,
|
|
20
22
|
line: issue.line,
|
|
21
23
|
col: issue.col,
|
|
22
24
|
pos: issue.pos,
|
|
@@ -44,7 +46,9 @@ export const getTableForType = (issues, cwd, options = { isUseColors: true }) =>
|
|
|
44
46
|
table.row();
|
|
45
47
|
const print = options.isUseColors && (issue.isFixed || issue.severity === 'warn') ? dim : plain;
|
|
46
48
|
const isFileIssue = issue.type === 'files';
|
|
47
|
-
const symbol = issue.symbols
|
|
49
|
+
const symbol = issue.symbols
|
|
50
|
+
? issue.symbols.map(s => s.symbol).join(issue.type === 'cycles' ? ' → ' : ', ')
|
|
51
|
+
: issue.symbol;
|
|
48
52
|
if (!isFileIssue)
|
|
49
53
|
table.cell('symbol', print(symbol), options.isUseColors ? highlightSymbol(issue) : () => symbol);
|
|
50
54
|
table.cell('parentSymbol', issue.parentSymbol && print(issue.parentSymbol));
|