knip 6.43.0 → 6.44.1
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/README.md +2 -4
- package/dist/CacheConsultant.d.ts +1 -0
- package/dist/CacheConsultant.js +2 -0
- package/dist/CatalogCounselor.d.ts +1 -3
- package/dist/CatalogCounselor.js +18 -15
- package/dist/ConfigurationChief.d.ts +24 -0
- package/dist/DependencyDeputy.d.ts +2 -1
- package/dist/DependencyDeputy.js +11 -6
- package/dist/IssueCollector.js +1 -0
- package/dist/ProjectPrincipal.d.ts +4 -2
- package/dist/ProjectPrincipal.js +32 -10
- package/dist/WorkspaceWorker.d.ts +5 -2
- package/dist/WorkspaceWorker.js +20 -7
- package/dist/binaries/resolvers/bun.js +7 -2
- package/dist/binaries/util.js +2 -1
- package/dist/cli.js +6 -1
- package/dist/compilers/index.d.ts +5 -0
- package/dist/compilers/index.js +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/graph/analyze.js +3 -2
- package/dist/graph/build.d.ts +2 -0
- package/dist/graph/build.js +37 -22
- package/dist/graph-explorer/cache.d.ts +2 -1
- package/dist/graph-explorer/cache.js +5 -1
- package/dist/graph-explorer/explorer.d.ts +3 -5
- package/dist/graph-explorer/explorer.js +24 -3
- package/dist/plugins/babel/index.js +6 -1
- package/dist/plugins/biome/index.js +1 -1
- package/dist/plugins/cspell/index.js +10 -2
- package/dist/plugins/dependency-cruiser/index.js +2 -2
- package/dist/plugins/docusaurus/helpers.js +4 -4
- package/dist/plugins/electron-vite/index.js +2 -2
- package/dist/plugins/eleventy/index.js +2 -2
- package/dist/plugins/expressive-code/index.d.ts +1 -1
- package/dist/plugins/expressive-code/index.js +2 -2
- package/dist/plugins/gatsby/index.js +6 -6
- package/dist/plugins/gatsby/types.d.ts +1 -1
- package/dist/plugins/github-actions/index.js +1 -1
- package/dist/plugins/i18next-parser/index.js +2 -2
- package/dist/plugins/index.d.ts +5 -1
- package/dist/plugins/index.js +8 -0
- package/dist/plugins/jasmine/index.js +2 -2
- package/dist/plugins/karma/index.js +4 -4
- package/dist/plugins/kysely-codegen/index.d.ts +3 -0
- package/dist/plugins/kysely-codegen/index.js +20 -0
- package/dist/plugins/lefthook/index.js +2 -2
- package/dist/plugins/lingui/index.d.ts +3 -0
- package/dist/plugins/lingui/index.js +16 -0
- package/dist/plugins/lockfile-lint/index.js +2 -2
- package/dist/plugins/lost-pixel/index.js +2 -2
- package/dist/plugins/lunaria/index.js +2 -2
- package/dist/plugins/marko/index.js +5 -6
- package/dist/plugins/mastra/index.d.ts +3 -0
- package/dist/plugins/mastra/index.js +57 -0
- package/dist/plugins/mcp/index.js +1 -1
- package/dist/plugins/mise/index.js +0 -3
- package/dist/plugins/mocha/index.js +43 -4
- package/dist/plugins/mocha/types.d.ts +1 -0
- package/dist/plugins/npm-package-json-lint/index.js +1 -1
- package/dist/plugins/npm-package-json-lint/types.d.ts +1 -1
- package/dist/plugins/nx/index.js +3 -8
- package/dist/plugins/nyc/index.js +1 -1
- package/dist/plugins/openapi-ts/index.js +2 -2
- package/dist/plugins/oxfmt/index.js +2 -2
- package/dist/plugins/playwright/index.js +6 -11
- package/dist/plugins/pnpm/index.js +2 -4
- package/dist/plugins/purgecss/index.d.ts +3 -0
- package/dist/plugins/purgecss/index.js +16 -0
- package/dist/plugins/railway/index.js +1 -4
- package/dist/plugins/relay/index.js +1 -1
- package/dist/plugins/release-it/index.js +1 -1
- package/dist/plugins/remix/index.js +1 -1
- package/dist/plugins/rsbuild/index.js +29 -1
- package/dist/plugins/rsbuild/types.d.ts +8 -0
- package/dist/plugins/rstest/index.js +2 -2
- package/dist/plugins/serverless-framework/index.js +1 -1
- package/dist/plugins/storybook/index.js +5 -5
- package/dist/plugins/sveltekit/resolveFromAST.js +1 -1
- package/dist/plugins/svgr/index.js +2 -1
- package/dist/plugins/swc/index.js +8 -3
- package/dist/plugins/syncpack/index.js +2 -2
- package/dist/plugins/tanstack-router/index.js +3 -2
- package/dist/plugins/taskfile/index.js +4 -7
- package/dist/plugins/textlint/helpers.js +2 -2
- package/dist/plugins/typescript/index.js +7 -3
- package/dist/plugins/unocss/index.js +2 -2
- package/dist/plugins/vite-plugin-pwa/index.js +1 -4
- package/dist/plugins/vite-plugin-pwa/resolveFromAST.d.ts +0 -2
- package/dist/plugins/vite-plugin-pwa/resolveFromAST.js +2 -2
- package/dist/plugins/vite-pwa-assets-generator/index.js +2 -2
- package/dist/plugins/vitest/helpers.js +4 -7
- package/dist/plugins/vitest/index.js +1 -1
- package/dist/plugins/webpack/index.d.ts +2 -0
- package/dist/plugins/webpack/index.js +11 -6
- package/dist/plugins/yarn/index.js +2 -4
- package/dist/reporters/codeclimate.d.ts +2 -2
- package/dist/reporters/codeclimate.js +2 -4
- package/dist/reporters/codeowners.d.ts +2 -2
- package/dist/reporters/codeowners.js +9 -9
- package/dist/reporters/compact.d.ts +2 -2
- package/dist/reporters/compact.js +8 -7
- package/dist/reporters/cycles.d.ts +2 -2
- package/dist/reporters/cycles.js +7 -6
- package/dist/reporters/disclosure.d.ts +2 -2
- package/dist/reporters/disclosure.js +6 -4
- package/dist/reporters/github-actions.d.ts +2 -2
- package/dist/reporters/github-actions.js +7 -5
- package/dist/reporters/index.d.ts +10 -10
- package/dist/reporters/json.d.ts +2 -2
- package/dist/reporters/json.js +2 -4
- package/dist/reporters/markdown.d.ts +2 -2
- package/dist/reporters/markdown.js +11 -9
- package/dist/reporters/sarif.d.ts +2 -2
- package/dist/reporters/sarif.js +2 -3
- package/dist/reporters/symbols.d.ts +2 -2
- package/dist/reporters/symbols.js +6 -4
- package/dist/run.d.ts +1 -1
- package/dist/run.js +3 -10
- package/dist/schema/configuration.d.ts +60 -0
- package/dist/schema/plugins.d.ts +20 -0
- package/dist/schema/plugins.js +4 -0
- package/dist/session/configuration.d.ts +15 -0
- package/dist/session/configuration.js +62 -0
- package/dist/session/incremental.d.ts +54 -0
- package/dist/session/incremental.js +49 -0
- package/dist/session/session.d.ts +1 -1
- package/dist/session/session.js +63 -27
- package/dist/session/watch.d.ts +2 -0
- package/dist/session/watch.js +41 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +4 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/issues.d.ts +4 -0
- package/dist/types/package-json.d.ts +0 -3
- package/dist/typescript/get-imports-and-exports.js +2 -0
- package/dist/typescript/visitors/calls.js +15 -11
- package/dist/typescript/visitors/imports.d.ts +3 -1
- package/dist/typescript/visitors/imports.js +77 -53
- package/dist/typescript/visitors/members.js +23 -26
- package/dist/typescript/visitors/walk.d.ts +3 -0
- package/dist/typescript/visitors/walk.js +43 -2
- package/dist/util/cli-arguments.d.ts +2 -1
- package/dist/util/cli-arguments.js +3 -0
- package/dist/util/create-input-handler.js +1 -1
- package/dist/util/create-options.d.ts +43 -2
- package/dist/util/create-options.js +17 -4
- package/dist/util/file-entry-cache.d.ts +2 -0
- package/dist/util/file-entry-cache.js +19 -1
- package/dist/util/gitignore-cache.d.ts +1 -0
- package/dist/util/gitignore-cache.js +1 -0
- package/dist/util/glob-core.js +4 -2
- package/dist/util/glob.d.ts +1 -0
- package/dist/util/glob.js +6 -0
- package/dist/util/input.d.ts +2 -0
- package/dist/util/loader.d.ts +1 -0
- package/dist/util/loader.js +29 -1
- package/dist/util/modules.js +5 -2
- package/dist/util/path.d.ts +1 -0
- package/dist/util/path.js +1 -0
- package/dist/util/reporter.d.ts +1 -1
- package/dist/util/reporter.js +53 -9
- package/dist/util/watch.d.ts +5 -11
- package/dist/util/watch.js +84 -68
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schema.json +16 -0
|
@@ -2,6 +2,7 @@ import { OPAQUE } from '../../constants.js';
|
|
|
2
2
|
import { addValue } from '../../util/module-graph.js';
|
|
3
3
|
import { getStringValue, isStringLiteral } from '../ast-nodes.js';
|
|
4
4
|
import { isShadowed } from './walk.js';
|
|
5
|
+
const chainNames = [];
|
|
5
6
|
function markWholeObjectRead(internalImport, id) {
|
|
6
7
|
(internalImport.enumerated ??= new Set()).add(id);
|
|
7
8
|
}
|
|
@@ -9,7 +10,10 @@ function isNumericKey(value) {
|
|
|
9
10
|
return value != null && Number.isFinite(Number(value)) && String(Number(value)) === value;
|
|
10
11
|
}
|
|
11
12
|
export function handleMemberExpression(node, s) {
|
|
12
|
-
if (node.object.type === 'MemberExpression' &&
|
|
13
|
+
if (node.object.type === 'MemberExpression' &&
|
|
14
|
+
node.object.object.type === 'MemberExpression' &&
|
|
15
|
+
!node.computed &&
|
|
16
|
+
node.property.type === 'Identifier') {
|
|
13
17
|
s.chainedMemberExprs.add(node.object);
|
|
14
18
|
}
|
|
15
19
|
if (node.object.type === 'Identifier') {
|
|
@@ -143,34 +147,27 @@ export function handleMemberExpression(node, s) {
|
|
|
143
147
|
}
|
|
144
148
|
}
|
|
145
149
|
if (node.object.type === 'MemberExpression' &&
|
|
146
|
-
!node.object.computed &&
|
|
147
150
|
node.object.object.type === 'MemberExpression' &&
|
|
148
|
-
!
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (!isShadowed(
|
|
156
|
-
const _import = s.localImportMap.get(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
151
|
+
!s.chainedMemberExprs.has(node)) {
|
|
152
|
+
chainNames.length = 0;
|
|
153
|
+
let root = node;
|
|
154
|
+
while (root.type === 'MemberExpression' && !root.computed && root.property.type === 'Identifier') {
|
|
155
|
+
chainNames.push(root.property.name);
|
|
156
|
+
root = root.object;
|
|
157
|
+
}
|
|
158
|
+
if (root.type === 'Identifier' && !isShadowed(root.name, root.start)) {
|
|
159
|
+
const _import = s.localImportMap.get(root.name);
|
|
160
|
+
const internalImport = _import && s.internal.get(_import.filePath);
|
|
161
|
+
if (internalImport || !_import) {
|
|
162
|
+
let path = '';
|
|
163
|
+
for (let i = chainNames.length - 1; i >= 0; i--) {
|
|
164
|
+
path = path ? `${path}.${chainNames[i]}` : chainNames[i];
|
|
165
|
+
if (internalImport)
|
|
166
|
+
s.addNsMemberRefs(internalImport, root.name, path);
|
|
167
|
+
else
|
|
168
|
+
s.memberRefsInFile.push(root.name, path);
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
|
-
else {
|
|
169
|
-
const a = node.object.object.property.name;
|
|
170
|
-
const b = node.object.property.name;
|
|
171
|
-
const c = node.property.name;
|
|
172
|
-
s.memberRefsInFile.push(rootName, a, rootName, `${a}.${b}`, rootName, `${a}.${b}.${c}`);
|
|
173
|
-
}
|
|
174
171
|
}
|
|
175
172
|
}
|
|
176
173
|
if (node.object.type === 'MemberExpression' &&
|
|
@@ -44,6 +44,7 @@ interface WalkContext {
|
|
|
44
44
|
programFiles: Set<string>;
|
|
45
45
|
entryFiles: Set<string>;
|
|
46
46
|
handledImportExpressions: Set<number>;
|
|
47
|
+
caughtImportExpressions: Set<number>;
|
|
47
48
|
visitor: Visitor;
|
|
48
49
|
getJSDocTags: (nodeStart: number) => Set<string>;
|
|
49
50
|
}
|
|
@@ -53,6 +54,8 @@ export interface WalkState extends WalkContext {
|
|
|
53
54
|
isJS: boolean;
|
|
54
55
|
isModuleFile: boolean;
|
|
55
56
|
handledImportExpressions: Set<number>;
|
|
57
|
+
caughtTryBlockEnds: number[];
|
|
58
|
+
functionCaughtTryBlockEnds: number[][];
|
|
56
59
|
bareExprRefs: Set<string>;
|
|
57
60
|
accessedAliases: Set<string>;
|
|
58
61
|
nsContainers: Map<string, Map<string, string>>;
|
|
@@ -7,7 +7,7 @@ import { collectAugmentationRefs, getLineAndCol, getStringValue, isStringLiteral
|
|
|
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';
|
|
10
|
-
import { handleImportExpression, handleVariableDeclarator } from './imports.js';
|
|
10
|
+
import { getPromiseAllElements, handleImportExpression, handleImportThen, handleVariableDeclarator, } from './imports.js';
|
|
11
11
|
import { handleJSXMemberExpression, handleMemberExpression } from './members.js';
|
|
12
12
|
let state;
|
|
13
13
|
const _getFix = (start, end, flags) => state.options.isFixExports ? [start, end, flags ?? FIX_FLAGS.NONE] : undefined;
|
|
@@ -267,8 +267,10 @@ const coreVisitorObject = {
|
|
|
267
267
|
state.scopeEnds[state.scopeDepth] = node.end;
|
|
268
268
|
state.scopeDepth++;
|
|
269
269
|
},
|
|
270
|
-
'BlockStatement:exit'() {
|
|
270
|
+
'BlockStatement:exit'(node) {
|
|
271
271
|
state.scopeDepth--;
|
|
272
|
+
if (state.caughtTryBlockEnds[state.caughtTryBlockEnds.length - 1] === node.end)
|
|
273
|
+
state.caughtTryBlockEnds.pop();
|
|
272
274
|
},
|
|
273
275
|
TSModuleDeclaration(node) {
|
|
274
276
|
state.nsRanges.push([node.start, node.end]);
|
|
@@ -319,6 +321,8 @@ const coreVisitorObject = {
|
|
|
319
321
|
state.staticBlockDepth--;
|
|
320
322
|
},
|
|
321
323
|
FunctionDeclaration(node) {
|
|
324
|
+
state.functionCaughtTryBlockEnds.push(state.caughtTryBlockEnds);
|
|
325
|
+
state.caughtTryBlockEnds = [];
|
|
322
326
|
if (node.id?.name) {
|
|
323
327
|
state.localDeclarationTypes.set(node.id.name, SYMBOL_TYPE.FUNCTION);
|
|
324
328
|
state.localDeclarations.set(node.id.name, node);
|
|
@@ -327,12 +331,25 @@ const coreVisitorObject = {
|
|
|
327
331
|
}
|
|
328
332
|
_addParamShadows(node.params, node.body);
|
|
329
333
|
},
|
|
334
|
+
'FunctionDeclaration:exit'() {
|
|
335
|
+
state.caughtTryBlockEnds = state.functionCaughtTryBlockEnds.pop();
|
|
336
|
+
},
|
|
330
337
|
FunctionExpression(node) {
|
|
338
|
+
state.functionCaughtTryBlockEnds.push(state.caughtTryBlockEnds);
|
|
339
|
+
state.caughtTryBlockEnds = [];
|
|
331
340
|
_addParamShadows(node.params, node.body);
|
|
332
341
|
},
|
|
342
|
+
'FunctionExpression:exit'() {
|
|
343
|
+
state.caughtTryBlockEnds = state.functionCaughtTryBlockEnds.pop();
|
|
344
|
+
},
|
|
333
345
|
ArrowFunctionExpression(node) {
|
|
346
|
+
state.functionCaughtTryBlockEnds.push(state.caughtTryBlockEnds);
|
|
347
|
+
state.caughtTryBlockEnds = [];
|
|
334
348
|
_addParamShadows(node.params, node.body);
|
|
335
349
|
},
|
|
350
|
+
'ArrowFunctionExpression:exit'() {
|
|
351
|
+
state.caughtTryBlockEnds = state.functionCaughtTryBlockEnds.pop();
|
|
352
|
+
},
|
|
336
353
|
CatchClause(node) {
|
|
337
354
|
if (node.param?.type === 'Identifier' && node.body) {
|
|
338
355
|
_addShadowRange(node.param.name, [node.body.start, node.body.end]);
|
|
@@ -380,7 +397,29 @@ const coreVisitorObject = {
|
|
|
380
397
|
ImportExpression(node) {
|
|
381
398
|
handleImportExpression(node, state);
|
|
382
399
|
},
|
|
400
|
+
TryStatement(node) {
|
|
401
|
+
if (node.handler)
|
|
402
|
+
state.caughtTryBlockEnds.push(node.block.end);
|
|
403
|
+
},
|
|
404
|
+
AwaitExpression(node) {
|
|
405
|
+
if (state.caughtTryBlockEnds.length === 0)
|
|
406
|
+
return;
|
|
407
|
+
const { argument } = node;
|
|
408
|
+
if (argument.type === 'ImportExpression') {
|
|
409
|
+
state.caughtImportExpressions.add(argument.start);
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
const elements = getPromiseAllElements(argument);
|
|
413
|
+
if (!elements)
|
|
414
|
+
return;
|
|
415
|
+
for (const element of elements) {
|
|
416
|
+
if (element?.type === 'ImportExpression')
|
|
417
|
+
state.caughtImportExpressions.add(element.start);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
},
|
|
383
421
|
CallExpression(node) {
|
|
422
|
+
handleImportThen(node, state);
|
|
384
423
|
handleCallExpression(node, state);
|
|
385
424
|
},
|
|
386
425
|
NewExpression(node) {
|
|
@@ -833,6 +872,8 @@ function walkAST(program, sourceText, filePath, hasModuleSyntax, ctx) {
|
|
|
833
872
|
localToExports: new Map(),
|
|
834
873
|
customElementRegistries: new Set(),
|
|
835
874
|
classNameStack: [],
|
|
875
|
+
caughtTryBlockEnds: [],
|
|
876
|
+
functionCaughtTryBlockEnds: [],
|
|
836
877
|
staticBlockDepth: 0,
|
|
837
878
|
addExport: _addExport,
|
|
838
879
|
getFix: _getFix,
|
|
@@ -1,4 +1,4 @@
|
|
|
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 Include 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,catalogReferences\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, catalogReferences, 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, sarif\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 Include 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,catalogReferences\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 --output-file Write reporter output to a file instead of stdout ([reporter=]path), can be repeated\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, catalogReferences, 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, sarif\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 --reporter symbols --reporter json --output-file json=knip.json\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
|
|
2
2
|
export type ParsedCLIArgs = ReturnType<typeof parseCLIArgs>;
|
|
3
3
|
export declare const parseNumericOption: (value: string | undefined, option: string) => number | undefined;
|
|
4
4
|
export default function parseCLIArgs(): {
|
|
@@ -29,6 +29,7 @@ export default function parseCLIArgs(): {
|
|
|
29
29
|
'no-gitignore'?: boolean | undefined;
|
|
30
30
|
'no-progress'?: boolean | undefined;
|
|
31
31
|
'no-tag-hints'?: boolean | undefined;
|
|
32
|
+
'output-file'?: string[] | undefined;
|
|
32
33
|
performance?: boolean | undefined;
|
|
33
34
|
'performance-fn'?: string | undefined;
|
|
34
35
|
production?: boolean | undefined;
|
|
@@ -44,6 +44,7 @@ Output
|
|
|
44
44
|
--preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)
|
|
45
45
|
--reporter Select reporter (default: symbols), can be repeated (3)
|
|
46
46
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
47
|
+
--output-file Write reporter output to a file instead of stdout ([reporter=]path), can be repeated
|
|
47
48
|
--no-config-hints Suppress configuration hints
|
|
48
49
|
--no-tag-hints Suppress tag hints
|
|
49
50
|
--treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints
|
|
@@ -77,6 +78,7 @@ $ knip --workspace @myorg/* --workspace '!@myorg/legacy'
|
|
|
77
78
|
$ knip --workspace './apps/*' --workspace '@shared/utils'
|
|
78
79
|
$ knip -c ./config/knip.json --reporter compact
|
|
79
80
|
$ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'
|
|
81
|
+
$ knip --reporter symbols --reporter json --output-file json=knip.json
|
|
80
82
|
$ knip --tags=-lintignore
|
|
81
83
|
|
|
82
84
|
Website: https://knip.dev`;
|
|
@@ -118,6 +120,7 @@ export default function parseCLIArgs() {
|
|
|
118
120
|
'no-gitignore': { type: 'boolean' },
|
|
119
121
|
'no-progress': { type: 'boolean', short: 'n' },
|
|
120
122
|
'no-tag-hints': { type: 'boolean' },
|
|
123
|
+
'output-file': { type: 'string', multiple: true },
|
|
121
124
|
performance: { type: 'boolean' },
|
|
122
125
|
'performance-fn': { type: 'string' },
|
|
123
126
|
production: { type: 'boolean', short: 'p' },
|
|
@@ -60,7 +60,7 @@ export const createInputHandler = (deputy, chief, isGitIgnored, addIssue, extern
|
|
|
60
60
|
isDevOnly: isConfig(input),
|
|
61
61
|
isTypeOnly: input.isTypeOnly,
|
|
62
62
|
});
|
|
63
|
-
if (input.
|
|
63
|
+
if (input.alsoReferenceOwner && input.containingFilePath) {
|
|
64
64
|
const owningWorkspace = chief.findWorkspaceByFilePath(input.containingFilePath);
|
|
65
65
|
if (owningWorkspace && owningWorkspace !== inputWorkspace) {
|
|
66
66
|
const isOwnerHandled = deputy.maybeAddReferencedExternalDependency(owningWorkspace, packageName, {
|
|
@@ -3,9 +3,10 @@ import { type ParsedCLIArgs } from './cli-arguments.ts';
|
|
|
3
3
|
interface CreateOptions extends Partial<Options> {
|
|
4
4
|
args?: ParsedCLIArgs;
|
|
5
5
|
}
|
|
6
|
-
export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
6
|
+
export declare const createOptions: (options: CreateOptions, isReload?: boolean) => Promise<{
|
|
7
|
+
createdFrom: CreateOptions;
|
|
7
8
|
cacheLocation: string;
|
|
8
|
-
catalog: import("../CatalogCounselor.ts").CatalogContainer;
|
|
9
|
+
catalog: import("../CatalogCounselor.ts").CatalogContainer[];
|
|
9
10
|
config: string | undefined;
|
|
10
11
|
configFilePath: string | undefined;
|
|
11
12
|
cwd: string;
|
|
@@ -326,6 +327,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
326
327
|
entry?: string | string[] | undefined;
|
|
327
328
|
project?: string | string[] | undefined;
|
|
328
329
|
} | undefined;
|
|
330
|
+
'kysely-codegen'?: string | boolean | string[] | {
|
|
331
|
+
config?: string | string[] | undefined;
|
|
332
|
+
entry?: string | string[] | undefined;
|
|
333
|
+
project?: string | string[] | undefined;
|
|
334
|
+
} | undefined;
|
|
329
335
|
ladle?: string | boolean | string[] | {
|
|
330
336
|
config?: string | string[] | undefined;
|
|
331
337
|
entry?: string | string[] | undefined;
|
|
@@ -341,6 +347,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
341
347
|
entry?: string | string[] | undefined;
|
|
342
348
|
project?: string | string[] | undefined;
|
|
343
349
|
} | undefined;
|
|
350
|
+
lingui?: string | boolean | string[] | {
|
|
351
|
+
config?: string | string[] | undefined;
|
|
352
|
+
entry?: string | string[] | undefined;
|
|
353
|
+
project?: string | string[] | undefined;
|
|
354
|
+
} | undefined;
|
|
344
355
|
'lint-staged'?: string | boolean | string[] | {
|
|
345
356
|
config?: string | string[] | undefined;
|
|
346
357
|
entry?: string | string[] | undefined;
|
|
@@ -381,6 +392,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
381
392
|
entry?: string | string[] | undefined;
|
|
382
393
|
project?: string | string[] | undefined;
|
|
383
394
|
} | undefined;
|
|
395
|
+
mastra?: string | boolean | string[] | {
|
|
396
|
+
config?: string | string[] | undefined;
|
|
397
|
+
entry?: string | string[] | undefined;
|
|
398
|
+
project?: string | string[] | undefined;
|
|
399
|
+
} | undefined;
|
|
384
400
|
mcp?: string | boolean | string[] | {
|
|
385
401
|
config?: string | string[] | undefined;
|
|
386
402
|
entry?: string | string[] | undefined;
|
|
@@ -611,6 +627,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
611
627
|
entry?: string | string[] | undefined;
|
|
612
628
|
project?: string | string[] | undefined;
|
|
613
629
|
} | undefined;
|
|
630
|
+
purgecss?: string | boolean | string[] | {
|
|
631
|
+
config?: string | string[] | undefined;
|
|
632
|
+
entry?: string | string[] | undefined;
|
|
633
|
+
project?: string | string[] | undefined;
|
|
634
|
+
} | undefined;
|
|
614
635
|
quasar?: string | boolean | string[] | {
|
|
615
636
|
config?: string | string[] | undefined;
|
|
616
637
|
entry?: string | string[] | undefined;
|
|
@@ -1348,6 +1369,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1348
1369
|
entry?: string | string[] | undefined;
|
|
1349
1370
|
project?: string | string[] | undefined;
|
|
1350
1371
|
} | undefined;
|
|
1372
|
+
'kysely-codegen'?: string | boolean | string[] | {
|
|
1373
|
+
config?: string | string[] | undefined;
|
|
1374
|
+
entry?: string | string[] | undefined;
|
|
1375
|
+
project?: string | string[] | undefined;
|
|
1376
|
+
} | undefined;
|
|
1351
1377
|
ladle?: string | boolean | string[] | {
|
|
1352
1378
|
config?: string | string[] | undefined;
|
|
1353
1379
|
entry?: string | string[] | undefined;
|
|
@@ -1363,6 +1389,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1363
1389
|
entry?: string | string[] | undefined;
|
|
1364
1390
|
project?: string | string[] | undefined;
|
|
1365
1391
|
} | undefined;
|
|
1392
|
+
lingui?: string | boolean | string[] | {
|
|
1393
|
+
config?: string | string[] | undefined;
|
|
1394
|
+
entry?: string | string[] | undefined;
|
|
1395
|
+
project?: string | string[] | undefined;
|
|
1396
|
+
} | undefined;
|
|
1366
1397
|
'lint-staged'?: string | boolean | string[] | {
|
|
1367
1398
|
config?: string | string[] | undefined;
|
|
1368
1399
|
entry?: string | string[] | undefined;
|
|
@@ -1403,6 +1434,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1403
1434
|
entry?: string | string[] | undefined;
|
|
1404
1435
|
project?: string | string[] | undefined;
|
|
1405
1436
|
} | undefined;
|
|
1437
|
+
mastra?: string | boolean | string[] | {
|
|
1438
|
+
config?: string | string[] | undefined;
|
|
1439
|
+
entry?: string | string[] | undefined;
|
|
1440
|
+
project?: string | string[] | undefined;
|
|
1441
|
+
} | undefined;
|
|
1406
1442
|
mcp?: string | boolean | string[] | {
|
|
1407
1443
|
config?: string | string[] | undefined;
|
|
1408
1444
|
entry?: string | string[] | undefined;
|
|
@@ -1633,6 +1669,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1633
1669
|
entry?: string | string[] | undefined;
|
|
1634
1670
|
project?: string | string[] | undefined;
|
|
1635
1671
|
} | undefined;
|
|
1672
|
+
purgecss?: string | boolean | string[] | {
|
|
1673
|
+
config?: string | string[] | undefined;
|
|
1674
|
+
entry?: string | string[] | undefined;
|
|
1675
|
+
project?: string | string[] | undefined;
|
|
1676
|
+
} | undefined;
|
|
1636
1677
|
quasar?: string | boolean | string[] | {
|
|
1637
1678
|
config?: string | string[] | undefined;
|
|
1638
1679
|
entry?: string | string[] | undefined;
|
|
@@ -8,12 +8,12 @@ import { findFile, loadJSON } from './fs.js';
|
|
|
8
8
|
import { getIncludedIssueTypes, shorthandCycles, shorthandDeps, shorthandExports, shorthandFiles, } from './get-included-issue-types.js';
|
|
9
9
|
import { defaultRules } from './issue-initializers.js';
|
|
10
10
|
import { loadResolvedConfigFile } from './load-config.js';
|
|
11
|
-
import { _load } from './loader.js';
|
|
11
|
+
import { _load, unload } from './loader.js';
|
|
12
12
|
import { logWarning } from './log.js';
|
|
13
13
|
import { getKeysByValue } from './object.js';
|
|
14
14
|
import { isAbsolute, isInternal, join, resolveCwd, toAbsolute } from './path.js';
|
|
15
15
|
import { splitTags } from './tag.js';
|
|
16
|
-
export const createOptions = async (options) => {
|
|
16
|
+
export const createOptions = async (options, isReload = false) => {
|
|
17
17
|
const { args = {} } = options;
|
|
18
18
|
const cwd = resolveCwd(options.cwd ?? args.directory ?? '.');
|
|
19
19
|
const manifestPath = findFile(cwd, 'package.json');
|
|
@@ -32,6 +32,8 @@ export const createOptions = async (options) => {
|
|
|
32
32
|
if (args.config && !configFilePath && !manifest.knip) {
|
|
33
33
|
throw new ConfigurationError(`Unable to find ${args.config} or package.json#knip`);
|
|
34
34
|
}
|
|
35
|
+
if (options.isSession && !isReload && configFilePath)
|
|
36
|
+
unload([configFilePath]);
|
|
35
37
|
const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath, args) : {});
|
|
36
38
|
const validIssueTypes = new Set(ISSUE_TYPES);
|
|
37
39
|
for (const key of ['rules', 'include', 'exclude']) {
|
|
@@ -60,6 +62,16 @@ export const createOptions = async (options) => {
|
|
|
60
62
|
configFilePath = manifestPath;
|
|
61
63
|
const pnpmWorkspacePath = findFile(cwd, 'pnpm-workspace.yaml');
|
|
62
64
|
const pnpmWorkspace = pnpmWorkspacePath && (await _load(pnpmWorkspacePath));
|
|
65
|
+
const catalog = [await getCatalogContainer(cwd, manifest, manifestPath, pnpmWorkspacePath, pnpmWorkspace)];
|
|
66
|
+
for (const source in pnpmWorkspace?.include) {
|
|
67
|
+
if (!source.startsWith('.'))
|
|
68
|
+
continue;
|
|
69
|
+
const filePath = join(cwd, source);
|
|
70
|
+
const included = await _load(filePath);
|
|
71
|
+
if (!included)
|
|
72
|
+
continue;
|
|
73
|
+
catalog.push({ filePath, catalog: included.catalog, catalogs: included.catalogs, overrides: included.overrides });
|
|
74
|
+
}
|
|
63
75
|
const workspaces = pnpmWorkspace?.packages ??
|
|
64
76
|
(manifest.workspaces
|
|
65
77
|
? Array.isArray(manifest.workspaces)
|
|
@@ -102,8 +114,9 @@ export const createOptions = async (options) => {
|
|
|
102
114
|
const preprocessorOptions = args['preprocessor-options'] ??
|
|
103
115
|
(parsedConfig.preprocessorOptions ? JSON.stringify(parsedConfig.preprocessorOptions) : '');
|
|
104
116
|
return {
|
|
117
|
+
createdFrom: options,
|
|
105
118
|
cacheLocation: args['cache-location'] ?? join(cwd, 'node_modules', '.cache', 'knip'),
|
|
106
|
-
catalog
|
|
119
|
+
catalog,
|
|
107
120
|
config: args.config,
|
|
108
121
|
configFilePath,
|
|
109
122
|
cwd,
|
|
@@ -145,7 +158,7 @@ export const createOptions = async (options) => {
|
|
|
145
158
|
includedIssueTypes.enumMembers ||
|
|
146
159
|
includedIssueTypes.namespaceMembers,
|
|
147
160
|
isReportValues: includedIssueTypes.exports || includedIssueTypes.nsExports,
|
|
148
|
-
isSession: options.isSession ?? false,
|
|
161
|
+
isSession: options.isSession ?? args.watch ?? options.isWatch ?? false,
|
|
149
162
|
isShowProgress: !isDebug &&
|
|
150
163
|
!isTrace &&
|
|
151
164
|
args['no-progress'] !== true &&
|
|
@@ -14,8 +14,10 @@ export declare class FileEntryCache<T> {
|
|
|
14
14
|
filePath: string;
|
|
15
15
|
cache: Map<string, MetaData<T>>;
|
|
16
16
|
normalizedEntries: Map<string, FileDescriptor<T>>;
|
|
17
|
+
private isDirty;
|
|
17
18
|
constructor(cacheId: string, _path: string);
|
|
18
19
|
getFileDescriptor(filePath: string): FileDescriptor<T>;
|
|
20
|
+
setFileData(filePath: string, data: T): void;
|
|
19
21
|
removeEntry(entryName: string): void;
|
|
20
22
|
reconcile(): void;
|
|
21
23
|
}
|
|
@@ -18,6 +18,7 @@ export class FileEntryCache {
|
|
|
18
18
|
filePath;
|
|
19
19
|
cache = new Map();
|
|
20
20
|
normalizedEntries = new Map();
|
|
21
|
+
isDirty = false;
|
|
21
22
|
constructor(cacheId, _path) {
|
|
22
23
|
this.filePath = path.resolve(_path, cacheId);
|
|
23
24
|
if (isFile(this.filePath))
|
|
@@ -58,22 +59,39 @@ export class FileEntryCache {
|
|
|
58
59
|
meta = { size: cSize, mtime: cTime };
|
|
59
60
|
this.cache.set(filePath, meta);
|
|
60
61
|
}
|
|
62
|
+
if (changed)
|
|
63
|
+
this.isDirty = true;
|
|
61
64
|
const fd = { key: filePath, changed, meta };
|
|
62
65
|
this.normalizedEntries.set(filePath, fd);
|
|
63
66
|
return fd;
|
|
64
67
|
}
|
|
68
|
+
setFileData(filePath, data) {
|
|
69
|
+
const fd = this.getFileDescriptor(filePath);
|
|
70
|
+
if (!fd.meta)
|
|
71
|
+
return;
|
|
72
|
+
fd.meta.data = data;
|
|
73
|
+
this.isDirty = true;
|
|
74
|
+
}
|
|
65
75
|
removeEntry(entryName) {
|
|
66
76
|
if (!isAbsolute(entryName))
|
|
67
77
|
entryName = resolve(entryName);
|
|
68
78
|
this.normalizedEntries.delete(entryName);
|
|
69
|
-
this.cache.delete(entryName)
|
|
79
|
+
if (this.cache.delete(entryName))
|
|
80
|
+
this.isDirty = true;
|
|
70
81
|
}
|
|
71
82
|
reconcile() {
|
|
83
|
+
for (const filePath of this.cache.keys()) {
|
|
84
|
+
if (!this.normalizedEntries.has(filePath))
|
|
85
|
+
this.removeEntry(filePath);
|
|
86
|
+
}
|
|
87
|
+
if (!this.isDirty)
|
|
88
|
+
return;
|
|
72
89
|
try {
|
|
73
90
|
const dir = path.dirname(this.filePath);
|
|
74
91
|
if (!isDirectory(dir))
|
|
75
92
|
fs.mkdirSync(dir, { recursive: true });
|
|
76
93
|
fs.writeFileSync(this.filePath, serialize(this.cache));
|
|
94
|
+
this.isDirty = false;
|
|
77
95
|
}
|
|
78
96
|
catch (_err) {
|
|
79
97
|
debugLog('*', `Error writing cache to ${this.filePath}`);
|
|
@@ -5,6 +5,7 @@ export interface CachedGitignoreResult {
|
|
|
5
5
|
gitignoreFiles: string[];
|
|
6
6
|
perDirIgnores: Map<string, Gitignores>;
|
|
7
7
|
}
|
|
8
|
+
export declare const clearGitignoreCache: () => void;
|
|
8
9
|
export declare const initGitignoreCache: (cacheLocation: string) => void;
|
|
9
10
|
export declare const isGitignoreCacheEnabled: () => boolean;
|
|
10
11
|
export declare const flushGitignoreCache: () => void;
|
|
@@ -2,6 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { createDiskCache, mtimeMatches } from './disk-cache.js';
|
|
4
4
|
const store = createDiskCache('gitignore');
|
|
5
|
+
export const clearGitignoreCache = store.clear;
|
|
5
6
|
export const initGitignoreCache = store.init;
|
|
6
7
|
export const isGitignoreCacheEnabled = store.isEnabled;
|
|
7
8
|
export const flushGitignoreCache = store.flush;
|
package/dist/util/glob-core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { readdir, readFileSync } from 'node:fs';
|
|
3
|
-
import { escapePath, glob as tinyGlob } from 'tinyglobby';
|
|
3
|
+
import { escapePath, glob as tinyGlob, isDynamicPattern } from 'tinyglobby';
|
|
4
4
|
import picomatch from 'picomatch';
|
|
5
5
|
import { GLOBAL_IGNORE_PATTERNS } from '../constants.js';
|
|
6
6
|
import { compact, partition } from './array.js';
|
|
@@ -292,7 +292,9 @@ export async function glob(_patterns, options) {
|
|
|
292
292
|
}
|
|
293
293
|
cachedGlobIgnores.set(options.dir, compact(_ignore));
|
|
294
294
|
}
|
|
295
|
-
const
|
|
295
|
+
const ignores = cachedIgnores ?? _ignore;
|
|
296
|
+
const isStatic = options.gitignore && !patterns.some(pattern => isDynamicPattern(pattern));
|
|
297
|
+
const ignorePatterns = (isStatic ? expandIgnorePatterns(ignores) : ignores).concat(negatedPatterns.map(pattern => pattern.slice(1)));
|
|
296
298
|
const { dir, label, ...fgOptions } = {
|
|
297
299
|
...options,
|
|
298
300
|
ignore: ignorePatterns,
|
package/dist/util/glob.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ interface GlobOptions {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const removeProductionSuffix: (pattern: string) => string;
|
|
10
10
|
export declare const prependDirToPattern: (dir: string, pattern: string) => string;
|
|
11
|
+
export declare const rebasePattern: (pattern: string, base: string, dir: string) => string;
|
|
11
12
|
export declare const negate: (pattern: string) => string;
|
|
12
13
|
export declare const hasProductionSuffix: (pattern: string) => boolean;
|
|
13
14
|
export declare const hasNoProductionSuffix: (pattern: string) => boolean;
|
package/dist/util/glob.js
CHANGED
|
@@ -23,6 +23,12 @@ export const prependDirToPattern = (dir, pattern) => {
|
|
|
23
23
|
return `!${join(dir, pattern.slice(1))}`;
|
|
24
24
|
return join(dir, pattern);
|
|
25
25
|
};
|
|
26
|
+
export const rebasePattern = (pattern, base, dir) => {
|
|
27
|
+
const isNegated = pattern.startsWith('!');
|
|
28
|
+
const id = isNegated ? pattern.slice(1) : pattern;
|
|
29
|
+
const rebased = relative(dir, isAbsolute(id) ? id : join(base, id));
|
|
30
|
+
return isNegated ? `!${rebased}` : rebased;
|
|
31
|
+
};
|
|
26
32
|
export const negate = (pattern) => pattern.replace(/^!?/, '!');
|
|
27
33
|
export const hasProductionSuffix = (pattern) => pattern.endsWith('!');
|
|
28
34
|
export const hasNoProductionSuffix = (pattern) => !pattern.endsWith('!');
|
package/dist/util/input.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface Input {
|
|
|
7
7
|
production?: boolean;
|
|
8
8
|
optional?: boolean;
|
|
9
9
|
isTypeOnly?: boolean;
|
|
10
|
+
alsoReferenceOwner?: boolean;
|
|
10
11
|
dir?: string;
|
|
11
12
|
containingFilePath?: string;
|
|
12
13
|
allowIncludeExports?: boolean;
|
|
@@ -33,6 +34,7 @@ interface IgnoreInput extends Input {
|
|
|
33
34
|
type Options = {
|
|
34
35
|
optional?: boolean;
|
|
35
36
|
isTypeOnly?: boolean;
|
|
37
|
+
alsoReferenceOwner?: boolean;
|
|
36
38
|
dir?: string;
|
|
37
39
|
containingFilePath?: string;
|
|
38
40
|
allowIncludeExports?: boolean;
|
package/dist/util/loader.d.ts
CHANGED
package/dist/util/loader.js
CHANGED
|
@@ -6,11 +6,25 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
9
11
|
import { LoaderError } from './errors.js';
|
|
10
12
|
import { loadFile, loadJSON, loadJSONC, loadTOML, loadYAML, parseJSONC, parseYAML } from './fs.js';
|
|
11
13
|
import { jiti } from './jiti.js';
|
|
12
14
|
import { timerify } from './Performance.js';
|
|
13
|
-
import { extname, isInternal } from './path.js';
|
|
15
|
+
import { extname, isInternal, toNative } from './path.js';
|
|
16
|
+
const versions = new Map();
|
|
17
|
+
const isReloadable = (ext) => ext === '.js' || ext === '.mjs' || ext === '.cjs';
|
|
18
|
+
const reload = async (filePath, version) => {
|
|
19
|
+
let imported;
|
|
20
|
+
try {
|
|
21
|
+
imported = jiti(filePath);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
imported = await import(__rewriteRelativeImportExtension(`${pathToFileURL(filePath).href}?v=${version}`));
|
|
25
|
+
}
|
|
26
|
+
return imported.default ?? imported;
|
|
27
|
+
};
|
|
14
28
|
const load = async (filePath) => {
|
|
15
29
|
try {
|
|
16
30
|
const ext = extname(filePath);
|
|
@@ -42,6 +56,10 @@ const load = async (filePath) => {
|
|
|
42
56
|
if (ext === '.toml') {
|
|
43
57
|
return await loadTOML(filePath);
|
|
44
58
|
}
|
|
59
|
+
const version = versions.get(filePath) ?? 0;
|
|
60
|
+
versions.set(filePath, version);
|
|
61
|
+
if (version && isReloadable(ext))
|
|
62
|
+
return await reload(filePath, version);
|
|
45
63
|
return await jiti.import(filePath, { default: true });
|
|
46
64
|
}
|
|
47
65
|
catch (error) {
|
|
@@ -49,3 +67,13 @@ const load = async (filePath) => {
|
|
|
49
67
|
}
|
|
50
68
|
};
|
|
51
69
|
export const _load = timerify(load);
|
|
70
|
+
const { cache } = createRequire(import.meta.url);
|
|
71
|
+
export const unload = (filePaths) => {
|
|
72
|
+
for (const filePath of filePaths) {
|
|
73
|
+
delete cache[filePath];
|
|
74
|
+
delete cache[toNative(filePath)];
|
|
75
|
+
const version = versions.get(filePath);
|
|
76
|
+
if (version !== undefined)
|
|
77
|
+
versions.set(filePath, version + 1);
|
|
78
|
+
}
|
|
79
|
+
};
|
package/dist/util/modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { DT_SCOPE, PROTOCOL_VIRTUAL } from '../constants.js';
|
|
2
|
+
import { DT_SCOPE, PROTOCOL_CLOUDFLARE, PROTOCOL_VIRTUAL } from '../constants.js';
|
|
3
3
|
import { isAbsolute, isInNodeModules, join, toPosix } from './path.js';
|
|
4
4
|
export const getPackageNameFromModuleSpecifier = (specifier) => {
|
|
5
5
|
if (!isStartsLikePackageName(specifier) && !isTildePackageName(specifier))
|
|
@@ -53,7 +53,9 @@ const isPackageNameStart = (ch) => (ch >= 65 && ch <= 90) || (ch >= 97 && ch <=
|
|
|
53
53
|
const isPackageScopeStart = (ch) => isPackageNameStart(ch) || ch === 46 || ch === 95 || ch === 126;
|
|
54
54
|
export const isStartsLikePackageName = (specifier) => {
|
|
55
55
|
const ch = specifier.charCodeAt(0);
|
|
56
|
-
return ch === 64
|
|
56
|
+
return ch === 64
|
|
57
|
+
? isPackageScopeStart(specifier.charCodeAt(1))
|
|
58
|
+
: isPackageNameStart(ch) && specifier.charCodeAt(1) !== 58;
|
|
57
59
|
};
|
|
58
60
|
const isTildePackageName = (specifier) => specifier.charCodeAt(0) === 126 && isPackageNameStart(specifier.charCodeAt(1));
|
|
59
61
|
export const stripVersionFromSpecifier = (specifier) => specifier.replace(/(\S+)@.*/, '$1');
|
|
@@ -87,6 +89,7 @@ const CHAR_HASH = 35;
|
|
|
87
89
|
const CHAR_QUESTION = 63;
|
|
88
90
|
export const sanitizeSpecifier = (specifier) => {
|
|
89
91
|
if (specifier.startsWith('node:') ||
|
|
92
|
+
specifier.startsWith(PROTOCOL_CLOUDFLARE) ||
|
|
90
93
|
isAbsolute(specifier) ||
|
|
91
94
|
specifier.charCodeAt(0) === CHAR_COLON ||
|
|
92
95
|
specifier.startsWith(PROTOCOL_VIRTUAL)) {
|