knip 5.25.1 → 5.26.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/dist/ConfigurationChief.js +3 -2
- package/dist/DependencyDeputy.js +2 -2
- package/dist/PrincipalFactory.d.ts +2 -1
- package/dist/PrincipalFactory.js +5 -1
- package/dist/ProjectPrincipal.js +5 -5
- package/dist/constants.d.ts +5 -0
- package/dist/constants.js +5 -0
- package/dist/index.js +4 -4
- package/dist/plugins/graphql-codegen/index.js +5 -3
- package/dist/typescript/find-internal-references.d.ts +3 -0
- package/dist/typescript/find-internal-references.js +45 -0
- package/dist/typescript/getImportsAndExports.js +5 -47
- package/dist/typescript/resolveModuleNames.js +35 -13
- package/dist/util/globby.d.ts +2 -2
- package/dist/util/globby.js +2 -2
- package/dist/util/modules.js +10 -6
- package/dist/util/regex.js +2 -1
- package/dist/util/tag.js +5 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -2
|
@@ -152,11 +152,12 @@ export class ConfigurationChief {
|
|
|
152
152
|
}
|
|
153
153
|
async setWorkspaces() {
|
|
154
154
|
this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
|
|
155
|
-
|
|
155
|
+
this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
|
|
156
|
+
const workspaceNames = compact([...this.getListedWorkspaces(), ...this.additionalWorkspaceNames]);
|
|
157
|
+
const [byName, byPkgName] = await mapWorkspaces(this.cwd, workspaceNames);
|
|
156
158
|
this.workspacePackages = byName;
|
|
157
159
|
this.workspacePackagesByName = byPkgName;
|
|
158
160
|
this.addRootPackage();
|
|
159
|
-
this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
|
|
160
161
|
this.availableWorkspaceNames = this.getAvailableWorkspaceNames(byName.keys());
|
|
161
162
|
this.availableWorkspacePkgNames = this.getAvailableWorkspacePkgNames(byPkgName.keys());
|
|
162
163
|
this.availableWorkspaceDirs = this.availableWorkspaceNames
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
|
-
import { IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES, IGNORED_RUNTIME_DEPENDENCIES, IGNORE_DEFINITELY_TYPED, ROOT_WORKSPACE_NAME, } from './constants.js';
|
|
2
|
+
import { DT_SCOPE, IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES, IGNORED_RUNTIME_DEPENDENCIES, IGNORE_DEFINITELY_TYPED, ROOT_WORKSPACE_NAME, } from './constants.js';
|
|
3
3
|
import { getDependencyMetaData } from './manifest/index.js';
|
|
4
4
|
import { getDefinitelyTypedFor, getPackageFromDefinitelyTyped, isDefinitelyTyped } from './util/modules.js';
|
|
5
5
|
import { findMatch, toRegexOrString } from './util/regex.js';
|
|
@@ -174,7 +174,7 @@ export class DependencyDeputy {
|
|
|
174
174
|
if (isPeerDep && peerDepRecs[dependency])
|
|
175
175
|
return false;
|
|
176
176
|
const [scope, typedDependency] = dependency.split('/');
|
|
177
|
-
if (scope ===
|
|
177
|
+
if (scope === DT_SCOPE) {
|
|
178
178
|
if (hasTypesIncluded?.has(typedDependency))
|
|
179
179
|
return false;
|
|
180
180
|
const typedPackageName = getPackageFromDefinitelyTyped(typedDependency);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ts from 'typescript';
|
|
2
2
|
import { ProjectPrincipal } from './ProjectPrincipal.js';
|
|
3
3
|
import type { AsyncCompilers, SyncCompilers } from './compilers/types.js';
|
|
4
4
|
type Paths = ts.CompilerOptions['paths'];
|
|
@@ -11,6 +11,7 @@ type Principal = {
|
|
|
11
11
|
type Principals = Set<Principal>;
|
|
12
12
|
export type PrincipalOptions = {
|
|
13
13
|
cwd: string;
|
|
14
|
+
isFile: boolean;
|
|
14
15
|
compilerOptions: ts.CompilerOptions;
|
|
15
16
|
paths: Paths;
|
|
16
17
|
compilers: [SyncCompilers, AsyncCompilers];
|
package/dist/PrincipalFactory.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
1
2
|
import { ProjectPrincipal } from './ProjectPrincipal.js';
|
|
2
3
|
import { debugLog } from './util/debug.js';
|
|
3
4
|
import { toAbsolute, toRelative } from './util/path.js';
|
|
@@ -16,8 +17,10 @@ const mergePaths = (cwd, compilerOptions, paths = {}) => {
|
|
|
16
17
|
export class PrincipalFactory {
|
|
17
18
|
principals = new Set();
|
|
18
19
|
getPrincipal(options) {
|
|
19
|
-
const { cwd, compilerOptions, paths, pkgName, isIsolateWorkspaces, compilers } = options;
|
|
20
|
+
const { cwd, compilerOptions, isFile, paths, pkgName, isIsolateWorkspaces, compilers } = options;
|
|
20
21
|
options.compilerOptions = mergePaths(cwd, compilerOptions, paths);
|
|
22
|
+
if (isFile)
|
|
23
|
+
compilerOptions.moduleResolution ??= ts.ModuleResolutionKind.Bundler;
|
|
21
24
|
const principal = this.findReusablePrincipal(compilerOptions);
|
|
22
25
|
if (!isIsolateWorkspaces && principal) {
|
|
23
26
|
this.linkPrincipal(principal, cwd, compilerOptions, pkgName, compilers);
|
|
@@ -41,6 +44,7 @@ export class PrincipalFactory {
|
|
|
41
44
|
const { pathsBasePath, paths } = compilerOptions;
|
|
42
45
|
if (pathsBasePath)
|
|
43
46
|
principal.principal.compilerOptions.pathsBasePath = pathsBasePath;
|
|
47
|
+
principal.principal.compilerOptions.moduleResolution ??= compilerOptions.moduleResolution;
|
|
44
48
|
for (const p of Object.keys(paths ?? {}))
|
|
45
49
|
principal.pathKeys.add(p);
|
|
46
50
|
principal.principal.addPaths(paths);
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { CacheConsultant } from './CacheConsultant.js';
|
|
3
3
|
import { getCompilerExtensions } from './compilers/index.js';
|
|
4
|
-
import { ANONYMOUS, DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS } from './constants.js';
|
|
4
|
+
import { ANONYMOUS, DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS, PUBLIC_TAG } from './constants.js';
|
|
5
5
|
import { createHosts } from './typescript/createHosts.js';
|
|
6
6
|
import { _getImportsAndExports } from './typescript/getImportsAndExports.js';
|
|
7
7
|
import { timerify } from './util/Performance.js';
|
|
@@ -19,11 +19,11 @@ const baseCompilerOptions = {
|
|
|
19
19
|
jsx: ts.JsxEmit.Preserve,
|
|
20
20
|
jsxImportSource: undefined,
|
|
21
21
|
lib: [],
|
|
22
|
-
types: ['node'],
|
|
23
22
|
noEmit: true,
|
|
24
23
|
skipDefaultLibCheck: true,
|
|
25
24
|
skipLibCheck: true,
|
|
26
25
|
sourceMap: false,
|
|
26
|
+
types: ['node'],
|
|
27
27
|
};
|
|
28
28
|
const tsCreateProgram = timerify(ts.createProgram);
|
|
29
29
|
export class ProjectPrincipal {
|
|
@@ -47,7 +47,7 @@ export class ProjectPrincipal {
|
|
|
47
47
|
this.compilerOptions = {
|
|
48
48
|
...compilerOptions,
|
|
49
49
|
...baseCompilerOptions,
|
|
50
|
-
types: compact([...(compilerOptions.types ?? []), ...baseCompilerOptions.types]),
|
|
50
|
+
types: compact([...(compilerOptions.types ?? []), ...(baseCompilerOptions.types ?? [])]),
|
|
51
51
|
allowNonTsExtensions: true,
|
|
52
52
|
};
|
|
53
53
|
const [syncCompilers, asyncCompilers] = compilers;
|
|
@@ -218,7 +218,7 @@ export class ProjectPrincipal {
|
|
|
218
218
|
this.findReferences = timerify(languageService.findReferences);
|
|
219
219
|
}
|
|
220
220
|
return members.filter(member => {
|
|
221
|
-
if (member.jsDocTags.has(
|
|
221
|
+
if (member.jsDocTags.has(PUBLIC_TAG))
|
|
222
222
|
return false;
|
|
223
223
|
const referencedSymbols = this.findReferences?.(filePath, member.pos) ?? [];
|
|
224
224
|
const refs = referencedSymbols.flatMap(refs => refs.references).filter(ref => !ref.isDefinition);
|
|
@@ -226,7 +226,7 @@ export class ProjectPrincipal {
|
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
hasExternalReferences(filePath, exportedItem) {
|
|
229
|
-
if (exportedItem.jsDocTags.has(
|
|
229
|
+
if (exportedItem.jsDocTags.has(PUBLIC_TAG))
|
|
230
230
|
return false;
|
|
231
231
|
if (!this.findReferences) {
|
|
232
232
|
const languageService = ts.createLanguageService(this.backend.languageServiceHost, ts.createDocumentRegistry());
|
package/dist/constants.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ export declare const ANONYMOUS = "__anonymous";
|
|
|
5
5
|
export declare const KNIP_CONFIG_LOCATIONS: string[];
|
|
6
6
|
export declare const DEFAULT_EXTENSIONS: string[];
|
|
7
7
|
export declare const GLOBAL_IGNORE_PATTERNS: string[];
|
|
8
|
+
export declare const PUBLIC_TAG = "@public";
|
|
9
|
+
export declare const INTERNAL_TAG = "@internal";
|
|
10
|
+
export declare const BETA_TAG = "@beta";
|
|
11
|
+
export declare const ALIAS_TAG = "@alias";
|
|
12
|
+
export declare const DT_SCOPE = "@types";
|
|
8
13
|
export declare const IGNORED_GLOBAL_BINARIES: Set<string>;
|
|
9
14
|
export declare const IGNORED_DEPENDENCIES: Set<string>;
|
|
10
15
|
export declare const IGNORED_RUNTIME_DEPENDENCIES: Set<string>;
|
package/dist/constants.js
CHANGED
|
@@ -13,6 +13,11 @@ export const KNIP_CONFIG_LOCATIONS = [
|
|
|
13
13
|
];
|
|
14
14
|
export const DEFAULT_EXTENSIONS = ['.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx', '.mts', '.cts'];
|
|
15
15
|
export const GLOBAL_IGNORE_PATTERNS = ['**/node_modules/**', '.yarn'];
|
|
16
|
+
export const PUBLIC_TAG = '@public';
|
|
17
|
+
export const INTERNAL_TAG = '@internal';
|
|
18
|
+
export const BETA_TAG = '@beta';
|
|
19
|
+
export const ALIAS_TAG = '@alias';
|
|
20
|
+
export const DT_SCOPE = '@types';
|
|
16
21
|
export const IGNORED_GLOBAL_BINARIES = new Set([
|
|
17
22
|
'aws',
|
|
18
23
|
'bash',
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { debugLog, debugLogArray, debugLogObject } from './util/debug.js';
|
|
|
15
15
|
import { addNsValues, addValues, createFileNode } from './util/dependency-graph.js';
|
|
16
16
|
import { isFile } from './util/fs.js';
|
|
17
17
|
import { _glob, negate } from './util/glob.js';
|
|
18
|
-
import {
|
|
18
|
+
import { getGitIgnoredHandler } from './util/globby.js';
|
|
19
19
|
import { getHandler } from './util/handle-dependency.js';
|
|
20
20
|
import { getHasStrictlyNsReferences, getType } from './util/has-strictly-ns-references.js';
|
|
21
21
|
import { getIsIdentifierReferencedHandler } from './util/is-identifier-referenced.js';
|
|
@@ -33,7 +33,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
33
33
|
const deputy = new DependencyDeputy({ isProduction, isStrict });
|
|
34
34
|
const factory = new PrincipalFactory();
|
|
35
35
|
const streamer = new ConsoleStreamer({ isEnabled: isShowProgress });
|
|
36
|
-
const isGitIgnored = await
|
|
36
|
+
const isGitIgnored = await getGitIgnoredHandler({ cwd, gitignore });
|
|
37
37
|
const toSourceFilePath = getToSourcePathHandler(chief);
|
|
38
38
|
streamer.cast('Reading workspace configuration(s)...');
|
|
39
39
|
await chief.init();
|
|
@@ -74,6 +74,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
74
74
|
const principal = factory.getPrincipal({
|
|
75
75
|
cwd: dir,
|
|
76
76
|
paths: config.paths,
|
|
77
|
+
isFile,
|
|
77
78
|
compilerOptions,
|
|
78
79
|
compilers,
|
|
79
80
|
pkgName,
|
|
@@ -270,9 +271,8 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
270
271
|
const resolvedFiles = principal.getUsedResolvedFiles();
|
|
271
272
|
const files = resolvedFiles.filter(filePath => !analyzedFiles.has(filePath));
|
|
272
273
|
debugLogArray('*', `Analyzing used resolved files [P${principals.indexOf(principal) + 1}/${++round}]`, files);
|
|
273
|
-
for (const filePath of files)
|
|
274
|
+
for (const filePath of files)
|
|
274
275
|
analyzeSourceFile(filePath, principal);
|
|
275
|
-
}
|
|
276
276
|
} while (size !== principal.entryPaths.size);
|
|
277
277
|
for (const filePath of principal.getUnreferencedFiles())
|
|
278
278
|
unreferencedFiles.add(filePath);
|
|
@@ -29,11 +29,13 @@ const resolveConfig = config => {
|
|
|
29
29
|
const presets = configurationOutput
|
|
30
30
|
.map(configOutput => (configOutput.preset ? configOutput.preset : undefined))
|
|
31
31
|
.filter((preset) => typeof preset === 'string')
|
|
32
|
-
.map(presetName =>
|
|
32
|
+
.map(presetName => presetName.startsWith('@graphql-codegen/')
|
|
33
|
+
? presetName
|
|
34
|
+
: `@graphql-codegen/${presetName}${presetName.endsWith('-preset') ? '' : '-preset'}`);
|
|
33
35
|
const flatPlugins = generateSet
|
|
34
36
|
.filter((config) => !isConfigurationOutput(config))
|
|
35
37
|
.flatMap(item => Object.keys(item))
|
|
36
|
-
.map(plugin => `@graphql-codegen/${plugin}`);
|
|
38
|
+
.map(plugin => plugin.includes('codegen-') ? plugin : `@graphql-codegen/${plugin}`);
|
|
37
39
|
const nestedPlugins = configurationOutput
|
|
38
40
|
.flatMap(configOutput => (configOutput.plugins ? configOutput.plugins : []))
|
|
39
41
|
.flatMap(plugin => {
|
|
@@ -46,7 +48,7 @@ const resolveConfig = config => {
|
|
|
46
48
|
return [];
|
|
47
49
|
if (isInternal(plugin))
|
|
48
50
|
return [toEntryPattern(plugin)];
|
|
49
|
-
return [`@graphql-codegen/${plugin}`];
|
|
51
|
+
return [plugin.includes('codegen-') ? plugin : `@graphql-codegen/${plugin}`];
|
|
50
52
|
});
|
|
51
53
|
return [...presets, ...flatPlugins, ...nestedPlugins];
|
|
52
54
|
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import type { Export, ExportMember } from '../types/dependency-graph.js';
|
|
3
|
+
export declare const findInternalReferences: (item: Export | ExportMember, sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, referencedSymbolsInExportedTypes: Set<ts.Symbol>) => [number, boolean];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { isIdChar } from '../util/regex.js';
|
|
3
|
+
const isType = (item) => item.type === 'type' || item.type === 'interface' || item.type === 'member';
|
|
4
|
+
export const findInternalReferences = (item, sourceFile, typeChecker, referencedSymbolsInExportedTypes) => {
|
|
5
|
+
if (!item.symbol)
|
|
6
|
+
return [0, false];
|
|
7
|
+
if (item.symbol.flags & ts.SymbolFlags.AliasExcludes)
|
|
8
|
+
return [1, false];
|
|
9
|
+
const text = sourceFile.text;
|
|
10
|
+
const id = item.identifier;
|
|
11
|
+
const symbols = new Set();
|
|
12
|
+
let refCount = 0;
|
|
13
|
+
let isSymbolInExportedType = false;
|
|
14
|
+
let index = 0;
|
|
15
|
+
while (index < text.length && (index = text.indexOf(id, index)) !== -1) {
|
|
16
|
+
if (!isIdChar(text.charAt(index - 1)) && !isIdChar(text.charAt(index + id.length))) {
|
|
17
|
+
const isExportDeclaration = index === item.pos || index === item.pos + 1;
|
|
18
|
+
if (!isExportDeclaration) {
|
|
19
|
+
const symbol = typeChecker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, index));
|
|
20
|
+
if (symbol) {
|
|
21
|
+
const isInExportedType = referencedSymbolsInExportedTypes.has(symbol);
|
|
22
|
+
if (isInExportedType)
|
|
23
|
+
isSymbolInExportedType = true;
|
|
24
|
+
if (item.symbol === symbol) {
|
|
25
|
+
refCount++;
|
|
26
|
+
if (isInExportedType || isType(item))
|
|
27
|
+
return [refCount, isSymbolInExportedType];
|
|
28
|
+
}
|
|
29
|
+
const declaration = symbol.declarations?.[0];
|
|
30
|
+
if (declaration) {
|
|
31
|
+
if (item.symbol === declaration.name?.flowNode?.node?.symbol) {
|
|
32
|
+
return [++refCount, isSymbolInExportedType];
|
|
33
|
+
}
|
|
34
|
+
if (ts.isImportSpecifier(declaration) && symbols.has(symbol)) {
|
|
35
|
+
return [++refCount, isSymbolInExportedType];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
symbols.add(symbol);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
index += id.length;
|
|
43
|
+
}
|
|
44
|
+
return [refCount, isSymbolInExportedType];
|
|
45
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
2
|
import ts from 'typescript';
|
|
3
|
-
import { ANONYMOUS, DEFAULT_EXTENSIONS, IMPORT_STAR } from '../constants.js';
|
|
3
|
+
import { ALIAS_TAG, ANONYMOUS, DEFAULT_EXTENSIONS, IMPORT_STAR } from '../constants.js';
|
|
4
4
|
import { timerify } from '../util/Performance.js';
|
|
5
5
|
import { addNsValue, addValue, createImports } from '../util/dependency-graph.js';
|
|
6
6
|
import { isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
|
|
7
7
|
import { extname, isInNodeModules } from '../util/path.js';
|
|
8
|
-
import { isIdChar } from '../util/regex.js';
|
|
9
8
|
import { shouldIgnore } from '../util/tag.js';
|
|
10
9
|
import { getAccessMembers, getDestructuredIds, getJSDocTags, getLineAndCharacterOfPosition, getTypeName, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, isReferencedInExportedType, } from './ast-helpers.js';
|
|
10
|
+
import { findInternalReferences } from './find-internal-references.js';
|
|
11
11
|
import getDynamicImportVisitors from './visitors/dynamic-imports/index.js';
|
|
12
12
|
import getExportVisitors from './visitors/exports/index.js';
|
|
13
13
|
import { getImportsFromPragmas } from './visitors/helpers.js';
|
|
@@ -33,7 +33,6 @@ const createMember = (node, member, pos) => {
|
|
|
33
33
|
jsDocTags: getJSDocTags(member.node),
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
-
const isType = (item) => item.type === 'type' || item.type === 'interface' || item.type === 'member';
|
|
37
36
|
const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) => {
|
|
38
37
|
const { skipTypeOnly, tags, ignoreExportsUsedInFile } = options;
|
|
39
38
|
const internalImports = new Map();
|
|
@@ -193,7 +192,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
193
192
|
isReExport,
|
|
194
193
|
});
|
|
195
194
|
}
|
|
196
|
-
if (!jsDocTags.has(
|
|
195
|
+
if (!jsDocTags.has(ALIAS_TAG)) {
|
|
197
196
|
if (ts.isExportAssignment(node))
|
|
198
197
|
maybeAddAliasedExport(node.expression, 'default');
|
|
199
198
|
if (ts.isVariableDeclaration(node))
|
|
@@ -308,54 +307,13 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
308
307
|
if (pragmaImports)
|
|
309
308
|
for (const node of pragmaImports)
|
|
310
309
|
addImport(node, sourceFile);
|
|
311
|
-
const setRefs = (item) => {
|
|
312
|
-
if (!item.symbol)
|
|
313
|
-
return;
|
|
314
|
-
if (item.symbol.flags & ts.SymbolFlags.AliasExcludes) {
|
|
315
|
-
item.refs = [1, false];
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
const symbols = new Set();
|
|
319
|
-
let index = 0;
|
|
320
|
-
const text = sourceFile.text;
|
|
321
|
-
const id = item.identifier;
|
|
322
|
-
while (index < text.length && (index = text.indexOf(id, index)) !== -1) {
|
|
323
|
-
if (!isIdChar(text.charAt(index - 1)) && !isIdChar(text.charAt(index + id.length))) {
|
|
324
|
-
const isExportDeclaration = index === item.pos || index === item.pos + 1;
|
|
325
|
-
if (!isExportDeclaration) {
|
|
326
|
-
const symbol = typeChecker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, index));
|
|
327
|
-
if (symbol) {
|
|
328
|
-
const isInExportedType = referencedSymbolsInExportedTypes.has(symbol);
|
|
329
|
-
if (item.symbol === symbol) {
|
|
330
|
-
item.refs = [1, isInExportedType];
|
|
331
|
-
if (isInExportedType || isType(item))
|
|
332
|
-
break;
|
|
333
|
-
}
|
|
334
|
-
const declaration = symbol.declarations?.[0];
|
|
335
|
-
if (declaration) {
|
|
336
|
-
if (item.symbol === declaration.name?.flowNode?.node?.symbol) {
|
|
337
|
-
item.refs = [1, isInExportedType];
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
if (ts.isImportSpecifier(declaration) && symbols.has(symbol)) {
|
|
341
|
-
item.refs = [1, isInExportedType];
|
|
342
|
-
break;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
symbols.add(symbol);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
index += id.length;
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
310
|
const isSetRefs = ignoreExportsUsedInFile;
|
|
353
311
|
for (const item of exports.values()) {
|
|
354
312
|
if (isSetRefs === true || (typeof isSetRefs === 'object' && item.type !== 'unknown' && !!isSetRefs[item.type])) {
|
|
355
|
-
|
|
313
|
+
item.refs = findInternalReferences(item, sourceFile, typeChecker, referencedSymbolsInExportedTypes);
|
|
356
314
|
}
|
|
357
315
|
for (const member of item.members) {
|
|
358
|
-
|
|
316
|
+
member.refs = findInternalReferences(member, sourceFile, typeChecker, referencedSymbolsInExportedTypes);
|
|
359
317
|
member.symbol = undefined;
|
|
360
318
|
}
|
|
361
319
|
item.symbol = undefined;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { isBuiltin } from 'node:module';
|
|
3
|
-
import { createMatchPath } from 'tsconfig-paths';
|
|
4
3
|
import ts from 'typescript';
|
|
5
4
|
import { DEFAULT_EXTENSIONS } from '../constants.js';
|
|
6
5
|
import { timerify } from '../util/Performance.js';
|
|
7
6
|
import { sanitizeSpecifier } from '../util/modules.js';
|
|
8
|
-
import { dirname, extname, isAbsolute, isInNodeModules, join
|
|
7
|
+
import { dirname, extname, isAbsolute, isInNodeModules, join } from '../util/path.js';
|
|
9
8
|
import { resolveSync } from '../util/resolve.js';
|
|
10
9
|
import { isDeclarationFileExtension } from './ast-helpers.js';
|
|
11
10
|
const resolutionCache = new Map();
|
|
@@ -23,6 +22,21 @@ const fileExists = (name, containingFile) => {
|
|
|
23
22
|
export function createCustomModuleResolver(compilerOptions, customCompilerExtensions, toSourceFilePath, useCache = true) {
|
|
24
23
|
const customCompilerExtensionsSet = new Set(customCompilerExtensions);
|
|
25
24
|
const extensions = [...DEFAULT_EXTENSIONS, ...customCompilerExtensions];
|
|
25
|
+
const virtualDeclarationFiles = new Map();
|
|
26
|
+
const tsSys = {
|
|
27
|
+
...ts.sys,
|
|
28
|
+
fileExists(path) {
|
|
29
|
+
if (ts.sys.fileExists(path)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
const original = originalFromDeclarationPath(path);
|
|
33
|
+
if (original && ts.sys.fileExists(original.path)) {
|
|
34
|
+
virtualDeclarationFiles.set(path, original);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
26
40
|
function resolveModuleNames(moduleNames, containingFile) {
|
|
27
41
|
return moduleNames.map(moduleName => {
|
|
28
42
|
if (!useCache)
|
|
@@ -38,7 +52,6 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
|
|
|
38
52
|
return resolvedModule;
|
|
39
53
|
});
|
|
40
54
|
}
|
|
41
|
-
const tsMatchPath = createMatchPath(compilerOptions.baseUrl ?? '/', compilerOptions.paths || {});
|
|
42
55
|
function resolveModuleName(name, containingFile) {
|
|
43
56
|
const sanitizedSpecifier = sanitizeSpecifier(name);
|
|
44
57
|
if (isBuiltin(sanitizedSpecifier) || isInNodeModules(name))
|
|
@@ -64,16 +77,7 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
|
|
|
64
77
|
resolvedUsingTsExtension: false,
|
|
65
78
|
};
|
|
66
79
|
}
|
|
67
|
-
const
|
|
68
|
-
if (pathMappedFileName) {
|
|
69
|
-
const ext = extname(pathMappedFileName);
|
|
70
|
-
return {
|
|
71
|
-
resolvedFileName: toPosix(pathMappedFileName),
|
|
72
|
-
extension: customCompilerExtensionsSet.has(ext) ? ts.Extension.Js : ext,
|
|
73
|
-
isExternalLibraryImport: false,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
const tsResolvedModule = ts.resolveModuleName(sanitizedSpecifier, containingFile, compilerOptions, ts.sys).resolvedModule;
|
|
80
|
+
const tsResolvedModule = ts.resolveModuleName(sanitizedSpecifier, containingFile, compilerOptions, tsSys).resolvedModule;
|
|
77
81
|
if (tsResolvedModule) {
|
|
78
82
|
if (isDeclarationFileExtension(tsResolvedModule.extension)) {
|
|
79
83
|
const srcFilePath = toSourceFilePath(tsResolvedModule.resolvedFileName);
|
|
@@ -86,6 +90,14 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
|
|
|
86
90
|
};
|
|
87
91
|
}
|
|
88
92
|
}
|
|
93
|
+
const original = virtualDeclarationFiles.get(tsResolvedModule.resolvedFileName);
|
|
94
|
+
if (original) {
|
|
95
|
+
return {
|
|
96
|
+
...tsResolvedModule,
|
|
97
|
+
resolvedFileName: original.path,
|
|
98
|
+
extension: customCompilerExtensionsSet.has(original.ext) ? ts.Extension.Js : original.ext,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
89
101
|
return tsResolvedModule;
|
|
90
102
|
}
|
|
91
103
|
const module = fileExists(sanitizedSpecifier, containingFile);
|
|
@@ -95,3 +107,13 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
|
|
|
95
107
|
}
|
|
96
108
|
return timerify(resolveModuleNames);
|
|
97
109
|
}
|
|
110
|
+
const declarationPathRe = /^(.*)\.d(\.[^.]+)\.ts$/;
|
|
111
|
+
function originalFromDeclarationPath(path) {
|
|
112
|
+
const match = declarationPathRe.exec(path);
|
|
113
|
+
if (match) {
|
|
114
|
+
return {
|
|
115
|
+
path: match[1] + match[2],
|
|
116
|
+
ext: match[2],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
package/dist/util/globby.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Options as FastGlobOptions } from 'fast-glob';
|
|
2
2
|
type Options = {
|
|
3
3
|
gitignore: boolean;
|
|
4
4
|
cwd: string;
|
|
@@ -10,5 +10,5 @@ type GlobOptions = {
|
|
|
10
10
|
} & FastGlobOptionsWithoutCwd;
|
|
11
11
|
type FastGlobOptionsWithoutCwd = Pick<FastGlobOptions, 'onlyDirectories' | 'ignore' | 'absolute' | 'dot'>;
|
|
12
12
|
export declare function globby(patterns: string | string[], options: GlobOptions): Promise<string[]>;
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function getGitIgnoredHandler(options: Options): Promise<(path: string) => boolean>;
|
|
14
14
|
export {};
|
package/dist/util/globby.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import { walk as _walk } from '@nodelib/fs.walk';
|
|
4
|
-
import fg from 'fast-glob';
|
|
4
|
+
import fg, {} from 'fast-glob';
|
|
5
5
|
import picomatch from 'picomatch';
|
|
6
6
|
import { GLOBAL_IGNORE_PATTERNS, ROOT_WORKSPACE_NAME } from '../constants.js';
|
|
7
7
|
import { timerify } from './Performance.js';
|
|
@@ -128,7 +128,7 @@ export async function globby(patterns, options) {
|
|
|
128
128
|
debugLogObject(relative(options.cwd, dir) || ROOT_WORKSPACE_NAME, 'Glob options', { patterns, ...options });
|
|
129
129
|
return fg.glob(patterns, fastGlobOptions);
|
|
130
130
|
}
|
|
131
|
-
export async function
|
|
131
|
+
export async function getGitIgnoredHandler(options) {
|
|
132
132
|
cachedIgnores.clear();
|
|
133
133
|
if (options.gitignore === false)
|
|
134
134
|
return () => false;
|
package/dist/util/modules.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
|
+
import { DT_SCOPE } from '../constants.js';
|
|
2
3
|
import { _glob } from './glob.js';
|
|
3
4
|
import { getStringValues } from './object.js';
|
|
4
5
|
import { isAbsolute, toPosix } from './path.js';
|
|
@@ -8,26 +9,28 @@ export const getPackageNameFromModuleSpecifier = (moduleSpecifier) => {
|
|
|
8
9
|
const parts = moduleSpecifier.split('/').slice(0, 2);
|
|
9
10
|
return moduleSpecifier.startsWith('@') ? parts.join('/') : parts[0];
|
|
10
11
|
};
|
|
12
|
+
const lastPackageNameMatch = /(?<=node_modules\/)(@[^/]+\/[^/]+|[^/]+)/g;
|
|
11
13
|
export const getPackageNameFromFilePath = (value) => {
|
|
12
|
-
const match = toPosix(value).match(
|
|
14
|
+
const match = toPosix(value).match(lastPackageNameMatch);
|
|
13
15
|
if (match)
|
|
14
16
|
return match[match.length - 1];
|
|
15
17
|
return value;
|
|
16
18
|
};
|
|
19
|
+
const packageNameMatch = /.*\/node_modules\/(.+)/;
|
|
17
20
|
export const normalizeSpecifierFromFilePath = (value) => {
|
|
18
|
-
const match = toPosix(value).match(
|
|
21
|
+
const match = toPosix(value).match(packageNameMatch);
|
|
19
22
|
if (match)
|
|
20
23
|
return match[match.length - 1];
|
|
21
24
|
return value;
|
|
22
25
|
};
|
|
23
26
|
export const isStartsLikePackageName = (specifier) => /^@?[a-z0-9]/.test(specifier);
|
|
24
|
-
export const isDefinitelyTyped = (packageName) => packageName.startsWith(
|
|
27
|
+
export const isDefinitelyTyped = (packageName) => packageName.startsWith(`${DT_SCOPE}/`);
|
|
25
28
|
export const getDefinitelyTypedFor = (packageName) => {
|
|
26
29
|
if (isDefinitelyTyped(packageName))
|
|
27
30
|
return packageName;
|
|
28
31
|
if (packageName.startsWith('@'))
|
|
29
|
-
return
|
|
30
|
-
return
|
|
32
|
+
return [DT_SCOPE, packageName.slice(1).replace('/', '__')].join('/');
|
|
33
|
+
return [DT_SCOPE, packageName].join('/');
|
|
31
34
|
};
|
|
32
35
|
export const getPackageFromDefinitelyTyped = (typedDependency) => {
|
|
33
36
|
if (typedDependency.includes('__')) {
|
|
@@ -58,6 +61,7 @@ export const getEntryPathFromManifest = (manifest, sharedGlobOptions) => {
|
|
|
58
61
|
entryPaths.add(typings);
|
|
59
62
|
return _glob({ ...sharedGlobOptions, patterns: Array.from(entryPaths) });
|
|
60
63
|
};
|
|
64
|
+
const matchDirectives = /^([?!|-]+)?([^!?:]+).*/;
|
|
61
65
|
export const sanitizeSpecifier = (specifier) => {
|
|
62
66
|
if (isBuiltin(specifier))
|
|
63
67
|
return specifier;
|
|
@@ -65,5 +69,5 @@ export const sanitizeSpecifier = (specifier) => {
|
|
|
65
69
|
return specifier;
|
|
66
70
|
if (specifier.startsWith('virtual:'))
|
|
67
71
|
return specifier;
|
|
68
|
-
return specifier.replace(
|
|
72
|
+
return specifier.replace(matchDirectives, '$2');
|
|
69
73
|
};
|
package/dist/util/regex.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
const isRegexLike = /[*+\\(|{^$]/;
|
|
2
|
+
export const toRegexOrString = (value) => typeof value === 'string' && isRegexLike.test(value) ? new RegExp(value) : value;
|
|
2
3
|
export const findMatch = (haystack, needle) => haystack?.find(n => (typeof n === 'string' ? n === needle : n.test(needle)));
|
|
3
4
|
const idCharMatch = /[a-zA-Z0-9$_]/;
|
|
4
5
|
export const isIdChar = (text) => idCharMatch.test(text);
|
package/dist/util/tag.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ALIAS_TAG, BETA_TAG, INTERNAL_TAG, PUBLIC_TAG } from '../constants.js';
|
|
1
2
|
export const splitTags = (rawTags) => {
|
|
2
3
|
const tags = rawTags.flatMap(tag => tag.split(','));
|
|
3
4
|
return tags.reduce(([incl, excl], tag) => {
|
|
@@ -16,8 +17,8 @@ export const shouldIgnore = (jsDocTags, tags) => {
|
|
|
16
17
|
return true;
|
|
17
18
|
return false;
|
|
18
19
|
};
|
|
19
|
-
export const getShouldIgnoreHandler = (isProduction) => (jsDocTags) => jsDocTags.has(
|
|
20
|
-
jsDocTags.has(
|
|
21
|
-
jsDocTags.has(
|
|
22
|
-
(isProduction && jsDocTags.has(
|
|
20
|
+
export const getShouldIgnoreHandler = (isProduction) => (jsDocTags) => jsDocTags.has(PUBLIC_TAG) ||
|
|
21
|
+
jsDocTags.has(BETA_TAG) ||
|
|
22
|
+
jsDocTags.has(ALIAS_TAG) ||
|
|
23
|
+
(isProduction && jsDocTags.has(INTERNAL_TAG));
|
|
23
24
|
export const getShouldIgnoreTagHandler = (tags) => (jsDocTags) => shouldIgnore(jsDocTags, tags);
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.26.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.26.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.26.0",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://knip.dev",
|
|
6
6
|
"repository": {
|
|
@@ -75,7 +75,6 @@
|
|
|
75
75
|
"smol-toml": "^1.1.4",
|
|
76
76
|
"strip-json-comments": "5.0.1",
|
|
77
77
|
"summary": "2.1.0",
|
|
78
|
-
"tsconfig-paths": "^4.2.0",
|
|
79
78
|
"zod": "^3.22.4",
|
|
80
79
|
"zod-validation-error": "^3.0.3"
|
|
81
80
|
},
|