knip 6.5.0 → 6.6.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.
Files changed (41) hide show
  1. package/dist/ConfigurationChief.d.ts +8 -3
  2. package/dist/WorkspaceWorker.d.ts +2 -1
  3. package/dist/WorkspaceWorker.js +18 -0
  4. package/dist/compilers/index.d.ts +10 -0
  5. package/dist/graph/build.js +18 -10
  6. package/dist/plugins/astro/index.js +4 -2
  7. package/dist/plugins/astro/resolveFromAST.d.ts +1 -0
  8. package/dist/plugins/astro/resolveFromAST.js +40 -1
  9. package/dist/plugins/index.d.ts +1 -0
  10. package/dist/plugins/index.js +2 -0
  11. package/dist/plugins/sveltejs-package/helpers.d.ts +8 -0
  12. package/dist/plugins/sveltejs-package/helpers.js +65 -0
  13. package/dist/plugins/sveltejs-package/index.d.ts +3 -0
  14. package/dist/plugins/sveltejs-package/index.js +27 -0
  15. package/dist/plugins/vitest/helpers.d.ts +3 -1
  16. package/dist/plugins/vitest/helpers.js +18 -0
  17. package/dist/plugins/vitest/index.js +5 -19
  18. package/dist/reporters/trace.js +3 -3
  19. package/dist/reporters/util/util.d.ts +2 -2
  20. package/dist/reporters/util/util.js +13 -12
  21. package/dist/reporters/watch.js +4 -4
  22. package/dist/schema/configuration.d.ts +15 -0
  23. package/dist/schema/plugins.d.ts +5 -0
  24. package/dist/schema/plugins.js +1 -0
  25. package/dist/types/PluginNames.d.ts +2 -2
  26. package/dist/types/PluginNames.js +1 -0
  27. package/dist/types/config.d.ts +13 -0
  28. package/dist/typescript/ast-helpers.d.ts +2 -0
  29. package/dist/typescript/ast-helpers.js +3 -3
  30. package/dist/util/colors.d.ts +18 -0
  31. package/dist/util/colors.js +24 -0
  32. package/dist/util/create-options.d.ts +10 -0
  33. package/dist/util/debug.js +2 -4
  34. package/dist/util/glob-core.js +18 -14
  35. package/dist/util/log.js +3 -3
  36. package/dist/util/to-source-path.d.ts +3 -1
  37. package/dist/util/to-source-path.js +43 -20
  38. package/dist/util/trace.js +8 -8
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +2 -3
@@ -1,4 +1,4 @@
1
- import type { Configuration, IgnorePatterns, RawConfiguration, WorkspaceConfiguration } from './types/config.ts';
1
+ import type { Configuration, IgnorePatterns, RawConfiguration, SourceMap, WorkspaceConfiguration } from './types/config.ts';
2
2
  import type { ConfigurationHint } from './types/issues.ts';
3
3
  import type { WorkspacePackage } from './types/package-json.ts';
4
4
  import type { MainOptions } from './util/create-options.ts';
@@ -14,8 +14,7 @@ export type Workspace = {
14
14
  manifestPath: string;
15
15
  manifestStr: string;
16
16
  ignoreMembers: IgnorePatterns;
17
- srcDir?: string;
18
- outDir?: string;
17
+ sourceMaps?: SourceMap[];
19
18
  };
