knip 5.51.1 → 5.53.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.
@@ -150,6 +150,7 @@ export declare class ConfigurationChief {
150
150
  stryker?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
151
151
  stylelint?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
152
152
  svelte?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
153
+ svgo?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
153
154
  syncpack?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
154
155
  tailwind?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
155
156
  travis?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
@@ -307,7 +307,7 @@ export class ConfigurationChief {
307
307
  getNegatedWorkspacePatterns(name) {
308
308
  const descendentWorkspaces = this.getDescendentWorkspaces(name);
309
309
  const matchName = new RegExp(`^${name}/`);
310
- const ignoredWorkspaces = this.getIgnoredWorkspacesFor(name);
310
+ const ignoredWorkspaces = this.getIgnoredWorkspacesFor(name).map(p => p.replace(/\/\*$/, '/**'));
311
311
  return [...ignoredWorkspaces, ...descendentWorkspaces]
312
312
  .map(workspaceName => workspaceName.replace(matchName, ''))
313
313
  .map(workspaceName => `!${workspaceName}`);
@@ -236,7 +236,7 @@ export class WorkspaceWorker {
236
236
  addInput(toInput(id));
237
237
  }
238
238
  else if ((!plugin.resolveEntryPaths && !plugin.resolveFromAST) ||
239
- (configFilePaths.length === 0 &&
239
+ (configFilePaths.filter(path => basename(path) !== 'package.json').length === 0 &&
240
240
  (!this.configFilesMap.get(wsName)?.get(pluginName) ||
241
241
  this.configFilesMap.get(wsName)?.get(pluginName)?.size === 0))) {
242
242
  if (plugin.entry)
@@ -66,7 +66,7 @@ export const resolve = (_binary, args, options) => {
66
66
  return resolveDlx(argsForDlx, options);
67
67
  }
68
68
  const { manifestScriptNames, fromArgs } = options;
69
- if (parsed.filter)
69
+ if (parsed.filter && !parsed.recursive)
70
70
  return [];
71
71
  if (manifestScriptNames.has(command) || commands.includes(command))
72
72
  return [];
package/dist/cli.js CHANGED
@@ -1,4 +1,3 @@
1
- import prettyMilliseconds from 'pretty-ms';
2
1
  import { main } from './index.js';
3
2
  import { perfObserver } from './util/Performance.js';
4
3
  import parsedArgValues, { helpText } from './util/cli-arguments.js';
@@ -6,6 +5,7 @@ import { getKnownError, isConfigurationError, isDisplayReason, isKnownError } fr
6
5
  import { logError, logWarning } from './util/log.js';
7
6
  import { cwd, join, toPosix } from './util/path.js';
8
7
  import { runPreprocessors, runReporters } from './util/reporter.js';
8
+ import { prettyMilliseconds } from './util/string.js';
9
9
  import { splitTags } from './util/tag.js';
10
10
  import { isTrace } from './util/trace.js';
11
11
  import { version } from './version.js';
@@ -70,12 +70,15 @@ const run = async () => {
70
70
  const totalErrorCount = Object.keys(finalData.report)
71
71
  .filter(reportGroup => finalData.report[reportGroup] && rules[reportGroup] === 'error')
72
72
  .reduce((errorCount, reportGroup) => errorCount + finalData.counters[reportGroup], 0);
73
- if (perfObserver.isEnabled) {
73
+ if (perfObserver.isEnabled)
74
74
  await perfObserver.finalize();
75
- console.log(`\n${perfObserver.getTable()}`);
76
- const mem = perfObserver.getCurrentMemUsageInMb();
75
+ if (perfObserver.isPerformanceEnabled)
76
+ console.log(`\n${perfObserver.getPerformanceTable()}`);
77
+ if (perfObserver.isMemoryEnabled)
78
+ console.log(`\n${perfObserver.getMemoryTable()}`);
79
+ if (perfObserver.isEnabled) {
77
80
  const duration = perfObserver.getCurrentDurationInMs();
78
- console.log('\nTotal running time:', prettyMilliseconds(duration), `(mem: ${mem}MB)`);
81
+ console.log('\nTotal running time:', prettyMilliseconds(duration));
79
82
  perfObserver.reset();
80
83
  }
81
84
  if (experimentalTags.length > 0) {
@@ -399,6 +399,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
399
399
  entry?: string | string[] | undefined;
400
400
  project?: string | string[] | undefined;
401
401
  } | undefined;
402
+ svgo?: string | boolean | string[] | {
403
+ config?: string | string[] | undefined;
404
+ entry?: string | string[] | undefined;
405
+ project?: string | string[] | undefined;
406
+ } | undefined;
402
407
  syncpack?: string | boolean | string[] | {
403
408
  config?: string | string[] | undefined;
404
409
  entry?: string | string[] | undefined;
@@ -915,6 +920,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
915
920
  entry?: string | string[] | undefined;
916
921
  project?: string | string[] | undefined;
917
922
  } | undefined;
923
+ svgo?: string | boolean | string[] | {
924
+ config?: string | string[] | undefined;
925
+ entry?: string | string[] | undefined;
926
+ project?: string | string[] | undefined;
927
+ } | undefined;
918
928
  syncpack?: string | boolean | string[] | {
919
929
  config?: string | string[] | undefined;
920
930
  entry?: string | string[] | undefined;
@@ -2,6 +2,7 @@ import { WorkspaceWorker } from '../WorkspaceWorker.js';
2
2
  import { _getInputsFromScripts } from '../binaries/index.js';
3
3
  import { getCompilerExtensions, getIncludedCompilers } from '../compilers/index.js';
4
4
  import { DEFAULT_EXTENSIONS } from '../constants.js';
5
+ import { perfObserver } from '../util/Performance.js';
5
6
  import { debugLog, debugLogArray } from '../util/debug.js';
6
7
  import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
7
8
  import { _glob, negate } from '../util/glob.js';
@@ -291,12 +292,13 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
291
292
  for (const filePath of principal.entryPaths)
292
293
  entryPaths.add(filePath);
293
294
  principal.reconcileCache(graph);
294
- if (!isIsolateWorkspaces && isSkipLibs && !isWatch) {
295
+ if (isIsolateWorkspaces || (isSkipLibs && !isWatch)) {
295
296
  factory.deletePrincipal(principal);
296
297
  principals[i] = undefined;
297
298
  }
299
+ perfObserver.addMemoryMark(factory.principals.size);
298
300
  }
299
- if (isIsolateWorkspaces) {
301
+ if (!isWatch && isSkipLibs && !isIsolateWorkspaces) {
300
302
  for (const principal of principals) {
301
303
  if (principal)
302
304
  factory.deletePrincipal(principal);
@@ -635,6 +635,12 @@ export declare const Plugins: {
635
635
  entry: string[];
636
636
  production: string[];
637
637
  };
638
+ svgo: {
639
+ title: string;
640
+ enablers: string[];
641
+ isEnabled: import("../types/config.js").IsPluginEnabled;
642
+ entry: string[];
643
+ };
638
644
  syncpack: {
639
645
  title: string;
640
646
  enablers: string[];
@@ -76,6 +76,7 @@ import { default as storybook } from './storybook/index.js';
76
76
  import { default as stryker } from './stryker/index.js';
77
77
  import { default as stylelint } from './stylelint/index.js';
78
78
  import { default as svelte } from './svelte/index.js';
79
+ import { default as svgo } from './svgo/index.js';
79
80
  import { default as syncpack } from './syncpack/index.js';
80
81
  import { default as tailwind } from './tailwind/index.js';
81
82
  import { default as travis } from './travis/index.js';
@@ -177,6 +178,7 @@ export const Plugins = {
177
178
  stryker,
178
179
  stylelint,
179
180
  svelte,
181
+ svgo,
180
182
  syncpack,
181
183
  tailwind,
182
184
  travis,
@@ -0,0 +1,8 @@
1
+ import type { IsPluginEnabled } from '../../types/config.js';
2
+ declare const _default: {
3
+ title: string;
4
+ enablers: string[];
5
+ isEnabled: IsPluginEnabled;
6
+ entry: string[];
7
+ };
8
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ const title = 'SVGO';
3
+ const enablers = ['svgo'];
4
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
+ const entry = ['svgo.config.{js,cjs,mjs}'];
6
+ export default {
7
+ title,
8
+ enablers,
9
+ isEnabled,
10
+ entry,
11
+ };
@@ -1,20 +1,20 @@
1
- import EasyTable from 'easy-table';
2
1
  import { relative } from '../util/path.js';
2
+ import { Table } from '../util/table.js';
3
3
  import { getTitle } from './util.js';
4
4
  const printHeader = (size, title) => console.log(`<details>\n${title ? `<summary>${title} (${size})</summary>\n` : ''}\n\`\`\``);
5
5
  const printFooter = () => console.log('```\n\n</details>\n');
6
6
  const logIssueRecord = (issues) => {
7
- const table = new EasyTable();
7
+ const table = new Table();
8
8
  for (const issue of issues) {
9
9
  table.cell('symbol', issue.symbols ? issue.symbols.map(s => s.symbol).join(', ') : issue.symbol);
10
- issue.parentSymbol && table.cell('parentSymbol', issue.parentSymbol);
11
- issue.symbolType && table.cell('symbolType', issue.symbolType);
10
+ table.cell('parentSymbol', issue.parentSymbol && issue.parentSymbol);
11
+ table.cell('symbolType', issue.symbolType && issue.symbolType);
12
12
  const pos = issue.line === undefined ? '' : `:${issue.line}${issue.col === undefined ? '' : `:${issue.col}`}`;
13
13
  const cell = issue.type === 'files' ? '' : `${relative(issue.filePath)}${pos}`;
14
14
  table.cell('filePath', cell);
15
15
  table.newRow();
16
16
  }
17
- console.log(table.sort(['filePath', 'parentSymbol', 'symbol']).print().trim());
17
+ console.log(table.sort('filePath').toString());
18
18
  };
19
19
  export default ({ report, issues }) => {
20
20
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
@@ -1,17 +1,17 @@
1
- import EasyTable from 'easy-table';
2
1
  import picocolors from 'picocolors';
3
2
  import { ROOT_WORKSPACE_NAME } from '../constants.js';
4
3
  import { SymbolType } from '../types/issues.js';
5
4
  import { relative, toRelative } from '../util/path.js';
6
5
  import { truncate } from '../util/string.js';
6
+ import { Table } from '../util/table.js';
7
7
  import { getTitle, identity, logTitle, logTitleDimmed } from './util.js';
8
8
  const dim = picocolors.gray;
9
9
  const bright = picocolors.whiteBright;
10
10
  const TRUNCATE_WIDTH = 40;
11
11
  const truncateStart = (text, width) => (text.length > width ? `...${text.slice(-(width - 3))}` : text);
12
12
  const sortByPos = (a, b) => {
13
- const [f, r, c] = a.filePath.split(':');
14
- const [f2, r2, c2] = b.filePath.split(':');
13
+ const [f, r, c] = a.filePath.value.split(':');
14
+ const [f2, r2, c2] = b.filePath.value.split(':');
15
15
  return f === f2 ? (Number(r) === Number(r2) ? Number(c) - Number(c2) : Number(r) - Number(r2)) : f.localeCompare(f2);
16
16
  };
17
17
  const hl = (issue) => {
@@ -26,20 +26,20 @@ const hl = (issue) => {
26
26
  return issue.symbol;
27
27
  };
28
28
  const logIssueRecord = (issues) => {
29
- const table = new EasyTable();
29
+ const table = new Table({ truncateStart: ['filePath'], noTruncate: ['symbolType'] });
30
30
  for (const issue of issues) {
31
+ table.newRow();
31
32
  const print = issue.isFixed || issue.severity === 'warn' ? dim : identity;
32
33
  const symbols = issue.symbols;
33
34
  table.cell('symbol', print(symbols ? truncate(symbols.map(s => s.symbol).join(', '), TRUNCATE_WIDTH) : hl(issue)));
34
- issue.parentSymbol && table.cell('parentSymbol', print(issue.parentSymbol));
35
- issue.symbolType && issue.symbolType !== SymbolType.UNKNOWN && table.cell('symbolType', print(issue.symbolType));
35
+ table.cell('parentSymbol', issue.parentSymbol && print(issue.parentSymbol));
36
+ table.cell('symbolType', issue.symbolType && issue.symbolType !== SymbolType.UNKNOWN && print(issue.symbolType));
36
37
  const pos = issue.line === undefined ? '' : `:${issue.line}${issue.col === undefined ? '' : `:${issue.col}`}`;
37
38
  const cell = issue.type === 'files' ? '' : `${relative(issue.filePath)}${pos}`;
38
39
  table.cell('filePath', print(cell));
39
- issue.isFixed && table.cell('fixed', print('(removed)'));
40
- table.newRow();
40
+ table.cell('fixed', issue.isFixed && print('(removed)'));
41
41
  }
42
- console.log(table.sort(sortByPos).print().trim());
42
+ console.log(table.sort(sortByPos).toString());
43
43
  };
44
44
  export default ({ report, issues, tagHints, configurationHints, isDisableConfigHints, isTreatConfigHintsAsErrors, isShowProgress, }) => {
45
45
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
@@ -1,7 +1,7 @@
1
1
  import picocolors from 'picocolors';
2
- import prettyMilliseconds from 'pretty-ms';
3
2
  import { perfObserver } from '../util/Performance.js';
4
3
  import { relative } from '../util/path.js';
4
+ import { prettyMilliseconds } from '../util/string.js';
5
5
  import { getTitle } from './util.js';
6
6
  export default ({ report, issues, streamer, startTime, size, isDebug }) => {
7
7
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export declare const knipConfigurationSchema: z.ZodObject<{
2
+ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<z.objectUtil.extendShape<{
3
3
  $schema: z.ZodOptional<z.ZodString>;
4
4
  rules: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, z.ZodEnum<["error", "warn", "off"]>>>;
5
5
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -18,11 +18,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
18
18
  asyncCompilers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodString], z.ZodUnknown>, z.ZodPromise<z.ZodString>>>>;
19
19
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
20
  treatConfigHintsAsErrors: z.ZodOptional<z.ZodBoolean>;
21
- } & {
21
+ }, {
22
22
  include: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, "many">>;
23
23
  exclude: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, "many">>;
24
- } & {
25
- workspaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
24
+ }>, {
25
+ workspaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<z.objectUtil.extendShape<{
26
26
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
27
27
  project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
28
28
  paths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
@@ -32,7 +32,7 @@ export declare const knipConfigurationSchema: z.ZodObject<{
32
32
  ignoreMembers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
33
33
  ignoreUnresolved: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
34
34
  includeEntryExports: z.ZodOptional<z.ZodBoolean>;
35
- } & {
35
+ }, {
36
36
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
37
37
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
38
38
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -1047,6 +1047,19 @@ export declare const knipConfigurationSchema: z.ZodObject<{
1047
1047
  entry?: string | string[] | undefined;
1048
1048
  project?: string | string[] | undefined;
1049
1049
  }>]>>;
1050
+ svgo: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
1051
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1052
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1053
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1054
+ }, "strip", z.ZodTypeAny, {
1055
+ config?: string | string[] | undefined;
1056
+ entry?: string | string[] | undefined;
1057
+ project?: string | string[] | undefined;
1058
+ }, {
1059
+ config?: string | string[] | undefined;
1060
+ entry?: string | string[] | undefined;
1061
+ project?: string | string[] | undefined;
1062
+ }>]>>;
1050
1063
  syncpack: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
1051
1064
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1052
1065
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -1333,7 +1346,7 @@ export declare const knipConfigurationSchema: z.ZodObject<{
1333
1346
  entry?: string | string[] | undefined;
1334
1347
  project?: string | string[] | undefined;
1335
1348
  }>]>>;
1336
- }, "strip", z.ZodTypeAny, {
1349
+ }>, "strip", z.ZodTypeAny, {
1337
1350
  node?: string | boolean | string[] | {
1338
1351
  config?: string | string[] | undefined;
1339
1352
  entry?: string | string[] | undefined;
@@ -1726,6 +1739,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
1726
1739
  entry?: string | string[] | undefined;
1727
1740
  project?: string | string[] | undefined;
1728
1741
  } | undefined;
1742
+ svgo?: string | boolean | string[] | {
1743
+ config?: string | string[] | undefined;
1744
+ entry?: string | string[] | undefined;
1745
+ project?: string | string[] | undefined;
1746
+ } | undefined;
1729
1747
  syncpack?: string | boolean | string[] | {
1730
1748
  config?: string | string[] | undefined;
1731
1749
  entry?: string | string[] | undefined;
@@ -2236,6 +2254,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
2236
2254
  entry?: string | string[] | undefined;
2237
2255
  project?: string | string[] | undefined;
2238
2256
  } | undefined;
2257
+ svgo?: string | boolean | string[] | {
2258
+ config?: string | string[] | undefined;
2259
+ entry?: string | string[] | undefined;
2260
+ project?: string | string[] | undefined;
2261
+ } | undefined;
2239
2262
  syncpack?: string | boolean | string[] | {
2240
2263
  config?: string | string[] | undefined;
2241
2264
  entry?: string | string[] | undefined;
@@ -2354,7 +2377,7 @@ export declare const knipConfigurationSchema: z.ZodObject<{
2354
2377
  ignoreUnresolved?: (string | RegExp)[] | undefined;
2355
2378
  includeEntryExports?: boolean | undefined;
2356
2379
  }>>>;
2357
- } & {
2380
+ }>, {
2358
2381
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
2359
2382
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
2360
2383
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -3369,6 +3392,19 @@ export declare const knipConfigurationSchema: z.ZodObject<{
3369
3392
  entry?: string | string[] | undefined;
3370
3393
  project?: string | string[] | undefined;
3371
3394
  }>]>>;
3395
+ svgo: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
3396
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
3397
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
3398
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
3399
+ }, "strip", z.ZodTypeAny, {
3400
+ config?: string | string[] | undefined;
3401
+ entry?: string | string[] | undefined;
3402
+ project?: string | string[] | undefined;
3403
+ }, {
3404
+ config?: string | string[] | undefined;
3405
+ entry?: string | string[] | undefined;
3406
+ project?: string | string[] | undefined;
3407
+ }>]>>;
3372
3408
  syncpack: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
3373
3409
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
3374
3410
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -3655,7 +3691,7 @@ export declare const knipConfigurationSchema: z.ZodObject<{
3655
3691
  entry?: string | string[] | undefined;
3656
3692
  project?: string | string[] | undefined;
3657
3693
  }>]>>;
3658
- }, "strict", z.ZodTypeAny, {
3694
+ }>, "strict", z.ZodTypeAny, {
3659
3695
  exclude?: ("dependencies" | "exports" | "files" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[] | undefined;
3660
3696
  tags?: string[] | undefined;
3661
3697
  include?: ("dependencies" | "exports" | "files" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[] | undefined;
@@ -4051,6 +4087,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
4051
4087
  entry?: string | string[] | undefined;
4052
4088
  project?: string | string[] | undefined;
4053
4089
  } | undefined;
4090
+ svgo?: string | boolean | string[] | {
4091
+ config?: string | string[] | undefined;
4092
+ entry?: string | string[] | undefined;
4093
+ project?: string | string[] | undefined;
4094
+ } | undefined;
4054
4095
  syncpack?: string | boolean | string[] | {
4055
4096
  config?: string | string[] | undefined;
4056
4097
  entry?: string | string[] | undefined;
@@ -4569,6 +4610,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
4569
4610
  entry?: string | string[] | undefined;
4570
4611
  project?: string | string[] | undefined;
4571
4612
  } | undefined;
4613
+ svgo?: string | boolean | string[] | {
4614
+ config?: string | string[] | undefined;
4615
+ entry?: string | string[] | undefined;
4616
+ project?: string | string[] | undefined;
4617
+ } | undefined;
4572
4618
  syncpack?: string | boolean | string[] | {
4573
4619
  config?: string | string[] | undefined;
4574
4620
  entry?: string | string[] | undefined;
@@ -5083,6 +5129,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
5083
5129
  entry?: string | string[] | undefined;
5084
5130
  project?: string | string[] | undefined;
5085
5131
  } | undefined;
5132
+ svgo?: string | boolean | string[] | {
5133
+ config?: string | string[] | undefined;
5134
+ entry?: string | string[] | undefined;
5135
+ project?: string | string[] | undefined;
5136
+ } | undefined;
5086
5137
  syncpack?: string | boolean | string[] | {
5087
5138
  config?: string | string[] | undefined;
5088
5139
  entry?: string | string[] | undefined;
@@ -5601,6 +5652,11 @@ export declare const knipConfigurationSchema: z.ZodObject<{
5601
5652
  entry?: string | string[] | undefined;
5602
5653
  project?: string | string[] | undefined;
5603
5654
  } | undefined;
5655
+ svgo?: string | boolean | string[] | {
5656
+ config?: string | string[] | undefined;
5657
+ entry?: string | string[] | undefined;
5658
+ project?: string | string[] | undefined;
5659
+ } | undefined;
5604
5660
  syncpack?: string | boolean | string[] | {
5605
5661
  config?: string | string[] | undefined;
5606
5662
  entry?: string | string[] | undefined;
@@ -1028,6 +1028,19 @@ export declare const pluginsSchema: z.ZodObject<{
1028
1028
  entry?: string | string[] | undefined;
1029
1029
  project?: string | string[] | undefined;
1030
1030
  }>]>;
1031
+ svgo: z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
1032
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1033
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1034
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1035
+ }, "strip", z.ZodTypeAny, {
1036
+ config?: string | string[] | undefined;
1037
+ entry?: string | string[] | undefined;
1038
+ project?: string | string[] | undefined;
1039
+ }, {
1040
+ config?: string | string[] | undefined;
1041
+ entry?: string | string[] | undefined;
1042
+ project?: string | string[] | undefined;
1043
+ }>]>;
1031
1044
  syncpack: z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
1032
1045
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1033
1046
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -1705,6 +1718,11 @@ export declare const pluginsSchema: z.ZodObject<{
1705
1718
  entry?: string | string[] | undefined;
1706
1719
  project?: string | string[] | undefined;
1707
1720
  };
1721
+ svgo: string | boolean | string[] | {
1722
+ config?: string | string[] | undefined;
1723
+ entry?: string | string[] | undefined;
1724
+ project?: string | string[] | undefined;
1725
+ };
1708
1726
  syncpack: string | boolean | string[] | {
1709
1727
  config?: string | string[] | undefined;
1710
1728
  entry?: string | string[] | undefined;
@@ -2206,6 +2224,11 @@ export declare const pluginsSchema: z.ZodObject<{
2206
2224
  entry?: string | string[] | undefined;
2207
2225
  project?: string | string[] | undefined;
2208
2226
  };
2227
+ svgo: string | boolean | string[] | {
2228
+ config?: string | string[] | undefined;
2229
+ entry?: string | string[] | undefined;
2230
+ project?: string | string[] | undefined;
2231
+ };
2209
2232
  syncpack: string | boolean | string[] | {
2210
2233
  config?: string | string[] | undefined;
2211
2234
  entry?: string | string[] | undefined;
@@ -88,6 +88,7 @@ export const pluginsSchema = z.object({
88
88
  stryker: pluginSchema,
89
89
  stylelint: pluginSchema,
90
90
  svelte: pluginSchema,
91
+ svgo: pluginSchema,
91
92
  syncpack: pluginSchema,
92
93
  tailwind: pluginSchema,
93
94
  travis: pluginSchema,
@@ -1,2 +1,2 @@
1
- export type PluginName = 'angular' | 'astro' | 'ava' | 'babel' | 'bun' | 'c8' | 'capacitor' | 'changesets' | 'commitizen' | 'commitlint' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'dependency-cruiser' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'expo' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'node' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'oxlint' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'postcss' | 'preconstruct' | 'prettier' | 'react-cosmos' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rollup' | 'rsbuild' | 'rspack' | 'semantic-release' | 'sentry' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'syncpack' | 'tailwind' | 'travis' | 'ts-node' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie';
2
- export declare const pluginNames: readonly ["angular", "astro", "ava", "babel", "bun", "c8", "capacitor", "changesets", "commitizen", "commitlint", "create-typescript-app", "cspell", "cucumber", "cypress", "dependency-cruiser", "dotenv", "drizzle", "eleventy", "eslint", "expo", "gatsby", "github-action", "github-actions", "glob", "graphql-codegen", "husky", "i18next-parser", "jest", "karma", "ladle", "lefthook", "lint-staged", "linthtml", "lockfile-lint", "lost-pixel", "markdownlint", "metro", "mocha", "moonrepo", "msw", "nano-staged", "nest", "netlify", "next", "node", "nodemon", "npm-package-json-lint", "nuxt", "nx", "nyc", "oclif", "oxlint", "playwright", "playwright-ct", "playwright-test", "plop", "postcss", "preconstruct", "prettier", "react-cosmos", "react-router", "relay", "release-it", "remark", "remix", "rollup", "rsbuild", "rspack", "semantic-release", "sentry", "simple-git-hooks", "size-limit", "sst", "starlight", "storybook", "stryker", "stylelint", "svelte", "syncpack", "tailwind", "travis", "ts-node", "tsup", "tsx", "typedoc", "typescript", "unbuild", "unocss", "vercel-og", "vike", "vite", "vitest", "vue", "webdriver-io", "webpack", "wireit", "wrangler", "xo", "yarn", "yorkie"];
1
+ export type PluginName = 'angular' | 'astro' | 'ava' | 'babel' | 'bun' | 'c8' | 'capacitor' | 'changesets' | 'commitizen' | 'commitlint' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'dependency-cruiser' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'expo' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'node' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'oxlint' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'postcss' | 'preconstruct' | 'prettier' | 'react-cosmos' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rollup' | 'rsbuild' | 'rspack' | 'semantic-release' | 'sentry' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'svgo' | 'syncpack' | 'tailwind' | 'travis' | 'ts-node' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie';
2
+ export declare const pluginNames: readonly ["angular", "astro", "ava", "babel", "bun", "c8", "capacitor", "changesets", "commitizen", "commitlint", "create-typescript-app", "cspell", "cucumber", "cypress", "dependency-cruiser", "dotenv", "drizzle", "eleventy", "eslint", "expo", "gatsby", "github-action", "github-actions", "glob", "graphql-codegen", "husky", "i18next-parser", "jest", "karma", "ladle", "lefthook", "lint-staged", "linthtml", "lockfile-lint", "lost-pixel", "markdownlint", "metro", "mocha", "moonrepo", "msw", "nano-staged", "nest", "netlify", "next", "node", "nodemon", "npm-package-json-lint", "nuxt", "nx", "nyc", "oclif", "oxlint", "playwright", "playwright-ct", "playwright-test", "plop", "postcss", "preconstruct", "prettier", "react-cosmos", "react-router", "relay", "release-it", "remark", "remix", "rollup", "rsbuild", "rspack", "semantic-release", "sentry", "simple-git-hooks", "size-limit", "sst", "starlight", "storybook", "stryker", "stylelint", "svelte", "svgo", "syncpack", "tailwind", "travis", "ts-node", "tsup", "tsx", "typedoc", "typescript", "unbuild", "unocss", "vercel-og", "vike", "vite", "vitest", "vue", "webdriver-io", "webpack", "wireit", "wrangler", "xo", "yarn", "yorkie"];
@@ -77,6 +77,7 @@ export const pluginNames = [
77
77
  'stryker',
78
78
  'stylelint',
79
79
  'svelte',
80
+ 'svgo',
80
81
  'syncpack',
81
82
  'tailwind',
82
83
  'travis',
@@ -1,24 +1,42 @@
1
1
  import { type PerformanceEntry, PerformanceObserver } from 'node:perf_hooks';
2
2
  import { memoryUsage } from 'node:process';
3
3
  export declare const timerify: <T extends (...params: any[]) => any>(fn: T, name?: string) => T;
4
+ type MemInfo = {
5
+ heapUsed: number;
6
+ heapTotal: number;
7
+ freemem: number;
8
+ };
9
+ interface MemoryEntry extends PerformanceEntry {
10
+ detail: MemInfo;
11
+ }
4
12
  declare class Performance {
5
13
  isEnabled: boolean;
14
+ isPerformanceEnabled: boolean;
15
+ isMemoryEnabled: boolean;
6
16
  startTime: number;
7
17
  endTime: number;
8
- entries: PerformanceEntry[];
9
- instanceId?: number;
18
+ perfEntries: PerformanceEntry[];
19
+ memEntries: MemoryEntry[];
20
+ perfId?: string;
21
+ memId?: string;
10
22
  fnObserver?: PerformanceObserver;
11
- gcObserver?: PerformanceObserver;
23
+ memObserver?: PerformanceObserver;
12
24
  memoryUsageStart?: ReturnType<typeof memoryUsage>;
13
- constructor(isEnabled: boolean);
25
+ freeMemoryStart?: number;
26
+ constructor({ isPerformanceEnabled, isMemoryEnabled }: {
27
+ isPerformanceEnabled?: boolean | undefined;
28
+ isMemoryEnabled?: boolean | undefined;
29
+ });
14
30
  private setMark;
15
31
  private clearMark;
16
32
  private flush;
17
- private getEntriesByName;
18
- getTable(): string;
33
+ private getPerfEntriesByName;
34
+ getPerformanceTable(): string;
35
+ addMemoryMark(index: number): void;
36
+ getMemoryTable(): string;
19
37
  getCurrentDurationInMs(startTime?: number): number;
20
38
  getMemHeapUsage(): number;
21
- getCurrentMemUsageInMb(): number;
39
+ getCurrentMemUsageInMb(): any;
22
40
  finalize(): Promise<void>;
23
41
  reset(): void;
24
42
  }
@@ -1,54 +1,69 @@
1
+ import os from 'node:os';
1
2
  import { PerformanceObserver, performance } from 'node:perf_hooks';
2
- import { constants } from 'node:perf_hooks';
3
3
  import { memoryUsage } from 'node:process';
4
- import EasyTable from 'easy-table';
5
- import prettyMilliseconds from 'pretty-ms';
6
4
  import parsedArgValues from './cli-arguments.js';
7
- import { debugLog } from './debug.js';
8
5
  import { getStats } from './math.js';
9
- const { performance: isEnabled = false } = parsedArgValues;
6
+ import { Table } from './table.js';
7
+ const { performance: isPerformanceEnabled = false, memory: isMemoryEnabled = false, 'memory-realtime': memoryRealtime = false, } = parsedArgValues;
10
8
  export const timerify = (fn, name = fn.name) => {
11
- if (!isEnabled)
9
+ if (!isPerformanceEnabled)
12
10
  return fn;
13
11
  return performance.timerify(Object.defineProperty(fn, 'name', { get: () => name }));
14
12
  };
13
+ const getMemInfo = () => Object.assign({ freemem: os.freemem() }, memoryUsage());
14
+ const twoFixed = (value) => (typeof value === 'number' ? value.toFixed(2) : value);
15
+ const inMB = (bytes) => bytes / 1024 / 1024;
16
+ const keys = ['heapUsed', 'heapTotal', 'freemem'];
17
+ const logHead = () => console.log(keys.map(key => key.padStart(10)).join(' '));
18
+ const log = (memInfo) => console.log(keys.map(key => twoFixed(inMB(memInfo[key])).padStart(10)).join(' '));
15
19
  class Performance {
16
20
  isEnabled;
21
+ isPerformanceEnabled;
22
+ isMemoryEnabled;
17
23
  startTime = 0;
18
24
  endTime = 0;
19
- entries = [];
20
- instanceId;
25
+ perfEntries = [];
26
+ memEntries = [];
27
+ perfId;
28
+ memId;
21
29
  fnObserver;
22
- gcObserver;
30
+ memObserver;
23
31
  memoryUsageStart;
24
- constructor(isEnabled) {
25
- if (isEnabled) {
26
- this.startTime = performance.now();
27
- this.instanceId = Math.floor(performance.now() * 100);
32
+ freeMemoryStart;
33
+ constructor({ isPerformanceEnabled = false, isMemoryEnabled = false }) {
34
+ this.isEnabled = isPerformanceEnabled || isMemoryEnabled;
35
+ this.isPerformanceEnabled = isPerformanceEnabled;
36
+ this.isMemoryEnabled = isMemoryEnabled;
37
+ this.startTime = performance.now();
38
+ const instanceId = Math.floor(performance.now() * 100);
39
+ this.perfId = `perf-${instanceId}`;
40
+ this.memId = `mem-${instanceId}`;
41
+ if (isPerformanceEnabled) {
28
42
  this.fnObserver = new PerformanceObserver(items => {
29
43
  for (const entry of items.getEntries()) {
30
- this.entries.push(entry);
44
+ this.perfEntries.push(entry);
31
45
  }
32
46
  });
33
- this.fnObserver.observe({ entryTypes: ['function'] });
34
- this.gcObserver = new PerformanceObserver(items => {
35
- for (const item of items.getEntries()) {
36
- if (item.detail?.kind === constants.NODE_PERFORMANCE_GC_MAJOR) {
37
- debugLog('*', `GC (after ${prettyMilliseconds(item.startTime)} in ${prettyMilliseconds(item.duration)})`);
38
- }
47
+ this.fnObserver.observe({ type: 'function' });
48
+ }
49
+ if (isMemoryEnabled) {
50
+ this.memObserver = new PerformanceObserver(items => {
51
+ for (const entry of items.getEntries()) {
52
+ this.memEntries.push(entry);
39
53
  }
40
54
  });
41
- this.gcObserver.observe({ entryTypes: ['gc'] });
42
- this.memoryUsageStart = memoryUsage();
55
+ this.memObserver.observe({ type: 'mark' });
56
+ if (memoryRealtime)
57
+ logHead();
58
+ this.addMemoryMark(0);
43
59
  }
44
- this.isEnabled = isEnabled;
45
60
  }
46
61
  setMark(name) {
47
- const id = `${this.instanceId}:${name}`;
62
+ const id = `${this.perfId}:${name}`;
48
63
  performance.mark(`${id}:start`);
49
64
  }
50
65
  clearMark(name) {
51
- const id = `${this.instanceId}:${name}`;
66
+ const id = `${this.perfId}:${name}`;
52
67
  performance.mark(`${id}:end`);
53
68
  performance.measure(id, `${id}:start`, `${id}:end`);
54
69
  performance.clearMarks(`${id}:start`);
@@ -59,29 +74,50 @@ class Performance {
59
74
  await new Promise(resolve => setTimeout(resolve, 1));
60
75
  this.clearMark('_flush');
61
76
  }
62
- getEntriesByName() {
63
- return this.entries.reduce((entries, entry) => {
64
- const name = entry.name.replace(`${this.instanceId}:`, '');
77
+ getPerfEntriesByName() {
78
+ return this.perfEntries.reduce((entries, entry) => {
79
+ const name = entry.name.replace(`${this.perfId}:`, '');
65
80
  entries[name] = entries[name] ?? [];
66
81
  entries[name].push(entry.duration);
67
82
  return entries;
68
83
  }, {});
69
84
  }
70
- getTable() {
71
- const entriesByName = this.getEntriesByName();
72
- const table = new EasyTable();
85
+ getPerformanceTable() {
86
+ const entriesByName = this.getPerfEntriesByName();
87
+ const table = new Table({ header: true });
73
88
  for (const [name, values] of Object.entries(entriesByName)) {
74
89
  const stats = getStats(values);
90
+ table.newRow();
75
91
  table.cell('Name', name);
76
- table.cell('size', values.length, EasyTable.number(0));
77
- table.cell('min', stats.min, EasyTable.number(2));
78
- table.cell('max', stats.max, EasyTable.number(2));
79
- table.cell('median', stats.median, EasyTable.number(2));
80
- table.cell('sum', stats.sum, EasyTable.number(2));
92
+ table.cell('size', values.length);
93
+ table.cell('min', stats.min, twoFixed);
94
+ table.cell('max', stats.max, twoFixed);
95
+ table.cell('median', stats.median, twoFixed);
96
+ table.cell('sum', stats.sum, twoFixed);
97
+ }
98
+ table.sort('sum|desc');
99
+ return table.toString();
100
+ }
101
+ addMemoryMark(index) {
102
+ if (!this.isMemoryEnabled)
103
+ return;
104
+ const id = `${this.memId}:${index}`;
105
+ const detail = getMemInfo();
106
+ performance.mark(id, { detail });
107
+ if (memoryRealtime && detail)
108
+ log(detail);
109
+ }
110
+ getMemoryTable() {
111
+ const table = new Table({ header: true });
112
+ for (const entry of this.memEntries) {
113
+ if (!entry.detail)
114
+ continue;
81
115
  table.newRow();
116
+ table.cell('heapUsed', inMB(entry.detail.heapUsed), twoFixed);
117
+ table.cell('heapTotal', inMB(entry.detail.heapTotal), twoFixed);
118
+ table.cell('freemem', inMB(entry.detail.freemem), twoFixed);
82
119
  }
83
- table.sort(['sum|des']);
84
- return table.toString().trim();
120
+ return table.toString();
85
121
  }
86
122
  getCurrentDurationInMs(startTime) {
87
123
  return performance.now() - (startTime ?? this.startTime);
@@ -90,7 +126,7 @@ class Performance {
90
126
  return (memoryUsage().heapUsed ?? 0) - (this.memoryUsageStart?.heapUsed ?? 0);
91
127
  }
92
128
  getCurrentMemUsageInMb() {
93
- return Math.round((this.getMemHeapUsage() / 1024 / 1024) * 100) / 100;
129
+ return twoFixed(inMB(this.getMemHeapUsage()));
94
130
  }
95
131
  async finalize() {
96
132
  if (!this.isEnabled)
@@ -98,8 +134,9 @@ class Performance {
98
134
  await this.flush();
99
135
  }
100
136
  reset() {
101
- this.entries = [];
137
+ this.perfEntries = [];
102
138
  this.fnObserver?.disconnect();
139
+ this.memObserver?.disconnect();
103
140
  }
104
141
  }
105
- export const perfObserver = new Performance(isEnabled);
142
+ export const perfObserver = new Performance({ isPerformanceEnabled, isMemoryEnabled });
@@ -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 -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\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 --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\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: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --trace Show trace output\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n --performance Measure count and running time of expensive functions and display stats table\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n(2) Fixable issue types: dependencies, exports, types\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\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 -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\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 --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\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: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --trace Show trace output\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n --performance Measure count and running time of key functions and display stats table\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n(2) Fixable issue types: dependencies, exports, types\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
2
2
  declare const _default: {
3
3
  cache?: boolean | undefined;
4
4
  'cache-location'?: string | undefined;
@@ -21,6 +21,8 @@ declare const _default: {
21
21
  'include-entry-exports'?: boolean | undefined;
22
22
  'isolate-workspaces'?: boolean | undefined;
23
23
  'max-issues'?: string | undefined;
24
+ memory?: boolean | undefined;
25
+ 'memory-realtime'?: boolean | undefined;
24
26
  'no-config-hints'?: boolean | undefined;
25
27
  'no-exit-code'?: boolean | undefined;
26
28
  'no-gitignore'?: boolean | undefined;
@@ -39,7 +39,9 @@ Options:
39
39
  --trace Show trace output
40
40
  --trace-export [name] Show trace output for named export(s)
41
41
  --trace-file [file] Show trace output for exports in file
42
- --performance Measure count and running time of expensive functions and display stats table
42
+ --performance Measure count and running time of key functions and display stats table
43
+ --memory Measure memory usage and display data table
44
+ --memory-realtime Log memory usage in realtime
43
45
  -h, --help Print this help text
44
46
  -V, --version Print version
45
47
 
@@ -81,6 +83,8 @@ try {
81
83
  'include-entry-exports': { type: 'boolean' },
82
84
  'isolate-workspaces': { type: 'boolean' },
83
85
  'max-issues': { type: 'string' },
86
+ memory: { type: 'boolean' },
87
+ 'memory-realtime': { type: 'boolean' },
84
88
  'no-config-hints': { type: 'boolean' },
85
89
  'no-exit-code': { type: 'boolean' },
86
90
  'no-gitignore': { type: 'boolean' },
@@ -79,20 +79,22 @@ export const findAndParseGitignores = async (cwd) => {
79
79
  dirIgnores.add(pattern2);
80
80
  }
81
81
  else {
82
- const ignore = join(base, pattern1);
83
- const extraIgnore = join(base, pattern2);
84
- ignores.add(ignore);
85
- ignores.add(extraIgnore);
86
- dirIgnores.add(ignore);
87
- dirIgnores.add(extraIgnore);
82
+ if (!(pattern1.startsWith('**/') && ignores.has(pattern1))) {
83
+ const ignore = join(base, pattern1);
84
+ const extraIgnore = join(base, pattern2);
85
+ ignores.add(ignore);
86
+ ignores.add(extraIgnore);
87
+ dirIgnores.add(ignore);
88
+ dirIgnores.add(extraIgnore);
89
+ }
88
90
  }
89
91
  }
90
92
  }
91
93
  const cacheDir = ancestor ? cwd : dir;
92
- const cacheForDir = cachedGitIgnores.get(cwd);
94
+ const cacheForDir = cachedGitIgnores.get(cacheDir);
93
95
  if (cacheForDir) {
94
96
  for (const pattern of dirIgnores)
95
- cacheForDir?.ignores.add(pattern);
97
+ cacheForDir.ignores.add(pattern);
96
98
  cacheForDir.unignores = Array.from(new Set([...cacheForDir.unignores, ...dirUnignores]));
97
99
  }
98
100
  else {
@@ -1 +1,4 @@
1
1
  export declare const truncate: (text: string, width: number) => string;
2
+ export declare const truncateStart: (text: string, width: number) => string;
3
+ export declare const pad: (value: string, width: number, fillString?: string, align?: "left" | "center" | "right") => string;
4
+ export declare const prettyMilliseconds: (ms: number) => string;
@@ -1 +1,17 @@
1
1
  export const truncate = (text, width) => text.length > width ? `${text.slice(0, width - 3)}...` : text;
2
+ export const truncateStart = (text, width) => text.length > width ? `...${text.slice(-(width - 3))}` : text;
3
+ export const pad = (value, width, fillString, align) => align === 'right'
4
+ ? value.padStart(width, fillString)
5
+ : align === 'center'
6
+ ? value.padStart((value.length + width) / 2, fillString).padEnd(width, fillString)
7
+ : value.padEnd(width, fillString);
8
+ export const prettyMilliseconds = (ms) => {
9
+ const seconds = ms / 1000;
10
+ const minutes = Math.floor(seconds / 60);
11
+ const hours = Math.floor(minutes / 60);
12
+ if (hours > 0)
13
+ return `${hours}h ${minutes % 60}m ${Math.floor(seconds % 60)}s`;
14
+ if (minutes > 0)
15
+ return `${minutes}m ${Math.floor(seconds % 60)}s`;
16
+ return seconds % 1 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds)}s`;
17
+ };
@@ -0,0 +1,20 @@
1
+ type Value = string | number | undefined | false | null;
2
+ export declare class Table {
3
+ private columns;
4
+ private rows;
5
+ private header;
6
+ private maxWidth;
7
+ private truncateStart;
8
+ private noTruncate;
9
+ constructor(options?: {
10
+ maxWidth?: number;
11
+ header?: boolean;
12
+ truncateStart?: string[];
13
+ noTruncate?: string[];
14
+ });
15
+ cell(column: string, value: Value, formatter?: (value: Value) => string): this;
16
+ newRow(): this;
17
+ sort(compareFn: ((a: any, b: any) => number) | string): this;
18
+ toString(): string;
19
+ }
20
+ export {};
@@ -0,0 +1,100 @@
1
+ import { pad, truncate, truncateStart } from './string.js';
2
+ const DEFAULT_MAX_WIDTH = process.stdout.columns || 120;
3
+ const MIN_TRUNCATED_WIDTH = 4;
4
+ const COLUMN_SEPARATOR = ' ';
5
+ export class Table {
6
+ columns = [];
7
+ rows = [];
8
+ header;
9
+ maxWidth;
10
+ truncateStart = [];
11
+ noTruncate = [];
12
+ constructor(options) {
13
+ this.header = options?.header ?? false;
14
+ this.maxWidth = options?.maxWidth || DEFAULT_MAX_WIDTH;
15
+ this.truncateStart = options?.truncateStart || [];
16
+ this.noTruncate = options?.noTruncate || [];
17
+ }
18
+ cell(column, value, formatter) {
19
+ if (!this.columns.includes(column))
20
+ this.columns.push(column);
21
+ const row = this.rows[this.rows.length - 1];
22
+ row[column] = {
23
+ value,
24
+ formatted: formatter ? formatter(value) : undefined,
25
+ align: typeof value === 'number' ? 'right' : 'left',
26
+ };
27
+ return this;
28
+ }
29
+ newRow() {
30
+ this.rows.push({});
31
+ return this;
32
+ }
33
+ sort(compareFn) {
34
+ if (typeof compareFn === 'function') {
35
+ this.rows.sort(compareFn);
36
+ return this;
37
+ }
38
+ this.rows.sort((a, b) => {
39
+ const [col, order] = compareFn.split('|');
40
+ const vA = a[col].value;
41
+ const vB = b[col].value;
42
+ if (typeof vA === 'string' && typeof vB === 'string')
43
+ return (order === 'desc' ? -1 : 1) * vA.localeCompare(vB);
44
+ if (typeof vA === 'number' && typeof vB === 'number')
45
+ return order === 'desc' ? vB - vA : vA - vB;
46
+ return !vA ? 1 : !vB ? -1 : 0;
47
+ });
48
+ return this;
49
+ }
50
+ toString() {
51
+ const columns = this.columns.filter(col => this.rows.some(row => typeof row[col].value === 'string' || typeof row[col].value === 'number'));
52
+ if (this.header) {
53
+ const headerRow = {};
54
+ const linesRow = {};
55
+ for (const col of columns) {
56
+ headerRow[col] = { value: col, align: this.rows[0][col].align === 'right' ? 'center' : 'left' };
57
+ linesRow[col] = { value: '', fill: '-' };
58
+ }
59
+ this.rows.unshift(linesRow);
60
+ this.rows.unshift(headerRow);
61
+ }
62
+ const columnWidths = columns.reduce((acc, col) => {
63
+ acc[col] = Math.max(...this.rows.map(row => String(row[col]?.formatted || row[col]?.value || '').length));
64
+ return acc;
65
+ }, {});
66
+ const separatorWidth = (columns.length - 1) * COLUMN_SEPARATOR.length;
67
+ const totalWidth = Object.values(columnWidths).reduce((sum, width) => sum + width, 0) + separatorWidth;
68
+ if (totalWidth > this.maxWidth) {
69
+ const reservedWidth = columns
70
+ .filter(col => this.noTruncate.includes(col))
71
+ .reduce((sum, col) => sum + columnWidths[col], 0);
72
+ const truncatableColumns = columns.filter(col => !this.noTruncate.includes(col));
73
+ const minWidth = truncatableColumns.length * 4;
74
+ const availableWidth = this.maxWidth - separatorWidth - reservedWidth - minWidth;
75
+ const truncatableWidth = truncatableColumns.reduce((sum, col) => sum + columnWidths[col], 0) - minWidth;
76
+ const reduction = availableWidth / truncatableWidth;
77
+ let roundingDiff = availableWidth;
78
+ for (const col of truncatableColumns) {
79
+ const reducedWidth = MIN_TRUNCATED_WIDTH + Math.floor((columnWidths[col] - MIN_TRUNCATED_WIDTH) * reduction);
80
+ columnWidths[col] = reducedWidth;
81
+ roundingDiff -= reducedWidth - MIN_TRUNCATED_WIDTH;
82
+ }
83
+ if (roundingDiff > 0) {
84
+ columnWidths[truncatableColumns.length > 0 ? truncatableColumns[0] : columns[0]] += roundingDiff;
85
+ }
86
+ }
87
+ return this.rows
88
+ .map(row => columns
89
+ .map((col, index) => {
90
+ const cell = row[col];
91
+ const width = columnWidths[col];
92
+ const fill = cell.fill || ' ';
93
+ const padded = pad(String(cell.formatted || cell.value || ''), width, fill, cell.align);
94
+ const truncated = this.truncateStart.includes(col) ? truncateStart(padded, width) : truncate(padded, width);
95
+ return index === 0 ? truncated : COLUMN_SEPARATOR + truncated;
96
+ })
97
+ .join(''))
98
+ .join('\n');
99
+ }
100
+ }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.51.1";
1
+ export declare const version = "5.53.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.51.1';
1
+ export const version = '5.53.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.51.1",
3
+ "version": "5.53.0",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {
@@ -61,7 +61,6 @@
61
61
  ],
62
62
  "dependencies": {
63
63
  "@nodelib/fs.walk": "^1.2.3",
64
- "easy-table": "1.2.0",
65
64
  "enhanced-resolve": "^5.18.1",
66
65
  "fast-glob": "^3.3.3",
67
66
  "jiti": "^2.4.2",
@@ -69,7 +68,6 @@
69
68
  "minimist": "^1.2.8",
70
69
  "picocolors": "^1.1.0",
71
70
  "picomatch": "^4.0.1",
72
- "pretty-ms": "^9.0.0",
73
71
  "smol-toml": "^1.3.1",
74
72
  "strip-json-comments": "5.0.1",
75
73
  "zod": "^3.22.4",
package/schema.json CHANGED
@@ -607,6 +607,10 @@
607
607
  "title": "svelte plugin configuration (https://knip.dev/reference/plugins/svelte)",
608
608
  "$ref": "#/definitions/plugin"
609
609
  },
610
+ "svgo": {
611
+ "title": "svgo plugin configuration (https://knip.dev/reference/plugins/svgo)",
612
+ "$ref": "#/definitions/plugin"
613
+ },
610
614
  "syncpack": {
611
615
  "title": "syncpack plugin configuration (https://knip.dev/reference/plugins/syncpack)",
612
616
  "$ref": "#/definitions/plugin"