knip 2.17.2 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -143,7 +143,7 @@ Using workspaces in a monorepo? Please see [workspaces][1] for more details abou
143
143
  --dependencies Shortcut for --include dependencies,unlisted,unresolved
144
144
  --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
145
145
  --include-entry-exports Include entry files when reporting unused exports
146
- -n, --no-progress Don't show dynamic progress updates
146
+ -n, --no-progress Don't show dynamic progress updates (this is automatically enabled in CI environments)
147
147
  --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
148
148
  --reporter-options Pass extra options to the reporter (as JSON string, see example)
149
149
  --no-config-hints Suppress configuration hints
package/dist/cli.js CHANGED
@@ -39,6 +39,7 @@ const run = async () => {
39
39
  noConfigHints,
40
40
  cwd,
41
41
  isProduction,
42
+ isShowProgress,
42
43
  options: reporterOptions,
43
44
  });
44
45
  const totalErrorCount = Object.keys(report)
package/dist/constants.js CHANGED
@@ -48,6 +48,8 @@ export const IGNORED_FILE_EXTENSIONS = [
48
48
  '.webp',
49
49
  '.woff',
50
50
  '.woff2',
51
+ '.yaml',
52
+ '.yml',
51
53
  ];
52
54
  export const IGNORE_DEFINITELY_TYPED = ['node'];
53
55
  export const ISSUE_TYPES = [
@@ -9,4 +9,5 @@ type GetDependenciesDeep = (configFilePath: string, dependencies: Set<string>, o
9
9
  manifest: Manifest;
10
10
  }) => Promise<Set<string>>;
11
11
  export declare const getDependenciesDeep: GetDependenciesDeep;
12
+ export declare const resolveExtendsSpecifier: (specifier: string) => string | undefined;
12
13
  export {};
@@ -56,14 +56,15 @@ const resolvePackageName = (namespace, pluginName) => {
56
56
  : `${namespace}-${pluginName}`;
57
57
  };
58
58
  const resolvePluginPackageName = (pluginName) => resolvePackageName('eslint-plugin', pluginName);