20
19
  export declare class ConfigurationChief {
21
20
  cwd: string;
@@ -637,6 +636,11 @@ export declare class ConfigurationChief {
637
636
  entry?: string | string[] | undefined;
638
637
  project?: string | string[] | undefined;
639
638
  } | undefined;
639
+ 'sveltejs-package'?: string | boolean | string[] | {
640
+ config?: string | string[] | undefined;
641
+ entry?: string | string[] | undefined;
642
+ project?: string | string[] | undefined;
643
+ } | undefined;
640
644
  sveltekit?: string | boolean | string[] | {
641
645
  config?: string | string[] | undefined;
642
646
  entry?: string | string[] | undefined;
@@ -931,6 +935,7 @@ export declare class ConfigurationChief {
931
935
  stryker?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
932
936
  stylelint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
933
937
  svelte?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
938
+ "sveltejs-package"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
934
939
  sveltekit?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
935
940
  svgo?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
936
941
  svgr?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1,6 +1,6 @@
1
1
  import { CacheConsultant } from './CacheConsultant.ts';
2
2
  import { type Workspace } from './ConfigurationChief.ts';
3
- import type { HandleInput, RegisterCompiler, RegisterVisitorsOptions, WorkspaceConfiguration } from './types/config.ts';
3
+ import type { HandleInput, RegisterCompiler, RegisterVisitorsOptions, SourceMap, WorkspaceConfiguration } from './types/config.ts';
4
4
  import type { ConfigurationHint } from './types/issues.ts';
5
5
  import type { PluginName } from './types/PluginNames.ts';
6
6
  import type { PackageJson } from './types/package-json.ts';
@@ -60,6 +60,7 @@ export declare class WorkspaceWorker {
60
60
  getProductionProjectFilePatterns(negatedTestFilePatterns: string[]): string[];
61
61
  private getConfigurationFilePatterns;
62
62
  registerCompilers(registerCompiler: RegisterCompiler): Promise<void>;
63
+ resolveSourceMaps(): Promise<SourceMap[]>;
63
64
  registerVisitors(options: RegisterVisitorsOptions): void;
64
65
  runPlugins(): Promise<Input[]>;
65
66
  private filterTransitiveDependencies;
@@ -170,6 +170,24 @@ export class WorkspaceWorker {
170
170
  await plugin.registerCompilers({ cwd, hasDependency, registerCompiler });
171
171
  }
172
172
  }
173
+ async resolveSourceMaps() {
174
+ const options = {
175
+ cwd: this.dir,
176
+ rootCwd: this.options.cwd,
177
+ manifest: this.manifest,
178
+ rootManifest: this.rootManifest,
179
+ dependencies: this.dependencies,
180
+ };
181
+ const pairs = [];
182
+ for (const pluginName of this.enabledPlugins) {
183
+ const plugin = Plugins[pluginName];
184
+ if (!plugin.resolveSourceMap)
185
+ continue;
186
+ for (const pair of await plugin.resolveSourceMap(options))
187
+ pairs.push(pair);
188
+ }
189
+ return pairs;
190
+ }
173
191
  registerVisitors(options) {
174
192
  for (const pluginName of this.enabledPlugins) {
175
193
  if (options.registeredPlugins.has(pluginName))
@@ -583,6 +583,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
583
583
  entry?: string | string[] | undefined;
584
584
  project?: string | string[] | undefined;
585
585
  } | undefined;
586
+ 'sveltejs-package'?: string | boolean | string[] | {
587
+ config?: string | string[] | undefined;
588
+ entry?: string | string[] | undefined;
589
+ project?: string | string[] | undefined;
590
+ } | undefined;
586
591
  sveltekit?: string | boolean | string[] | {
587
592
  config?: string | string[] | undefined;
588
593
  entry?: string | string[] | undefined;
@@ -1339,6 +1344,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
1339
1344
  entry?: string | string[] | undefined;
1340
1345
  project?: string | string[] | undefined;
1341
1346
  } | undefined;
1347
+ 'sveltejs-package'?: string | boolean | string[] | {
1348
+ config?: string | string[] | undefined;
1349
+ entry?: string | string[] | undefined;
1350
+ project?: string | string[] | undefined;
1351
+ } | undefined;
1342
1352
  sveltekit?: string | boolean | string[] | {
1343
1353
  config?: string | string[] | undefined;
1344
1354
  entry?: string | string[] | undefined;
@@ -14,7 +14,7 @@ import { getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpe
14
14
  import { perfObserver } from '../util/Performance.js';
15
15
  import { getEntrySpecifiersFromManifest, getManifestImportDependencies } from '../util/package-json.js';
16
16
  import { dirname, extname, isAbsolute, isInNodeModules, join, relative } from '../util/path.js';
17
- import { augmentWorkspace, getToSourcePathsHandler } from '../util/to-source-path.js';
17
+ import { augmentWorkspace, getToSourcePathsHandler, toSourceMappedSpecifiers } from '../util/to-source-path.js';
18
18
  import { WorkspaceWorker } from '../WorkspaceWorker.js';
19
19
  export async function build({ chief, collector, counselor, deputy, principal, isGitIgnored, streamer, workspaces, options, }) {
20
20
  const configFilesMap = new Map();
@@ -57,8 +57,6 @@ export async function build({ chief, collector, counselor, deputy, principal, is
57
57
  const tsConfigFilePath = join(dir, options.tsConfigFile ?? 'tsconfig.json');
58
58
  const { isFile, compilerOptions, fileNames } = await loadTSConfig(tsConfigFilePath);
59
59
  const [definitionPaths, tscSourcePaths] = partition(fileNames, filePath => IS_DTS.test(filePath));
60
- if (isFile)
61
- augmentWorkspace(workspace, dir, compilerOptions);
62
60
  const worker = new WorkspaceWorker({
63
61
  name,
64
62
  dir,
@@ -89,6 +87,8 @@ export async function build({ chief, collector, counselor, deputy, principal, is
89
87
  const extensionGlobStr = `.{${[...DEFAULT_EXTENSIONS, ...extensions].map(ext => ext.slice(1)).join(',')}}`;
90
88
  const config = chief.getConfigForWorkspace(name, extensions);
91
89
  worker.config = config;
90
+ const pluginSourceMaps = await worker.resolveSourceMaps();
91
+ augmentWorkspace(workspace, dir, isFile ? compilerOptions : undefined, pluginSourceMaps);
92
92
  const inputs = new Set();
93
93
  if (definitionPaths.length > 0) {
94
94
  debugLogArray(name, 'Definition paths', definitionPaths);
@@ -105,13 +105,21 @@ export async function build({ chief, collector, counselor, deputy, principal, is
105
105
  inputs.add(toProductionEntry(filePath));
106
106
  }
107
107
  for (const identifier of entrySpecifiersFromManifest) {
108
- if (!identifier.startsWith('!') && !isGitIgnored(join(dir, identifier))) {
109
- const exists = identifier.includes('*')
110
- ? _syncGlob({ patterns: [identifier], cwd: dir }).length > 0
111
- : existsSync(join(dir, identifier));
112
- if (!exists) {
113
- collector.addConfigurationHint({ type: 'package-entry', filePath, identifier, workspaceName: name });
114
- }
108
+ if (identifier.startsWith('!') || isGitIgnored(join(dir, identifier)))
109
+ continue;
110
+ if (!identifier.startsWith('.') && !identifier.startsWith('/')) {
111
+ const packageName = getPackageNameFromModuleSpecifier(identifier);
112
+ if (packageName && dependencies.has(packageName))
113
+ continue;
114
+ }
115
+ const abs = prependDir(dir, identifier);
116
+ const mapped = toSourceMappedSpecifiers(workspace, abs, extensionGlobStr);
117
+ const hasWildcard = identifier.includes('*');
118
+ const exists = hasWildcard
119
+ ? _syncGlob({ patterns: [identifier, ...mapped], cwd: dir }).length > 0
120
+ : existsSync(abs) || mapped.some(pattern => _syncGlob({ patterns: [pattern], cwd: dir }).length > 0);
121
+ if (!exists) {
122
+ collector.addConfigurationHint({ type: 'package-entry', filePath, identifier, workspaceName: name });
115
123
  }
116
124
  }
117
125
  for (const dep of getManifestImportDependencies(manifest))
@@ -1,8 +1,9 @@
1
1
  import { toDependency, toEntry, toProductionEntry } from '../../util/input.js';
2
2
  import { hasDependency } from '../../util/plugin.js';
3
+ import { getAliasInputs } from '../vitest/helpers.js';
3
4
  import compiler from './compiler.js';
4
5
  import mdxCompiler from './compiler-mdx.js';
5
- import { getSrcDir, usesPassthroughImageService } from './resolveFromAST.js';
6
+ import { getSrcDir, getViteAliases, usesPassthroughImageService } from './resolveFromAST.js';
6
7
  const title = 'Astro';
7
8
  const enablers = ['astro'];
8
9
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
@@ -16,12 +17,13 @@ const production = [
16
17
  'src/middleware.{js,ts}',
17
18
  'src/actions/index.{js,ts}',
18
19
  ];
19
- const resolveFromAST = program => {
20
+ const resolveFromAST = (program, options) => {
20
21
  const srcDir = getSrcDir(program);
21
22
  const setSrcDir = (entry) => entry.replace(/^src\//, `${srcDir}/`);
22
23
  const inputs = [
23
24
  ...entry.map(setSrcDir).map(path => toEntry(path)),
24
25
  ...production.map(setSrcDir).map(path => toProductionEntry(path)),
26
+ ...getAliasInputs(getViteAliases(program), options.cwd),
25
27
  ];
26
28
  if (!usesPassthroughImageService(program))
27
29
  inputs.push(toDependency('sharp', { optional: true }));
@@ -1,3 +1,4 @@
1
1
  import type { Program } from 'oxc-parser';
2
2
  export declare const getSrcDir: (program: Program) => string;
3
3
  export declare const usesPassthroughImageService: (program: Program) => boolean;
4
+ export declare const getViteAliases: (program: Program) => Record<string, string>;
@@ -1,6 +1,45 @@
1
- import { collectPropertyValues, hasImportSpecifier } from '../../typescript/ast-helpers.js';
1
+ import { collectPropertyValues, findProperty, getPropertyKey, getStringValue, hasImportSpecifier, } from '../../typescript/ast-helpers.js';
2
2
  export const getSrcDir = (program) => {
3
3
  const values = collectPropertyValues(program, 'srcDir');
4
4
  return values.size > 0 ? Array.from(values)[0] : 'src';
5
5
  };
6
6
  export const usesPassthroughImageService = (program) => hasImportSpecifier(program, 'astro/config', 'passthroughImageService');
7
+ const findFirstStringArg = (node) => {
8
+ const literal = getStringValue(node);
9
+ if (literal)
10
+ return literal;
11
+ if (node?.type === 'CallExpression' || node?.type === 'NewExpression') {
12
+ for (const arg of node.arguments ?? []) {
13
+ const found = findFirstStringArg(arg);
14
+ if (found)
15
+ return found;
16
+ }
17
+ }
18
+ };
19
+ export const getViteAliases = (program) => {
20
+ const aliases = {};
21
+ for (const node of program.body ?? []) {
22
+ if (node.type !== 'ExportDefaultDeclaration')
23
+ continue;
24
+ const decl = node.declaration;
25
+ const root = decl?.type === 'ObjectExpression'
26
+ ? decl
27
+ : decl?.type === 'CallExpression' && decl.arguments?.[0]?.type === 'ObjectExpression'
28
+ ? decl.arguments[0]
29
+ : undefined;
30
+ const aliasNode = findProperty(findProperty(findProperty(root, 'vite'), 'resolve'), 'alias');
31
+ if (aliasNode?.type !== 'ObjectExpression')
32
+ continue;
33
+ for (const prop of aliasNode.properties ?? []) {
34
+ if (prop.type !== 'Property')
35
+ continue;
36
+ const key = getPropertyKey(prop);
37
+ if (!key)
38
+ continue;
39
+ const raw = findFirstStringArg(prop.value);
40
+ if (raw)
41
+ aliases[key] = raw;
42
+ }
43
+ }
44
+ return aliases;
45
+ };
@@ -120,6 +120,7 @@ export declare const Plugins: {
120
120
  stryker: import("../types/config.ts").Plugin;
121
121
  stylelint: import("../types/config.ts").Plugin;
122
122
  svelte: import("../types/config.ts").Plugin;
123
+ 'sveltejs-package': import("../types/config.ts").Plugin;
123
124
  sveltekit: import("../types/config.ts").Plugin;
124
125
  svgo: import("../types/config.ts").Plugin;
125
126
  svgr: import("../types/config.ts").Plugin;
@@ -114,6 +114,7 @@ import { default as storybook } from './storybook/index.js';
114
114
  import { default as stryker } from './stryker/index.js';
115
115
  import { default as stylelint } from './stylelint/index.js';
116
116
  import { default as svelte } from './svelte/index.js';
117
+ import { default as sveltejsPackage } from './sveltejs-package/index.js';
117
118
  import { default as sveltekit } from './sveltekit/index.js';
118
119
  import { default as svgo } from './svgo/index.js';
119
120
  import { default as svgr } from './svgr/index.js';
@@ -262,6 +263,7 @@ export const Plugins = {
262
263
  stryker,
263
264
  stylelint,
264
265
  svelte,
266
+ 'sveltejs-package': sveltejsPackage,
265
267
  sveltekit,
266
268
  svgo,
267
269
  svgr,
@@ -0,0 +1,8 @@
1
+ export declare const DEFAULT_INPUT = "src/lib";
2
+ export declare const DEFAULT_OUTPUT = "dist";
3
+ interface IO {
4
+ input: string;
5
+ output: string;
6
+ }
7
+ export declare const parseScripts: (scripts: Record<string, string | undefined> | undefined) => IO[];
8
+ export {};
@@ -0,0 +1,65 @@
1
+ import parseArgs from 'minimist';
2
+ import { parse } from 'unbash';
3
+ const BIN = 'svelte-package';
4
+ export const DEFAULT_INPUT = 'src/lib';
5
+ export const DEFAULT_OUTPUT = 'dist';
6
+ const parseCommandIO = (args) => {
7
+ const parsed = parseArgs(args, { string: ['i', 'o', 'input', 'output'], alias: { input: ['i'], output: ['o'] } });
8
+ return { input: parsed.input ?? DEFAULT_INPUT, output: parsed.output ?? DEFAULT_OUTPUT };
9
+ };
10
+ const collectFromCommands = (statements, out) => {
11
+ for (const stmt of statements)
12
+ visit(stmt.command, out);
13
+ };
14
+ const visit = (node, out) => {
15
+ switch (node.type) {
16
+ case 'Command':
17
+ if (node.name?.value === BIN)
18
+ out.push(parseCommandIO(node.suffix.map(w => w.value)));
19
+ return;
20
+ case 'AndOr':
21
+ case 'Pipeline':
22
+ for (const n of node.commands)
23
+ visit(n, out);
24
+ return;
25
+ case 'If':
26
+ collectFromCommands(node.clause.commands, out);
27
+ collectFromCommands(node.then.commands, out);
28
+ if (node.else)
29
+ visit(node.else, out);
30
+ return;
31
+ case 'While':
32
+ collectFromCommands(node.clause.commands, out);
33
+ collectFromCommands(node.body.commands, out);
34
+ return;
35
+ case 'For':
36
+ case 'Select':
37
+ case 'Subshell':
38
+ case 'BraceGroup':
39
+ collectFromCommands(node.body.commands, out);
40
+ return;
41
+ case 'CompoundList':
42
+ collectFromCommands(node.commands, out);
43
+ return;
44
+ case 'Function':
45
+ case 'Coproc':
46
+ visit(node.body, out);
47
+ return;
48
+ case 'Statement':
49
+ visit(node.command, out);
50
+ }
51
+ };
52
+ export const parseScripts = (scripts) => {
53
+ const out = [];
54
+ for (const script of Object.values(scripts ?? {})) {
55
+ if (typeof script !== 'string' || !script.includes(BIN))
56
+ continue;
57
+ try {
58
+ const parsed = parse(script);
59
+ if (parsed.commands)
60
+ collectFromCommands(parsed.commands, out);
61
+ }
62
+ catch { }
63
+ }
64
+ return out;
65
+ };
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,27 @@
1
+ import { join } from '../../util/path.js';
2
+ import { hasDependency } from '../../util/plugin.js';
3
+ import { DEFAULT_INPUT, DEFAULT_OUTPUT, parseScripts } from './helpers.js';
4
+ const title = '@sveltejs/package';
5
+ const enablers = ['@sveltejs/package'];
6
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
+ const resolveSourceMap = ({ cwd, manifest }) => {
8
+ const ios = parseScripts(manifest.scripts);
9
+ const effective = ios.length > 0 ? ios : [{ input: DEFAULT_INPUT, output: DEFAULT_OUTPUT }];
10
+ const seen = new Set();
11
+ const pairs = [];
12
+ for (const { input, output } of effective) {
13
+ const key = `${input}→${output}`;
14
+ if (seen.has(key))
15
+ continue;
16
+ seen.add(key);
17
+ pairs.push({ srcDir: join(cwd, input), outDir: join(cwd, output) });
18
+ }
19
+ return pairs;
20
+ };
21
+ const plugin = {
22
+ title,
23
+ enablers,
24
+ isEnabled,
25
+ resolveSourceMap,
26
+ };
27
+ export default plugin;
@@ -1,3 +1,5 @@
1
- import type { ViteConfig } from './types.ts';
1
+ import { type Input } from '../../util/input.ts';
2
+ import type { AliasOptions, ViteConfig } from './types.ts';
2
3
  export declare const getEnvSpecifier: (env: string) => string;
4
+ export declare const getAliasInputs: (aliasOptions: AliasOptions, cwd: string) => Input[];
3
5
  export declare const getExternalReporters: (reporters?: ViteConfig['test']['reporters']) => string[];
@@ -1,3 +1,5 @@
1
+ import { toAlias } from '../../util/input.js';
2
+ import { join, toPosix } from '../../util/path.js';
1
3
  const environments = {
2
4
  node: null,
3
5
  jsdom: null,
@@ -29,6 +31,22 @@ const builtInReporters = [
29
31
  'tree',
30
32
  'verbose',
31
33
  ];
34
+ const addStar = (value) => (value.endsWith('*') ? value : join(value, '*').replace(/\/\*\*$/, '/*'));
35
+ export const getAliasInputs = (aliasOptions, cwd) => {
36
+ const inputs = [];
37
+ for (const [alias, value] of Object.entries(aliasOptions)) {
38
+ if (!value)
39
+ continue;
40
+ const prefixes = [value]
41
+ .flat()
42
+ .filter((value) => typeof value === 'string')
43
+ .map(prefix => (toPosix(prefix).startsWith(cwd) ? prefix : join(cwd, prefix)));
44
+ if (alias.length > 1)
45
+ inputs.push(toAlias(alias, prefixes));
46
+ inputs.push(toAlias(addStar(alias), prefixes.map(addStar)));
47
+ }
48
+ return inputs;
49
+ };
32
50
  export const getExternalReporters = (reporters) => reporters
33
51
  ? [reporters]
34
52
  .flat()
@@ -1,10 +1,10 @@
1
1
  import { DEFAULT_EXTENSIONS } from '../../constants.js';
2
2
  import { _glob } from '../../util/glob.js';
3
- import { toAlias, toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
4
- import { isAbsolute, isInternal, join, toAbsolute, toPosix } from '../../util/path.js';
3
+ import { toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
4
+ import { isAbsolute, isInternal, join, toAbsolute } from '../../util/path.js';
5
5
  import { hasDependency } from '../../util/plugin.js';
6
6
  import { getIndexHtmlEntries } from '../vite/helpers.js';
7
- import { getEnvSpecifier, getExternalReporters } from './helpers.js';
7
+ import { getAliasInputs, getEnvSpecifier, getExternalReporters } from './helpers.js';
8
8
  const title = 'Vitest';
9
9
  const enablers = ['vitest'];
10
10
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
@@ -106,23 +106,9 @@ export const resolveConfig = async (localConfig, options) => {
106
106
  }
107
107
  }
108
108
  }
109
- const addStar = (value) => (value.endsWith('*') ? value : join(value, '*').replace(/\/\*\*$/, '/*'));
110
109
  const addAliases = (aliasOptions) => {
111
- for (const [alias, value] of Object.entries(aliasOptions)) {
112
- if (!value)
113
- continue;
114
- const prefixes = [value]
115
- .flat()
116
- .filter(value => typeof value === 'string')
117
- .map(prefix => {
118
- if (toPosix(prefix).startsWith(options.cwd))
119
- return prefix;
120
- return join(options.cwd, prefix);
121
- });
122
- if (alias.length > 1)
123
- inputs.add(toAlias(alias, prefixes));
124
- inputs.add(toAlias(addStar(alias), prefixes.map(addStar)));
125
- }
110
+ for (const input of getAliasInputs(aliasOptions, options.cwd))
111
+ inputs.add(input);
126
112
  };
127
113
  const seenRoots = new Set();
128
114
  for (const cfg of configs) {
@@ -1,4 +1,4 @@
1
- import pc from 'picocolors';
1
+ import st from '../util/colors.js';
2
2
  import { toRelative } from '../util/path.js';
3
3
  import { toRegexOrString } from '../util/regex.js';
4
4
  import { Table } from '../util/table.js';
@@ -19,8 +19,8 @@ export default ({ graph, explorer, options, workspaceFilePathFilter }) => {
19
19
  continue;
20
20
  seen.add(key);
21
21
  table.row();
22
- table.cell('filePath', pc.whiteBright(`${toRel(_import.filePath)}${pos}`));
23
- table.cell('package', pc.cyanBright(packageName));
22
+ table.cell('filePath', st.whiteBright(`${toRel(_import.filePath)}${pos}`));
23
+ table.cell('package', st.cyanBright(packageName));
24
24
  }
25
25
  }
26
26
  for (const line of table.toRows())
@@ -1,8 +1,8 @@
1
1
  import { ISSUE_TYPE_TITLE } from '../../constants.ts';
2
2
  import type { Issue, IssueRecords, IssueSeverity, IssueSymbol, IssueType } from '../../types/issues.ts';
3
3
  import { Table } from '../../util/table.ts';
4
- export declare const dim: import("picocolors/types").Formatter;
5
- export declare const bright: import("picocolors/types").Formatter;
4
+ export declare const dim: (text: string | number | null | undefined) => string;
5
+ export declare const bright: (text: string | number | null | undefined) => string;
6
6
  export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => "Duplicate exports" | "Exported types in used namespace" | "Exports in used namespace" | "Referenced optional peerDependencies" | "Unlisted binaries" | "Unlisted dependencies" | "Unresolved imports" | "Unused catalog entries" | "Unused dependencies" | "Unused devDependencies" | "Unused exported enum members" | "Unused exported namespace members" | "Unused exported types" | "Unused exports" | "Unused files";
7
7
  export declare const getColoredTitle: (title: string, count: number) => string;
8
8
  export declare const getDimmedTitle: (title: string, count: number) => string;
@@ -1,19 +1,18 @@
1
- import picocolors from 'picocolors';
2
1
  import { ISSUE_TYPE_TITLE, SYMBOL_TYPE } from '../../constants.js';
2
+ import st from '../../util/colors.js';
3
3
  import { relative } from '../../util/path.js';
4
4
  import { Table } from '../../util/table.js';
5
5
  const plain = (text) => text;
6
- export const dim = picocolors.gray;
7
- export const bright = picocolors.whiteBright;
8
- const yellow = picocolors.yellow;
6
+ export const dim = st.gray;
7
+ export const bright = st.whiteBright;
9
8
  export const getIssueTypeTitle = (reportType) => ISSUE_TYPE_TITLE[reportType];
10
- export const getColoredTitle = (title, count) => `${picocolors.yellowBright(picocolors.underline(title))} (${count})`;
11
- export const getDimmedTitle = (title, count) => `${yellow(`${picocolors.underline(title)} (${count})`)}`;
9
+ export const getColoredTitle = (title, count) => `${st.style(['yellowBright', 'underline'], title)} (${count})`;
10
+ export const getDimmedTitle = (title, count) => `${st.yellow(`${st.underline(title)} (${count})`)}`;
12
11
  export const getIssueLine = ({ owner, filePath, symbols, parentSymbol, severity }, cwd) => {
13
12
  const symbol = symbols ? `: ${symbols.map(s => s.symbol).join(', ')}` : '';
14
13
  const parent = parentSymbol ? ` (${parentSymbol})` : '';
15
14
  const print = severity === 'warn' ? dim : plain;
16
- return `${owner ? `${picocolors.cyan(owner)} ` : ''}${print(`${relative(cwd, filePath)}${symbol}${parent}`)}`;
15
+ return `${owner ? `${st.cyan(owner)} ` : ''}${print(`${relative(cwd, filePath)}${symbol}${parent}`)}`;
17
16
  };
18
17
  export const convert = (issue) => ({
19
18
  namespace: 'parentSymbol' in issue ? issue.parentSymbol : undefined,
@@ -32,12 +31,14 @@ const sortByPos = (a, b) => {
32
31
  : filePathA.localeCompare(filePathB);
33
32
  };
34
33
  const highlightSymbol = (issue) => (_) => {
35
- if (issue.specifier && issue.specifier !== issue.symbol && issue.specifier.includes(issue.symbol)) {
36
- const parts = issue.specifier.split(issue.symbol);
37
- const rest = parts.slice(1).join('');
38
- return [dim(parts[0]), bright(issue.symbol), dim(rest)].join('');
34
+ const { specifier, symbol } = issue;
35
+ if (specifier && specifier !== symbol) {
36
+ const idx = specifier.indexOf(symbol);
37
+ if (idx !== -1) {
38
+ return `${dim(specifier.slice(0, idx))}${bright(symbol)}${dim(specifier.slice(idx + symbol.length))}`;
39
+ }
39
40
  }
40
- return issue.symbol;
41
+ return symbol;
41
42
  };
42
43
  export const getTableForType = (issues, cwd, options = { isUseColors: true }) => {
43
44
  const table = new Table({ truncateStart: ['filePath'], noTruncate: ['symbolType'] });
@@ -1,4 +1,4 @@
1
- import picocolors from 'picocolors';
1
+ import st from '../util/colors.js';
2
2
  import { perfObserver } from '../util/Performance.js';
3
3
  import { prettyMilliseconds } from '../util/string.js';
4
4
  import { flattenIssues, getIssueTypeTitle, getTableForType } from './util/util.js';
@@ -12,7 +12,7 @@ export default (options, { issues, streamer, duration, size }) => {
12
12
  const issuesForType = flattenIssues(issues[reportType]);
13
13
  if (issuesForType.length > 0) {
14
14
  if (title) {
15
- lines.push(`${picocolors.yellowBright(picocolors.underline(title))} (${issuesForType.length})`);
15
+ lines.push(`${st.style(['yellowBright', 'underline'], title)} (${issuesForType.length})`);
16
16
  }
17
17
  lines.push(...getTableForType(issuesForType, options.cwd).toRows());
18
18
  }
@@ -23,8 +23,8 @@ export default (options, { issues, streamer, duration, size }) => {
23
23
  const ms = duration ?? perfObserver.getCurrentDurationInMs();
24
24
  const summary = `${size} files (${prettyMilliseconds(ms)} • ${mem}MB)`;
25
25
  const messages = totalIssues === 0
26
- ? ['✂️ Excellent, Knip found no issues.', '', picocolors.gray(summary)]
27
- : [...lines, '', picocolors.gray(summary)];
26
+ ? ['✂️ Excellent, Knip found no issues.', '', st.gray(summary)]
27
+ : [...lines, '', st.gray(summary)];
28
28
  if (options.isDebug)
29
29
  console.log(messages.join('\n'));
30
30
  else
@@ -581,6 +581,11 @@ export declare const workspaceConfigurationSchema: z.ZodMiniObject<{
581
581
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
582
582
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
583
583
  }, z.core.$strip>]>>;
584
+ 'sveltejs-package': z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
585
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
586
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
587
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
588
+ }, z.core.$strip>]>>;
584
589
  sveltekit: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
585
590
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
586
591
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -1328,6 +1333,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1328
1333
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1329
1334
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1330
1335
  }, z.core.$strip>]>>;
1336
+ 'sveltejs-package': z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
1337
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1338
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1339
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1340
+ }, z.core.$strip>]>>;
1331
1341
  sveltekit: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
1332
1342
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1333
1343
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -2092,6 +2102,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
2092
2102
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2093
2103
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2094
2104
  }, z.core.$strip>]>>;
2105
+ 'sveltejs-package': z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
2106
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2107
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2108
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2109
+ }, z.core.$strip>]>>;
2095
2110
  sveltekit: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
2096
2111
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
2097
2112
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -586,6 +586,11 @@ export declare const pluginsSchema: z.ZodMiniObject<{
586
586
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
587
587
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
588
588
  }, z.core.$strip>]>;
589
+ 'sveltejs-package': z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
590
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
591
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
592
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
593
+ }, z.core.$strip>]>;
589
594
  sveltekit: z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
590
595
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
591
596
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -126,6 +126,7 @@ export const pluginsSchema = z.object({
126
126
  stryker: pluginSchema,
127
127
  stylelint: pluginSchema,
128
128
  svelte: pluginSchema,
129
+ 'sveltejs-package': pluginSchema,
129
130
  sveltekit: pluginSchema,
130
131
  svgo: pluginSchema,
131
132
  svgr: pluginSchema,
@@ -1,2 +1,2 @@
1
- export type PluginName = 'angular' | 'astro' | 'astro-db' | 'astro-og-canvas' | 'ava' | 'babel' | 'biome' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'danger' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'execa' | 'expo' | 'expressive-code' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'knex' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'mdx' | 'mdxlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'next-intl' | 'next-mdx' | 'nitro' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'openapi-ts' | 'oxfmt' | 'oxlint' | 'panda-css' | 'parcel' | 'payload' | 'pino' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pm2' | 'pnpm' | 'postcss' | 'preconstruct' | 'prettier' | 'prisma' | 'qwik' | 'raycast' | 'react-cosmos' | 'react-email' | 'react-native' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rolldown' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'sanity' | 'semantic-release' | 'sentry' | 'serverless-framework' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'stencil' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'sveltekit' | 'svgo' | 'svgr' | 'swc' | 'syncpack' | 'tailwind' | 'tanstack-router' | 'taskfile' | 'travis' | 'ts-node' | 'tsdown' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitepress' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie' | 'zx';
2
- export declare const pluginNames: readonly ['angular', 'astro', 'astro-db', 'astro-og-canvas', 'ava', 'babel', 'biome', 'bumpp', 'bun', 'c8', 'capacitor', 'changelogen', 'changelogithub', 'changesets', 'commitizen', 'commitlint', 'convex', 'create-typescript-app', 'cspell', 'cucumber', 'cypress', 'danger', 'dependency-cruiser', 'docusaurus', 'dotenv', 'drizzle', 'eleventy', 'eslint', 'execa', 'expo', 'expressive-code', 'gatsby', 'github-action', 'github-actions', 'glob', 'graphql-codegen', 'hardhat', 'husky', 'i18next-parser', 'jest', 'karma', 'knex', 'ladle', 'lefthook', 'lint-staged', 'linthtml', 'lockfile-lint', 'lost-pixel', 'markdownlint', 'mdx', 'mdxlint', 'metro', 'mocha', 'moonrepo', 'msw', 'nano-staged', 'nest', 'netlify', 'next', 'next-intl', 'next-mdx', 'nitro', 'node', 'node-modules-inspector', 'nodemon', 'npm-package-json-lint', 'nuxt', 'nx', 'nyc', 'oclif', 'openapi-ts', 'oxfmt', 'oxlint', 'panda-css', 'parcel', 'payload', 'pino', 'playwright', 'playwright-ct', 'playwright-test', 'plop', 'pm2', 'pnpm', 'postcss', 'preconstruct', 'prettier', 'prisma', 'qwik', 'raycast', 'react-cosmos', 'react-email', 'react-native', 'react-router', 'relay', 'release-it', 'remark', 'remix', 'rolldown', 'rollup', 'rsbuild', 'rslib', 'rspack', 'rstest', 'sanity', 'semantic-release', 'sentry', 'serverless-framework', 'simple-git-hooks', 'size-limit', 'sst', 'starlight', 'stencil', 'storybook', 'stryker', 'stylelint', 'svelte', 'sveltekit', 'svgo', 'svgr', 'swc', 'syncpack', 'tailwind', 'tanstack-router', 'taskfile', 'travis', 'ts-node', 'tsdown', 'tsup', 'tsx', 'typedoc', 'typescript', 'unbuild', 'unocss', 'vercel-og', 'vike', 'vite', 'vitepress', 'vitest', 'vue', 'webdriver-io', 'webpack', 'wireit', 'wrangler', 'xo', 'yarn', 'yorkie', 'zx'];
1
+ export type PluginName = 'angular' | 'astro' | 'astro-db' | 'astro-og-canvas' | 'ava' | 'babel' | 'biome' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'danger' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'execa' | 'expo' | 'expressive-code' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'knex' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'mdx' | 'mdxlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'next-intl' | 'next-mdx' | 'nitro' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'openapi-ts' | 'oxfmt' | 'oxlint' | 'panda-css' | 'parcel' | 'payload' | 'pino' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pm2' | 'pnpm' | 'postcss' | 'preconstruct' | 'prettier' | 'prisma' | 'qwik' | 'raycast' | 'react-cosmos' | 'react-email' | 'react-native' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rolldown' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'sanity' | 'semantic-release' | 'sentry' | 'serverless-framework' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'stencil' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'sveltejs-package' | 'sveltekit' | 'svgo' | 'svgr' | 'swc' | 'syncpack' | 'tailwind' | 'tanstack-router' | 'taskfile' | 'travis' | 'ts-node' | 'tsdown' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitepress' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie' | 'zx';
2
+ export declare const pluginNames: readonly ['angular', 'astro', 'astro-db', 'astro-og-canvas', 'ava', 'babel', 'biome', 'bumpp', 'bun', 'c8', 'capacitor', 'changelogen', 'changelogithub', 'changesets', 'commitizen', 'commitlint', 'convex', 'create-typescript-app', 'cspell', 'cucumber', 'cypress', 'danger', 'dependency-cruiser', 'docusaurus', 'dotenv', 'drizzle', 'eleventy', 'eslint', 'execa', 'expo', 'expressive-code', 'gatsby', 'github-action', 'github-actions', 'glob', 'graphql-codegen', 'hardhat', 'husky', 'i18next-parser', 'jest', 'karma', 'knex', 'ladle', 'lefthook', 'lint-staged', 'linthtml', 'lockfile-lint', 'lost-pixel', 'markdownlint', 'mdx', 'mdxlint', 'metro', 'mocha', 'moonrepo', 'msw', 'nano-staged', 'nest', 'netlify', 'next', 'next-intl', 'next-mdx', 'nitro', 'node', 'node-modules-inspector', 'nodemon', 'npm-package-json-lint', 'nuxt', 'nx', 'nyc', 'oclif', 'openapi-ts', 'oxfmt', 'oxlint', 'panda-css', 'parcel', 'payload', 'pino', 'playwright', 'playwright-ct', 'playwright-test', 'plop', 'pm2', 'pnpm', 'postcss', 'preconstruct', 'prettier', 'prisma', 'qwik', 'raycast', 'react-cosmos', 'react-email', 'react-native', 'react-router', 'relay', 'release-it', 'remark', 'remix', 'rolldown', 'rollup', 'rsbuild', 'rslib', 'rspack', 'rstest', 'sanity', 'semantic-release', 'sentry', 'serverless-framework', 'simple-git-hooks', 'size-limit', 'sst', 'starlight', 'stencil', 'storybook', 'stryker', 'stylelint', 'svelte', 'sveltejs-package', 'sveltekit', 'svgo', 'svgr', 'swc', 'syncpack', 'tailwind', 'tanstack-router', 'taskfile', 'travis', 'ts-node', 'tsdown', 'tsup', 'tsx', 'typedoc', 'typescript', 'unbuild', 'unocss', 'vercel-og', 'vike', 'vite', 'vitepress', 'vitest', 'vue', 'webdriver-io', 'webpack', 'wireit', 'wrangler', 'xo', 'yarn', 'yorkie', 'zx'];
@@ -115,6 +115,7 @@ export const pluginNames = [
115
115
  'stryker',
116
116
  'stylelint',
117
117
  'svelte',
118
+ 'sveltejs-package',
118
119
  'sveltekit',
119
120
  'svgo',
120
121
  'svgr',
@@ -96,6 +96,18 @@ type PluginSetup = () => Promise<void> | void;
96
96
  export type IsLoadConfig = (options: PluginOptions, dependencies: Set<string>) => boolean;
97
97
  export type ResolveConfig<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];
98
98
  export type Resolve = (options: PluginOptions) => Promise<Input[]> | Input[];
99
+ export type SourceMap = {
100
+ srcDir: string;
101
+ outDir: string;
102
+ };
103
+ export interface ResolveSourceMapOptions {
104
+ cwd: string;
105
+ manifest: PackageJson;
106
+ dependencies: Set<string>;
107
+ rootCwd: string;
108
+ rootManifest: PackageJson | undefined;
109
+ }
110
+ export type ResolveSourceMap = (options: ResolveSourceMapOptions) => Promise<SourceMap[]> | SourceMap[];
99
111
  export type HandleInput = (input: Input) => string | undefined;
100
112
  export type RegisterCompilerInput = {
101
113
  extension: string;
@@ -141,6 +153,7 @@ export interface Plugin {
141
153
  isLoadConfig?: IsLoadConfig;
142
154
  resolveConfig?: ResolveConfig;
143
155
  resolve?: Resolve;
156
+ resolveSourceMap?: ResolveSourceMap;
144
157
  resolveFromAST?: ResolveFromAST;
145
158
  isFilterTransitiveDependencies?: boolean;
146
159
  registerCompilers?: RegisterCompilers;
@@ -1,4 +1,6 @@
1
1
  import type { ParseResult, Program } from 'oxc-parser';
2
+ export declare const getStringValue: (node: any) => string | undefined;
3
+ export declare const getPropertyKey: (prop: any) => string | undefined;
2
4
  export declare const getImportMap: (program: Program) => Map<string, string>;
3
5
  export declare const getDefaultImportName: (importMap: Map<string, string>, specifier: string) => string | undefined;
4
6
  export declare const getPropertyValues: (node: any, propertyName: string) => Set<string>;
@@ -3,7 +3,8 @@ import stripJsonComments from 'strip-json-comments';
3
3
  import { extname, isInternal } from '../util/path.js';
4
4
  import { parseFile } from './visitors/helpers.js';
5
5
  const isStringLiteral = (node) => node?.type === 'StringLiteral' || (node?.type === 'Literal' && typeof node.value === 'string');
6
- const getStringValue = (node) => (isStringLiteral(node) ? node.value : undefined);
6
+ export const getStringValue = (node) => (isStringLiteral(node) ? node.value : undefined);
7
+ export const getPropertyKey = (prop) => prop?.key?.type === 'Identifier' ? prop.key.name : getStringValue(prop?.key);
7
8
  export const getImportMap = (program) => {
8
9
  const importMap = new Map();
9
10
  for (const node of program.body ?? []) {
@@ -101,9 +102,8 @@ export const findProperty = (node, name) => {
101
102
  if (node?.type !== 'ObjectExpression')
102
103
  return;
103
104
  for (const prop of node.properties ?? []) {
104
- if (prop.type === 'Property' && (prop.key?.name === name || prop.key?.value === name)) {
105
+ if (prop.type === 'Property' && getPropertyKey(prop) === name)
105
106
  return prop.value;
106
- }
107
107
  }
108
108
  };
109
109
  export const getStringValues = (node) => {
@@ -0,0 +1,18 @@
1
+ import { styleText } from 'node:util';
2
+ type Modifier = Parameters<typeof styleText>[0];
3
+ type Input = string | number | null | undefined;
4
+ declare const st: {
5
+ red: (text: Input) => string;
6
+ green: (text: Input) => string;
7
+ yellow: (text: Input) => string;
8
+ cyan: (text: Input) => string;
9
+ white: (text: Input) => string;
10
+ gray: (text: Input) => string;
11
+ dim: (text: Input) => string;
12
+ underline: (text: Input) => string;
13
+ cyanBright: (text: Input) => string;
14
+ whiteBright: (text: Input) => string;
15
+ yellowBright: (text: Input) => string;
16
+ style: (mods: Modifier, text: Input) => string;
17
+ };
18
+ export default st;
@@ -0,0 +1,24 @@
1
+ import { styleText } from 'node:util';
2
+ const isColors = !process.env.NO_COLOR && (process.env.FORCE_COLOR === '1' || !!process.stdout.isTTY);
3
+ const make = (mod) => (text) => {
4
+ const str = String(text);
5
+ return isColors ? styleText(mod, str, { validateStream: false }) : str;
6
+ };
7
+ const st = {
8
+ red: make('red'),
9
+ green: make('green'),
10
+ yellow: make('yellow'),
11
+ cyan: make('cyan'),
12
+ white: make('white'),
13
+ gray: make('gray'),
14
+ dim: make('dim'),
15
+ underline: make('underline'),
16
+ cyanBright: make('cyanBright'),
17
+ whiteBright: make('whiteBright'),
18
+ yellowBright: make('yellowBright'),
19
+ style: (mods, text) => {
20
+ const str = String(text);
21
+ return isColors ? styleText(mods, str, { validateStream: false }) : str;
22
+ },
23
+ };
24
+ export default st;
@@ -621,6 +621,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
621
621
  entry?: string | string[] | undefined;
622
622
  project?: string | string[] | undefined;
623
623
  } | undefined;
624
+ 'sveltejs-package'?: string | boolean | string[] | {
625
+ config?: string | string[] | undefined;
626
+ entry?: string | string[] | undefined;
627
+ project?: string | string[] | undefined;
628
+ } | undefined;
624
629
  sveltekit?: string | boolean | string[] | {
625
630
  config?: string | string[] | undefined;
626
631
  entry?: string | string[] | undefined;
@@ -1379,6 +1384,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1379
1384
  entry?: string | string[] | undefined;
1380
1385
  project?: string | string[] | undefined;
1381
1386
  } | undefined;
1387
+ 'sveltejs-package'?: string | boolean | string[] | {
1388
+ config?: string | string[] | undefined;
1389
+ entry?: string | string[] | undefined;
1390
+ project?: string | string[] | undefined;
1391
+ } | undefined;
1382
1392
  sveltekit?: string | boolean | string[] | {
1383
1393
  config?: string | string[] | undefined;
1384
1394
  entry?: string | string[] | undefined;
@@ -1,14 +1,12 @@
1
1
  import util, { parseArgs } from 'node:util';
2
- import picocolors from 'picocolors';
2
+ import st from './colors.js';
3
3
  const { values } = parseArgs({ strict: false, options: { debug: { type: 'boolean' } } });
4
4
  const IS_DEBUG_ENABLED = values.debug ?? false;
5
5
  const IS_COLORS = !process.env.NO_COLOR;
6
6
  const noop = () => { };
7
7
  const inspectOptions = { maxArrayLength: null, depth: null, colors: IS_COLORS };
8
8
  export const inspect = (obj) => console.log(util.inspect(obj, inspectOptions));
9
- const ctx = (text) => typeof text === 'string'
10
- ? picocolors.yellow(`[${text}]`)
11
- : `${picocolors.yellow(`[${text[0]}]`)} ${picocolors.cyan(text[1])}`;
9
+ const ctx = (text) => typeof text === 'string' ? st.yellow(`[${text}]`) : `${st.yellow(`[${text[0]}]`)} ${st.cyan(text[1])}`;
12
10
  const logArray = (collection) => {
13
11
  console.log(util.inspect(collection.sort(), inspectOptions));
14
12
  };
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { promisify } from 'node:util';
3
- import { walk as _walk } from '@nodelib/fs.walk';
2
+ import { basename } from 'node:path';
3
+ import { fdir } from 'fdir';
4
4
  import { glob as tinyGlob } from 'tinyglobby';
5
5
  import picomatch from 'picomatch';
6
6
  import { GLOBAL_IGNORE_PATTERNS } from '../constants.js';
@@ -10,7 +10,6 @@ import { isDirectory, isFile } from './fs.js';
10
10
  import { timerify } from './Performance.js';
11
11
  import { expandIgnorePatterns, parseAndConvertGitignorePatterns } from './parse-and-convert-gitignores.js';
12
12
  import { dirname, join, relative, toPosix } from './path.js';
13
- const walk = promisify(_walk);
14
13
  const cachedGitIgnores = new Map();
15
14
  const cachedGlobIgnores = new Map();
16
15
  const isGitRoot = (dir) => isDirectory(dir, '.git') || isFile(dir, '.git');
@@ -155,19 +154,24 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
155
154
  };
156
155
  }
157
156
  }
158
- const entryFilter = (entry) => {
159
- if (entry.dirent.isFile() && entry.name === '.gitignore') {
160
- addFile(entry.path);
157
+ const cwdPrefixLen = cwd.length + 1;
158
+ const walkGitignores = async () => {
159
+ await new fdir()
160
+ .withFullPaths()
161
+ .exclude((_dirName, dirPath) => {
162
+ const absPath = toPosix(dirPath.slice(0, -1));
163
+ return (isRelevantDir && !isRelevantDir(absPath)) || getMatcher()(absPath.slice(cwdPrefixLen));
164
+ })
165
+ .filter((filePath, isDir) => {
166
+ if (isDir || basename(filePath) !== '.gitignore')
167
+ return false;
168
+ addFile(filePath);
161
169
  return true;
162
- }
163
- return false;
170
+ })
171
+ .crawl(cwd)
172
+ .withPromise();
164
173
  };
165
- const deepFilter = (entry) => (!isRelevantDir || isRelevantDir(toPosix(entry.path))) && !getMatcher()(relative(cwd, entry.path));
166
- await walk(cwd, {
167
- concurrency: 16,
168
- entryFilter,
169
- deepFilter,
170
- });
174
+ await timerify(walkGitignores)();
171
175
  if (unignores.size > 0) {
172
176
  const unignorePaths = new Set();
173
177
  for (const u of unignores) {
package/dist/util/log.js CHANGED
@@ -1,7 +1,7 @@
1
- import picocolors from 'picocolors';
1
+ import st from './colors.js';
2
2
  export const logWarning = (prefix, message) => {
3
- console.warn(`${picocolors.yellow(prefix)}: ${message}`);
3
+ console.warn(`${st.yellow(prefix)}: ${message}`);
4
4
  };
5
5
  export const logError = (prefix, message) => {
6
- console.error(`${picocolors.red(prefix)}: ${message}`);
6
+ console.error(`${st.red(prefix)}: ${message}`);
7
7
  };
@@ -1,6 +1,8 @@
1
+ import type { SourceMap } from '../types/config.ts';
1
2
  import type { CompilerOptions } from '../types/project.ts';
2
3
  import type { ConfigurationChief, Workspace } from '../ConfigurationChief.ts';
3
- export declare const augmentWorkspace: (workspace: Workspace, dir: string, compilerOptions: CompilerOptions) => void;
4
+ export declare const augmentWorkspace: (workspace: Workspace, dir: string, compilerOptions: CompilerOptions | undefined, pluginSourceMaps?: SourceMap[]) => void;
4
5
  export declare const getModuleSourcePathHandler: (chief: ConfigurationChief) => (filePath: string) => string | undefined;
5
6
  export declare const getToSourcePathsHandler: (chief: ConfigurationChief) => (specifiers: Set<string>, dir: string, extensions: (string | undefined) | undefined, label: string) => Promise<string[]>;
7
+ export declare const toSourceMappedSpecifiers: (ws: Workspace | undefined, absSpecifier: string, extensions?: string) => string[];
6
8
  export type ToSourceFilePath = ReturnType<typeof getModuleSourcePathHandler>;
@@ -7,11 +7,26 @@ const defaultExtensions = `.{${[...DEFAULT_EXTENSIONS].map(ext => ext.slice(1)).
7
7
  const hasTSExt = /(?<!\.d)\.(m|c)?tsx?$/;
8
8
  const matchExt = /(\.d)?\.(m|c)?(j|t)s$/;
9
9
  const sourceExtensions = [...DEFAULT_EXTENSIONS];
10
- export const augmentWorkspace = (workspace, dir, compilerOptions) => {
10
+ const tsconfigSourceMap = (dir, compilerOptions) => {
11
11
  const srcDir = join(dir, 'src');
12
12
  const outDirHasSrc = compilerOptions.outDir && isDirectory(compilerOptions.outDir, 'src');
13
- workspace.srcDir = compilerOptions.rootDir ?? (outDirHasSrc ? dir : isDirectory(srcDir) ? srcDir : dir);
14
- workspace.outDir = compilerOptions.outDir || workspace.srcDir;
13
+ const resolvedSrc = compilerOptions.rootDir ?? (outDirHasSrc ? dir : isDirectory(srcDir) ? srcDir : dir);
14
+ return { srcDir: resolvedSrc, outDir: compilerOptions.outDir || resolvedSrc };
15
+ };
16
+ export const augmentWorkspace = (workspace, dir, compilerOptions, pluginSourceMaps = []) => {
17
+ const all = compilerOptions ? [...pluginSourceMaps, tsconfigSourceMap(dir, compilerOptions)] : pluginSourceMaps;
18
+ if (all.length === 0)
19
+ return;
20
+ workspace.sourceMaps = all.sort((a, b) => b.outDir.length - a.outDir.length);
21
+ };
22
+ const isUnderOutDir = (absPath, outDir) => absPath === outDir || absPath.startsWith(`${outDir}/`);
23
+ const isUnderSrcDir = (absPath, srcDir) => absPath === srcDir || absPath.startsWith(`${srcDir}/`);
24
+ const rewritePattern = (sourceMaps, absSpecifier, extensions) => {
25
+ for (const { srcDir, outDir } of sourceMaps) {
26
+ if (!isUnderSrcDir(absSpecifier, srcDir) && isUnderOutDir(absSpecifier, outDir)) {
27
+ return srcDir + absSpecifier.slice(outDir.length).replace(matchExt, extensions);
28
+ }
29
+ }
15
30
  };
16
31
  export const getModuleSourcePathHandler = (chief) => {
17
32
  const toSourceMapCache = new Map();
@@ -21,16 +36,18 @@ export const getModuleSourcePathHandler = (chief) => {
21
36
  if (toSourceMapCache.has(filePath))
22
37
  return toSourceMapCache.get(filePath);
23
38
  const workspace = chief.findWorkspaceByFilePath(filePath);
24
- if (workspace?.srcDir && workspace.outDir) {
25
- if (filePath.startsWith(workspace.outDir) || workspace.srcDir === workspace.outDir) {
26
- const basePath = filePath.replace(workspace.outDir, workspace.srcDir).replace(matchExt, '');
27
- const srcFilePath = findFileWithExtensions(basePath, sourceExtensions);
28
- if (srcFilePath) {
29
- toSourceMapCache.set(filePath, srcFilePath);
30
- if (srcFilePath !== filePath) {
31
- debugLog('*', `Source mapping ${toRelative(filePath, chief.cwd)} → ${toRelative(srcFilePath, chief.cwd)}`);
32
- return srcFilePath;
33
- }
39
+ if (!workspace?.sourceMaps)
40
+ return;
41
+ for (const { srcDir, outDir } of workspace.sourceMaps) {
42
+ if (!(isUnderOutDir(filePath, outDir) || srcDir === outDir))
43
+ continue;
44
+ const basePath = (srcDir + filePath.slice(outDir.length)).replace(matchExt, '');
45
+ const srcFilePath = findFileWithExtensions(basePath, sourceExtensions);
46
+ if (srcFilePath) {
47
+ toSourceMapCache.set(filePath, srcFilePath);
48
+ if (srcFilePath !== filePath) {
49
+ debugLog('*', `Source mapping ${toRelative(filePath, chief.cwd)} → ${toRelative(srcFilePath, chief.cwd)}`);
50
+ return srcFilePath;
34
51
  }
35
52
  }
36
53
  }
@@ -42,16 +59,22 @@ export const getToSourcePathsHandler = (chief) => {
42
59
  for (const specifier of specifiers) {
43
60
  const absSpecifier = isAbsolute(specifier) ? specifier : prependDirToPattern(dir, specifier);
44
61
  const ws = chief.findWorkspaceByFilePath(absSpecifier);
45
- if (ws?.srcDir && ws.outDir && !absSpecifier.startsWith(ws.srcDir) && absSpecifier.startsWith(ws.outDir)) {
46
- const pattern = absSpecifier.replace(ws.outDir, ws.srcDir).replace(matchExt, extensions);
47
- patterns.add(pattern);
48
- }
49
- else {
50
- patterns.add(absSpecifier);
51
- }
62
+ const mapped = ws?.sourceMaps && rewritePattern(ws.sourceMaps, absSpecifier, extensions);
63
+ patterns.add(mapped ?? absSpecifier);
52
64
  }
53
65
  const filePaths = await _glob({ patterns: Array.from(patterns), cwd: dir, label });
54
66
  debugLogArray(toRelative(dir, chief.cwd), 'Source mapping (package.json)', filePaths);
55
67
  return filePaths;
56
68
  };
57
69
  };
70
+ export const toSourceMappedSpecifiers = (ws, absSpecifier, extensions = defaultExtensions) => {
71
+ const out = [];
72
+ if (!ws?.sourceMaps)
73
+ return out;
74
+ for (const { srcDir, outDir } of ws.sourceMaps) {
75
+ if (!isUnderSrcDir(absSpecifier, srcDir) && isUnderOutDir(absSpecifier, outDir)) {
76
+ out.push(srcDir + absSpecifier.slice(outDir.length).replace(matchExt, extensions));
77
+ }
78
+ }
79
+ return out;
80
+ };
@@ -1,13 +1,13 @@
1
- import pc from 'picocolors';
1
+ import st from './colors.js';
2
2
  export const formatTrace = (node, toRelative, isReferenced, memberStatuses) => {
3
3
  const lines = [];
4
- const file = pc.white;
5
- const id = pc.cyanBright;
6
- const ref = pc.cyanBright;
7
- const via = pc.dim;
8
- const ok = pc.green;
9
- const fail = pc.red;
10
- const dim = pc.dim;
4
+ const file = st.white;
5
+ const id = st.cyanBright;
6
+ const ref = st.cyanBright;
7
+ const via = st.dim;
8
+ const ok = st.green;
9
+ const fail = st.red;
10
+ const dim = st.dim;
11
11
  const entryMarker = node.isEntry ? dim(' ⎆') : '';
12
12
  lines.push(`${file(toRelative(node.filePath))}${dim(':')}${id(node.identifier)}${entryMarker}`);
13
13
  const formatVia = (child) => {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "6.5.0";
1
+ export declare const version = "6.6.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '6.5.0';
1
+ export const version = '6.6.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "6.5.0",
3
+ "version": "6.6.0",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "keywords": [
6
6
  "analysis",
@@ -77,14 +77,13 @@
77
77
  }
78
78
  },
79
79
  "dependencies": {
80
- "@nodelib/fs.walk": "^1.2.3",
80
+ "fdir": "^6.5.0",
81
81
  "formatly": "^0.3.0",
82
82
  "get-tsconfig": "4.14.0",
83
83
  "jiti": "^2.6.0",
84
84
  "minimist": "^1.2.8",
85
85
  "oxc-parser": "^0.126.0",
86
86
  "oxc-resolver": "^11.19.1",
87
- "picocolors": "^1.1.1",
88
87
  "picomatch": "^4.0.4",
89
88
  "smol-toml": "^1.6.1",
90
89
  "strip-json-comments": "5.0.3",