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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { _syncGlob } from '../util/glob.js';
|
|
3
|
+
import { dirname, isAbsolute, join, toRelative } from '../util/path.js';
|
|
4
|
+
function resolveBaseDir(base, dir, resolveGlobPattern) {
|
|
5
|
+
if (base.startsWith('.'))
|
|
6
|
+
return join(dir, base);
|
|
7
|
+
if (isAbsolute(base))
|
|
8
|
+
return base;
|
|
9
|
+
for (const resolved of resolveGlobPattern(base, dir)) {
|
|
10
|
+
if (resolved !== base && existsSync(resolved))
|
|
11
|
+
return resolved;
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
export function resolveImportGlobs(items, containingFile, resolveGlobPattern, workspaceRoot) {
|
|
16
|
+
const filePaths = [];
|
|
17
|
+
const dir = dirname(containingFile);
|
|
18
|
+
for (const { patterns, base, filter } of items) {
|
|
19
|
+
if (base !== undefined) {
|
|
20
|
+
const cwd = resolveBaseDir(base, dir, resolveGlobPattern);
|
|
21
|
+
if (!cwd)
|
|
22
|
+
continue;
|
|
23
|
+
for (const filePath of _syncGlob({ patterns, cwd })) {
|
|
24
|
+
if (!filter || filter.test(`./${toRelative(filePath, cwd)}`))
|
|
25
|
+
filePaths.push(filePath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const resolved = [];
|
|
30
|
+
for (const pattern of patterns) {
|
|
31
|
+
const isNegated = pattern[0] === '!';
|
|
32
|
+
const specifier = isNegated ? pattern.slice(1) : pattern;
|
|
33
|
+
if (specifier[0] === '/') {
|
|
34
|
+
const rooted = join(workspaceRoot, specifier);
|
|
35
|
+
resolved.push(isNegated ? `!${rooted}` : rooted);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
for (const p of resolveGlobPattern(pattern, dir))
|
|
39
|
+
resolved.push(p);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (resolved.length === 0)
|
|
43
|
+
continue;
|
|
44
|
+
for (const filePath of _syncGlob({ patterns: resolved, cwd: dir }))
|
|
45
|
+
filePaths.push(filePath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return filePaths;
|
|
49
|
+
}
|
|
@@ -9,6 +9,8 @@ type ScopedRootDirs = Array<{
|
|
|
9
9
|
rootDirs: string[];
|
|
10
10
|
}>;
|
|
11
11
|
export declare function clearModuleResolutionCaches(): void;
|
|
12
|
+
export type ResolveGlobPattern = (pattern: string, dir: string) => string[];
|
|
13
|
+
export declare function createGlobAliasResolver(scopedPaths: ScopedPaths | undefined): ResolveGlobPattern;
|
|
12
14
|
export declare function createCustomModuleResolver(compilerOptions: {
|
|
13
15
|
scopedPaths?: ScopedPaths;
|
|
14
16
|
scopedRootDirs?: ScopedRootDirs;
|
|
@@ -3,7 +3,7 @@ import { isBuiltin } from 'node:module';
|
|
|
3
3
|
import { DEFAULT_EXTENSIONS, DTS_EXTENSIONS } from '../constants.js';
|
|
4
4
|
import { sanitizeSpecifier } from '../util/modules.js';
|
|
5
5
|
import { timerify } from '../util/Performance.js';
|
|
6
|
-
import { dirname, extname, isAbsolute, isInNodeModules, join } from '../util/path.js';
|
|
6
|
+
import { dirname, extname, isAbsolute, isInNodeModules, join, toPosix } from '../util/path.js';
|
|
7
7
|
import { _createSyncModuleResolver, _resolveModuleSync } from '../util/resolve.js';
|
|
8
8
|
function pickStringTarget(value) {
|
|
9
9
|
if (typeof value === 'string')
|
|
@@ -56,6 +56,40 @@ function compileRootDirs(scopedRootDirs) {
|
|
|
56
56
|
scoped.sort((a, b) => b.scope.length - a.scope.length);
|
|
57
57
|
return scoped;
|
|
58
58
|
}
|
|
59
|
+
export function createGlobAliasResolver(scopedPaths) {
|
|
60
|
+
const mappings = compilePathMappings(scopedPaths);
|
|
61
|
+
return (pattern, dir) => {
|
|
62
|
+
if (!mappings)
|
|
63
|
+
return [pattern];
|
|
64
|
+
const isNegated = pattern[0] === '!';
|
|
65
|
+
const specifier = isNegated ? pattern.slice(1) : pattern;
|
|
66
|
+
let best;
|
|
67
|
+
for (const mapping of mappings) {
|
|
68
|
+
const { prefix, wildcard, scope } = mapping;
|
|
69
|
+
if (dir !== scope && !dir.startsWith(`${scope}/`))
|
|
70
|
+
continue;
|
|
71
|
+
const matches = wildcard
|
|
72
|
+
? specifier.startsWith(prefix)
|
|
73
|
+
: specifier === prefix || specifier.startsWith(`${prefix}/`);
|
|
74
|
+
if (!matches)
|
|
75
|
+
continue;
|
|
76
|
+
if (!best ||
|
|
77
|
+
scope.length > best.scope.length ||
|
|
78
|
+
(scope.length === best.scope.length && prefix.length > best.prefix.length))
|
|
79
|
+
best = mapping;
|
|
80
|
+
}
|
|
81
|
+
if (!best)
|
|
82
|
+
return [pattern];
|
|
83
|
+
const captured = specifier.slice(best.prefix.length);
|
|
84
|
+
const resolved = [];
|
|
85
|
+
for (const value of best.values) {
|
|
86
|
+
const starIdx = value.indexOf('*');
|
|
87
|
+
const mapped = toPosix(starIdx >= 0 ? value.slice(0, starIdx) + captured + value.slice(starIdx + 1) : value + captured);
|
|
88
|
+
resolved.push(isNegated ? `!${mapped}` : mapped);
|
|
89
|
+
}
|
|
90
|
+
return resolved;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
59
93
|
export function createCustomModuleResolver(compilerOptions, customCompilerExtensions, toSourceFilePath, findWorkspaceManifestImports, tsConfigFile) {
|
|
60
94
|
const customCompilerExtensionsSet = new Set(customCompilerExtensions);
|
|
61
95
|
const hasCustomExts = customCompilerExtensionsSet.size > 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IMPORT_FLAGS, OPAQUE } from '../../constants.js';
|
|
2
2
|
import { addValue } from '../../util/module-graph.js';
|
|
3
|
-
import { getSafeScriptFromArgs, getStringValue, isStringLiteral } from '../ast-nodes.js';
|
|
3
|
+
import { getSafeScriptFromArgs, getScriptFromArg, getStringValue, isStringLiteral } from '../ast-nodes.js';
|
|
4
4
|
import { isShadowed } from './walk.js';
|
|
5
5
|
function getRegisteredCustomElement(node, s) {
|
|
6
6
|
const callee = node.callee;
|
|
@@ -162,11 +162,9 @@ export function handleCallExpression(node, s) {
|
|
|
162
162
|
if (method) {
|
|
163
163
|
const arg = node.arguments[0];
|
|
164
164
|
if (CHILD_PROCESS_COMMAND_METHODS.has(method)) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
s.scripts.add(command);
|
|
169
|
-
}
|
|
165
|
+
const command = getScriptFromArg(arg);
|
|
166
|
+
if (command)
|
|
167
|
+
s.scripts.add(command);
|
|
170
168
|
return;
|
|
171
169
|
}
|
|
172
170
|
if (CHILD_PROCESS_FILE_METHODS.has(method)) {
|
|
@@ -26,16 +26,16 @@ export function handleVariableDeclarator(node, s) {
|
|
|
26
26
|
: undefined;
|
|
27
27
|
const localName = prop.value?.type === 'Identifier' ? prop.value.name : importedName;
|
|
28
28
|
const alias = localName !== importedName ? localName : undefined;
|
|
29
|
-
s.addImport(specifier, importedName, alias, undefined, prop.key?.start ?? prop.start, IMPORT_FLAGS.
|
|
29
|
+
s.addImport(specifier, importedName, alias, undefined, prop.key?.start ?? prop.start, IMPORT_FLAGS.DYNAMIC);
|
|
30
30
|
}
|
|
31
31
|
else if (prop.type === 'RestElement' && prop.argument?.type === 'Identifier') {
|
|
32
|
-
s.addImport(specifier, IMPORT_STAR, prop.argument.name, undefined, prop.start, IMPORT_FLAGS.
|
|
32
|
+
s.addImport(specifier, IMPORT_STAR, prop.argument.name, undefined, prop.start, IMPORT_FLAGS.DYNAMIC);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
else if (node.id.type === 'Identifier') {
|
|
37
37
|
if (init.type === 'AwaitExpression') {
|
|
38
|
-
s.addImport(specifier, 'default', node.id.name, undefined, importExpr.source.start, IMPORT_FLAGS.
|
|
38
|
+
s.addImport(specifier, 'default', node.id.name, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC);
|
|
39
39
|
const resolved = s.resolveModule(specifier, s.filePath);
|
|
40
40
|
if (resolved && !resolved.isExternalLibraryImport && !isInNodeModules(resolved.resolvedFileName)) {
|
|
41
41
|
s.localImportMap.set(node.id.name, {
|
|
@@ -47,11 +47,11 @@ export function handleVariableDeclarator(node, s) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
|
-
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.OPAQUE);
|
|
50
|
+
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.OPAQUE);
|
|
54
|
+
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE);
|
|
55
55
|
}
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
@@ -117,10 +117,10 @@ export function handleVariableDeclarator(node, s) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
else if (binding?.type === 'Identifier') {
|
|
120
|
-
s.addImport(specifier, 'default', binding.name, undefined, imp.source.start, IMPORT_FLAGS.
|
|
120
|
+
s.addImport(specifier, 'default', binding.name, undefined, imp.source.start, IMPORT_FLAGS.DYNAMIC);
|
|
121
121
|
}
|
|
122
122
|
else {
|
|
123
|
-
s.addImport(specifier, undefined, undefined, undefined, imp.source.start, IMPORT_FLAGS.SIDE_EFFECTS);
|
|
123
|
+
s.addImport(specifier, undefined, undefined, undefined, imp.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.SIDE_EFFECTS);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -257,6 +257,6 @@ export function handleImportExpression(node, s) {
|
|
|
257
257
|
return;
|
|
258
258
|
const specifier = getStringValue(node.source);
|
|
259
259
|
if (specifier) {
|
|
260
|
-
s.addImport(specifier, undefined, undefined, undefined, node.source.start, IMPORT_FLAGS.OPAQUE);
|
|
260
|
+
s.addImport(specifier, undefined, undefined, undefined, node.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { getScriptFromTemplate } from '../ast-nodes.js';
|
|
1
2
|
export function createBunShellVisitor(ctx) {
|
|
2
3
|
return {
|
|
3
4
|
TaggedTemplateExpression(node) {
|
|
4
5
|
const tag = node.tag;
|
|
5
6
|
if (tag.type === 'Identifier' && tag.name === '$') {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
const script = getScriptFromTemplate(node.quasi);
|
|
8
|
+
if (script)
|
|
9
|
+
ctx.addScript(script);
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
};
|
|
@@ -3,7 +3,7 @@ import { FIX_FLAGS, IMPORT_FLAGS, OPAQUE, SYMBOL_TYPE } from '../../constants.js
|
|
|
3
3
|
import { addValue } from '../../util/module-graph.js';
|
|
4
4
|
import { isInNodeModules } from '../../util/path.js';
|
|
5
5
|
import { timerify } from '../../util/Performance.js';
|
|
6
|
-
import { getLineAndCol, getStringValue, isStringLiteral } from '../ast-nodes.js';
|
|
6
|
+
import { collectAugmentationRefs, getLineAndCol, getStringValue, isStringLiteral, } from '../ast-nodes.js';
|
|
7
7
|
import { EMPTY_TAGS } from './jsdoc.js';
|
|
8
8
|
import { handleCallExpression, handleNewExpression, trackCustomElementRegistry } from './calls.js';
|
|
9
9
|
import { handleExportAssignment, handleExportDefault, handleExportNamed, handleExpressionStatement, } from './exports.js';
|
|
@@ -211,6 +211,11 @@ const coreVisitorObject = {
|
|
|
211
211
|
},
|
|
212
212
|
TSModuleDeclaration(node) {
|
|
213
213
|
state.nsRanges.push([node.start, node.end]);
|
|
214
|
+
if (node.kind !== 'global' && isStringLiteral(node.id)) {
|
|
215
|
+
const specifier = getStringValue(node.id);
|
|
216
|
+
for (const name of collectAugmentationRefs(node))
|
|
217
|
+
state.addImport(specifier, name, undefined, undefined, node.id.start, IMPORT_FLAGS.TYPE_ONLY | IMPORT_FLAGS.AUGMENT);
|
|
218
|
+
}
|
|
214
219
|
},
|
|
215
220
|
ClassDeclaration(node) {
|
|
216
221
|
state.classNameStack.push(node.id?.name ?? '');
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -h, --help Print this help text\n -V, --version Print version\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n -c, --config [file] Configuration file path\n (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n --use-tsconfig-files Use tsconfig.json to define project files (override `project` patterns)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n\nMode\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --include-entry-exports Include entry files when reporting unused exports\n --no-gitignore Don't respect .gitignore\n -p, --production Analyze only production source files (e.g. no test files, devDependencies)\n -s, --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -w, --watch Watch mode\n\nScope\n -W, --workspace [filter] Filter workspaces by name, directory, or glob (can be repeated)\n -D, --directory [dir] Run process from a different directory (default: cwd)\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved,catalog\n --exports Shortcut for --include exports,nsExports,types,nsTypes,enumMembers,namespaceMembers,duplicates\n --files Shortcut for --include files\n --tags Include or exclude tagged exports\n\nFix\n -f, --fix Fix issues (modifies files in your repo)\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --allow-remove-files Allow Knip to remove files (with --fix)\n -F, --format Format modified files after --fix using the local formatter\n\nOutput\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter (default: symbols), can be repeated (3)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-tag-hints Suppress tag hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --treat-tag-hints-as-errors Exit with non-zero code (1) if there are any tag hints\n --max-issues Maximum number of total issues before non-zero exit code (default: 0)\n --max-show-issues Maximum number of issues to display per type\n --no-exit-code Always exit with code zero (0)\n\nTroubleshooting\n -d, --debug Show debug output\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n --performance Measure count and running time of key functions and display stats table\n --performance-fn [name] Measure only function [name]\n -u, --duration Print total running time (zero overhead, no instrumentation)\n --trace Show trace output\n --trace-dependency [name] Show files that import the named dependency\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, types, nsTypes, enumMembers, namespaceMembers, duplicates, catalog\n(2) Fixable issue types: dependencies, exports, types, files, catalog\n(3) Built-in reporters: symbols (default), compact, codeowners, json, codeclimate, markdown, disclosure, github-actions\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip --workspace @myorg/* --workspace '!@myorg/legacy'\n$ knip --workspace './apps/*' --workspace '@shared/utils'\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
|
|
1
|
+
export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -h, --help Print this help text\n -V, --version Print version\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n -c, --config [file] Configuration file path\n (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n --use-tsconfig-files Use tsconfig.json to define project files (override `project` patterns)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n\nMode\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --include-entry-exports Include entry files when reporting unused exports\n --no-gitignore Don't respect .gitignore\n -p, --production Analyze only production source files (e.g. no test files, devDependencies)\n -s, --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -w, --watch Watch mode\n\nScope\n -W, --workspace [filter] Filter workspaces by name, directory, or glob (can be repeated)\n -D, --directory [dir] Run process from a different directory (default: cwd)\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved,catalog\n --exports Shortcut for --include exports,nsExports,types,nsTypes,enumMembers,namespaceMembers,duplicates\n --files Shortcut for --include files\n --cycles Shortcut for --include cycles (circular dependencies)\n --tags Include or exclude tagged exports\n\nFix\n -f, --fix Fix issues (modifies files in your repo)\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --allow-remove-files Allow Knip to remove files (with --fix)\n -F, --format Format modified files after --fix using the local formatter\n\nOutput\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter (default: symbols), can be repeated (3)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-tag-hints Suppress tag hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --treat-tag-hints-as-errors Exit with non-zero code (1) if there are any tag hints\n --max-issues Maximum number of total issues before non-zero exit code (default: 0)\n --max-show-issues Maximum number of issues to display per type\n --no-exit-code Always exit with code zero (0)\n\nTroubleshooting\n -d, --debug Show debug output\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n --performance Measure count and running time of key functions and display stats table\n --performance-fn [name] Measure only function [name]\n -u, --duration Print total running time (zero overhead, no instrumentation)\n --trace Show trace output\n --trace-dependency [name] Show files that import the named dependency\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, types, nsTypes, enumMembers, namespaceMembers, duplicates, catalog, cycles\n(2) Fixable issue types: dependencies, exports, types, files, catalog\n(3) Built-in reporters: symbols (default), compact, codeowners, cycles, json, codeclimate, markdown, disclosure, github-actions\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip --workspace @myorg/* --workspace '!@myorg/legacy'\n$ knip --workspace './apps/*' --workspace '@shared/utils'\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
|
|
2
2
|
export type ParsedCLIArgs = ReturnType<typeof parseCLIArgs>;
|
|
3
3
|
export default function parseCLIArgs(): {
|
|
4
4
|
cache?: boolean | undefined;
|
|
5
5
|
'cache-location'?: string | undefined;
|
|
6
6
|
config?: string | undefined;
|
|
7
|
+
cycles?: boolean | undefined;
|
|
7
8
|
debug?: boolean | undefined;
|
|
8
9
|
dependencies?: boolean | undefined;
|
|
9
10
|
directory?: string | undefined;
|
|
@@ -29,6 +29,7 @@ Scope
|
|
|
29
29
|
--dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved,catalog
|
|
30
30
|
--exports Shortcut for --include exports,nsExports,types,nsTypes,enumMembers,namespaceMembers,duplicates
|
|
31
31
|
--files Shortcut for --include files
|
|
32
|
+
--cycles Shortcut for --include cycles (circular dependencies)
|
|
32
33
|
--tags Include or exclude tagged exports
|
|
33
34
|
|
|
34
35
|
Fix
|
|
@@ -62,9 +63,9 @@ Troubleshooting
|
|
|
62
63
|
--trace-export [name] Show trace output for named export(s)
|
|
63
64
|
--trace-file [file] Show trace output for exports in file
|
|
64
65
|
|
|
65
|
-
(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, types, nsTypes, enumMembers, namespaceMembers, duplicates, catalog
|
|
66
|
+
(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, types, nsTypes, enumMembers, namespaceMembers, duplicates, catalog, cycles
|
|
66
67
|
(2) Fixable issue types: dependencies, exports, types, files, catalog
|
|
67
|
-
(3) Built-in reporters: symbols (default), compact, codeowners, json, codeclimate, markdown, disclosure, github-actions
|
|
68
|
+
(3) Built-in reporters: symbols (default), compact, codeowners, cycles, json, codeclimate, markdown, disclosure, github-actions
|
|
68
69
|
|
|
69
70
|
Examples:
|
|
70
71
|
|
|
@@ -84,6 +85,7 @@ export default function parseCLIArgs() {
|
|
|
84
85
|
cache: { type: 'boolean' },
|
|
85
86
|
'cache-location': { type: 'string' },
|
|
86
87
|
config: { type: 'string', short: 'c' },
|
|
88
|
+
cycles: { type: 'boolean' },
|
|
87
89
|
debug: { type: 'boolean', short: 'd' },
|
|
88
90
|
dependencies: { type: 'boolean' },
|
|
89
91
|
directory: { type: 'string', short: 'D' },
|
|
@@ -9,6 +9,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
9
9
|
config: string | undefined;
|
|
10
10
|
configFilePath: string | undefined;
|
|
11
11
|
cwd: string;
|
|
12
|
+
cycles: boolean;
|
|
12
13
|
dependencies: boolean;
|
|
13
14
|
exports: boolean;
|
|
14
15
|
files: boolean;
|
|
@@ -30,6 +31,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
30
31
|
isProduction: boolean;
|
|
31
32
|
isReportDependencies: boolean;
|
|
32
33
|
isReportExports: boolean;
|
|
34
|
+
isReportCycles: boolean;
|
|
33
35
|
isReportFiles: boolean;
|
|
34
36
|
isReportTypes: boolean;
|
|
35
37
|
isReportValues: boolean;
|
|
@@ -193,6 +195,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
193
195
|
entry?: string | string[] | undefined;
|
|
194
196
|
project?: string | string[] | undefined;
|
|
195
197
|
} | undefined;
|
|
198
|
+
eve?: string | boolean | string[] | {
|
|
199
|
+
config?: string | string[] | undefined;
|
|
200
|
+
entry?: string | string[] | undefined;
|
|
201
|
+
project?: string | string[] | undefined;
|
|
202
|
+
} | undefined;
|
|
196
203
|
execa?: string | boolean | string[] | {
|
|
197
204
|
config?: string | string[] | undefined;
|
|
198
205
|
entry?: string | string[] | undefined;
|
|
@@ -213,6 +220,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
213
220
|
entry?: string | string[] | undefined;
|
|
214
221
|
project?: string | string[] | undefined;
|
|
215
222
|
} | undefined;
|
|
223
|
+
fumadocs?: string | boolean | string[] | {
|
|
224
|
+
config?: string | string[] | undefined;
|
|
225
|
+
entry?: string | string[] | undefined;
|
|
226
|
+
project?: string | string[] | undefined;
|
|
227
|
+
} | undefined;
|
|
216
228
|
gatsby?: string | boolean | string[] | {
|
|
217
229
|
config?: string | string[] | undefined;
|
|
218
230
|
entry?: string | string[] | undefined;
|
|
@@ -829,7 +841,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
829
841
|
project?: string | string[] | undefined;
|
|
830
842
|
} | undefined;
|
|
831
843
|
$schema?: string | undefined;
|
|
832
|
-
rules?: Partial<Record<"binaries" | "catalog" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved", "error" | "off" | "warn">> | undefined;
|
|
844
|
+
rules?: Partial<Record<"binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved", "error" | "off" | "warn">> | undefined;
|
|
833
845
|
entry?: string | string[] | undefined;
|
|
834
846
|
project?: string | string[] | undefined;
|
|
835
847
|
paths?: Record<string, string[]> | undefined;
|
|
@@ -840,7 +852,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
840
852
|
ignoreMembers?: (string | RegExp)[] | undefined;
|
|
841
853
|
ignoreUnresolved?: (string | RegExp)[] | undefined;
|
|
842
854
|
ignoreExportsUsedInFile?: boolean | Record<string, boolean | undefined> | undefined;
|
|
843
|
-
ignoreIssues?: Record<string, ("binaries" | "catalog" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
|
|
855
|
+
ignoreIssues?: Record<string, ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
|
|
856
|
+
cycles?: {
|
|
857
|
+
allow?: string[][] | undefined;
|
|
858
|
+
dynamicImports?: boolean | undefined;
|
|
859
|
+
} | undefined;
|
|
844
860
|
ignoreWorkspaces?: string[] | undefined;
|
|
845
861
|
includeEntryExports?: boolean | undefined;
|
|
846
862
|
compilers?: Record<string, true | import("../compilers/types.ts").CompilerAsync | import("../compilers/types.ts").CompilerSync> | undefined;
|
|
@@ -849,8 +865,8 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
849
865
|
tags?: string[] | undefined;
|
|
850
866
|
treatConfigHintsAsErrors?: boolean | undefined;
|
|
851
867
|
treatTagHintsAsErrors?: boolean | undefined;
|
|
852
|
-
include?: ("binaries" | "catalog" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
|
|
853
|
-
exclude?: ("binaries" | "catalog" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
|
|
868
|
+
include?: ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
|
|
869
|
+
exclude?: ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
|
|
854
870
|
workspaces?: Record<string, {
|
|
855
871
|
angular?: string | boolean | string[] | {
|
|
856
872
|
config?: string | string[] | undefined;
|
|
@@ -1002,6 +1018,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1002
1018
|
entry?: string | string[] | undefined;
|
|
1003
1019
|
project?: string | string[] | undefined;
|
|
1004
1020
|
} | undefined;
|
|
1021
|
+
eve?: string | boolean | string[] | {
|
|
1022
|
+
config?: string | string[] | undefined;
|
|
1023
|
+
entry?: string | string[] | undefined;
|
|
1024
|
+
project?: string | string[] | undefined;
|
|
1025
|
+
} | undefined;
|
|
1005
1026
|
execa?: string | boolean | string[] | {
|
|
1006
1027
|
config?: string | string[] | undefined;
|
|
1007
1028
|
entry?: string | string[] | undefined;
|
|
@@ -1022,6 +1043,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1022
1043
|
entry?: string | string[] | undefined;
|
|
1023
1044
|
project?: string | string[] | undefined;
|
|
1024
1045
|
} | undefined;
|
|
1046
|
+
fumadocs?: string | boolean | string[] | {
|
|
1047
|
+
config?: string | string[] | undefined;
|
|
1048
|
+
entry?: string | string[] | undefined;
|
|
1049
|
+
project?: string | string[] | undefined;
|
|
1050
|
+
} | undefined;
|
|
1025
1051
|
gatsby?: string | boolean | string[] | {
|
|
1026
1052
|
config?: string | string[] | undefined;
|
|
1027
1053
|
entry?: string | string[] | undefined;
|
|
@@ -1647,13 +1673,14 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1647
1673
|
ignoreMembers?: (string | RegExp)[] | undefined;
|
|
1648
1674
|
ignoreUnresolved?: (string | RegExp)[] | undefined;
|
|
1649
1675
|
ignoreExportsUsedInFile?: boolean | Record<string, boolean | undefined> | undefined;
|
|
1650
|
-
ignoreIssues?: Record<string, ("binaries" | "catalog" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
|
|
1676
|
+
ignoreIssues?: Record<string, ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
|
|
1651
1677
|
includeEntryExports?: boolean | undefined;
|
|
1652
1678
|
}> | undefined;
|
|
1653
1679
|
};
|
|
1654
1680
|
rules: {
|
|
1655
1681
|
binaries: import("../types/issues.ts").IssueSeverity;
|
|
1656
1682
|
catalog: import("../types/issues.ts").IssueSeverity;
|
|
1683
|
+
cycles: import("../types/issues.ts").IssueSeverity;
|
|
1657
1684
|
dependencies: import("../types/issues.ts").IssueSeverity;
|
|
1658
1685
|
devDependencies: import("../types/issues.ts").IssueSeverity;
|
|
1659
1686
|
duplicates: import("../types/issues.ts").IssueSeverity;
|
|
@@ -4,7 +4,7 @@ import { knipConfigurationSchema } from '../schema/configuration.js';
|
|
|
4
4
|
import { getCatalogContainer } from './catalog.js';
|
|
5
5
|
import { ConfigurationError } from './errors.js';
|
|
6
6
|
import { findFile, loadJSON } from './fs.js';
|
|
7
|
-
import { getIncludedIssueTypes, shorthandDeps, shorthandExports, shorthandFiles } from './get-included-issue-types.js';
|
|
7
|
+
import { getIncludedIssueTypes, shorthandCycles, shorthandDeps, shorthandExports, shorthandFiles, } from './get-included-issue-types.js';
|
|
8
8
|
import { defaultRules } from './issue-initializers.js';
|
|
9
9
|
import { loadResolvedConfigFile } from './load-config.js';
|
|
10
10
|
import { _load } from './loader.js';
|
|
@@ -82,6 +82,7 @@ export const createOptions = async (options) => {
|
|
|
82
82
|
...(args.dependencies ? shorthandDeps : []),
|
|
83
83
|
...(args.exports ? shorthandExports : []),
|
|
84
84
|
...(args.files ? shorthandFiles : []),
|
|
85
|
+
...(args.cycles ? shorthandCycles : []),
|
|
85
86
|
],
|
|
86
87
|
});
|
|
87
88
|
for (const [key, value] of Object.entries(includedIssueTypes)) {
|
|
@@ -98,6 +99,7 @@ export const createOptions = async (options) => {
|
|
|
98
99
|
config: args.config,
|
|
99
100
|
configFilePath,
|
|
100
101
|
cwd,
|
|
102
|
+
cycles: args.cycles ?? false,
|
|
101
103
|
dependencies: args.dependencies ?? false,
|
|
102
104
|
exports: args.exports ?? false,
|
|
103
105
|
files: args.files ?? false,
|
|
@@ -128,6 +130,7 @@ export const createOptions = async (options) => {
|
|
|
128
130
|
includedIssueTypes.enumMembers ||
|
|
129
131
|
includedIssueTypes.namespaceMembers ||
|
|
130
132
|
includedIssueTypes.duplicates,
|
|
133
|
+
isReportCycles: includedIssueTypes.cycles,
|
|
131
134
|
isReportFiles: includedIssueTypes.files,
|
|
132
135
|
isReportTypes: includedIssueTypes.types ||
|
|
133
136
|
includedIssueTypes.nsTypes ||
|
|
@@ -10,5 +10,6 @@ export declare const defaultExcludedIssueTypes: string[];
|
|
|
10
10
|
export declare const shorthandDeps: string[];
|
|
11
11
|
export declare const shorthandExports: string[];
|
|
12
12
|
export declare const shorthandFiles: string[];
|
|
13
|
+
export declare const shorthandCycles: string[];
|
|
13
14
|
export declare const getIncludedIssueTypes: (options: GetIncludedIssueTypesOptions) => Report;
|
|
14
15
|
export {};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ISSUE_TYPES } from '../constants.js';
|
|
2
2
|
import { ConfigurationError } from './errors.js';
|
|
3
|
-
export const defaultExcludedIssueTypes = ['nsExports', 'nsTypes'];
|
|
3
|
+
export const defaultExcludedIssueTypes = ['nsExports', 'nsTypes', 'cycles'];
|
|
4
|
+
const defaultAddOnIssueTypes = ['nsExports', 'nsTypes'];
|
|
4
5
|
const defaultIssueTypes = ISSUE_TYPES.filter(type => !defaultExcludedIssueTypes.includes(type));
|
|
5
6
|
const normalize = (values) => values.flatMap(value => value.split(','));
|
|
6
7
|
export const shorthandDeps = ['dependencies', 'unlisted', 'binaries', 'unresolved', 'catalog'];
|
|
7
8
|
export const shorthandExports = ['exports', 'types', 'enumMembers', 'namespaceMembers', 'duplicates'];
|
|
8
9
|
export const shorthandFiles = ['files'];
|
|
10
|
+
export const shorthandCycles = ['cycles'];
|
|
9
11
|
export const getIncludedIssueTypes = (options) => {
|
|
10
12
|
const incl = normalize(options.includeOverrides ?? []);
|
|
11
13
|
const excl = normalize(options.excludeOverrides ?? []);
|
|
@@ -28,7 +30,7 @@ export const getIncludedIssueTypes = (options) => {
|
|
|
28
30
|
_exclude.push('devDependencies', 'optionalPeerDependencies');
|
|
29
31
|
}
|
|
30
32
|
const included = (_include.length > 0
|
|
31
|
-
? _include.some(type => !
|
|
33
|
+
? _include.some(type => !defaultAddOnIssueTypes.includes(type))
|
|
32
34
|
? _include
|
|
33
35
|
: [..._include, ...defaultIssueTypes]
|
|
34
36
|
: defaultIssueTypes).filter(group => !_exclude.includes(group));
|
|
@@ -5,4 +5,4 @@ export const initCounters = () => ({
|
|
|
5
5
|
processed: 0,
|
|
6
6
|
total: 0,
|
|
7
7
|
});
|
|
8
|
-
export const defaultRules = Object.fromEntries(ISSUE_TYPES.map(issueType => [issueType, 'error']));
|
|
8
|
+
export const defaultRules = Object.fromEntries(ISSUE_TYPES.map(issueType => [issueType, issueType === 'cycles' ? 'warn' : 'error']));
|
|
@@ -2,7 +2,7 @@ import { parseTsconfig } from 'get-tsconfig';
|
|
|
2
2
|
import { compact } from './array.js';
|
|
3
3
|
import { isFile } from './fs.js';
|
|
4
4
|
import { _syncGlob } from './glob.js';
|
|
5
|
-
import { dirname, isAbsolute, join, toAbsolute } from './path.js';
|
|
5
|
+
import { dirname, isAbsolute, join, toAbsolute, toPosix } from './path.js';
|
|
6
6
|
const hasGlobChar = (p) => p.includes('*') || p.includes('?');
|
|
7
7
|
const hasExtension = (p) => {
|
|
8
8
|
const last = p.lastIndexOf('/');
|
|
@@ -17,7 +17,20 @@ const resolvePatterns = (patterns, dir, expandDirs = false) => {
|
|
|
17
17
|
return expandDirs && !hasGlobChar(p) && !hasExtension(p) ? join(resolved, '**/*') : resolved;
|
|
18
18
|
});
|
|
19
19
|
};
|
|
20
|
-
const
|
|
20
|
+
const getImplicitBaseUrl = (compilerOptions) => {
|
|
21
|
+
for (const symbol of Object.getOwnPropertySymbols(compilerOptions)) {
|
|
22
|
+
if (symbol.description === 'implicitBaseUrl') {
|
|
23
|
+
const value = Reflect.get(compilerOptions, symbol);
|
|
24
|
+
if (typeof value === 'string')
|
|
25
|
+
return toPosix(value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const pathsBaseDir = (compilerOptions, dir) => {
|
|
30
|
+
if (compilerOptions?.baseUrl)
|
|
31
|
+
return toAbsolute(compilerOptions.baseUrl, dir);
|
|
32
|
+
return (compilerOptions && getImplicitBaseUrl(compilerOptions)) ?? dir;
|
|
33
|
+
};
|
|
21
34
|
const collectPaths = (acc, paths, baseDir) => {
|
|
22
35
|
if (!paths)
|
|
23
36
|
return;
|
|
@@ -74,7 +87,7 @@ const walkReferences = (target, references, dir, visited, pairs, paths) => {
|
|
|
74
87
|
const refConfig = parseTsconfig(refPath);
|
|
75
88
|
const refDir = dirname(refPath);
|
|
76
89
|
const refOpts = refConfig.compilerOptions;
|
|
77
|
-
collectPaths(paths, refOpts?.paths, pathsBaseDir(refOpts
|
|
90
|
+
collectPaths(paths, refOpts?.paths, pathsBaseDir(refOpts, refDir));
|
|
78
91
|
const refOutDir = refOpts?.outDir ? absDir(refOpts.outDir, refDir) : undefined;
|
|
79
92
|
const refRootDir = refOpts?.rootDir ? absDir(refOpts.rootDir, refDir) : undefined;
|
|
80
93
|
if (refOutDir && refRootDir && refOutDir !== refRootDir)
|
|
@@ -109,7 +122,7 @@ export const loadTSConfig = async (tsConfigFilePath) => {
|
|
|
109
122
|
if (compilerOptions.rootDirs)
|
|
110
123
|
compilerOptions.rootDirs = compilerOptions.rootDirs.map(d => absDir(d, dir));
|
|
111
124
|
const tsconfigPaths = {};
|
|
112
|
-
collectPaths(tsconfigPaths, compilerOptions.paths, pathsBaseDir(compilerOptions
|
|
125
|
+
collectPaths(tsconfigPaths, compilerOptions.paths, pathsBaseDir(compilerOptions, dir));
|
|
113
126
|
const sourceMapPairs = [];
|
|
114
127
|
if (config.references?.length) {
|
|
115
128
|
walkReferences(compilerOptions, config.references, dir, new Set([tsConfigFilePath]), sourceMapPairs, tsconfigPaths);
|
package/dist/util/modules.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import { DT_SCOPE, PROTOCOL_VIRTUAL } from '../constants.js';
|
|
2
|
-
import { isAbsolute, isInNodeModules, toPosix } from './path.js';
|
|
3
|
+
import { isAbsolute, isInNodeModules, join, toPosix } from './path.js';
|
|
3
4
|
export const getPackageNameFromModuleSpecifier = (specifier) => {
|
|
4
5
|
if (!isStartsLikePackageName(specifier))
|
|
5
6
|
return;
|
|
@@ -18,13 +19,33 @@ export const getPackageNameFromModuleSpecifier = (specifier) => {
|
|
|
18
19
|
return specifier;
|
|
19
20
|
};
|
|
20
21
|
const lastPackageNameMatch = /(?<=node_modules\/)(@[^/]+\/[^/]+|[^/]+)/g;
|
|
22
|
+
const yarnPnpmStorePackageRoot = /^(.*\/node_modules\/\.store\/[^/]+\/package)(?:\/|$)/;
|
|
23
|
+
const yarnPnpmStoreNameCache = new Map();
|
|
24
|
+
const getPackageNameFromYarnPnpmStore = (posixPath) => {
|
|
25
|
+
const match = posixPath.match(yarnPnpmStorePackageRoot);
|
|
26
|
+
if (!match)
|
|
27
|
+
return;
|
|
28
|
+
const root = match[1];
|
|
29
|
+
if (yarnPnpmStoreNameCache.has(root))
|
|
30
|
+
return yarnPnpmStoreNameCache.get(root);
|
|
31
|
+
let name;
|
|
32
|
+
try {
|
|
33
|
+
name = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).name;
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
yarnPnpmStoreNameCache.set(root, name);
|
|
37
|
+
return name;
|
|
38
|
+
};
|
|
21
39
|
export const getPackageNameFromFilePath = (value) => {
|
|
22
40
|
const name = value.startsWith('file://') ? value.slice(7) : value;
|
|
23
41
|
if (name.includes('node_modules/.bin/'))
|
|
24
42
|
return extractBinary(name);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
const posixPath = toPosix(name);
|
|
44
|
+
const match = posixPath.match(lastPackageNameMatch);
|
|
45
|
+
if (match) {
|
|
46
|
+
const last = match[match.length - 1];
|
|
47
|
+
return last === '.store' ? (getPackageNameFromYarnPnpmStore(posixPath) ?? last) : last;
|
|
48
|
+
}
|
|
28
49
|
return name;
|
|
29
50
|
};
|
|
30
51
|
export const getPackageNameFromSpecifier = (specifier) => isInNodeModules(specifier) ? getPackageNameFromFilePath(specifier) : getPackageNameFromModuleSpecifier(specifier);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Command, type Node } from 'unbash';
|
|
2
|
+
export interface ScriptCommand {
|
|
3
|
+
binary: string;
|
|
4
|
+
args: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function walkCommands(node: Node): Generator<Command>;
|
|
7
|
+
export declare const getScriptCommands: (script: string) => ScriptCommand[];
|