59
- const resolveExtendsSpecifier = (specifier) => {
59
+ export const resolveExtendsSpecifier = (specifier) => {
60
60
  if (isInternal(specifier))
61
61
  return;
62
62
  if (/\/eslint-(config|plugin)/.test(specifier))
63
63
  return specifier;
64
- const strippedSpecifier = specifier
65
- .replace(/(^plugin:|:.+$)/, '')
66
- .replace(/\/(eslint-)?(recommended.*|stylistic.*|strict.*|all)$/, '');
64
+ const noProtocolSpecifier = specifier.replace(/(^plugin:|:.+$)/, '');
65
+ if (noProtocolSpecifier.startsWith('@typescript-eslint/'))
66
+ return '@typescript-eslint/eslint-plugin';
67
+ const strippedSpecifier = noProtocolSpecifier.replace(/\/(eslint-)?(recommended|all)$/, '');
67
68
  if (/eslint-(config|plugin)-/.test(strippedSpecifier))
68
69
  return strippedSpecifier;
69
70
  const packageName = getPackageNameFromModuleSpecifier(strippedSpecifier);
@@ -17,16 +17,12 @@ const resolveExtensibleConfig = async (configFilePath) => {
17
17
  }
18
18
  return config;
19
19
  };
20
- const findJestDependencies = async (configFilePath, { cwd, manifest }) => {
21
- let config = configFilePath.endsWith('package.json')
22
- ? manifest.jest
23
- : await resolveExtensibleConfig(configFilePath);
24
- if (typeof config === 'function')
25
- config = await config();
26
- if (!config)
27
- return [];
28
- const replaceRootDir = (name) => name.includes('<rootDir>') ? join(cwd, name.replace(/^.*<rootDir>/, '')) : name;
20
+ const resolveDependencies = (config) => {
29
21
  const presets = (config.preset ? [config.preset] : []).map(preset => isInternal(preset) ? preset : join(preset, 'jest-preset'));
22
+ const projects = Array.isArray(config.projects)
23
+ ? config.projects.map(config => (typeof config === 'string' ? config : resolveDependencies(config))).flat()
24
+ : [];
25
+ const runner = config.runner ? [config.runner] : [];
30
26
  const environments = config.testEnvironment === 'jsdom' ? ['jest-environment-jsdom'] : [];
31
27
  const resolvers = config.resolver ? [config.resolver] : [];
32
28
  const reporters = config.reporters
@@ -45,6 +41,8 @@ const findJestDependencies = async (configFilePath, { cwd, manifest }) => {
45
41
  : []).filter(value => !/\$[0-9]/.test(value));
46
42
  return [
47
43
  ...presets,
44
+ ...projects,
45
+ ...runner,
48
46
  ...environments,
49
47
  ...resolvers,
50
48
  ...reporters,
@@ -53,6 +51,17 @@ const findJestDependencies = async (configFilePath, { cwd, manifest }) => {
53
51
  ...setupFilesAfterEnv,
54
52
  ...transform,
55
53
  ...moduleNameMapper,
56
- ].map(replaceRootDir);
54
+ ];
55
+ };
56
+ const findJestDependencies = async (configFilePath, { cwd, manifest }) => {
57
+ let config = configFilePath.endsWith('package.json')
58
+ ? manifest.jest
59
+ : await resolveExtensibleConfig(configFilePath);
60
+ if (typeof config === 'function')
61
+ config = await config();
62
+ if (!config)
63
+ return [];
64
+ const replaceRootDir = (name) => name.includes('<rootDir>') ? join(cwd, name.replace(/^.*<rootDir>/, '')) : name;
65
+ return resolveDependencies(config).map(replaceRootDir);
57
66
  };
58
67
  export const findDependencies = timerify(findJestDependencies);
@@ -1,18 +1,34 @@
1
1
  import { compact } from '../../util/array.js';
2
- import { isInternal } from '../../util/path.js';
2
+ import { dirname, isInternal, toAbsolute } from '../../util/path.js';
3
3
  import { timerify } from '../../util/Performance.js';
4
4
  import { hasDependency, load } from '../../util/plugin.js';
5
5
  export const NAME = 'TypeScript';
6
6
  export const ENABLERS = ['typescript'];
7
7
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
8
  export const CONFIG_FILE_PATTERNS = ['tsconfig.json'];
9
- const findTypeScriptDependencies = async (configFilePath) => {
9
+ const resolveExtensibleConfig = async (configFilePath) => {
10
10
  const config = await load(configFilePath);
11
+ if (config?.extends) {
12
+ if (isInternal(config.extends)) {
13
+ const presetConfigPath = toAbsolute(config.extends, dirname(configFilePath));
14
+ const presetConfig = await resolveExtensibleConfig(presetConfigPath);
15
+ Object.assign(config, presetConfig);
16
+ }
17
+ }
18
+ return config;
19
+ };
20
+ const findTypeScriptDependencies = async (configFilePath) => {
21
+ const config = await resolveExtensibleConfig(configFilePath);
11
22
  if (!config)
12
23
  return [];
13
24
  const extend = config.extends ? [config.extends].flat().filter(extend => !isInternal(extend)) : [];
14
25
  const plugins = compact(config.compilerOptions?.plugins?.map(plugin => plugin.name) ?? []);
15
26
  const importHelpers = config.compilerOptions?.importHelpers ? ['tslib'] : [];
16
- return [...extend, ...plugins, ...importHelpers];
27
+ const jsx = config.compilerOptions?.jsxImportSource
28
+ ? [config.compilerOptions.jsxImportSource]
29
+ : config.compilerOptions?.jsx
30
+ ? ['react']
31
+ : [];
32
+ return [...extend, ...plugins, ...importHelpers, ...jsx];
17
33
  };
18
34
  export const findDependencies = timerify(findTypeScriptDependencies);
@@ -1,3 +1,3 @@
1
1
  import type { ReporterOptions } from '../types/issues.js';
2
- declare const _default: ({ report, issues, options }: ReporterOptions) => void;
2
+ declare const _default: ({ report, issues, isShowProgress, options }: ReporterOptions) => void;
3
3
  export default _default;
@@ -11,7 +11,7 @@ const logIssueRecord = (issues) => {
11
11
  const sortedByFilePath = issues.sort((a, b) => (a.owner < b.owner ? -1 : 1));
12
12
  sortedByFilePath.forEach(({ filePath, symbols, owner, parentSymbol }) => logIssueLine({ owner, filePath, symbols, parentSymbol }));
13
13
  };
14
- export default ({ report, issues, options }) => {
14
+ export default ({ report, issues, isShowProgress, options }) => {
15
15
  let opts = {};
16
16
  try {
17
17
  opts = options ? JSON.parse(options) : opts;
@@ -56,7 +56,7 @@ export default ({ report, issues, options }) => {
56
56
  totalIssues = totalIssues + issuesForType.length;
57
57
  }
58
58
  }
59
- if (totalIssues === 0) {
59
+ if (totalIssues === 0 && isShowProgress) {
60
60
  console.log('✂️ Excellent, Knip found no issues.');
61
61
  }
62
62
  };
@@ -1,3 +1,3 @@
1
1
  import type { ReporterOptions } from '../types/issues.js';
2
- declare const _default: ({ report, issues }: ReporterOptions) => void;
2
+ declare const _default: ({ report, issues, isShowProgress }: ReporterOptions) => void;
3
3
  export default _default;
@@ -3,7 +3,7 @@ const logIssueRecord = (issues) => {
3
3
  const sortedByFilePath = issues.sort((a, b) => (a.filePath > b.filePath ? 1 : -1));
4
4
  sortedByFilePath.forEach(logIssueLine);
5
5
  };
6
- export default ({ report, issues }) => {
6
+ export default ({ report, issues, isShowProgress }) => {
7
7
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
8
8
  let totalIssues = 0;
9
9
  for (const [reportType, isReportType] of Object.entries(report)) {
@@ -30,7 +30,7 @@ export default ({ report, issues }) => {
30
30
  totalIssues = totalIssues + issuesForType.length;
31
31
  }
32
32
  }
33
- if (totalIssues === 0) {
33
+ if (totalIssues === 0 && isShowProgress) {
34
34
  console.log('✂️ Excellent, Knip found no issues.');
35
35
  }
36
36
  };
@@ -1,7 +1,7 @@
1
1
  declare const _default: {
2
- symbols: ({ report, issues, configurationHints, noConfigHints }: import("../index.js").ReporterOptions) => void;
3
- compact: ({ report, issues }: import("../index.js").ReporterOptions) => void;
4
- codeowners: ({ report, issues, options }: import("../index.js").ReporterOptions) => void;
2
+ symbols: ({ report, issues, configurationHints, noConfigHints, isShowProgress }: import("../index.js").ReporterOptions) => void;
3
+ compact: ({ report, issues, isShowProgress }: import("../index.js").ReporterOptions) => void;
4
+ codeowners: ({ report, issues, isShowProgress, options }: import("../index.js").ReporterOptions) => void;
5
5
  json: ({ report, issues, options }: import("../index.js").ReporterOptions) => Promise<void>;
6
6
  };
7
7
  export default _default;
@@ -1,3 +1,3 @@
1
1
  import type { ReporterOptions } from '../types/issues.js';
2
- declare const _default: ({ report, issues, configurationHints, noConfigHints }: ReporterOptions) => void;
2
+ declare const _default: ({ report, issues, configurationHints, noConfigHints, isShowProgress }: ReporterOptions) => void;
3
3
  export default _default;
@@ -17,7 +17,7 @@ const logIssueRecord = (issues) => {
17
17
  });
18
18
  console.log(table.sort(['filePath', 'parentSymbol', 'symbol']).print().trim());
19
19
  };
20
- export default ({ report, issues, configurationHints, noConfigHints }) => {
20
+ export default ({ report, issues, configurationHints, noConfigHints, isShowProgress }) => {
21
21
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
22
22
  let totalIssues = 0;
23
23
  for (const [reportType, isReportType] of Object.entries(report)) {
@@ -48,7 +48,7 @@ export default ({ report, issues, configurationHints, noConfigHints }) => {
48
48
  console.warn(chalk.grey(`${message}${workspace}:`), identifier);
49
49
  });
50
50
  }
51
- if (totalIssues === 0) {
51
+ if (totalIssues === 0 && isShowProgress) {
52
52
  console.log('✂️ Excellent, Knip found no issues.');
53
53
  }
54
54
  };
@@ -47,6 +47,7 @@ export type ReporterOptions = {
47
47
  cwd: string;
48
48
  workingDir: string;
49
49
  isProduction: boolean;
50
+ isShowProgress: boolean;
50
51
  options: string;
51
52
  };
52
53
  export type Reporter = (options: ReporterOptions) => void;
@@ -3,10 +3,16 @@ type SymbolTable = Map<string, ts.Symbol>;
3
3
  type SymbolWithExports = ts.Symbol & {
4
4
  exports?: SymbolTable;
5
5
  };
6
+ type PragmaMap = {
7
+ arguments: {
8
+ factory: string;
9
+ };
10
+ };
6
11
  export interface BoundSourceFile extends ts.SourceFile {
7
12
  symbol?: SymbolWithExports;
8
13
  resolvedModules?: ts.ModeAwareCache<ts.ResolvedModuleWithFailedLookupLocations>;
9
14
  locals?: SymbolTable;
10
15
  scriptKind?: ts.ScriptKind;
16
+ pragmas?: Map<string, PragmaMap | PragmaMap[]>;
11
17
  }
12
18
  export {};
@@ -1,6 +1,6 @@
1
1
  import ts from 'typescript';
2
2
  import { debugLog } from '../util/debug.js';
3
- import { extname } from '../util/path.js';
3
+ import { extname, isInternal } from '../util/path.js';
4
4
  export class SourceFileManager {
5
5
  sourceFileCache = new Map();
6
6
  snapshotCache = new Map();
@@ -11,7 +11,8 @@ export class SourceFileManager {
11
11
  this.asyncCompilers = compilers[1];
12
12
  }
13
13
  createSourceFile(filePath, contents) {
14
- const sourceFile = ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true);
14
+ const setParentNodes = isInternal(filePath);
15
+ const sourceFile = ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, setParentNodes);
15
16
  this.sourceFileCache.set(filePath, sourceFile);
16
17
  return sourceFile;
17
18
  }
@@ -5,6 +5,7 @@ import { isMaybePackageName } from '../util/modules.js';
5
5
  import { isInNodeModules } from '../util/path.js';
6
6
  import { isDeclarationFileExtension, isAccessExpression, getAccessExpressionName } from './ast-helpers.js';
7
7
  import getExportVisitors from './visitors/exports/index.js';
8
+ import { getJSXImplicitImportBase } from './visitors/helpers.js';
8
9
  import getImportVisitors from './visitors/imports/index.js';
9
10
  import getScriptVisitors from './visitors/scripts/index.js';
10
11
  const getVisitors = (sourceFile) => ({
@@ -20,6 +21,9 @@ export const getImportsAndExports = (sourceFile, options) => {
20
21
  const aliasedExports = {};
21
22
  const scripts = new Set();
22
23
  const importedInternalSymbols = new Map();
24
+ const jsxImport = getJSXImplicitImportBase(sourceFile);
25
+ if (jsxImport)
26
+ externalImports.add(jsxImport);
23
27
  const visitors = getVisitors(sourceFile);
24
28
  const addInternalImport = (options) => {
25
29
  const { identifier, specifier, symbol, filePath, isReExport } = options;
@@ -1,3 +1,4 @@
1
1
  import { BoundSourceFile } from '../SourceFile.js';
2
2
  export declare const isNotJS: (sourceFile: BoundSourceFile) => boolean;
3
3
  export declare const isJS: (sourceFile: BoundSourceFile) => boolean;
4
+ export declare function getJSXImplicitImportBase(sourceFile: BoundSourceFile): string | undefined;
@@ -1,3 +1,10 @@
1
1
  import ts from 'typescript';
2
2
  export const isNotJS = (sourceFile) => sourceFile.scriptKind !== ts.ScriptKind.JS && sourceFile.scriptKind !== ts.ScriptKind.JSX;
3
3
  export const isJS = (sourceFile) => sourceFile.scriptKind === ts.ScriptKind.JS || sourceFile.scriptKind === ts.ScriptKind.JSX;
4
+ export function getJSXImplicitImportBase(sourceFile) {
5
+ const jsxImportSourcePragmas = sourceFile.pragmas?.get('jsximportsource');
6
+ const jsxImportSourcePragma = Array.isArray(jsxImportSourcePragmas)
7
+ ? jsxImportSourcePragmas[jsxImportSourcePragmas.length - 1]
8
+ : jsxImportSourcePragmas;
9
+ return jsxImportSourcePragma?.arguments.factory;
10
+ }
@@ -1,4 +1,4 @@
1
- export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports 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, knip.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 tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\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,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n -n, --no-progress Don't show dynamic progress updates\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress 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 --debug-file-filter Filter for files in debug output (regex as string)\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\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 --debug --debug-file-filter '(specific|particular)-module'\n\nMore documentation and bug reports: https://github.com/webpro/knip";
1
+ export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports 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, knip.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 tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\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,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n -n, --no-progress Don't show dynamic progress updates (this is automatically enabled in CI environments)\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress 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 --debug-file-filter Filter for files in debug output (regex as string)\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\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 --debug --debug-file-filter '(specific|particular)-module'\n\nMore documentation and bug reports: https://github.com/webpro/knip";
2
2
  declare const _default: {
3
3
  config: string | undefined;
4
4
  debug: boolean | undefined;
@@ -15,7 +15,7 @@ Options:
15
15
  --dependencies Shortcut for --include dependencies,unlisted,unresolved
16
16
  --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
17
17
  --include-entry-exports Include entry files when reporting unused exports
18
- -n, --no-progress Don't show dynamic progress updates
18
+ -n, --no-progress Don't show dynamic progress updates (this is automatically enabled in CI environments)
19
19
  --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
20
20
  --reporter-options Pass extra options to the reporter (as JSON string, see example)
21
21
  --no-config-hints Suppress configuration hints
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.17.2";
1
+ export declare const version = "2.18.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.17.2';
1
+ export const version = '2.18.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.17.2",
3
+ "version": "2.18.0",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -63,29 +63,29 @@
63
63
  "devDependencies": {
64
64
  "@jest/types": "29.6.1",
65
65
  "@npmcli/package-json": "4.0.1",
66
- "@release-it/bumper": "5.0.0",
66
+ "@release-it/bumper": "5.1.0",
67
67
  "@swc/cli": "0.1.62",
68
- "@swc/core": "1.3.70",
69
- "@types/eslint": "8.44.0",
68
+ "@swc/core": "1.3.73",
69
+ "@types/eslint": "8.44.1",
70
70
  "@types/js-yaml": "4.0.5",
71
71
  "@types/micromatch": "4.0.2",
72
72
  "@types/minimist": "1.2.2",
73
- "@types/node": "20.4.4",
73
+ "@types/node": "20.4.5",
74
74
  "@types/npmcli__map-workspaces": "3.0.1",
75
75
  "@types/webpack": "5.28.1",
76
- "@typescript-eslint/eslint-plugin": "6.1.0",
77
- "@typescript-eslint/parser": "6.1.0",
78
- "c8": "8.0.0",
79
- "eslint": "8.45.0",
76
+ "@typescript-eslint/eslint-plugin": "6.2.1",
77
+ "@typescript-eslint/parser": "6.2.1",
78
+ "c8": "8.0.1",
79
+ "eslint": "8.46.0",
80
80
  "eslint-import-resolver-typescript": "3.5.5",
81
- "eslint-plugin-import": "2.27.5",
81
+ "eslint-plugin-import": "2.28.0",
82
82
  "eslint-plugin-n": "16.0.1",
83
83
  "prettier": "3.0.0",
84
84
  "release-it": "16.1.3",
85
85
  "remark-cli": "11.0.0",
86
86
  "remark-preset-webpro": "0.0.3",
87
87
  "tsx": "3.12.7",
88
- "type-fest": "4.0.0"
88
+ "type-fest": "4.1.0"
89
89
  },
90
90
  "engines": {
91
91
  "node": ">=16.17.0 <17 || >=18.6.0"