From c628d2be673431599098fadb033343a0615b0bfb Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 14:05:58 +0200 Subject: [PATCH 01/12] Remove the depcheck-based dependency checker in favor of Knip. --- ...40527_ci_4564_remove_dependency_checker.md | 6 + .circleci/template.yml | 3 + .syncpackrc.cjs | 37 + README.md | 1 - knip.ts | 81 ++ package.json | 6 +- .../ckeditor5-dev-build-tools/package.json | 7 +- packages/ckeditor5-dev-changelog/package.json | 6 +- .../CHANGELOG.md | 6 - .../LICENSE.md | 16 - .../README.md | 17 - .../bin/dependencychecker.js | 87 -- .../lib/checkdependencies.js | 549 -------- .../lib/checkversionmatch.js | 274 ---- .../lib/index.js | 7 - .../package.json | 44 - .../tests/checkversionmatch.js | 611 --------- .../vitest.config.js | 27 - .../package.json | 5 +- .../lib/tasks/cleanuppackages.js | 2 + .../ckeditor5-dev-release-tools/package.json | 5 +- packages/ckeditor5-dev-stale-bot/package.json | 5 +- .../ckeditor5-dev-web-crawler/package.json | 1 - packages/typedoc-plugins/package.json | 7 +- pnpm-lock.yaml | 1210 ++++++++--------- .../ci/check-dependencies-versions-match.mjs | 40 +- scripts/validate-licenses.mjs | 6 - 27 files changed, 733 insertions(+), 2333 deletions(-) create mode 100644 .changelog/20260721140527_ci_4564_remove_dependency_checker.md create mode 100644 .syncpackrc.cjs create mode 100644 knip.ts delete mode 100644 packages/ckeditor5-dev-dependency-checker/CHANGELOG.md delete mode 100644 packages/ckeditor5-dev-dependency-checker/LICENSE.md delete mode 100644 packages/ckeditor5-dev-dependency-checker/README.md delete mode 100755 packages/ckeditor5-dev-dependency-checker/bin/dependencychecker.js delete mode 100644 packages/ckeditor5-dev-dependency-checker/lib/checkdependencies.js delete mode 100644 packages/ckeditor5-dev-dependency-checker/lib/checkversionmatch.js delete mode 100644 packages/ckeditor5-dev-dependency-checker/lib/index.js delete mode 100644 packages/ckeditor5-dev-dependency-checker/package.json delete mode 100644 packages/ckeditor5-dev-dependency-checker/tests/checkversionmatch.js delete mode 100644 packages/ckeditor5-dev-dependency-checker/vitest.config.js diff --git a/.changelog/20260721140527_ci_4564_remove_dependency_checker.md b/.changelog/20260721140527_ci_4564_remove_dependency_checker.md new file mode 100644 index 000000000..a2196af14 --- /dev/null +++ b/.changelog/20260721140527_ci_4564_remove_dependency_checker.md @@ -0,0 +1,6 @@ +--- +type: Major breaking change +scope: +--- + +Removed the `@ckeditor/ckeditor5-dev-dependency-checker` package. It was built on top of the deprecated `depcheck` library. Use [`knip`](https://knip.dev/) to validate dependencies instead. diff --git a/.circleci/template.yml b/.circleci/template.yml index 63dc68ce8..fc6d80994 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -108,6 +108,9 @@ jobs: - run: name: Validate versions of dependencies command: pnpm run check-versions-match + - run: + name: Validate dependencies + command: pnpm run check-dependencies - run: name: Type check the project command: pnpm run typecheck diff --git a/.syncpackrc.cjs b/.syncpackrc.cjs new file mode 100644 index 000000000..bd7c9ec65 --- /dev/null +++ b/.syncpackrc.cjs @@ -0,0 +1,37 @@ +/** + * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +'use strict'; + +/** + * Configuration for `syncpack`, which ensures that `dependencies` and `devDependencies` + * across the repository use consistent versions. Executed in CI via the + * `check-versions-match` script. Run it with the `--fix` argument to resolve reported + * issues automatically. + * + * Unlike in the `ckeditor5` repository, version ranges (the `^` operator) are allowed here. + * When the same dependency is declared with different versions, the highest one wins. + */ +module.exports = { + source: [ + 'package.json', + 'packages/*/package.json' + ], + + versionGroups: [ + { + label: 'Packages developed in this repository must use the workspace protocol.', + dependencies: [ '$LOCAL' ], + pinVersion: 'workspace:*' + } + ], + + semverGroups: [ + { + dependencies: [ '$LOCAL' ], + isIgnored: true + } + ] +}; diff --git a/README.md b/README.md index 07821b567..c3a21f5f6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ This repository is a monorepo. It contains multiple npm packages. | [`@ckeditor/ckeditor5-dev-bump-year`](/packages/ckeditor5-dev-bump-year) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-bump-year.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-bump-year) | | [`@ckeditor/ckeditor5-dev-changelog`](/packages/ckeditor5-dev-changelog) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-changelog.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-changelog) | | [`@ckeditor/ckeditor5-dev-ci`](/packages/ckeditor5-dev-ci) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-ci.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-ci) | -| [`@ckeditor/ckeditor5-dev-dependency-checker`](/packages/ckeditor5-dev-dependency-checker) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-dependency-checker.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-dependency-checker) | | [`@ckeditor/ckeditor5-dev-docs`](/packages/ckeditor5-dev-docs) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-docs.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-docs) | | [`@ckeditor/ckeditor5-dev-license-checker`](/packages/ckeditor5-dev-license-checker) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-license-checker.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-license-checker) | | [`@ckeditor/ckeditor5-dev-manual-server`](/packages/ckeditor5-dev-manual-server) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-manual-server.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-manual-server) | diff --git a/knip.ts b/knip.ts new file mode 100644 index 000000000..12e6843e2 --- /dev/null +++ b/knip.ts @@ -0,0 +1,81 @@ +/** + * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import type { KnipConfig } from 'knip'; + +/** + * Configuration for the dependency checks (`pnpm run check-dependencies`), executed as: + * + * knip --dependencies (unused and unlisted packages) + * knip --dependencies --production --strict (misplaced `dependencies` vs `devDependencies`) + * + * Patterns marked with the `!` suffix describe production code. They must match the folders + * that end up in the published packages (`lib`, `src`, `bin`, `theme`). + */ +const config: KnipConfig = { + compilers: { + // Extracts `@import` statements from plain CSS files, so packages imported in `theme/` + // participate in the dependency checks. See https://knip.dev/features/compilers. + css: ( text: string ) => [ ...text.matchAll( /(?<=@)import[^;]+/g ) ].join( '\n' ) + }, + + workspaces: { + '.': { + entry: [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ], + project: [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ], + ignoreDependencies: [ + // Spawned via an explicit `node_modules/.bin` path in + // `scripts/ci/check-dependencies-versions-match.mjs`, invisible to static analysis. + 'syncpack' + ] + }, + // Note: a specific workspace entry replaces the `packages/*` one, so it repeats the patterns. + 'packages/ckeditor5-dev-manual-server': { + ignore: [ 'tests/**/fixtures/**' ], + entry: [ + 'src/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}' + ], + project: [ + 'src/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}' + ], + ignoreDependencies: [ + // The package exports Vite plugins and imports `vite` only in type positions, + // but it deliberately ships `vite` as a runtime dependency for its consumers, + // which run the manual test server. + 'vite' + ] + }, + 'packages/*': { + // Test fixtures reference intentionally non-existent packages. + ignore: [ 'tests/**/fixtures/**' ], + entry: [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' + ], + project: [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' + ] + } + } +}; + +export default config; diff --git a/package.json b/package.json index 6e6d9dc3a..c05d3d61e 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "type": "module", "devDependencies": { + "@ckeditor/ckeditor5-dev-changelog": "workspace:*", "@inquirer/prompts": "^7.10.1", "@listr2/prompt-adapter-inquirer": "^2.0.22", "@vitest/coverage-v8": "^4.1.2", @@ -27,10 +28,11 @@ "globals": "^16.5.0", "husky": "^9.1.7", "js-yaml": "^4.2.0", + "knip": "^6.27.0", "lint-staged": "^16.4.0", "listr2": "^8.3.3", "minimist": "^1.2.8", - "semver": "^7.7.4", + "syncpack": "^15.3.2", "typescript": "5.5.4", "upath": "^2.0.1", "vite": "^8.1.0", @@ -50,7 +52,7 @@ "typecheck": "tsc", "precommit": "lint-staged", "reinstall": "pnpx rimraf --glob \"**/node_modules\" && pnpm install", - "check-dependencies": "ckeditor5-dev-dependency-checker" + "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints" }, "lint-staged": { "**/*": [ diff --git a/packages/ckeditor5-dev-build-tools/package.json b/packages/ckeditor5-dev-build-tools/package.json index 44dd15896..080532db4 100644 --- a/packages/ckeditor5-dev-build-tools/package.json +++ b/packages/ckeditor5-dev-build-tools/package.json @@ -40,7 +40,6 @@ "upath": "^2.0.1" }, "devDependencies": { - "@types/css": "^0.0.38", "@types/node": "^22.19.17", "@vitest/coverage-v8": "^4.1.2", "type-fest": "^4.41.0", @@ -52,9 +51,5 @@ "test": "vitest run --config vitest.config.ts", "coverage": "vitest run --config vitest.config.ts --coverage", "test:dev": "vitest dev" - }, - "depcheckIgnore": [ - "@types/css", - "@vitest/coverage-v8" - ] + } } diff --git a/packages/ckeditor5-dev-changelog/package.json b/packages/ckeditor5-dev-changelog/package.json index c18e72d38..ad7dd5552 100644 --- a/packages/ckeditor5-dev-changelog/package.json +++ b/packages/ckeditor5-dev-changelog/package.json @@ -49,9 +49,5 @@ "test": "vitest run --config vitest.config.ts", "coverage": "vitest run --config vitest.config.ts --coverage", "test:dev": "vitest dev" - }, - "depcheckIgnore": [ - "@vitest/coverage-v8", - "typescript" - ] + } } diff --git a/packages/ckeditor5-dev-dependency-checker/CHANGELOG.md b/packages/ckeditor5-dev-dependency-checker/CHANGELOG.md deleted file mode 100644 index b1b315b84..000000000 --- a/packages/ckeditor5-dev-dependency-checker/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -Changelog -========= - -All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5-dev/blob/master/CHANGELOG.md. - -This package was extracted from `ckeditor5-dev-tests` in version `v31.1.13`. Its previous changelog can be found here: [ckeditor5-dev-tests@31.1.13/CHANGELOG.md](https://github.com/ckeditor/ckeditor5-dev/blob/v31.1.13/packages/ckeditor5-dev-tests/CHANGELOG.md) diff --git a/packages/ckeditor5-dev-dependency-checker/LICENSE.md b/packages/ckeditor5-dev-dependency-checker/LICENSE.md deleted file mode 100644 index 24a241576..000000000 --- a/packages/ckeditor5-dev-dependency-checker/LICENSE.md +++ /dev/null @@ -1,16 +0,0 @@ -Software License Agreement -========================== - -Copyright (c) 2003-2026, [CKSource](http://cksource.com) Holding sp. z o.o. All rights reserved. - -Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). - -Sources of Intellectual Property Included in CKEditor ------------------------------------------------------ - -Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission. - -Trademarks ----------- - -**CKEditor** is a trademark of [CKSource](http://cksource.com) Holding sp. z o.o. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders. diff --git a/packages/ckeditor5-dev-dependency-checker/README.md b/packages/ckeditor5-dev-dependency-checker/README.md deleted file mode 100644 index 0b8d78e11..000000000 --- a/packages/ckeditor5-dev-dependency-checker/README.md +++ /dev/null @@ -1,17 +0,0 @@ -CKEditor 5 dependency checker -============================= - -[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-dependency-checker.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-dependency-checker) -[![CircleCI](https://circleci.com/gh/ckeditor/ckeditor5-dev.svg?style=shield)](https://app.circleci.com/pipelines/github/ckeditor/ckeditor5-dev?branch=master) - -Contains tools for validating dependencies specified in package.json. - -More information about development tools packages can be found at the following URL: . - -## Changelog - -See the [`CHANGELOG.md`](https://github.com/ckeditor/ckeditor5-dev/blob/master/packages/ckeditor5-dev-dependency-checker/CHANGELOG.md) file. - -## License - -Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file. diff --git a/packages/ckeditor5-dev-dependency-checker/bin/dependencychecker.js b/packages/ckeditor5-dev-dependency-checker/bin/dependencychecker.js deleted file mode 100755 index 0d5c3dbf8..000000000 --- a/packages/ckeditor5-dev-dependency-checker/bin/dependencychecker.js +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env node - -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import path from 'node:path'; -import minimist from 'minimist'; -import { tools } from '@ckeditor/ckeditor5-dev-utils'; -import checkDependencies from '../lib/checkdependencies.js'; - -const { packagePaths, options } = parseArguments( process.argv.slice( 2 ) ); - -checkDependencies( packagePaths, options ) - .then( foundError => { - if ( foundError ) { - process.exitCode = 1; - } - } ); - -/** - * Parses CLI arguments and options. - * - * @param {Array.} args CLI arguments containing package paths and options. - * @returns {object} result - * @returns {Set.} result.packagePaths Relative package paths. - * @returns {Object.} result.options Configuration options. - */ -function parseArguments( args ) { - const config = { - boolean: [ - 'quiet' - ], - - default: { - quiet: false - } - }; - - const parsedArgs = minimist( args, config ); - - const options = Object.assign( {}, parsedArgs ); - - // Delete arguments that didn't have an explicit option associated with them. - // In our case this is all package paths. - delete options._; - - return { - packagePaths: getPackagePaths( parsedArgs._ ), - options - }; -} - -/** - * Returns relative (to the current work directory) paths to packages. If the provided `args` array is empty, - * the packages will be read from the `packages/` directory. - * - * @param {Array.} args CLI arguments with relative or absolute package paths. - * @returns {Set.} Relative package paths. - */ -function getPackagePaths( args ) { - if ( !args.length ) { - return tools.getDirectories( path.join( process.cwd(), 'packages' ) ) - .map( packageName => `packages/${ packageName }` ); - } - - const PACKAGE_RELATIVE_PATH_REGEXP = /packages\/ckeditor5?-[^/]+/; - - const getPackageRelativePathFromAbsolutePath = path => { - const found = path.match( PACKAGE_RELATIVE_PATH_REGEXP ); - - return found ? found[ 0 ] : ''; - }; - - const isPackageRelativePath = path => !!path && PACKAGE_RELATIVE_PATH_REGEXP.test( path ); - - return args.reduce( ( paths, arg ) => { - const relativePath = path.isAbsolute( arg ) ? getPackageRelativePathFromAbsolutePath( arg ) : arg; - - if ( isPackageRelativePath( relativePath ) ) { - paths.add( relativePath ); - } - - return paths; - }, new Set() ); -} diff --git a/packages/ckeditor5-dev-dependency-checker/lib/checkdependencies.js b/packages/ckeditor5-dev-dependency-checker/lib/checkdependencies.js deleted file mode 100644 index 0354aa044..000000000 --- a/packages/ckeditor5-dev-dependency-checker/lib/checkdependencies.js +++ /dev/null @@ -1,549 +0,0 @@ -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import { styleText } from 'node:util'; -import fs from 'node:fs'; -import upath from 'upath'; -import { globSync } from 'glob'; -import depCheck from 'depcheck'; -import { parseAsync } from 'oxc-parser'; -import { walk } from 'oxc-walker'; - -const DEPCHECK_IGNORE_DEFAULT = [ - 'ckeditor5-root' -]; - -/** - * Checks dependencies sequentially in all provided packages. - * - * @param {Set.} packagePaths Relative paths to packages. - * @param {object} options Options. - * @param {boolean} [options.quiet=false] Whether to inform about the progress. - * @returns {Promise.} Resolves a promise with a flag informing whether detected an error. - */ -export default async function checkDependencies( packagePaths, options ) { - let foundError = false; - - for ( const packagePath of packagePaths ) { - const isSuccess = await checkDependenciesInPackage( packagePath, { - quiet: options.quiet - } ); - - // Mark result of this script execution as invalid. - if ( !isSuccess ) { - foundError = true; - } - } - - return Promise.resolve( foundError ); -} - -/** - * Checks dependencies in provided package. If the folder does not contain a package.json file the function quits with success. - * - * @param {string} packagePath Relative path to package. - * @param {object} options Options. - * @param {boolean} [options.quiet=false] Whether to inform about the progress. - * @returns {Promise.} The result of checking the dependencies in the package: true = no errors found. - */ -async function checkDependenciesInPackage( packagePath, options ) { - const packageAbsolutePath = upath.resolve( packagePath ); - const packageJsonPath = upath.join( packageAbsolutePath, 'package.json' ); - - if ( !fs.existsSync( packageJsonPath ) ) { - console.log( `⚠️ Missing package.json file in ${ styleText( 'bold', packagePath ) }, skipping...\n` ); - - return true; - } - - const packageJsonFile = fs.readFileSync( packageJsonPath, 'utf-8' ); - const packageJson = JSON.parse( packageJsonFile ); - - const missingCSSFiles = []; - const onMissingCSSFile = file => missingCSSFiles.push( file ); - - const depCheckOptions = { - // We need to add all values manually because if we modify it, the rest is being lost. - parsers: { - '**/*.css': filePath => parseCSS( filePath, onMissingCSSFile ), - '**/*.cjs': depCheck.parser.es6, - '**/*.mjs': filePath => parseModule( filePath, packageJson ), - '**/*.js': filePath => parseModule( filePath, packageJson ), - '**/*.jsx': filePath => parseModule( filePath, packageJson ), - '**/*.ts': filePath => parseModule( filePath, packageJson ), - '**/*.vue': depCheck.parser.vue - }, - ignorePatterns: [ 'docs', 'build', 'dist/browser' ], - ignoreMatches: [ 'eslint*', 'webpack*', 'husky', 'lint-staged' ] - }; - - const depcheckIgnore = Array.isArray( packageJson.depcheckIgnore ) ? packageJson.depcheckIgnore : []; - - depcheckIgnore.push( ...DEPCHECK_IGNORE_DEFAULT ); - - depCheckOptions.ignoreMatches.push( ...depcheckIgnore ); - - if ( !options.quiet ) { - console.log( `🔎 Checking dependencies in ${ styleText( 'bold', packageJson.name ) }...` ); - } - - const result = await depCheck( packageAbsolutePath, depCheckOptions ); - const missingPackages = groupMissingPackages( result.missing, packageJson.name ); - - const misplacedOptions = { - dependencies: packageJson.dependencies, - devDependencies: packageJson.devDependencies, - dependenciesToCheck: result.using, - dependenciesToIgnore: depcheckIgnore - }; - - const errors = [ - // Invalid itself imports. - getInvalidItselfImports( packageAbsolutePath ) - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Missing dependencies. - missingPackages.dependencies - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Missing devDependencies. - missingPackages.devDependencies - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Unused dependencies. - result.dependencies - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Unused devDependencies. - result.devDependencies - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Relative CSS imports (files do not exist). - missingCSSFiles - .map( entry => { - return `- "${ entry.file }" imports "${ entry.import }"`; - } ) - .join( '\n' ), - - // Duplicated `dependencies` and `devDependencies`. - findDuplicatedDependencies( packageJson.dependencies, packageJson.devDependencies ) - .map( entry => '- ' + entry ) - .join( '\n' ), - - // Misplaced `dependencies` or `devDependencies`. - // Checks whether any package, which is already listed in the `dependencies` or `devDependencies`, - // should belong to that list. - findMisplacedDependencies( misplacedOptions ) - .reduce( ( result, group ) => { - return result + '\n' + - group.description + '\n' + - group.packageNames.map( entry => '- ' + entry ).join( '\n' ) + '\n'; - }, '' ) - ]; - - const hasErrors = errors.some( error => !!error ); - - if ( !hasErrors ) { - if ( !options.quiet ) { - console.log( styleText( [ 'green', 'bold' ], '✨ All dependencies are defined correctly.\n' ) ); - } - - return true; - } - - console.log( styleText( [ 'red', 'bold' ], `🔥 Found some issue with dependencies in ${ styleText( 'bold', packageJson.name ) }.\n` ) ); - - showErrors( errors ); - - return false; -} - -/** - * Returns an array that contains list of files that import modules using full package name instead of relative path. - * - * @param repositoryPath An absolute path to the directory which should be checked. - * @returns {Array.} - */ -function getInvalidItselfImports( repositoryPath ) { - const packageJsonFile = fs.readFileSync( upath.join( repositoryPath, 'package.json' ), 'utf-8' ); - const packageJson = JSON.parse( packageJsonFile ); - const globPattern = upath.join( repositoryPath, '@(src|tests)/**/*.js' ); - const invalidImportsItself = new Set(); - - for ( const filePath of globSync( globPattern ) ) { - const fileContent = fs.readFileSync( filePath, 'utf-8' ); - const matchedImports = fileContent.match( /^import[^;]+from '(@ckeditor\/[^/]+)[^']+';/mg ); - - if ( !matchedImports ) { - continue; - } - - matchedImports - .map( importLine => importLine.match( /(@ckeditor\/[^/]+)/ ) ) - .filter( matchedImport => !!matchedImport ) - .forEach( matchedImport => { - // Current package should use relative links to itself. - if ( packageJson.name === matchedImport[ 1 ] ) { - invalidImportsItself.add( filePath.replace( repositoryPath + '/', '' ) ); - } - } ); - } - - return [ ...invalidImportsItself ].sort(); -} - -/** - * Groups missing dependencies returned by `depcheck` as `dependencies` or `devDependencies`. - * - * @param {object} missingPackages The `missing` value from object returned by `depcheck`. - * @param {string} currentPackage Name of current package. - * @returns {Object.>} - */ -function groupMissingPackages( missingPackages, currentPackage ) { - delete missingPackages[ currentPackage ]; - - const dependencies = []; - const devDependencies = []; - - for ( const packageName of Object.keys( missingPackages ) ) { - const absolutePaths = missingPackages[ packageName ]; - - if ( isProductionDependency( absolutePaths ) ) { - dependencies.push( packageName ); - } else { - devDependencies.push( packageName ); - } - } - - return { dependencies, devDependencies }; -} - -/** - * Checks whether all packages that have been imported by the CSS file are defined in `package.json` as `dependencies`. - * Returned array contains list of used packages. - * - * @param {string} filePath An absolute path to the checking file. - * @param {function} onMissingCSSFile Error handler called when a CSS file is not found. - * @returns {Array.|undefined} - */ -function parseCSS( filePath, onMissingCSSFile ) { - const fileContent = fs.readFileSync( filePath, 'utf-8' ); - const matchedImports = fileContent.match( /^@import "[^"]+";/mg ); - - if ( !matchedImports ) { - return; - } - - const usedPackages = new Set(); - - matchedImports - .map( importLine => { - const importedFile = importLine.match( /"([^"]+)"/ )[ 1 ]; - - // Scoped package. - // @import "@foo/bar/..."; - // @import "@foo/bar"; and its package.json: { "main": "foo-bar.css" } - if ( importedFile.startsWith( '@' ) ) { - return { - type: 'package', - name: importedFile.split( '/' ).slice( 0, 2 ).join( '/' ) - }; - } - - // Relative import. - // @import "./file.css"; or @import "../file.css"; - if ( importedFile.startsWith( './' ) || importedFile.startsWith( '../' ) ) { - return { - type: 'file', - path: importedFile - }; - } - - // Non-scoped package. - return { - type: 'package', - name: importedFile.split( '/' )[ 0 ] - }; - } ) - .forEach( importDetails => { - // If checked file imports another file, checks whether imported file exists. - if ( importDetails.type == 'file' ) { - const fileToImport = upath.resolve( filePath, '..', importDetails.path ); - - if ( !fs.existsSync( fileToImport ) ) { - onMissingCSSFile( { - file: filePath, - import: importDetails.path - } ); - } - - return; - } - - usedPackages.add( importDetails.name ); - } ); - - return [ ...usedPackages ].sort(); -} - -/** - * Returns all dependencies found in the file, including those from `import.meta.resolve`. - * - * @param {string} path - * @param {Record} packageJson - * @returns {Array} - */ -async function parseModule( path, packageJson ) { - const content = await fs.promises.readFile( path, 'utf-8' ); - const { errors, module, program } = await parseAsync( path, content ); - - if ( errors.length || !module.hasModuleSyntax ) { - // Use native `depcheck` parser if there was an error or if the file content is not ESM. - return depCheck.parser.es6( path ); - } - - const dependencies = Object.keys( { - ...packageJson.dependencies, - ...packageJson.devDependencies - } ); - - const deps = [ - // Get all static import paths: `import {} from 'package-name'`. - ...module.staticImports.map( statement => statement.moduleRequest.value ), - - // Get all static export paths: `export {} from 'package-name'`. - ...module.staticExports - .flatMap( staticExport => staticExport.entries.map( entry => entry.moduleRequest?.value ) ) - .filter( Boolean ) - ]; - - // Add paths passed to `import.meta.resolve` to the list of dependencies. - // This only works if the passed path is a string literal, not a variable. - walk( program, { - enter( node, parent ) { - if ( - node.type === 'MemberExpression' && - node.object.type === 'MetaProperty' && - node.property.name === 'resolve' && - parent.arguments[ 0 ].type === 'Literal' - ) { - deps.push( parent.arguments[ 0 ].value ); - } - } - } ); - - return deps - // Remove relative paths. - .filter( path => !path.startsWith( '.' ) ) - - /** - * Get only package names: - * - `packageName/some/path` -> `packageName`. - * - `@scope/packageName/some/path` -> `@scope/packageName`. - */ - .map( path => { - const parts = path.split( '/' ); - - return path.startsWith( '@' ) ? parts.slice( 0, 2 ).join( '/' ) : parts[ 0 ]; - } ) - - /** - * Add `@types` dependencies if they are defined in `package.json`: - * - `package-name` -> `@types/package-name`. - * - `@scope/package-name` -> `@types/scope__package-name`. - */ - .reduce( ( acc, dependency ) => { - const types = dependency.startsWith( '@' ) ? - `@types/${ dependency.replace( '@', '' ).replace( '/', '__' ) }` : - `@types/${ dependency }`; - - if ( dependencies.includes( types ) ) { - acc.push( types ); - } - - acc.push( dependency ); - - return acc; - }, [] ) - - // Remove duplicates. - .filter( ( value, index, self ) => self.indexOf( value ) === index ) - - // Sort the result. - .sort(); -} - -/** - * Checks whether packages specified as `devDependencies` are not duplicated with items defined as `dependencies`. - * - * @see https://github.com/ckeditor/ckeditor5/issues/7706#issuecomment-665569410 - * @param {object|undefined} dependencies - * @param {object|undefined} devDependencies - * @returns {Array.} - */ -function findDuplicatedDependencies( dependencies, devDependencies ) { - const deps = Object.keys( dependencies || {} ); - const devDeps = Object.keys( devDependencies || {} ); - - if ( !deps.length || !devDeps.length ) { - return []; - } - - const duplicatedPackages = new Set(); - - for ( const packageName of deps ) { - if ( devDeps.includes( packageName ) ) { - duplicatedPackages.add( packageName ); - } - } - - return [ ...duplicatedPackages ].sort(); -} - -/** - * Checks whether all packages, which are already listed in the `dependencies` or `devDependencies`, should belong to that list. - * The `devDependencies` list should contain packages, which are not used in the source. Otherwise, a given package should be - * added to the `dependencies` list. This function does not check missing dependencies, which is covered elsewhere, but it only - * verifies wrongly placed ones. - * - * @see https://github.com/ckeditor/ckeditor5/issues/8817#issuecomment-759353134 - * @param {object|undefined} options.dependencies Defined dependencies from package.json. - * @param {object|undefined} options.devDependencies Defined development dependencies from package.json. - * @param {object} options.dependenciesToCheck All dependencies that have been found and files where they are used. - * @param {Array.} options.dependenciesToIgnore An array of package names that should not be checked. - * @returns {Array.} Misplaced packages. Each array item is an object containing - * the `description` string and `packageNames` array of strings. - */ -function findMisplacedDependencies( options ) { - const { dependencies, devDependencies, dependenciesToCheck, dependenciesToIgnore } = options; - const deps = Object.keys( dependencies || {} ); - const devDeps = Object.keys( devDependencies || {} ); - - const misplacedPackages = { - missingInDependencies: { - description: 'The following packages are used in the source and should be moved to `dependencies`', - packageNames: new Set() - }, - missingInDevDependencies: { - description: 'The following packages are not used in the source and should be moved to `devDependencies`', - packageNames: new Set() - } - }; - - for ( const [ packageName, absolutePaths ] of Object.entries( dependenciesToCheck ) ) { - if ( dependenciesToIgnore.includes( packageName ) ) { - continue; - } - - const isProdDep = isProductionDependency( absolutePaths ); - const isMissingInDependencies = isProdDep && !deps.includes( packageName ) && devDeps.includes( packageName ); - const isMissingInDevDependencies = !isProdDep && deps.includes( packageName ) && !devDeps.includes( packageName ); - - if ( isMissingInDependencies ) { - misplacedPackages.missingInDependencies.packageNames.add( packageName ); - } - - if ( isMissingInDevDependencies ) { - misplacedPackages.missingInDevDependencies.packageNames.add( packageName ); - } - } - - return Object - .values( misplacedPackages ) - .filter( item => item.packageNames.size > 0 ) - .map( item => ( { - description: styleText( 'gray', item.description ), - packageNames: [ ...item.packageNames ].sort() - } ) ); -} - -/** - * These folders contain code that will be shipped to npm and run in the final projects. - * This means that all dependencies used in these folders are production dependencies. - */ -const foldersContainingProductionCode = [ - /** - * These folders contain the source code of the packages. - */ - /[/\\]bin[/\\]/, - /[/\\]src[/\\]/, - /[/\\]lib[/\\]/, - /[/\\]theme[/\\]/, - - /** - * This folder contains the compiled code of the packages. Most of this code is the same - * as the source, but during the build process some of the imports are replaced with those - * compatible with the "new installation methods", which may use different dependencies. - * - * For example, the `ckeditor5/src/core.js` import is replaced with `@ckeditor/ckeditor5-core/dist/index.js`. - * ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ - */ - /[/\\]dist[/\\]/ -]; - -/** - * Checks if a given package is a production dependency, i.e., it's used in build files or their typings. - * - * @param {Array.} paths Files where a given package has been imported. - * @returns {boolean} - */ -function isProductionDependency( paths ) { - return paths.some( - path => foldersContainingProductionCode.some( folder => path.match( folder ) ) - ); -} - -/** - * Displays all found errors. - * - * @param {Array.} data Collection of errors. - */ -function showErrors( data ) { - if ( data[ 0 ] ) { - console.log( styleText( 'red', '❌ Invalid itself imports found in:' ) ); - console.log( data[ 0 ] + '\n' ); - console.log( styleText( 'gray', 'Imports from local package must always use relative path.\n' ) ); - } - - if ( data[ 1 ] ) { - console.log( styleText( 'red', '❌ Missing dependencies:' ) ); - console.log( data[ 1 ] + '\n' ); - } - - if ( data[ 2 ] ) { - console.log( styleText( 'red', '❌ Missing devDependencies:' ) ); - console.log( data[ 2 ] + '\n' ); - } - - if ( data[ 3 ] ) { - console.log( styleText( 'red', '❌ Unused dependencies:' ) ); - console.log( data[ 3 ] + '\n' ); - } - - if ( data[ 4 ] ) { - console.log( styleText( 'red', '❌ Unused devDependencies:' ) ); - console.log( data[ 4 ] + '\n' ); - } - - if ( data[ 5 ] ) { - console.log( styleText( 'red', '❌ Importing CSS files that do not exist:' ) ); - console.log( data[ 5 ] + '\n' ); - } - - if ( data[ 6 ] ) { - console.log( styleText( 'red', '❌ Duplicated `dependencies` and `devDependencies`:' ) ); - console.log( data[ 6 ] + '\n' ); - } - - if ( data[ 7 ] ) { - console.log( styleText( 'red', '❌ Misplaced dependencies (`dependencies` or `devDependencies`):' ) ); - console.log( data[ 7 ] + '\n' ); - } -} diff --git a/packages/ckeditor5-dev-dependency-checker/lib/checkversionmatch.js b/packages/ckeditor5-dev-dependency-checker/lib/checkversionmatch.js deleted file mode 100644 index 9da844816..000000000 --- a/packages/ckeditor5-dev-dependency-checker/lib/checkversionmatch.js +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env node - -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import fs from 'node:fs'; -import { styleText } from 'node:util'; -import semver from 'semver'; -import { globSync } from 'glob'; -import { execSync } from 'node:child_process'; - -const PNPM_WORKSPACE_VERSION = 'workspace:*'; - -const DEPENDENCY_TYPES = [ - 'dependencies', - 'devDependencies' -]; - -const DEFAULT_PKG_JSON_PATTERNS = [ - 'package.json', - 'packages/*/package.json' -]; - -/** - * This script ensures that "dependencies" and "devDependencies" in package JSONs which match - * passed (or default) glob patterns use consistent dependencies versions. It also checks versions - * available on npm, bumps and pins a set version for dependencies using the "^" range operator. - * - * @param {object} options - * @param {string} options.cwd - * @param {boolean} [options.fix=false] Whether the script should automatically fix the errors instead of reporting them. - * @param {boolean} [options.allowRanges=false] It prevents dependencies using the "^" range operator from being bumped to - * latest version from npm matching them. Instead, they are bumped to highest version between them. - * @param {function} [options.devDependenciesFilter] Function that defines which "devDependencies" should be modified. - * All are modified by default - * @param {Array.} [options.pkgJsonPatterns] Array of glob patterns to find `package.json` files to modify. - * By default, it modifies root `package.json` and `packages/*\/package.json` files. - * @param {object} [options.versionExceptions] Allows setting `allowRanges` for packages defined as keys of this object, - * instead of globally. - * @param {Array.} [options.workspacePackages] Array of packages that should use `workspace:*` as version. - */ -export default async function checkVersionMatch( { - cwd, - fix = false, - allowRanges = false, - devDependenciesFilter = () => true, - pkgJsonPatterns = DEFAULT_PKG_JSON_PATTERNS, - versionExceptions = {}, - workspacePackages = [] -} ) { - console.log( styleText( 'blue', '🔍 Starting checking dependencies versions...' ) ); - - const versionsCache = {}; - - const [ packageJsons, pathMappings ] = getPackageJsons( { cwd, pkgJsonPatterns } ); - - const expectedDependencies = getExpectedDepsVersions( { - packageJsons, - devDependenciesFilter, - versionExceptions, - versionsCache, - allowRanges, - workspacePackages - } ); - - if ( fix ) { - fixDependenciesVersions( { expectedDependencies, packageJsons, pathMappings, devDependenciesFilter } ); - } else { - checkDependenciesMatch( { expectedDependencies, packageJsons, devDependenciesFilter } ); - } -} - -/** - * @param {object} options - * @param {object.} options.expectedDependencies - * @param {Array.} options.packageJsons - * @param {object.} options.pathMappings - * @param {function} options.devDependenciesFilter - */ -function fixDependenciesVersions( { expectedDependencies, packageJsons, pathMappings, devDependenciesFilter } ) { - packageJsons.forEach( packageJson => { - DEPENDENCY_TYPES.forEach( dependencyType => { - if ( !packageJson[ dependencyType ] ) { - return; - } - - Object.keys( packageJson[ dependencyType ] ).forEach( dependencyName => { - if ( dependencyType === 'devDependencies' && !devDependenciesFilter( dependencyName ) ) { - return; - } - - packageJson[ dependencyType ][ dependencyName ] = expectedDependencies[ dependencyName ]; - } ); - } ); - - fs.writeFileSync( pathMappings[ packageJson.name ], JSON.stringify( packageJson, null, 2 ) ); - } ); - - console.log( styleText( 'green', '✅ All dependencies fixed!' ) ); -} - -/** - * @param {object} options - * @param {Array.} options.packageJsons - * @param {function} options.devDependenciesFilter - * @param {object.} options.expectedDependencies - */ -function checkDependenciesMatch( { packageJsons, devDependenciesFilter, expectedDependencies } ) { - const errors = packageJsons.flatMap( packageJson => { - return DEPENDENCY_TYPES.flatMap( dependencyType => { - if ( !packageJson[ dependencyType ] ) { - return; - } - - return Object.entries( packageJson[ dependencyType ] ).flatMap( ( [ dependencyName, version ] ) => { - if ( dependencyType === 'devDependencies' && !devDependenciesFilter( dependencyName ) ) { - return; - } - - const expectedVersion = expectedDependencies[ dependencyName ]; - - if ( version === expectedVersion ) { - return; - } - - return `"${ - dependencyName - }" in "${ - packageJson.name - }" in version "${ - version - }" should be set to "${ - expectedVersion - }".`; - } ); - } ); - } ).filter( Boolean ); - - if ( errors.length ) { - console.error( - styleText( 'red', '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' ) - ); - console.error( styleText( 'red', errors.join( '\n' ) ) ); - process.exit( 1 ); - } else { - console.log( styleText( 'green', '✅ All dependencies are correct!' ) ); - } -} - -/** - * @param {object} options - * @param {Array.} options.packageJsons - * @param {function} options.devDependenciesFilter - * @param {object} options.versionExceptions - * @param {object} options.versionsCache - * @param {boolean} options.allowRanges - * @param {Array.} options.workspacePackages - * @return {object.} expectedDependencies - */ -function getExpectedDepsVersions( options ) { - const { packageJsons, devDependenciesFilter, versionExceptions, versionsCache, allowRanges, workspacePackages } = options; - - return packageJsons.reduce( ( expectedDependencies, packageJson ) => { - DEPENDENCY_TYPES.forEach( dependencyType => { - if ( !packageJson[ dependencyType ] ) { - return; - } - - Object.entries( packageJson[ dependencyType ] ).forEach( ( [ dependencyName, version ] ) => { - if ( workspacePackages.length && workspacePackages.includes( dependencyName ) ) { - expectedDependencies[ dependencyName ] = PNPM_WORKSPACE_VERSION; - - return; - } - - if ( dependencyType === 'devDependencies' && !devDependenciesFilter( dependencyName ) ) { - return; - } - - expectedDependencies[ dependencyName ] = getNewestVersion( { - dependencyName, - newVersion: version, - versionsCache, - versionExceptions, - allowRanges, - currentMaxVersion: expectedDependencies[ dependencyName ] - } ); - } ); - } ); - - return expectedDependencies; - }, {} ); -} - -/** - * @param {object} options - * @param {string} options.dependencyName - * @param {object} options.versionsCache - * @param {object} options.versionExceptions - * @param {boolean} options.allowRanges - * @param {string} [options.newVersion='0.0.0'] - * @param {string} [options.currentMaxVersion='0.0.0'] - * @return {string} - */ -function getNewestVersion( { - dependencyName, - versionsCache, - versionExceptions, - allowRanges, - newVersion = '0.0.0', - currentMaxVersion = '0.0.0' -} ) { - if ( versionExceptions[ dependencyName ] ) { - return newVersion; - } - - // If workspace:* detected when workspacePackages is empty, getting the newest version from npm. - if ( newVersion === PNPM_WORKSPACE_VERSION || currentMaxVersion === PNPM_WORKSPACE_VERSION ) { - const versions = getVersionsList( { dependencyName, versionsCache } ); - const stableVersions = versions.filter( v => !semver.prerelease( v ) ); - - return stableVersions.sort( semver.rcompare )[ 0 ]; - } - - if ( allowRanges ) { - return semver.gt( semver.minVersion( newVersion ), semver.minVersion( currentMaxVersion ) ) ? newVersion : currentMaxVersion; - } - - const newMaxVersion = semver.valid( newVersion ) ? - newVersion : - semver.maxSatisfying( getVersionsList( { dependencyName, versionsCache } ), newVersion ); - - return semver.gt( newMaxVersion, currentMaxVersion ) ? newMaxVersion : currentMaxVersion; -} - -/** - * @param {object} options - * @param {string} options.dependencyName - * @param {object} options.versionsCache - * @return {object.} - */ -function getVersionsList( { dependencyName, versionsCache } ) { - if ( !versionsCache[ dependencyName ] ) { - console.log( styleText( 'blue', `⬇️ Downloading "${ dependencyName }" versions from npm...` ) ); - const versionsJson = execSync( `npm view ${ dependencyName } versions --json`, { encoding: 'utf8' } ); - versionsCache[ dependencyName ] = JSON.parse( versionsJson ); - } - - return versionsCache[ dependencyName ]; -} - -/** - * @param {object} options - * @param {string} options.cwd - * @param {Array.} options.pkgJsonPatterns - * @return {[Array., object.]} - */ -function getPackageJsons( { cwd, pkgJsonPatterns } ) { - const packageJsonPaths = globSync( pkgJsonPatterns, { absolute: true, cwd } ); - const packageJsons = packageJsonPaths - .map( packageJsonPath => fs.readFileSync( packageJsonPath, 'utf-8' ) ) - .map( packageJsonContent => JSON.parse( packageJsonContent ) ); - - const nameToPathMappings = packageJsonPaths.reduce( ( accum, packageJsonPath ) => { - const file = fs.readFileSync( packageJsonPath, 'utf-8' ); - const { name } = JSON.parse( file ); - - return { ...accum, [ name ]: packageJsonPath }; - }, {} ); - - return [ packageJsons, nameToPathMappings ]; -} diff --git a/packages/ckeditor5-dev-dependency-checker/lib/index.js b/packages/ckeditor5-dev-dependency-checker/lib/index.js deleted file mode 100644 index 6a8ae74a8..000000000 --- a/packages/ckeditor5-dev-dependency-checker/lib/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -export { default as checkDependencies } from './checkdependencies.js'; -export { default as checkVersionMatch } from './checkversionmatch.js'; diff --git a/packages/ckeditor5-dev-dependency-checker/package.json b/packages/ckeditor5-dev-dependency-checker/package.json deleted file mode 100644 index 755b414b7..000000000 --- a/packages/ckeditor5-dev-dependency-checker/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@ckeditor/ckeditor5-dev-dependency-checker", - "version": "57.4.0", - "description": "Contains tools for validating dependencies specified in package.json.", - "keywords": [], - "author": "CKSource (http://cksource.com/)", - "license": "GPL-2.0-or-later", - "homepage": "https://github.com/ckeditor/ckeditor5-dev/tree/master/packages/ckeditor5-dev-dependency-checker", - "bugs": "https://github.com/ckeditor/ckeditor5/issues", - "repository": { - "type": "git", - "url": "https://github.com/ckeditor/ckeditor5-dev.git", - "directory": "packages/ckeditor5-dev-dependency-checker" - }, - "engines": { - "node": ">=24.11.0", - "npm": ">=5.7.1" - }, - "main": "lib/index.js", - "type": "module", - "files": [ - "bin", - "lib" - ], - "bin": { - "ckeditor5-dev-dependency-checker": "bin/dependencychecker.js" - }, - "dependencies": { - "@ckeditor/ckeditor5-dev-utils": "workspace:*", - "depcheck": "^1.4.7", - "glob": "^13.0.6", - "minimist": "^1.2.8", - "oxc-parser": "^0.72.3", - "oxc-walker": "^0.3.0", - "upath": "^2.0.1" - }, - "devDependencies": { - "vitest": "^4.1.2" - }, - "scripts": { - "test": "vitest run --config vitest.config.js", - "coverage": "vitest run --config vitest.config.js --coverage" - } -} diff --git a/packages/ckeditor5-dev-dependency-checker/tests/checkversionmatch.js b/packages/ckeditor5-dev-dependency-checker/tests/checkversionmatch.js deleted file mode 100644 index 9e62cd3e4..000000000 --- a/packages/ckeditor5-dev-dependency-checker/tests/checkversionmatch.js +++ /dev/null @@ -1,611 +0,0 @@ -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import { describe, expect, it, vi, beforeEach } from 'vitest'; -import fs from 'node:fs'; -import { globSync } from 'glob'; -import { execSync } from 'node:child_process'; -import checkVersionMatch from '../lib/checkversionmatch.js'; - -const hoists = vi.hoisted( () => ( { - styleText: vi.fn( ( _style, text ) => text ) -} ) ); - -vi.mock( 'node:fs' ); -vi.mock( 'node:util', () => ( { styleText: hoists.styleText } ) ); -vi.mock( 'glob' ); -vi.mock( 'node:child_process' ); - -describe( 'checkVersionMatch()', () => { - let options, files, packageVersions, processExitMock, consoleLogMock, consoleErrorMock; - - beforeEach( () => { - options = { - cwd: 'current/working/directory' - }; - - files = { - './package.json': { - name: 'rootPkg', - dependencies: { - 'dep1': '1.0.0' - }, - devDependencies: { - 'dep2': '2.0.0' - } - }, - './packages/foo/package.json': { - name: 'fooPkg', - dependencies: { - 'dep1': '1.0.0' - }, - devDependencies: { - 'dep2': '2.0.0' - } - }, - './packages/bar/package.json': { - name: 'barPkg', - dependencies: { - 'dep1': '1.0.0' - }, - devDependencies: { - 'dep2': '2.0.0' - } - } - }; - - packageVersions = { - 'dep1': [ - '1.0.0', - '1.0.1' - ], - 'dep2': [ - '2.0.0', - '2.0.1' - ], - 'dep3': [ - '3.0.0', - '3.0.1', - '3.0.2' - ] - }; - - processExitMock = vi.fn(); - consoleLogMock = vi.fn(); - consoleErrorMock = vi.fn(); - - vi.stubGlobal( 'process', { ...process, exit: processExitMock } ); - vi.stubGlobal( 'console', { ...console, log: consoleLogMock, error: consoleErrorMock } ); - - vi.mocked( fs.readFileSync ).mockImplementation( path => JSON.stringify( files[ path ] ) ); - vi.mocked( globSync ).mockReturnValue( Object.keys( files ) ); - vi.mocked( execSync ).mockImplementation( command => { - const [ , dependency ] = command.match( /npm view ([a-z0-9]+) versions --json/i ); - - return JSON.stringify( packageVersions[ dependency ] ); - } ); - } ); - - it( 'should be a function', () => { - expect( checkVersionMatch ).toBeInstanceOf( Function ); - } ); - - it( 'should log about dependencies being correct', () => { - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies are correct!' ); - } ); - - it( 'should log about dependencies using different versions', () => { - files[ './package.json' ].dependencies.dep1 = '1.0.1'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 1 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "fooPkg" in version "1.0.0" should be set to "1.0.1".', - '"dep1" in "barPkg" in version "1.0.0" should be set to "1.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should log about dependencies using different version ranges', () => { - files[ './package.json' ].dependencies.dep1 = '^1.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '⬇️ Downloading "dep1" versions from npm...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "rootPkg" in version "^1.0.0" should be set to "1.0.1".', - '"dep1" in "fooPkg" in version "1.0.0" should be set to "1.0.1".', - '"dep1" in "barPkg" in version "1.0.0" should be set to "1.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should log about dependencies using different version ranges when a package has no dependencies', () => { - files[ './package.json' ].dependencies.dep1 = '^1.0.0'; - delete files[ './packages/foo/package.json' ].dependencies; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '⬇️ Downloading "dep1" versions from npm...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "rootPkg" in version "^1.0.0" should be set to "1.0.1".', - '"dep1" in "barPkg" in version "1.0.0" should be set to "1.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should not log about filtered out dev dependencies using different versions', () => { - options.devDependenciesFilter = () => false; - files[ './package.json' ].devDependencies.dep2 = '2.0.1'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies are correct!' ); - } ); - - it( 'should log about dev dependencies using different versions', () => { - files[ './package.json' ].devDependencies.dep2 = '2.0.1'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 1 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep2" in "fooPkg" in version "2.0.0" should be set to "2.0.1".', - '"dep2" in "barPkg" in version "2.0.0" should be set to "2.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should log about dev dependencies using different version ranges', () => { - files[ './package.json' ].devDependencies.dep2 = '^2.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '⬇️ Downloading "dep2" versions from npm...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep2" in "rootPkg" in version "^2.0.0" should be set to "2.0.1".', - '"dep2" in "fooPkg" in version "2.0.0" should be set to "2.0.1".', - '"dep2" in "barPkg" in version "2.0.0" should be set to "2.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should log about dev dependencies using different version ranges when ranges are allowed', () => { - options.allowRanges = true; - files[ './package.json' ].devDependencies.dep2 = '^2.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 1 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep2" in "fooPkg" in version "2.0.0" should be set to "^2.0.0".', - '"dep2" in "barPkg" in version "2.0.0" should be set to "^2.0.0".' - ].join( '\n' ) ); - } ); - - it( 'should log about dev dependencies using different version ranges when a package has no devDependencies', () => { - files[ './package.json' ].devDependencies.dep2 = '^2.0.0'; - delete files[ './packages/foo/package.json' ].devDependencies; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '⬇️ Downloading "dep2" versions from npm...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep2" in "rootPkg" in version "^2.0.0" should be set to "2.0.1".', - '"dep2" in "barPkg" in version "2.0.0" should be set to "2.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should not log about dependencies using different version ranges when they are an exception', () => { - options.versionExceptions = { 'dep3': '^' }; - files[ './package.json' ].dependencies.dep3 = '^3.0.2'; - files[ './packages/foo/package.json' ].dependencies.dep3 = '^3.0.2'; - files[ './packages/bar/package.json' ].dependencies.dep3 = '^3.0.2'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies are correct!' ); - } ); - - it( 'should fix dependencies using different versions', () => { - options.fix = true; - - files[ './package.json' ].dependencies.dep1 = '1.0.1'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies fixed!' ); - - expect( fs.writeFileSync ).toHaveBeenCalledTimes( 3 ); - - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 1, - './package.json', - JSON.stringify( { - name: 'rootPkg', - dependencies: { - dep1: '1.0.1' - }, - devDependencies: { - dep2: '2.0.0' - } - }, null, 2 ) - ); - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 2, - './packages/foo/package.json', - JSON.stringify( { - name: 'fooPkg', - dependencies: { - dep1: '1.0.1' - }, - devDependencies: { - dep2: '2.0.0' - } - }, null, 2 ) - ); - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 3, - './packages/bar/package.json', - JSON.stringify( { - name: 'barPkg', - dependencies: { - dep1: '1.0.1' - }, - devDependencies: { - dep2: '2.0.0' - } - }, null, 2 ) - ); - } ); - - it( 'should fix devDependencies using different versions', () => { - options.fix = true; - - files[ './package.json' ].devDependencies.dep2 = '2.0.1'; - delete files[ './packages/foo/package.json' ].dependencies; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies fixed!' ); - - expect( fs.writeFileSync ).toHaveBeenCalledTimes( 3 ); - - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 1, - './package.json', - JSON.stringify( { - name: 'rootPkg', - dependencies: { - dep1: '1.0.0' - }, - devDependencies: { - dep2: '2.0.1' - } - }, null, 2 ) - ); - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 2, - './packages/foo/package.json', - JSON.stringify( { - name: 'fooPkg', - devDependencies: { - dep2: '2.0.1' - } - }, null, 2 ) - ); - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 3, - './packages/bar/package.json', - JSON.stringify( { - name: 'barPkg', - dependencies: { - dep1: '1.0.0' - }, - devDependencies: { - dep2: '2.0.1' - } - }, null, 2 ) - ); - } ); - - it( 'should test allowRanges logic for dependencies not in workspace filter', () => { - // Use a filter that excludes dep3 so it uses the old logic with allowRanges - options.devDependenciesFilter = depName => depName !== 'dep3'; - options.allowRanges = true; - files[ './package.json' ].dependencies.dep3 = '^3.0.1'; - files[ './packages/foo/package.json' ].dependencies.dep3 = '^3.0.2'; - files[ './packages/bar/package.json' ].dependencies.dep3 = '^3.0.0'; - // Set all other dependencies to workspace:* to match the new expected behavior - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './package.json' ].devDependencies.dep2 = 'workspace:*'; - files[ './packages/foo/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].devDependencies.dep2 = 'workspace:*'; - files[ './packages/bar/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/bar/package.json' ].devDependencies.dep2 = 'workspace:*'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 3 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "rootPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep3" in "rootPkg" in version "^3.0.1" should be set to "^3.0.2".', - '"dep2" in "rootPkg" in version "workspace:*" should be set to "2.0.1".', - '"dep1" in "fooPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep2" in "fooPkg" in version "workspace:*" should be set to "2.0.1".', - '"dep1" in "barPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep3" in "barPkg" in version "^3.0.0" should be set to "^3.0.2".', - '"dep2" in "barPkg" in version "workspace:*" should be set to "2.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should test npm version downloading for dependencies not in workspace filter', () => { - // Use a filter that excludes dep3 so it uses the old logic and downloads from npm - options.devDependenciesFilter = depName => depName !== 'dep3'; - files[ './package.json' ].dependencies.dep3 = '^3.0.1'; - files[ './packages/foo/package.json' ].dependencies.dep3 = '^3.0.2'; - files[ './packages/bar/package.json' ].dependencies.dep3 = '^3.0.0'; - // Set all other dependencies to workspace:* to match the new expected behavior - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './package.json' ].devDependencies.dep2 = 'workspace:*'; - files[ './packages/foo/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].devDependencies.dep2 = 'workspace:*'; - files[ './packages/bar/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/bar/package.json' ].devDependencies.dep2 = 'workspace:*'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 4 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '⬇️ Downloading "dep1" versions from npm...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "rootPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep3" in "rootPkg" in version "^3.0.1" should be set to "3.0.2".', - '"dep2" in "rootPkg" in version "workspace:*" should be set to "2.0.1".', - '"dep1" in "fooPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep3" in "fooPkg" in version "^3.0.2" should be set to "3.0.2".', - '"dep2" in "fooPkg" in version "workspace:*" should be set to "2.0.1".', - '"dep1" in "barPkg" in version "workspace:*" should be set to "1.0.1".', - '"dep3" in "barPkg" in version "^3.0.0" should be set to "3.0.2".', - '"dep2" in "barPkg" in version "workspace:*" should be set to "2.0.1".' - ].join( '\n' ) ); - } ); - - it( 'should skip filtered devDependencies in fix mode', () => { - options.fix = true; - options.devDependenciesFilter = depName => depName !== 'dep2'; - // Set all other dependencies to workspace:* to match the new expected behavior - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './package.json' ].devDependencies.dep2 = '2.0.1'; // This should be skipped - files[ './packages/foo/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].devDependencies.dep2 = '2.0.0'; // This should be skipped - files[ './packages/bar/package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/bar/package.json' ].devDependencies.dep2 = '2.0.0'; // This should be skipped - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 3 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 3, '✅ All dependencies fixed!' ); - - expect( fs.writeFileSync ).toHaveBeenCalledTimes( 3 ); - - // dep2 should remain unchanged since it's filtered out - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 1, - './package.json', - JSON.stringify( { - name: 'rootPkg', - dependencies: { - dep1: '1.0.1' - }, - devDependencies: { - dep2: '2.0.1' // Should remain unchanged due to filter - } - }, null, 2 ) - ); - } ); - - it( 'should expect workspace:* for dependencies that are not workspace:* when workspacePackages are specified', () => { - options.workspacePackages = [ 'dep1', 'dep2', 'dep3' ]; - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].dependencies.dep1 = '1.0.0'; - files[ './packages/bar/package.json' ].dependencies.dep1 = '1.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 1 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep2" in "rootPkg" in version "2.0.0" should be set to "workspace:*".', - '"dep1" in "fooPkg" in version "1.0.0" should be set to "workspace:*".', - '"dep2" in "fooPkg" in version "2.0.0" should be set to "workspace:*".', - '"dep1" in "barPkg" in version "1.0.0" should be set to "workspace:*".', - '"dep2" in "barPkg" in version "2.0.0" should be set to "workspace:*".' - ].join( '\n' ) ); - } ); - - it( 'should expect workspace:* for filtered dependencies that are not workspace:* when workspacePakcages are specified', () => { - options.workspacePackages = [ 'dep1', 'dep3' ]; - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].dependencies.dep1 = '1.0.0'; - files[ './packages/bar/package.json' ].dependencies.dep1 = '1.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 1 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 2 ); - expect( processExitMock ).toHaveBeenCalledTimes( 1 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 1, - '❌ Errors found. Run this script with an argument: `--fix` to resolve the issues automatically:' - ); - expect( consoleErrorMock ).toHaveBeenNthCalledWith( 2, [ - '"dep1" in "fooPkg" in version "1.0.0" should be set to "workspace:*".', - '"dep1" in "barPkg" in version "1.0.0" should be set to "workspace:*".' - ].join( '\n' ) ); - } ); - - it( 'should fix dependencies to workspace:* when workspacePackages are specified', () => { - options.fix = true; - options.workspacePackages = [ 'dep1', 'dep2', 'dep3' ]; - files[ './package.json' ].dependencies.dep1 = 'workspace:*'; - files[ './packages/foo/package.json' ].dependencies.dep1 = '1.0.0'; - files[ './packages/bar/package.json' ].dependencies.dep1 = '1.0.0'; - - checkVersionMatch( options ); - - expect( consoleLogMock ).toHaveBeenCalledTimes( 2 ); - expect( consoleErrorMock ).toHaveBeenCalledTimes( 0 ); - expect( processExitMock ).toHaveBeenCalledTimes( 0 ); - - expect( consoleLogMock ).toHaveBeenNthCalledWith( 1, '🔍 Starting checking dependencies versions...' ); - expect( consoleLogMock ).toHaveBeenNthCalledWith( 2, '✅ All dependencies fixed!' ); - - expect( fs.writeFileSync ).toHaveBeenCalledTimes( 3 ); - - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 1, - './package.json', - JSON.stringify( { - name: 'rootPkg', - dependencies: { - dep1: 'workspace:*' - }, - devDependencies: { - dep2: 'workspace:*' - } - }, null, 2 ) - ); - - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 2, - './packages/foo/package.json', - JSON.stringify( { - name: 'fooPkg', - dependencies: { - dep1: 'workspace:*' - }, - devDependencies: { - dep2: 'workspace:*' - } - }, null, 2 ) - ); - - expect( fs.writeFileSync ).toHaveBeenNthCalledWith( 3, - './packages/bar/package.json', - JSON.stringify( { - name: 'barPkg', - dependencies: { - dep1: 'workspace:*' - }, - devDependencies: { - dep2: 'workspace:*' - } - }, null, 2 ) - ); - } ); -} ); diff --git a/packages/ckeditor5-dev-dependency-checker/vitest.config.js b/packages/ckeditor5-dev-dependency-checker/vitest.config.js deleted file mode 100644 index c3bf2680c..000000000 --- a/packages/ckeditor5-dev-dependency-checker/vitest.config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import { defineConfig } from 'vitest/config'; - -export default defineConfig( { - test: { - testTimeout: 10000, - restoreMocks: true, - clearMocks: true, - mockReset: true, - unstubEnvs: true, - unstubGlobals: true, - include: [ - 'tests/**/*.js' - ], - coverage: { - provider: 'v8', - include: [ - 'lib/**' - ], - reporter: [ 'text', 'json', 'html', 'lcov' ] - } - } -} ); diff --git a/packages/ckeditor5-dev-license-checker/package.json b/packages/ckeditor5-dev-license-checker/package.json index 021eebaaa..96b572184 100644 --- a/packages/ckeditor5-dev-license-checker/package.json +++ b/packages/ckeditor5-dev-license-checker/package.json @@ -36,8 +36,5 @@ "dev": "rolldown -c rolldown.config.ts --watch", "test": "vitest run --config vitest.config.ts", "coverage": "vitest run --config vitest.config.ts --coverage" - }, - "depcheckIgnore": [ - "typescript" - ] + } } diff --git a/packages/ckeditor5-dev-release-tools/lib/tasks/cleanuppackages.js b/packages/ckeditor5-dev-release-tools/lib/tasks/cleanuppackages.js index 68656b85d..3e1ec5973 100644 --- a/packages/ckeditor5-dev-release-tools/lib/tasks/cleanuppackages.js +++ b/packages/ckeditor5-dev-release-tools/lib/tasks/cleanuppackages.js @@ -55,6 +55,8 @@ export default async function cleanUpPackages( options ) { * @returns {object} */ function parseOptions( options ) { + // The `depcheckIgnore` field was used by the removed `@ckeditor/ckeditor5-dev-dependency-checker` package. + // It is still stripped here because repositories that have not migrated to `knip` yet may carry it. const defaultPackageJsonFieldsToRemove = [ 'devDependencies', 'depcheckIgnore', 'scripts', 'private' ]; const packageJsonFieldsToRemove = typeof options.packageJsonFieldsToRemove === 'function' ? options.packageJsonFieldsToRemove( defaultPackageJsonFieldsToRemove ) : diff --git a/packages/ckeditor5-dev-release-tools/package.json b/packages/ckeditor5-dev-release-tools/package.json index d1b40ca60..b833e3ca9 100644 --- a/packages/ckeditor5-dev-release-tools/package.json +++ b/packages/ckeditor5-dev-release-tools/package.json @@ -41,8 +41,5 @@ "scripts": { "test": "vitest run --config vitest.config.js", "coverage": "vitest run --config vitest.config.js --coverage" - }, - "depcheckIgnore": [ - "virtual:parallelworker-integration-module" - ] + } } diff --git a/packages/ckeditor5-dev-stale-bot/package.json b/packages/ckeditor5-dev-stale-bot/package.json index d755ba304..8e8e74966 100644 --- a/packages/ckeditor5-dev-stale-bot/package.json +++ b/packages/ckeditor5-dev-stale-bot/package.json @@ -39,8 +39,5 @@ "scripts": { "test": "vitest run --config vitest.config.js", "coverage": "vitest run --config vitest.config.js --coverage" - }, - "depcheckIgnore": [ - "graphql" - ] + } } diff --git a/packages/ckeditor5-dev-web-crawler/package.json b/packages/ckeditor5-dev-web-crawler/package.json index a04b4f488..8af13878b 100644 --- a/packages/ckeditor5-dev-web-crawler/package.json +++ b/packages/ckeditor5-dev-web-crawler/package.json @@ -36,7 +36,6 @@ "devDependencies": { "@vitest/coverage-v8": "^4.1.2", "rolldown": "^1.1.2", - "upath": "^2.0.1", "vitest": "^4.1.2" } } diff --git a/packages/typedoc-plugins/package.json b/packages/typedoc-plugins/package.json index 857702f69..616917a2f 100644 --- a/packages/typedoc-plugins/package.json +++ b/packages/typedoc-plugins/package.json @@ -41,10 +41,5 @@ "test": "vitest run --config vitest.config.ts", "coverage": "vitest run --config vitest.config.ts --coverage", "test:dev": "vitest dev" - }, - "depcheckIgnore": [ - "typedoc", - "typedoc-plugin-rename-defaults", - "typescript" - ] + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9d2e42e0..5bc5c3620 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,9 @@ importers: .: devDependencies: + '@ckeditor/ckeditor5-dev-changelog': + specifier: workspace:* + version: link:packages/ckeditor5-dev-changelog '@inquirer/prompts': specifier: ^7.10.1 version: 7.10.1(@types/node@22.19.19) @@ -33,10 +36,10 @@ importers: version: 4.1.7(vitest@4.1.7) eslint: specifier: ^9.39.4 - version: 9.39.4 + version: 9.39.4(jiti@2.7.0) eslint-config-ckeditor5: specifier: ^13.0.1 - version: 13.0.1(eslint@9.39.4)(typescript@5.5.4) + version: 13.0.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) eslint-plugin-ckeditor5-rules: specifier: ^13.0.1 version: 13.0.1 @@ -55,6 +58,9 @@ importers: js-yaml: specifier: ^4.3.0 version: 4.3.0 + knip: + specifier: ^6.27.0 + version: 6.27.0 lint-staged: specifier: ^16.4.0 version: 16.4.0 @@ -64,9 +70,9 @@ importers: minimist: specifier: ^1.2.8 version: 1.2.8 - semver: - specifier: ^7.7.4 - version: 7.8.1 + syncpack: + specifier: ^15.3.2 + version: 15.3.2 typescript: specifier: 5.5.4 version: 5.5.4 @@ -75,10 +81,10 @@ importers: version: 2.0.1 vite: specifier: ^8.1.0 - version: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0) + version: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-build-tools: dependencies: @@ -116,9 +122,6 @@ importers: specifier: ^2.0.1 version: 2.0.1 devDependencies: - '@types/css': - specifier: ^0.0.38 - version: 0.0.38 '@types/node': specifier: ^22.19.17 version: 22.19.19 @@ -130,7 +133,7 @@ importers: version: 4.41.0 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-bump-year: dependencies: @@ -176,7 +179,7 @@ importers: version: 1.1.2 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-ci: dependencies: @@ -192,35 +195,7 @@ importers: devDependencies: vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) - - packages/ckeditor5-dev-dependency-checker: - dependencies: - '@ckeditor/ckeditor5-dev-utils': - specifier: workspace:* - version: link:../ckeditor5-dev-utils - depcheck: - specifier: ^1.4.7 - version: 1.4.7 - glob: - specifier: ^13.0.6 - version: 13.0.6 - minimist: - specifier: ^1.2.8 - version: 1.2.8 - oxc-parser: - specifier: ^0.72.3 - version: 0.72.3 - oxc-walker: - specifier: ^0.3.0 - version: 0.3.0(oxc-parser@0.72.3) - upath: - specifier: ^2.0.1 - version: 2.0.1 - devDependencies: - vitest: - specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-docs: dependencies: @@ -245,7 +220,7 @@ importers: version: 5.0.3 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-license-checker: dependencies: @@ -264,7 +239,7 @@ importers: version: 1.1.2 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-manual-server: dependencies: @@ -273,7 +248,7 @@ importers: version: 5.0.1 vite: specifier: ^8.1.0 - version: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0) + version: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) devDependencies: '@vitest/coverage-v8': specifier: ^4.1.2 @@ -283,7 +258,7 @@ importers: version: 1.1.2 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-release-tools: dependencies: @@ -326,7 +301,7 @@ importers: version: 5.5.0 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-stale-bot: dependencies: @@ -354,7 +329,7 @@ importers: devDependencies: vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-translations: dependencies: @@ -385,7 +360,7 @@ importers: devDependencies: vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-utils: dependencies: @@ -437,7 +412,7 @@ importers: version: 1.1.2 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/ckeditor5-dev-web-crawler: dependencies: @@ -454,12 +429,9 @@ importers: rolldown: specifier: ^1.1.2 version: 1.1.2 - upath: - specifier: ^2.0.1 - version: 2.0.1 vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages/typedoc-plugins: dependencies: @@ -481,7 +453,7 @@ importers: version: 0.7.3(typedoc@0.28.20(typescript@5.5.4)) vitest: specifier: ^4.1.2 - version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) packages: @@ -546,9 +518,15 @@ packages: '@colordx/core@5.4.3': resolution: {integrity: sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==} + '@emnapi/core@1.11.0': + resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==} + '@emnapi/core@1.11.1': resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + '@emnapi/runtime@1.11.0': + resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==} + '@emnapi/runtime@1.11.1': resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} @@ -950,9 +928,6 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -978,9 +953,6 @@ packages: peerDependencies: '@inquirer/prompts': '>= 3 < 8' - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@napi-rs/wasm-runtime@1.1.5': resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: @@ -1088,100 +1060,238 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@oxc-parser/binding-darwin-arm64@0.72.3': - resolution: {integrity: sha512-g6wgcfL7At4wHNHutl0NmPZTAju+cUSmSX5WGUMyTJmozRzhx8E9a2KL4rTqNJPwEpbCFrgC29qX9f4fpDnUpA==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-android-arm-eabi@0.137.0': + resolution: {integrity: sha512-KDs+0VPdEmasOkpuJHW9V5WCF+cvYdMQv2Jd+aJXt+cxIx12NToRQRbXaRwUEDsZw+/jMk81Ve8ZFbjUkJTOwA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.137.0': + resolution: {integrity: sha512-WhALNzfy3x/RfC6bsqX+csavuUY0yHHE7XfgPE5M542uhoBZUUoGTPG+nkMbGoG4+gcfss5s7urMyn5QBHu0sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.137.0': + resolution: {integrity: sha512-bFPr5hgmNMOMoyPTGtdsK4Ug21RovIPojRMgDDhSp1LtCnc/DkLwGONKjgRjszg677RlGnkYSviQ8hHaUPOVYA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.72.3': - resolution: {integrity: sha512-pc+tplB2fd0AqdnXY90FguqSF2OwbxXwrMOLAMmsUiK4/ytr8Z/ftd49+d27GgvQJKeg2LfnIbskaQtY/j2tAA==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-darwin-x64@0.137.0': + resolution: {integrity: sha512-CL5dMm1asqXIDZHg14FLxj3Mc36w8PI7xCWh1uA4is6z8g2XrIILoTcQYOxDbwzuk34RDPX5IAGUxZr6LA9KAg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.72.3': - resolution: {integrity: sha512-igBR6rOvL8t5SBm1f1rjtWNsjB53HNrM3au582JpYzWxOqCjeA5Jlm9KZbjQJC+J8SPB9xyljM7G+6yGZ2UAkQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-freebsd-x64@0.137.0': + resolution: {integrity: sha512-79h8rYGnSlKPGWo7mHr2ixO6ea7aW8B0CT965SZ8SLbNnCOH5aOYBTeVXUY6eMvEaiLyWr8Skuiugr5pDYgLGw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.72.3': - resolution: {integrity: sha512-/izdr3wg7bK+2RmNhZXC2fQwxbaTH3ELeqdR+Wg4FiEJ/C7ZBIjfB0E734bZGgbDu+rbEJTBlbG77XzY0wRX/Q==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm-gnueabihf@0.137.0': + resolution: {integrity: sha512-ASgmlSimhGyr0lksgVIo6hibz1obnDq4qJbiMX/AzltfgPnanRrzG1Q+23g8ljOHOjv6dsznkUuCYL3gg0sY1Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.72.3': - resolution: {integrity: sha512-Vz7C+qJb22HIFl3zXMlwvlTOR+MaIp5ps78060zsdeZh2PUGlYuUYkYXtGEjJV3kc8aKFj79XKqAY1EPG2NWQA==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm-musleabihf@0.137.0': + resolution: {integrity: sha512-AU2J9aa22Sx32wRGnDjybOU9TQXXQUud5sdUi+ZB0XxwM8aToWLweV+yA0wlQm0yIUVqljquqoHCYEq9II8gJQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.72.3': - resolution: {integrity: sha512-nomoMe2VpVxW767jhF+G3mDGmE0U6nvvi5nw9Edqd/5DIylQfq/lEGUWL7qITk+E72YXBsnwHtpRRlIAJOMyZg==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm64-gnu@0.137.0': + resolution: {integrity: sha512-GdEtiG89yMr7XkUGxifgodXEEm2f+xW2f9CpDjlgAnBOwhTmrpQMvhOGobLVKUyzf/qHBXW16smk5zbF3nZU6w==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.72.3': - resolution: {integrity: sha512-4DswiIK5dI7hFqcMKWtZ7IZnWkRuskh6poI1ad4gkY2p678NOGtl6uOGCCRlDmLOOhp3R27u4VCTzQ6zra977w==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm64-musl@0.137.0': + resolution: {integrity: sha512-EGJ+Bs8iXx8KBH8DQ5BLoEm5lnHaYjlh4/8j8vFhrr/6z4tqONy5BZDzLpKmmNWlN6Hlc5r8YOuBVHqZ9vRFEQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-riscv64-gnu@0.72.3': - resolution: {integrity: sha512-R9GEiA4WFPGU/3RxAhEd6SaMdpqongGTvGEyTvYCS/MAQyXKxX/LFvc2xwjdvESpjIemmc/12aTTq6if28vHkQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-ppc64-gnu@0.137.0': + resolution: {integrity: sha512-vzFUQENy/fnbSe5DZWovq6tIBc1uhuMztanSW6rz1e9WdQE4gHwYuD7ZII6JnrJifd1R3RSoqiZbgRFlVL2tYQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.137.0': + resolution: {integrity: sha512-SfVI14HBQs9gtLcUD5hTt5hsNbdrqSUNg9S8muN+LhVQ5nf1WwH3hAoK6B9NKgdYgWAQSXFXGiiBedQ4r/BKuw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-s390x-gnu@0.72.3': - resolution: {integrity: sha512-/sEYJQMVqikZO8gK9VDPT4zXo9du3gvvu8jp6erMmW5ev+14PErWRypJjktp0qoTj+uq4MzXro0tg7U+t5hP1w==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-riscv64-musl@0.137.0': + resolution: {integrity: sha512-e7Ppy4FCIFNQxT/ikSeIWFoQ0l+N9vgtRBtLcyZXeolTzApyVoPqEXsYPrcdM/9i0Bwk8knvYd37vaEMxHyi6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.137.0': + resolution: {integrity: sha512-Bho5qFwdhqsIFR7gipYEUlqvi3SRrY8sugxXig380MIaakBB1PyU9+7dBiBVScfImTNWhijUxdBwqrprGdq5WA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.72.3': - resolution: {integrity: sha512-hlyljEZ0sMPKJQCd5pxnRh2sAf/w+Ot2iJecgV9Hl3brrYrYCK2kofC0DFaJM3NRmG/8ZB3PlxnSRSKZTocwCw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-x64-gnu@0.137.0': + resolution: {integrity: sha512-36mGWtg7PyFzjJwGDkH6/F4o2nIDEoKXLPr/X/lwqklkomQwJJt1I5GJVmGhovUEmgPK5WAeAZMqlFCehwiy9Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.72.3': - resolution: {integrity: sha512-T17S8ORqAIq+YDFMvLfbNdAiYHYDM1+sLMNhesR5eWBtyTHX510/NbgEvcNemO9N6BNR7m4A9o+q468UG+dmbg==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-x64-musl@0.137.0': + resolution: {integrity: sha512-/Jqx6+N7A44n2BdvUr7pXhVr2vFjs6WGH3unZRczwrfiH0H1zY0QwKQMG/dtRiTlKGDKGukznPT8lx84/oEsZg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-wasm32-wasi@0.72.3': - resolution: {integrity: sha512-x0Ojn/jyRUk6MllvVB/puSvI2tczZBIYweKVYHNv1nBatjPRiqo+6/uXiKrZwSfGLkGARrKkTuHSa5RdZBMOdA==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-openharmony-arm64@0.137.0': + resolution: {integrity: sha512-9Uj0qHNNl+OgT1UTGwF7ixIXU6T1u2SbMidmgPy/h1h/fl2gRS6YpAxxY1gwHofcWjoTwkoMFd8xs5Vuj6GOFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.137.0': + resolution: {integrity: sha512-gW2vfkytNGgMVADiuzdvOfw0mWG9za20F/1fCJsif5aBMAvWJTSbpIXbIe0XkOe0VENk+PadpQ7cZgUy2sUJcA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-parser/binding-win32-arm64-msvc@0.72.3': - resolution: {integrity: sha512-kRVAl87ugRjLZTm9vGUyiXU50mqxLPHY81rgnZUP1HtNcqcmTQtM/wUKQL2UdqvhA6xm6zciqzqCgJfU+RW8uA==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-win32-arm64-msvc@0.137.0': + resolution: {integrity: sha512-x+pFANF0yL5uK/6T7lu6SlR5qid6sp//eZXKLq5iNsIE+EQg6EaS8/wsW7E91nXXjpnPhSoMOHXShSVhGRdn8w==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.72.3': - resolution: {integrity: sha512-vpVdoGAP5iGE5tIEPJgr7FkQJZA+sKjMkg5x1jarWJ1nnBamfGsfYiZum4QjCfW7jb+pl42rHVSS3lRmMPcyrQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-win32-ia32-msvc@0.137.0': + resolution: {integrity: sha512-sQUqym80PFi6McRsIqfJrSu2JrSClEZIXXD+/FjAFoULEKzOPsldIdFBG96xdX8aVMzCNQ9792FPx3MfkEIrFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.137.0': + resolution: {integrity: sha512-2AsevxlvNN4WKxpEn3RtqD5zbqMaXF+T7JXblsP4gVuY+vC9dXS4ED/PwfRCliFqoeisYS3Iro4DHzxr0TEvVA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] '@oxc-project/types@0.137.0': resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} - '@oxc-project/types@0.72.3': - resolution: {integrity: sha512-CfAC4wrmMkUoISpQkFAIfMVvlPfQV3xg7ZlcqPXPOIMQhdKIId44G8W0mCPgtpWdFFAyJ+SFtiM+9vbyCkoVng==} + '@oxc-resolver/binding-android-arm-eabi@11.21.3': + resolution: {integrity: sha512-eNU11A2WNizh04v3uyaJCootrHIaS0B9aHYXvAvVnPNk4xYSjMUjHnhQ6dewPN2MRYDskV85d1N0Aw0WNWhcyg==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.21.3': + resolution: {integrity: sha512-8Q+ZjTLvn2dIcWsrmhdrEihm7q+ag/k+mkry7Z+t0QbbHaVxXQfvH9AewyVMh/WrpEKhQ3DDgx9fYbqeCpeOEw==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.21.3': + resolution: {integrity: sha512-wkh0qKZGHXVUDxFw3oA1TXnU2BDYY/r775oJflGeIr8uDPPoN2pk8gijQIzYRT6hoql/lg3+Tx/SaTn9e2/aGg==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.21.3': + resolution: {integrity: sha512-HbNc23FAQYbuyDV2vBWMez4u4mrsm5RAkniGZAWqr6lYZ3N4beeqIb776jzwRl8qL2zRhHVXpUj97X0QgogVzg==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.21.3': + resolution: {integrity: sha512-K6xNsTUPEUdfrn0+kbMq5nOUB5w1C5pavPQngt4TM2FpN91lP0PBe2srSpamb4d69O7h86oAi/qWX/kZNRSjkw==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.21.3': + resolution: {integrity: sha512-VcFmOpcpWX1zoEy8M58tR2M9YxM+Z9RuQhqAx5q0CTmrruaP7Gveejg75hzd/5sg5nk9G3aLALEa3hE2FsmmTQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.21.3': + resolution: {integrity: sha512-quVoxFLBy43hWaQbbDtQNRwAX5vX76mv7n64icAtQcJ3eNgVeblqmkupF/hAneNthdqSlnd1sTjb3aQSaDPaCQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.21.3': + resolution: {integrity: sha512-X0AqNZgcD07Q4V3RDK18/vYOj/HQT/FnmEFGYS2jTWqY7JO13ryE3TEs3eAIgUJhBnNkpEaiXqz3VK8M7qQhWQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.21.3': + resolution: {integrity: sha512-YkaQnaKYdbuaXvRt5Qd0GpbihzVnyfR6z1SpYfIUC6RTu4NF7lDKPjVkYb+jRI2gedVO2rVpN35Y6akG6ud4Lw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.21.3': + resolution: {integrity: sha512-gB9HwhrPiFqUzDeEq+y/CgAijz1YdI6BnXz5GaH2Pa9cWdutchlkGFAiAuGb/PjVQpiK6NFKzFuztxrweoit7A==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.21.3': + resolution: {integrity: sha512-zjDWBlYk8QGv0H8dsPUWqkfjYIIjG2TvspGkzXL0eImbgxtZorA/klKeHyolevoT3Kvbi+1iMr9Lhrh7jf54Og==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.21.3': + resolution: {integrity: sha512-4UfsQvacV388y1zpXL7C1x1FNYaV52JtuNRiuzrfQA2z1z6ElVrsidkGsrvQ5EgeSq1Pj7kaKqrgGkvFuxJ/tw==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.21.3': + resolution: {integrity: sha512-b5uH+HKH0MP5mNBYaK75SKsJbw52URqrx2LavYdq6wb0l3ExAG5niYRP9DWUNHdKilpaBVM2bXk9HNWrH3ew7Q==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.21.3': + resolution: {integrity: sha512-PjYlmilBpNRh2ntXNYAK3Am5w/nPfEpnU/96iNx7CI8EzAn12J4JRiec63wHJTH31nLoCNxBg/829pN+3CfG3Q==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.21.3': + resolution: {integrity: sha512-QTBAb7JuHlZ7JUEyM8UiQi2f7m/L4swBhP2TNpYIDc9Wp/wRw1G/8sl6i13aIzQAXH7LKIm294LeOHd0lQR8zA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.21.3': + resolution: {integrity: sha512-4j1DFwjwv36ec9kds0jU/ucQ5Ha4ERO/H95BxR5JFf0kqUUAJ1kwII7XhTc1vZrkdJkvLGC9Q2MbpObpum8RBg==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.21.3': + resolution: {integrity: sha512-i8oluoel5kru/j1WNrjmQSiA3GQ7wvIYVR1IwIoZtKogAhya2iub+ZKIeSIkcJOrnzQ18Tzl/F+kL3fYOxZLvA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.21.3': + resolution: {integrity: sha512-M/8dw8dD6aOs+NlPJax401CZB9I7Aut84isQLgALGGwke4Afvw+/7yYhZb94yXf6t2sPLhQLmSmtSV+2FhsOWg==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.21.3': + resolution: {integrity: sha512-H7BCt/VnS9hnmMp42eGhZ99izSCRvlnWwy/N71K1/J8QoExwY4262Z8QiEkMDtduRJrztayDxETTckmUuAVL9Q==} + cpu: [x64] + os: [win32] '@puppeteer/browsers@2.13.2': resolution: {integrity: sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==} @@ -1531,9 +1641,6 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/css@0.0.38': - resolution: {integrity: sha512-FsAy4pBnrJb8qdKmIyDy582o4Xt8pHwpCwYRmIvXw4dslA7C4436oOM+8XNnMEsV/LSculbFNaZsBZmycDjARw==} - '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} @@ -1555,9 +1662,6 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - '@types/minimatch@3.0.5': - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -1579,9 +1683,6 @@ packages: '@types/pacote@11.1.8': resolution: {integrity: sha512-/XLR0VoTh2JEO0jJg1q/e6Rh9bxjBq9vorJuQmtT7rRrXSiWz7e7NsvXVYJQ0i8JxMlBMPPYDTnrRe7MZRFA8Q==} - '@types/parse-json@4.0.2': - resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} @@ -1697,21 +1798,6 @@ packages: '@vitest/utils@4.1.7': resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} - '@vue/compiler-core@3.5.34': - resolution: {integrity: sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==} - - '@vue/compiler-dom@3.5.34': - resolution: {integrity: sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==} - - '@vue/compiler-sfc@3.5.34': - resolution: {integrity: sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==} - - '@vue/compiler-ssr@3.5.34': - resolution: {integrity: sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==} - - '@vue/shared@3.5.34': - resolution: {integrity: sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==} - abbrev@4.0.0: resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} engines: {node: ^20.17.0 || >=22.9.0} @@ -1760,18 +1846,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-differ@3.0.0: - resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} - engines: {node: '>=8'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - arrify@2.0.1: - resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} - engines: {node: '>=8'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1864,9 +1938,6 @@ packages: brace-expansion@1.1.16: resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} - brace-expansion@2.1.2: - resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} - brace-expansion@5.0.7: resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} @@ -1898,17 +1969,10 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - callsite@1.0.0: - resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - camelcase@8.0.0: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} @@ -1977,9 +2041,6 @@ packages: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2020,9 +2081,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - content-type@2.0.0: resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} engines: {node: '>=18'} @@ -2030,10 +2088,6 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} - cosmiconfig@9.0.1: resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} @@ -2139,22 +2193,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - depcheck@1.4.7: - resolution: {integrity: sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==} - engines: {node: '>=10'} - hasBin: true - - deps-regex@0.2.0: - resolution: {integrity: sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==} - dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - detect-file@1.0.0: - resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} - engines: {node: '>=0.10.0'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -2213,10 +2255,6 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} - env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2358,10 +2396,6 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - expand-tilde@2.0.2: - resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} - engines: {node: '>=0.10.0'} - expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -2400,6 +2434,9 @@ packages: fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -2424,10 +2461,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - findup-sync@5.0.0: - resolution: {integrity: sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==} - engines: {node: '>= 10.13.0'} - flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -2443,6 +2476,11 @@ packages: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} + formatly@0.3.0: + resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} + engines: {node: '>=18.3.0'} + hasBin: true + fs-extra@11.3.5: resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} engines: {node: '>=14.14'} @@ -2483,6 +2521,9 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + get-uri@6.0.5: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} engines: {node: '>= 14'} @@ -2506,14 +2547,6 @@ packages: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} engines: {node: '>=10.0'} - global-modules@1.0.0: - resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} - engines: {node: '>=0.10.0'} - - global-prefix@1.0.2: - resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} - engines: {node: '>=0.10.0'} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -2565,10 +2598,6 @@ packages: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} - homedir-polyfill@1.0.3: - resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} - engines: {node: '>=0.10.0'} - hosted-git-info@9.0.3: resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==} engines: {node: ^20.17.0 || >=22.9.0} @@ -2626,9 +2655,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ini@6.0.0: resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} engines: {node: ^20.17.0 || >=22.9.0} @@ -2649,10 +2675,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -2697,10 +2719,6 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2737,6 +2755,10 @@ packages: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -2778,11 +2800,6 @@ packages: json-with-bigint@3.5.8: resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} @@ -2797,6 +2814,11 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + knip@6.27.0: + resolution: {integrity: sha512-CngYEYrD0n20N06FXA8n3u/0Wnnugoa+B9k14OP+iKIgkCHuzvIdsP3nfwjhByoc1WfogpxfiriMboAXFETDUw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -2917,9 +2939,6 @@ packages: lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - lodash@4.18.1: - resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - log-symbols@6.0.0: resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} engines: {node: '>=18'} @@ -2942,9 +2961,6 @@ packages: lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - magic-regexp@0.10.0: - resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -3140,10 +3156,6 @@ packages: minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@7.4.9: - resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} - engines: {node: '>=10'} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -3182,9 +3194,6 @@ packages: mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - mock-fs@5.5.0: resolution: {integrity: sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==} engines: {node: '>=12.0.0'} @@ -3192,10 +3201,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multimatch@5.0.0: - resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} - engines: {node: '>=10'} - mute-stream@1.0.0: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3295,14 +3300,12 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - oxc-parser@0.72.3: - resolution: {integrity: sha512-JYQeJKDcUTTZ/uTdJ+fZBGFjAjkLD1h0p3Tf44ZYXRcoMk+57d81paNPFAAwzrzzqhZmkGvKKXDxwyhJXYZlpg==} - engines: {node: '>=14.0.0'} + oxc-parser@0.137.0: + resolution: {integrity: sha512-yFImD+WLElJpLKy8llG1qe4DCmMsL18peRp8XP1JKfig/gISbJkglnpDtX2aTmAn10kZF7164HbN2H8QPsXxGg==} + engines: {node: ^20.19.0 || >=22.12.0} - oxc-walker@0.3.0: - resolution: {integrity: sha512-mGGgl9dmYHUX7Z3bxXhibwarI0fJVj2E64FNIOZQWUDvEeIPyJTe5ElyJmp4nmDdfdnrlG0bhdR+bR9D6DM/dA==} - peerDependencies: - oxc-parser: '>=0.72.0' + oxc-resolver@11.21.3: + resolution: {integrity: sha512-2Mx3fKQz7+xgrBONjsxOgCGtMHOn38/HxMzW1I5efwXB5a4lRN0Vp40gYUJFBWJslcrvwoofTrqoTnLbwTd3pA==} p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -3337,10 +3340,6 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse-passwd@1.0.0: - resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} - engines: {node: '>=0.10.0'} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3349,17 +3348,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -3377,12 +3369,6 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - please-upgrade-node@3.2.0: - resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} - plural-forms@0.5.5: resolution: {integrity: sha512-rJw4xp22izsfJOVqta5Hyvep2lR3xPkFUtj7dyQtpf/FbxUiX7PQCajTn2EHDRylizH5N/Uqqodfdu22I0ju+g==} @@ -3624,42 +3610,21 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - require-package-name@2.0.1: - resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} - - resolve-dir@1.0.1: - resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} - engines: {node: '>=0.10.0'} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} resolve.exports@2.0.3: resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -3773,6 +3738,10 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smol-toml@1.7.0: + resolution: {integrity: sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==} + engines: {node: '>= 18'} + snyk@1.1305.0: resolution: {integrity: sha512-dFBJW92gbJW0B85aSwq6ZCuC0jO1dDDyjN0WnKVjsfUdKNi7CXvlSPiXteUgaPNy0qbM4jJec9fQZB5/A2LHwg==} engines: {node: '>=12'} @@ -3865,6 +3834,10 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + stylehacks@7.0.11: resolution: {integrity: sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -3875,15 +3848,56 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - svgo@4.0.1: resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} engines: {node: '>=16'} hasBin: true + syncpack-darwin-arm64@15.3.2: + resolution: {integrity: sha512-rQwZOvWJbvUzhBySbKnvs+F5khmdkH2W/kTZo+zz6UfH651K9z2fiOYlcpDPX0L97m566gRxVmOr930ygB97ZQ==} + cpu: [arm64] + os: [darwin] + + syncpack-darwin-x64@15.3.2: + resolution: {integrity: sha512-91CWe9Pamfmlm2nY8bCL5z8GYOafGJUm/nQqtvaQDZ9SS25c6Gn8LDfRu6JSKV0dcI1zOH3EiRCM0K/kn9Mpiw==} + cpu: [x64] + os: [darwin] + + syncpack-linux-arm64-musl@15.3.2: + resolution: {integrity: sha512-IzI4Sr1rFDuF7FFbZ+ti+qA2/0Rp/aGNgzoUzNH28wYJkJMv9KBBr3Nygc1jsoO1+XE1JkYsXkJHuSFrwiwtgA==} + cpu: [arm64] + os: [linux] + + syncpack-linux-arm64@15.3.2: + resolution: {integrity: sha512-eApeUFLb8yFHAFnCyHicDieTBW0eR3HsaKSWPMmz+VOQOpZYl0cmqbRLtunsYN6OykRi9Sl1faYjKmyETow7Gg==} + cpu: [arm64] + os: [linux] + + syncpack-linux-x64-musl@15.3.2: + resolution: {integrity: sha512-dohyuYgUVHdSFz1KYW/XngyYSiSV3tarroYRsloYsT8bcSStkh2vJVBht0eMl1OFTh3Hb6lNEC12Pgtw4gWTcg==} + cpu: [x64] + os: [linux] + + syncpack-linux-x64@15.3.2: + resolution: {integrity: sha512-xrzBZx3DjKoece2h3Olv/Y/U7b1eNorWTMiF407m0tO5KJp5u926TMeHlldaA5GRCkVJBe5VaI33WYTJF753oQ==} + cpu: [x64] + os: [linux] + + syncpack-windows-arm64@15.3.2: + resolution: {integrity: sha512-ZGjVpyS8PW6Y69HyXOb8RYVWRQ+hlRklqdgOp+x+eqrCRidGho8z2nN5tleMGzcaMC7hg+qSPFh5u6Fy/BXr4w==} + cpu: [arm64] + os: [win32] + + syncpack-windows-x64@15.3.2: + resolution: {integrity: sha512-9zKWNXGhd3rryQjcpBjs02pKgvIzuz3PUS+vKL4vWnDu5VoHad4e6TzL4pvn+VfAm4wXzcuS9fZkxLBEMPLerw==} + cpu: [x64] + os: [win32] + + syncpack@15.3.2: + resolution: {integrity: sha512-RKYfXFQlrIWosTheNbyJg3xHNjTDrW2mOvwxAz3XGghrUDN4hDjhKPCTAQrUtGZw9hNeIr37qRO3/+EP927Vtg==} + engines: {node: '>=14.17.0'} + hasBin: true + tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} @@ -3956,9 +3970,6 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-level-regexp@0.1.17: - resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} - typed-query-selector@2.12.2: resolution: {integrity: sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==} @@ -3989,8 +4000,9 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + unbash@4.0.3: + resolution: {integrity: sha512-3cudTErfToSc4Ggv8XGXVNVli/xHKUtUZvaY5UVwhOcUPbQGz7PeaEnT/SAVgNziZtX67KEN9swMUYkLghxA1w==} + engines: {node: '>=14'} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -4018,10 +4030,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - unplugin@2.3.11: - resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} - engines: {node: '>=18.12.0'} - upath@2.0.1: resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} engines: {node: '>=4'} @@ -4130,16 +4138,13 @@ packages: jsdom: optional: true + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + webdriver-bidi-protocol@0.4.1: resolution: {integrity: sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==} - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -4197,27 +4202,15 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@1.10.3: - resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} - engines: {node: '>= 6'} - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} hasBin: true - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -4236,6 +4229,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -4299,12 +4295,23 @@ snapshots: '@colordx/core@5.4.3': {} + '@emnapi/core@1.11.0': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + '@emnapi/core@1.11.1': dependencies: '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.0': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 @@ -4401,9 +4408,9 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0))': dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -4645,11 +4652,6 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': @@ -4678,10 +4680,10 @@ snapshots: '@inquirer/prompts': 7.10.1(@types/node@22.19.19) '@inquirer/type': 1.5.5 - '@napi-rs/wasm-runtime@0.2.12': + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 '@tybys/wasm-util': 0.10.2 optional: true @@ -4823,53 +4825,132 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 - '@oxc-parser/binding-darwin-arm64@0.72.3': + '@oxc-parser/binding-android-arm-eabi@0.137.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.137.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.137.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.137.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.137.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.137.0': optional: true - '@oxc-parser/binding-darwin-x64@0.72.3': + '@oxc-parser/binding-linux-arm-musleabihf@0.137.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.72.3': + '@oxc-parser/binding-linux-arm64-gnu@0.137.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.72.3': + '@oxc-parser/binding-linux-arm64-musl@0.137.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.72.3': + '@oxc-parser/binding-linux-ppc64-gnu@0.137.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.72.3': + '@oxc-parser/binding-linux-riscv64-gnu@0.137.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.72.3': + '@oxc-parser/binding-linux-riscv64-musl@0.137.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.72.3': + '@oxc-parser/binding-linux-s390x-gnu@0.137.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.72.3': + '@oxc-parser/binding-linux-x64-gnu@0.137.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.72.3': + '@oxc-parser/binding-linux-x64-musl@0.137.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.72.3': + '@oxc-parser/binding-openharmony-arm64@0.137.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.72.3': + '@oxc-parser/binding-wasm32-wasi@0.137.0': dependencies: - '@napi-rs/wasm-runtime': 0.2.12 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.137.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.72.3': + '@oxc-parser/binding-win32-ia32-msvc@0.137.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.72.3': + '@oxc-parser/binding-win32-x64-msvc@0.137.0': optional: true '@oxc-project/types@0.137.0': {} - '@oxc-project/types@0.72.3': {} + '@oxc-resolver/binding-android-arm-eabi@11.21.3': + optional: true + + '@oxc-resolver/binding-android-arm64@11.21.3': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.21.3': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.21.3': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.21.3': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.21.3': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.21.3': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.21.3': + dependencies: + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.21.3': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.21.3': + optional: true '@puppeteer/browsers@2.13.2': dependencies: @@ -5114,10 +5195,10 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@4.4.1(eslint@9.39.4)(typescript@5.5.4)': + '@stylistic/eslint-plugin@4.4.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4)': dependencies: - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.5.4) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) + eslint: 9.39.4(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -5145,8 +5226,6 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 - '@types/css@0.0.38': {} - '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -5168,8 +5247,6 @@ snapshots: dependencies: '@types/unist': 3.0.3 - '@types/minimatch@3.0.5': {} - '@types/ms@2.1.0': {} '@types/node-fetch@2.6.13': @@ -5202,8 +5279,6 @@ snapshots: '@types/npmlog': 7.0.0 '@types/ssri': 7.1.5 - '@types/parse-json@4.0.2': {} - '@types/semver@7.7.1': {} '@types/shelljs@0.10.0': @@ -5226,15 +5301,15 @@ snapshots: '@types/node': 22.19.19 optional: true - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4)(typescript@5.5.4))(eslint@9.39.4)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4))(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0(eslint@9.39.4)(typescript@5.5.4) + '@typescript-eslint/parser': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0(eslint@9.39.4)(typescript@5.5.4) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) + '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) '@typescript-eslint/visitor-keys': 8.60.0 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@5.5.4) @@ -5242,14 +5317,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.0(eslint@9.39.4)(typescript@5.5.4)': + '@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 8.60.0 '@typescript-eslint/types': 8.60.0 '@typescript-eslint/typescript-estree': 8.60.0(typescript@5.5.4) '@typescript-eslint/visitor-keys': 8.60.0 debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.7.0) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -5272,13 +5347,13 @@ snapshots: dependencies: typescript: 5.5.4 - '@typescript-eslint/type-utils@8.60.0(eslint@9.39.4)(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 8.60.0 '@typescript-eslint/typescript-estree': 8.60.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.5.4) + '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@5.5.4) typescript: 5.5.4 transitivePeerDependencies: @@ -5301,13 +5376,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.5.4)': + '@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) '@typescript-eslint/scope-manager': 8.60.0 '@typescript-eslint/types': 8.60.0 '@typescript-eslint/typescript-estree': 8.60.0(typescript@5.5.4) - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.7.0) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -5329,7 +5404,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + vitest: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) '@vitest/expect@4.1.7': dependencies: @@ -5340,13 +5415,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.7(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0))': + '@vitest/mocker@4.1.7(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) '@vitest/pretty-format@4.1.7': dependencies: @@ -5372,38 +5447,6 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@vue/compiler-core@3.5.34': - dependencies: - '@babel/parser': 7.29.7 - '@vue/shared': 3.5.34 - entities: 7.0.1 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.34': - dependencies: - '@vue/compiler-core': 3.5.34 - '@vue/shared': 3.5.34 - - '@vue/compiler-sfc@3.5.34': - dependencies: - '@babel/parser': 7.29.7 - '@vue/compiler-core': 3.5.34 - '@vue/compiler-dom': 3.5.34 - '@vue/compiler-ssr': 3.5.34 - '@vue/shared': 3.5.34 - estree-walker: 2.0.2 - magic-string: 0.30.21 - postcss: 8.5.15 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.34': - dependencies: - '@vue/compiler-dom': 3.5.34 - '@vue/shared': 3.5.34 - - '@vue/shared@3.5.34': {} - abbrev@4.0.0: {} acorn-jsx@5.3.2(acorn@8.16.0): @@ -5439,12 +5482,6 @@ snapshots: argparse@2.0.1: {} - array-differ@3.0.0: {} - - array-union@2.1.0: {} - - arrify@2.0.1: {} - assertion-error@2.0.1: {} ast-types@0.13.4: @@ -5512,10 +5549,6 @@ snapshots: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.1.2: - dependencies: - balanced-match: 1.0.2 - brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -5557,12 +5590,8 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - callsite@1.0.0: {} - callsites@3.1.0: {} - camelcase@6.3.0: {} - camelcase@8.0.0: {} caniuse-api@3.0.0: @@ -5622,12 +5651,6 @@ snapshots: cli-width@4.1.0: {} - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -5659,20 +5682,10 @@ snapshots: concat-map@0.0.1: {} - confbox@0.1.8: {} - content-type@2.0.0: {} convert-source-map@2.0.0: {} - cosmiconfig@7.1.0: - dependencies: - '@types/parse-json': 4.0.2 - import-fresh: 3.3.1 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.3 - cosmiconfig@9.0.1(typescript@5.5.4): dependencies: env-paths: 2.2.1 @@ -5804,40 +5817,8 @@ snapshots: delayed-stream@1.0.0: {} - depcheck@1.4.7: - dependencies: - '@babel/parser': 7.29.7 - '@babel/traverse': 7.29.7 - '@vue/compiler-sfc': 3.5.34 - callsite: 1.0.0 - camelcase: 6.3.0 - cosmiconfig: 7.1.0 - debug: 4.4.3 - deps-regex: 0.2.0 - findup-sync: 5.0.0 - ignore: 5.3.2 - is-core-module: 2.16.2 - js-yaml: 4.3.0 - json5: 2.2.3 - lodash: 4.18.1 - minimatch: 7.4.9 - multimatch: 5.0.0 - please-upgrade-node: 3.2.0 - readdirp: 3.6.0 - require-package-name: 2.0.1 - resolve: 1.22.12 - resolve-from: 5.0.0 - semver: 7.8.1 - yargs: 16.2.0 - transitivePeerDependencies: - - supports-color - - deps-regex@0.2.0: {} - dequal@2.0.3: {} - detect-file@1.0.0: {} - detect-libc@2.1.2: {} detect-node@2.1.0: {} @@ -5893,8 +5874,6 @@ snapshots: entities@4.5.0: {} - entities@7.0.1: {} - env-paths@2.2.1: {} environment@1.1.0: {} @@ -5968,17 +5947,17 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-ckeditor5@13.0.1(eslint@9.39.4)(typescript@5.5.4): + eslint-config-ckeditor5@13.0.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4): dependencies: '@eslint/js': 9.39.4 '@eslint/markdown': 6.6.0 - '@stylistic/eslint-plugin': 4.4.1(eslint@9.39.4)(typescript@5.5.4) - eslint: 9.39.4 + '@stylistic/eslint-plugin': 4.4.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) + eslint: 9.39.4(jiti@2.7.0) eslint-plugin-ckeditor5-rules: 13.0.1 - eslint-plugin-mocha: 11.3.0(eslint@9.39.4) + eslint-plugin-mocha: 11.3.0(eslint@9.39.4(jiti@2.7.0)) globals: 16.5.0 typescript: 5.5.4 - typescript-eslint: 8.60.0(eslint@9.39.4)(typescript@5.5.4) + typescript-eslint: 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) transitivePeerDependencies: - supports-color @@ -5991,10 +5970,10 @@ snapshots: validate-npm-package-name: 6.0.2 yaml: 2.9.0 - eslint-plugin-mocha@11.3.0(eslint@9.39.4): + eslint-plugin-mocha@11.3.0(eslint@9.39.4(jiti@2.7.0)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - eslint: 9.39.4 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + eslint: 9.39.4(jiti@2.7.0) globals: 15.15.0 eslint-scope@8.4.0: @@ -6008,9 +5987,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.4: + eslint@9.39.4(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -6044,6 +6023,8 @@ snapshots: minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 transitivePeerDependencies: - supports-color @@ -6093,10 +6074,6 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - expand-tilde@2.0.2: - dependencies: - homedir-polyfill: 1.0.3 - expect-type@1.3.0: {} exponential-backoff@3.1.3: {} @@ -6139,6 +6116,10 @@ snapshots: dependencies: format: 0.2.2 + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -6160,13 +6141,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - findup-sync@5.0.0: - dependencies: - detect-file: 1.0.0 - is-glob: 4.0.3 - micromatch: 4.0.8 - resolve-dir: 1.0.1 - flat-cache@4.0.1: dependencies: flatted: 3.4.2 @@ -6184,6 +6158,10 @@ snapshots: format@0.2.2: {} + formatly@0.3.0: + dependencies: + fd-package-json: 2.0.0 + fs-extra@11.3.5: dependencies: graceful-fs: 4.2.11 @@ -6227,6 +6205,10 @@ snapshots: get-stream@6.0.1: {} + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + get-uri@6.0.5: dependencies: basic-ftp: 5.3.1 @@ -6260,20 +6242,6 @@ snapshots: semver: 7.8.1 serialize-error: 7.0.1 - global-modules@1.0.0: - dependencies: - global-prefix: 1.0.2 - is-windows: 1.0.2 - resolve-dir: 1.0.1 - - global-prefix@1.0.2: - dependencies: - expand-tilde: 2.0.2 - homedir-polyfill: 1.0.3 - ini: 1.3.8 - is-windows: 1.0.2 - which: 1.3.1 - globals@14.0.0: {} globals@15.15.0: {} @@ -6312,10 +6280,6 @@ snapshots: dependencies: function-bind: 1.1.2 - homedir-polyfill@1.0.3: - dependencies: - parse-passwd: 1.0.0 - hosted-git-info@9.0.3: dependencies: lru-cache: 11.5.0 @@ -6365,8 +6329,6 @@ snapshots: inherits@2.0.4: {} - ini@1.3.8: {} - ini@6.0.0: {} inquirer@12.11.1(@types/node@22.19.19): @@ -6385,10 +6347,6 @@ snapshots: is-arrayish@0.2.1: {} - is-core-module@2.16.2: - dependencies: - hasown: 2.0.4 - is-extendable@0.1.1: {} is-extglob@2.1.1: {} @@ -6415,8 +6373,6 @@ snapshots: is-unicode-supported@2.1.0: {} - is-windows@1.0.2: {} - isexe@2.0.0: {} isexe@4.0.0: {} @@ -6447,6 +6403,8 @@ snapshots: jest-get-type@29.6.3: {} + jiti@2.7.0: {} + js-tokens@10.0.0: {} js-tokens@4.0.0: {} @@ -6473,8 +6431,6 @@ snapshots: json-with-bigint@3.5.8: {} - json5@2.2.3: {} - jsonfile@6.2.1: dependencies: universalify: 2.0.1 @@ -6489,6 +6445,22 @@ snapshots: kind-of@6.0.3: {} + knip@6.27.0: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + formatly: 0.3.0 + get-tsconfig: 4.14.0 + jiti: 2.7.0 + oxc-parser: 0.137.0 + oxc-resolver: 11.21.3 + picomatch: 4.0.4 + smol-toml: 1.7.0 + strip-json-comments: 5.0.3 + tinyglobby: 0.2.17 + unbash: 4.0.3 + yaml: 2.9.0 + zod: 4.4.3 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -6596,8 +6568,6 @@ snapshots: lodash.uniq@4.5.0: {} - lodash@4.18.1: {} - log-symbols@6.0.0: dependencies: chalk: 5.6.2 @@ -6619,16 +6589,6 @@ snapshots: lunr@2.3.9: {} - magic-regexp@0.10.0: - dependencies: - estree-walker: 3.0.3 - magic-string: 0.30.21 - mlly: 1.8.2 - regexp-tree: 0.1.27 - type-level-regexp: 0.1.17 - ufo: 1.6.4 - unplugin: 2.3.11 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -7021,10 +6981,6 @@ snapshots: dependencies: brace-expansion: 1.1.16 - minimatch@7.4.9: - dependencies: - brace-expansion: 2.1.2 - minimist@1.2.8: {} minipass-collect@2.0.1: @@ -7063,25 +7019,10 @@ snapshots: mitt@3.0.1: {} - mlly@1.8.2: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 - mock-fs@5.5.0: {} ms@2.1.3: {} - multimatch@5.0.0: - dependencies: - '@types/minimatch': 3.0.5 - array-differ: 3.0.0 - array-union: 2.1.0 - arrify: 2.0.1 - minimatch: 3.1.5 - mute-stream@1.0.0: {} mute-stream@2.0.0: {} @@ -7200,30 +7141,52 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 - oxc-parser@0.72.3: + oxc-parser@0.137.0: dependencies: - '@oxc-project/types': 0.72.3 + '@oxc-project/types': 0.137.0 optionalDependencies: - '@oxc-parser/binding-darwin-arm64': 0.72.3 - '@oxc-parser/binding-darwin-x64': 0.72.3 - '@oxc-parser/binding-freebsd-x64': 0.72.3 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.72.3 - '@oxc-parser/binding-linux-arm-musleabihf': 0.72.3 - '@oxc-parser/binding-linux-arm64-gnu': 0.72.3 - '@oxc-parser/binding-linux-arm64-musl': 0.72.3 - '@oxc-parser/binding-linux-riscv64-gnu': 0.72.3 - '@oxc-parser/binding-linux-s390x-gnu': 0.72.3 - '@oxc-parser/binding-linux-x64-gnu': 0.72.3 - '@oxc-parser/binding-linux-x64-musl': 0.72.3 - '@oxc-parser/binding-wasm32-wasi': 0.72.3 - '@oxc-parser/binding-win32-arm64-msvc': 0.72.3 - '@oxc-parser/binding-win32-x64-msvc': 0.72.3 - - oxc-walker@0.3.0(oxc-parser@0.72.3): - dependencies: - estree-walker: 3.0.3 - magic-regexp: 0.10.0 - oxc-parser: 0.72.3 + '@oxc-parser/binding-android-arm-eabi': 0.137.0 + '@oxc-parser/binding-android-arm64': 0.137.0 + '@oxc-parser/binding-darwin-arm64': 0.137.0 + '@oxc-parser/binding-darwin-x64': 0.137.0 + '@oxc-parser/binding-freebsd-x64': 0.137.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.137.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.137.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.137.0 + '@oxc-parser/binding-linux-arm64-musl': 0.137.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.137.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.137.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.137.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.137.0 + '@oxc-parser/binding-linux-x64-gnu': 0.137.0 + '@oxc-parser/binding-linux-x64-musl': 0.137.0 + '@oxc-parser/binding-openharmony-arm64': 0.137.0 + '@oxc-parser/binding-wasm32-wasi': 0.137.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.137.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.137.0 + '@oxc-parser/binding-win32-x64-msvc': 0.137.0 + + oxc-resolver@11.21.3: + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.21.3 + '@oxc-resolver/binding-android-arm64': 11.21.3 + '@oxc-resolver/binding-darwin-arm64': 11.21.3 + '@oxc-resolver/binding-darwin-x64': 11.21.3 + '@oxc-resolver/binding-freebsd-x64': 11.21.3 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.21.3 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.21.3 + '@oxc-resolver/binding-linux-arm64-gnu': 11.21.3 + '@oxc-resolver/binding-linux-arm64-musl': 11.21.3 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.21.3 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.21.3 + '@oxc-resolver/binding-linux-riscv64-musl': 11.21.3 + '@oxc-resolver/binding-linux-s390x-gnu': 11.21.3 + '@oxc-resolver/binding-linux-x64-gnu': 11.21.3 + '@oxc-resolver/binding-linux-x64-musl': 11.21.3 + '@oxc-resolver/binding-openharmony-arm64': 11.21.3 + '@oxc-resolver/binding-wasm32-wasi': 11.21.3 + '@oxc-resolver/binding-win32-arm64-msvc': 11.21.3 + '@oxc-resolver/binding-win32-x64-msvc': 11.21.3 p-limit@3.1.0: dependencies: @@ -7286,21 +7249,15 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse-passwd@1.0.0: {} - path-exists@4.0.0: {} path-key@3.1.1: {} - path-parse@1.0.7: {} - path-scurry@2.0.2: dependencies: lru-cache: 11.5.0 minipass: 7.1.3 - path-type@4.0.0: {} - pathe@2.0.3: {} pend@1.2.0: {} @@ -7311,16 +7268,6 @@ snapshots: picomatch@4.0.4: {} - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - please-upgrade-node@3.2.0: - dependencies: - semver-compare: 1.0.0 - plural-forms@0.5.5: {} pofile@1.1.4: {} @@ -7583,34 +7530,14 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.2 - - regexp-tree@0.1.27: {} - require-directory@2.1.1: {} - require-package-name@2.0.1: {} - - resolve-dir@1.0.1: - dependencies: - expand-tilde: 2.0.2 - global-modules: 1.0.0 - resolve-from@4.0.0: {} - resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} resolve.exports@2.0.3: {} - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -7770,6 +7697,8 @@ snapshots: smart-buffer@4.2.0: {} + smol-toml@1.7.0: {} + snyk@1.1305.0: dependencies: '@sentry/node': 7.120.4 @@ -7866,6 +7795,8 @@ snapshots: strip-json-comments@3.1.1: {} + strip-json-comments@5.0.3: {} + stylehacks@7.0.11(postcss@8.5.15): dependencies: browserslist: 4.28.2 @@ -7876,8 +7807,6 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - svgo@4.0.1: dependencies: commander: 11.1.0 @@ -7888,6 +7817,41 @@ snapshots: picocolors: 1.1.1 sax: 1.6.0 + syncpack-darwin-arm64@15.3.2: + optional: true + + syncpack-darwin-x64@15.3.2: + optional: true + + syncpack-linux-arm64-musl@15.3.2: + optional: true + + syncpack-linux-arm64@15.3.2: + optional: true + + syncpack-linux-x64-musl@15.3.2: + optional: true + + syncpack-linux-x64@15.3.2: + optional: true + + syncpack-windows-arm64@15.3.2: + optional: true + + syncpack-windows-x64@15.3.2: + optional: true + + syncpack@15.3.2: + optionalDependencies: + syncpack-darwin-arm64: 15.3.2 + syncpack-darwin-x64: 15.3.2 + syncpack-linux-arm64: 15.3.2 + syncpack-linux-arm64-musl: 15.3.2 + syncpack-linux-x64: 15.3.2 + syncpack-linux-x64-musl: 15.3.2 + syncpack-windows-arm64: 15.3.2 + syncpack-windows-x64: 15.3.2 + tapable@2.3.3: {} tar-fs@3.1.2: @@ -7983,8 +7947,6 @@ snapshots: type-fest@4.41.0: {} - type-level-regexp@0.1.17: {} - typed-query-selector@2.12.2: {} typedoc-plugin-rename-defaults@0.7.3(typedoc@0.28.20(typescript@5.5.4)): @@ -8001,13 +7963,13 @@ snapshots: typescript: 5.5.4 yaml: 2.9.0 - typescript-eslint@8.60.0(eslint@9.39.4)(typescript@5.5.4): + typescript-eslint@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4): dependencies: - '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4)(typescript@5.5.4))(eslint@9.39.4)(typescript@5.5.4) - '@typescript-eslint/parser': 8.60.0(eslint@9.39.4)(typescript@5.5.4) + '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4))(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) + '@typescript-eslint/parser': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) '@typescript-eslint/typescript-estree': 8.60.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.5.4) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.5.4) + eslint: 9.39.4(jiti@2.7.0) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -8016,7 +7978,7 @@ snapshots: uc.micro@2.1.0: {} - ufo@1.6.4: {} + unbash@4.0.3: {} undici-types@6.21.0: {} @@ -8045,13 +8007,6 @@ snapshots: universalify@2.0.1: {} - unplugin@2.3.11: - dependencies: - '@jridgewell/remapping': 2.3.5 - acorn: 8.16.0 - picomatch: 4.0.4 - webpack-virtual-modules: 0.6.2 - upath@2.0.1: {} update-browserslist-db@1.2.3(browserslist@4.28.2): @@ -8070,7 +8025,7 @@ snapshots: validate-npm-package-name@7.0.2: {} - vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0): + vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -8081,13 +8036,14 @@ snapshots: '@types/node': 22.19.19 esbuild: 0.28.1 fsevents: 2.3.3 + jiti: 2.7.0 terser: 5.48.0 yaml: 2.9.0 - vitest@4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)): + vitest@4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0)) + '@vitest/mocker': 4.1.7(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.7 '@vitest/runner': 4.1.7 '@vitest/snapshot': 4.1.7 @@ -8104,7 +8060,7 @@ snapshots: tinyexec: 1.2.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(terser@5.48.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.19 @@ -8112,13 +8068,9 @@ snapshots: transitivePeerDependencies: - msw - webdriver-bidi-protocol@0.4.1: {} - - webpack-virtual-modules@0.6.2: {} + walk-up-path@4.0.0: {} - which@1.3.1: - dependencies: - isexe: 2.0.0 + webdriver-bidi-protocol@0.4.1: {} which@2.0.2: dependencies: @@ -8163,24 +8115,10 @@ snapshots: yallist@5.0.0: {} - yaml@1.10.3: {} - yaml@2.9.0: {} - yargs-parser@20.2.9: {} - yargs-parser@21.1.1: {} - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -8202,4 +8140,6 @@ snapshots: zod@3.25.76: {} + zod@4.4.3: {} + zwitch@2.0.4: {} diff --git a/scripts/ci/check-dependencies-versions-match.mjs b/scripts/ci/check-dependencies-versions-match.mjs index 423203895..cfcbc46a8 100644 --- a/scripts/ci/check-dependencies-versions-match.mjs +++ b/scripts/ci/check-dependencies-versions-match.mjs @@ -1,34 +1,32 @@ +#!/usr/bin/env node + /** * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md. */ +import { spawnSync } from 'node:child_process'; import upath from 'upath'; -import { glob } from 'glob'; -import fs from 'fs-extra'; -import { checkVersionMatch } from '../../packages/ckeditor5-dev-dependency-checker/lib/index.js'; +/** + * Runs `syncpack` (see `.syncpackrc.cjs`) to verify that `dependencies` and `devDependencies` + * across the repository use consistent versions. + */ const shouldFix = process.argv[ 2 ] === '--fix'; const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..', '..' ); -const PACKAGES_DIRECTORY = upath.join( ROOT_DIRECTORY, 'packages' ); - -const allPathsToPackageJson = await glob( PACKAGES_DIRECTORY + '/*/package.json', { - cwd: ROOT_DIRECTORY, - nodir: true, - absolute: true -} ); - -const allPackageJson = await Promise.all( - allPathsToPackageJson.map( pathToPackageJson => fs.readJson( pathToPackageJson ) ) +const { status } = spawnSync( + upath.join( ROOT_DIRECTORY, 'node_modules', '.bin', 'syncpack' ), + [ + shouldFix ? 'fix' : 'lint', + '--config', upath.join( ROOT_DIRECTORY, '.syncpackrc.cjs' ), + '--dependency-types', 'prod,dev' + ], + { + cwd: ROOT_DIRECTORY, + stdio: 'inherit' + } ); -const allPackageNames = allPackageJson.map( packageJson => packageJson.name ); - -checkVersionMatch( { - cwd: ROOT_DIRECTORY, - fix: shouldFix, - allowRanges: true, - workspacePackages: allPackageNames -} ); +process.exit( status ); diff --git a/scripts/validate-licenses.mjs b/scripts/validate-licenses.mjs index c8dee5bf8..fe0bac36c 100644 --- a/scripts/validate-licenses.mjs +++ b/scripts/validate-licenses.mjs @@ -45,12 +45,6 @@ validateLicenseFiles( { dependencies: [ minimistOverride ] - }, { - packageName: '@ckeditor/ckeditor5-dev-dependency-checker', - dependencies: [ - { license: 'MIT', name: 'oxc-walker', copyright: 'Copyright (c) 2024 Daniel Roe.' }, - minimistOverride - ] }, { packageName: '@ckeditor/ckeditor5-dev-docs', dependencies: [ From c19525b6076fc2a697cd8aa92e7a568c52d39cb0 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 14:38:10 +0200 Subject: [PATCH 02/12] Exit with an error code when syncpack fails to start. --- scripts/ci/check-dependencies-versions-match.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/ci/check-dependencies-versions-match.mjs b/scripts/ci/check-dependencies-versions-match.mjs index cfcbc46a8..65ae65f0f 100644 --- a/scripts/ci/check-dependencies-versions-match.mjs +++ b/scripts/ci/check-dependencies-versions-match.mjs @@ -29,4 +29,5 @@ const { status } = spawnSync( } ); -process.exit( status ); +// `status` is `null` when `syncpack` failed to start or was killed by a signal. +process.exit( status ?? 1 ); From 82a30b3e0c870de7790a86f81550f5c90aca4a76 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 14:51:21 +0200 Subject: [PATCH 03/12] Move type packages used by production code to production dependencies. --- knip.ts | 51 ++++++++++++------- .../ckeditor5-dev-build-tools/package.json | 2 +- packages/ckeditor5-dev-changelog/package.json | 2 +- packages/ckeditor5-dev-utils/package.json | 2 +- pnpm-lock.yaml | 18 +++---- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/knip.ts b/knip.ts index 12e6843e2..b20dbaf5e 100644 --- a/knip.ts +++ b/knip.ts @@ -14,6 +14,34 @@ import type { KnipConfig } from 'knip'; * Patterns marked with the `!` suffix describe production code. They must match the folders * that end up in the published packages (`lib`, `src`, `bin`, `theme`). */ +// Shared patterns for `packages/*` workspaces. Knip does not merge a specific workspace entry +// with the `packages/*` one, so specific entries must repeat them. +const packagePatterns = [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' +]; + +/** + * Type packages imported by production code live in `dependencies`, because type-only imports + * that are part of a package's public API must resolve in consumer projects, for example under + * Yarn PnP. See https://github.com/ckeditor/ckeditor5/issues/17213. + * + * Knip expects the opposite (type-only imports in `devDependencies`) and its strict production + * mode would report such packages as unused, so they are ignored there (the `!` suffix scopes + * the ignore to production mode). See https://github.com/webpro-nl/knip/issues/248. + */ +const typeDependencyWorkspace = ( ignoreDependencies: Array ) => ( { + ignore: [ 'tests/**/fixtures/**' ], + entry: [ ...packagePatterns ], + project: [ ...packagePatterns ], + ignoreDependencies: ignoreDependencies.map( dependency => `${ dependency }!` ) +} ); + const config: KnipConfig = { compilers: { // Extracts `@import` statements from plain CSS files, so packages imported in `theme/` @@ -53,27 +81,14 @@ const config: KnipConfig = { 'vite' ] }, + 'packages/ckeditor5-dev-build-tools': typeDependencyWorkspace( [ 'type-fest' ] ), + 'packages/ckeditor5-dev-changelog': typeDependencyWorkspace( [ '@types/semver' ] ), + 'packages/ckeditor5-dev-utils': typeDependencyWorkspace( [ '@types/pacote' ] ), 'packages/*': { // Test fixtures reference intentionally non-existent packages. ignore: [ 'tests/**/fixtures/**' ], - entry: [ - 'lib/**/*.{js,mjs,cjs}!', - 'src/**/*.{js,mjs,cjs,ts}!', - 'bin/**/*.{js,mjs,cjs}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}', - 'scripts/**/*.{js,mjs,cjs,ts}' - ], - project: [ - 'lib/**/*.{js,mjs,cjs}!', - 'src/**/*.{js,mjs,cjs,ts}!', - 'bin/**/*.{js,mjs,cjs}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}', - 'scripts/**/*.{js,mjs,cjs,ts}' - ] + entry: [ ...packagePatterns ], + project: [ ...packagePatterns ] } } }; diff --git a/packages/ckeditor5-dev-build-tools/package.json b/packages/ckeditor5-dev-build-tools/package.json index 080532db4..479f6eae7 100644 --- a/packages/ckeditor5-dev-build-tools/package.json +++ b/packages/ckeditor5-dev-build-tools/package.json @@ -37,12 +37,12 @@ "purgecss": "^8.0.0", "rolldown": "^1.1.2", "source-map": "^0.7.6", + "type-fest": "^4.41.0", "upath": "^2.0.1" }, "devDependencies": { "@types/node": "^22.19.17", "@vitest/coverage-v8": "^4.1.2", - "type-fest": "^4.41.0", "vitest": "^4.1.2" }, "scripts": { diff --git a/packages/ckeditor5-dev-changelog/package.json b/packages/ckeditor5-dev-changelog/package.json index ad7dd5552..be16cd173 100644 --- a/packages/ckeditor5-dev-changelog/package.json +++ b/packages/ckeditor5-dev-changelog/package.json @@ -30,6 +30,7 @@ "dependencies": { "@11ty/gray-matter": "^2.1.0", "@ckeditor/ckeditor5-dev-utils": "workspace:*", + "@types/semver": "^7.7.1", "cac": "^7.0.0", "date-fns": "^4.1.0", "glob": "^13.0.6", @@ -38,7 +39,6 @@ "upath": "^2.0.1" }, "devDependencies": { - "@types/semver": "^7.7.1", "@vitest/coverage-v8": "^4.1.2", "rolldown": "^1.1.2", "vitest": "^4.1.2" diff --git a/packages/ckeditor5-dev-utils/package.json b/packages/ckeditor5-dev-utils/package.json index 4bbab2002..e4ee13552 100644 --- a/packages/ckeditor5-dev-utils/package.json +++ b/packages/ckeditor5-dev-utils/package.json @@ -23,6 +23,7 @@ "dist" ], "dependencies": { + "@types/pacote": "^11.1.8", "@types/shelljs": "^0.10.0", "@types/through2": "^2.0.41", "cli-cursor": "^5.0.0", @@ -36,7 +37,6 @@ "upath": "^2.0.1" }, "devDependencies": { - "@types/pacote": "^11.1.8", "@vitest/coverage-v8": "^4.1.2", "jest-extended": "^5.0.3", "rolldown": "^1.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5bc5c3620..90b858e8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,6 +118,9 @@ importers: source-map: specifier: ^0.7.6 version: 0.7.6 + type-fest: + specifier: ^4.41.0 + version: 4.41.0 upath: specifier: ^2.0.1 version: 2.0.1 @@ -128,9 +131,6 @@ importers: '@vitest/coverage-v8': specifier: ^4.1.2 version: 4.1.7(vitest@4.1.7) - type-fest: - specifier: ^4.41.0 - version: 4.41.0 vitest: specifier: ^4.1.2 version: 4.1.7(@types/node@22.19.19)(@vitest/coverage-v8@4.1.7)(vite@8.1.0(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) @@ -149,6 +149,9 @@ importers: '@ckeditor/ckeditor5-dev-utils': specifier: workspace:* version: link:../ckeditor5-dev-utils + '@types/semver': + specifier: ^7.7.1 + version: 7.7.1 cac: specifier: ^7.0.0 version: 7.0.0 @@ -168,9 +171,6 @@ importers: specifier: ^2.0.1 version: 2.0.1 devDependencies: - '@types/semver': - specifier: ^7.7.1 - version: 7.7.1 '@vitest/coverage-v8': specifier: ^4.1.2 version: 4.1.7(vitest@4.1.7) @@ -364,6 +364,9 @@ importers: packages/ckeditor5-dev-utils: dependencies: + '@types/pacote': + specifier: ^11.1.8 + version: 11.1.8 '@types/shelljs': specifier: ^0.10.0 version: 0.10.0 @@ -398,9 +401,6 @@ importers: specifier: ^2.0.1 version: 2.0.1 devDependencies: - '@types/pacote': - specifier: ^11.1.8 - version: 11.1.8 '@vitest/coverage-v8': specifier: ^4.1.2 version: 4.1.7(vitest@4.1.7) From 93aa0740f0f8253e260034e22944ff1aa9ffc6ec Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:19:21 +0200 Subject: [PATCH 04/12] Reduce the dependency check configuration boilerplate. --- knip.ts | 83 ++++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/knip.ts b/knip.ts index b20dbaf5e..5eb9eb03b 100644 --- a/knip.ts +++ b/knip.ts @@ -14,17 +14,35 @@ import type { KnipConfig } from 'knip'; * Patterns marked with the `!` suffix describe production code. They must match the folders * that end up in the published packages (`lib`, `src`, `bin`, `theme`). */ -// Shared patterns for `packages/*` workspaces. Knip does not merge a specific workspace entry -// with the `packages/*` one, so specific entries must repeat them. -const packagePatterns = [ - 'lib/**/*.{js,mjs,cjs}!', - 'src/**/*.{js,mjs,cjs,ts}!', - 'bin/**/*.{js,mjs,cjs}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}', - 'scripts/**/*.{js,mjs,cjs,ts}' -]; + +/** + * Common configuration for the `packages/*` workspaces. Knip supports workspace configuration + * only in the root config and a specific workspace entry does not merge with the `packages/*` + * one, so single-package overrides go through this helper instead of repeating the patterns. + */ +const packageWorkspace = ( ignoreDependencies: Array = [] ) => ( { + // Test fixtures reference intentionally non-existent packages. + ignore: [ 'tests/**/fixtures/**' ], + entry: [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' + ], + project: [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' + ], + ignoreDependencies +} ); /** * Type packages imported by production code live in `dependencies`, because type-only imports @@ -35,12 +53,8 @@ const packagePatterns = [ * mode would report such packages as unused, so they are ignored there (the `!` suffix scopes * the ignore to production mode). See https://github.com/webpro-nl/knip/issues/248. */ -const typeDependencyWorkspace = ( ignoreDependencies: Array ) => ( { - ignore: [ 'tests/**/fixtures/**' ], - entry: [ ...packagePatterns ], - project: [ ...packagePatterns ], - ignoreDependencies: ignoreDependencies.map( dependency => `${ dependency }!` ) -} ); +const typeDependencyWorkspace = ( ignoreDependencies: Array ) => + packageWorkspace( ignoreDependencies.map( dependency => `${ dependency }!` ) ); const config: KnipConfig = { compilers: { @@ -59,37 +73,16 @@ const config: KnipConfig = { 'syncpack' ] }, - // Note: a specific workspace entry replaces the `packages/*` one, so it repeats the patterns. - 'packages/ckeditor5-dev-manual-server': { - ignore: [ 'tests/**/fixtures/**' ], - entry: [ - 'src/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}' - ], - project: [ - 'src/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}' - ], - ignoreDependencies: [ - // The package exports Vite plugins and imports `vite` only in type positions, - // but it deliberately ships `vite` as a runtime dependency for its consumers, - // which run the manual test server. - 'vite' - ] - }, + 'packages/ckeditor5-dev-manual-server': packageWorkspace( [ + // The package exports Vite plugins and imports `vite` only in type positions, + // but it deliberately ships `vite` as a runtime dependency for its consumers, + // which run the manual test server. + 'vite' + ] ), 'packages/ckeditor5-dev-build-tools': typeDependencyWorkspace( [ 'type-fest' ] ), 'packages/ckeditor5-dev-changelog': typeDependencyWorkspace( [ '@types/semver' ] ), 'packages/ckeditor5-dev-utils': typeDependencyWorkspace( [ '@types/pacote' ] ), - 'packages/*': { - // Test fixtures reference intentionally non-existent packages. - ignore: [ 'tests/**/fixtures/**' ], - entry: [ ...packagePatterns ], - project: [ ...packagePatterns ] - } + 'packages/*': packageWorkspace() } }; From 0c96ca1266fad53a7d475ede2345e8222ff0b126 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:26:14 +0200 Subject: [PATCH 05/12] Use ESM for the syncpack configuration. --- .syncpackrc.cjs => .syncpackrc.mjs | 4 +--- scripts/ci/check-dependencies-versions-match.mjs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) rename .syncpackrc.cjs => .syncpackrc.mjs (96%) diff --git a/.syncpackrc.cjs b/.syncpackrc.mjs similarity index 96% rename from .syncpackrc.cjs rename to .syncpackrc.mjs index bd7c9ec65..eb8233e8c 100644 --- a/.syncpackrc.cjs +++ b/.syncpackrc.mjs @@ -3,8 +3,6 @@ * For licensing, see LICENSE.md. */ -'use strict'; - /** * Configuration for `syncpack`, which ensures that `dependencies` and `devDependencies` * across the repository use consistent versions. Executed in CI via the @@ -14,7 +12,7 @@ * Unlike in the `ckeditor5` repository, version ranges (the `^` operator) are allowed here. * When the same dependency is declared with different versions, the highest one wins. */ -module.exports = { +export default { source: [ 'package.json', 'packages/*/package.json' diff --git a/scripts/ci/check-dependencies-versions-match.mjs b/scripts/ci/check-dependencies-versions-match.mjs index 65ae65f0f..57944c9bd 100644 --- a/scripts/ci/check-dependencies-versions-match.mjs +++ b/scripts/ci/check-dependencies-versions-match.mjs @@ -20,7 +20,7 @@ const { status } = spawnSync( upath.join( ROOT_DIRECTORY, 'node_modules', '.bin', 'syncpack' ), [ shouldFix ? 'fix' : 'lint', - '--config', upath.join( ROOT_DIRECTORY, '.syncpackrc.cjs' ), + '--config', upath.join( ROOT_DIRECTORY, '.syncpackrc.mjs' ), '--dependency-types', 'prod,dev' ], { From a7ec603d18748b3e7ba3ca1068b1a9e51f564159 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:31:24 +0200 Subject: [PATCH 06/12] Deduplicate the entry and project patterns in the dependency check configuration. --- knip.ts | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/knip.ts b/knip.ts index 5eb9eb03b..0a9228e2e 100644 --- a/knip.ts +++ b/knip.ts @@ -20,27 +20,26 @@ import type { KnipConfig } from 'knip'; * only in the root config and a specific workspace entry does not merge with the `packages/*` * one, so single-package overrides go through this helper instead of repeating the patterns. */ +// The `entry` and `project` options receive the same patterns: for dependency checks every +// analyzed file acts as an entry point, and restricting `project` prevents Knip from pulling +// unrelated files into the analysis. +const packageFiles = [ + 'lib/**/*.{js,mjs,cjs}!', + 'src/**/*.{js,mjs,cjs,ts}!', + 'bin/**/*.{js,mjs,cjs}!', + 'theme/**/*.{js,mjs,cjs,ts}!', + 'theme/**/*.css!', + 'tests/**/*.{js,mjs,cjs,ts}', + 'scripts/**/*.{js,mjs,cjs,ts}' +]; + +const rootFiles = [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ]; + const packageWorkspace = ( ignoreDependencies: Array = [] ) => ( { // Test fixtures reference intentionally non-existent packages. ignore: [ 'tests/**/fixtures/**' ], - entry: [ - 'lib/**/*.{js,mjs,cjs}!', - 'src/**/*.{js,mjs,cjs,ts}!', - 'bin/**/*.{js,mjs,cjs}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}', - 'scripts/**/*.{js,mjs,cjs,ts}' - ], - project: [ - 'lib/**/*.{js,mjs,cjs}!', - 'src/**/*.{js,mjs,cjs,ts}!', - 'bin/**/*.{js,mjs,cjs}!', - 'theme/**/*.{js,mjs,cjs,ts}!', - 'theme/**/*.css!', - 'tests/**/*.{js,mjs,cjs,ts}', - 'scripts/**/*.{js,mjs,cjs,ts}' - ], + entry: packageFiles, + project: packageFiles, ignoreDependencies } ); @@ -65,8 +64,8 @@ const config: KnipConfig = { workspaces: { '.': { - entry: [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ], - project: [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ], + entry: rootFiles, + project: rootFiles, ignoreDependencies: [ // Spawned via an explicit `node_modules/.bin` path in // `scripts/ci/check-dependencies-versions-match.mjs`, invisible to static analysis. From b17a442158c1c170c75d5312f7c8f165421513b1 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:45:37 +0200 Subject: [PATCH 07/12] Restore the CSS import and self-import checks and launch syncpack portably. --- eslint.config.js | 3 +- package.json | 2 +- .../bin/generate-template.js | 2 +- scripts/ci/check-css-imports.mjs | 38 +++++++++++++++++++ .../ci/check-dependencies-versions-match.mjs | 12 +++++- 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 scripts/ci/check-css-imports.mjs diff --git a/eslint.config.js b/eslint.config.js index 0b1ad5759..03be03359 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -61,7 +61,8 @@ export default defineConfig( [ { extensions: [ '.ts', '.js', '.json' ] } - ] + ], + 'ckeditor5-rules/no-scoped-imports-within-package': 'error' } }, { diff --git a/package.json b/package.json index c05d3d61e..c7dc1bed3 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "typecheck": "tsc", "precommit": "lint-staged", "reinstall": "pnpx rimraf --glob \"**/node_modules\" && pnpm install", - "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints" + "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints && node ./scripts/ci/check-css-imports.mjs" }, "lint-staged": { "**/*": [ diff --git a/packages/ckeditor5-dev-changelog/bin/generate-template.js b/packages/ckeditor5-dev-changelog/bin/generate-template.js index b8e7bf251..bb65826ee 100755 --- a/packages/ckeditor5-dev-changelog/bin/generate-template.js +++ b/packages/ckeditor5-dev-changelog/bin/generate-template.js @@ -7,6 +7,6 @@ 'use strict'; -import { generateTemplate } from '@ckeditor/ckeditor5-dev-changelog/dist/template.js'; +import { generateTemplate } from '../dist/template.js'; await generateTemplate(); diff --git a/scripts/ci/check-css-imports.mjs b/scripts/ci/check-css-imports.mjs new file mode 100644 index 000000000..dfcb9fb7a --- /dev/null +++ b/scripts/ci/check-css-imports.mjs @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +/** + * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import fs from 'node:fs'; +import { styleText } from 'node:util'; +import upath from 'upath'; +import { glob } from 'glob'; + +/** + * Validates that every relative `@import` in the stylesheets of the `packages/*` directories + * points at an existing file. The dependency checker (`knip`) verifies packages imported in + * CSS, but it silently skips unresolvable relative specifiers coming from compiled sources. + */ +const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..', '..' ); + +const cssPaths = await glob( 'packages/*/theme/**/*.css', { cwd: ROOT_DIRECTORY, absolute: true } ); + +const errors = cssPaths.flatMap( cssPath => { + const content = fs.readFileSync( cssPath, 'utf-8' ); + + return [ ...content.matchAll( /@import\s+(?:url\(\s*)?["']([^"']+)["']/g ) ] + .map( ( [ , specifier ] ) => specifier ) + .filter( specifier => specifier.startsWith( './' ) || specifier.startsWith( '../' ) ) + .filter( specifier => !fs.existsSync( upath.join( upath.dirname( cssPath ), specifier ) ) ) + .map( specifier => `"${ upath.relative( ROOT_DIRECTORY, cssPath ) }" imports "${ specifier }", which does not exist.` ); +} ); + +if ( errors.length ) { + console.error( styleText( 'red', '❌ Broken CSS imports found:' ) ); + console.error( styleText( 'red', errors.join( '\n' ) ) ); + process.exit( 1 ); +} else { + console.log( styleText( 'green', '✅ All relative CSS imports point at existing files.' ) ); +} diff --git a/scripts/ci/check-dependencies-versions-match.mjs b/scripts/ci/check-dependencies-versions-match.mjs index 57944c9bd..14ddbcfb4 100644 --- a/scripts/ci/check-dependencies-versions-match.mjs +++ b/scripts/ci/check-dependencies-versions-match.mjs @@ -6,19 +6,27 @@ */ import { spawnSync } from 'node:child_process'; +import { createRequire } from 'node:module'; import upath from 'upath'; /** - * Runs `syncpack` (see `.syncpackrc.cjs`) to verify that `dependencies` and `devDependencies` + * Runs `syncpack` (see `.syncpackrc.mjs`) to verify that `dependencies` and `devDependencies` * across the repository use consistent versions. */ const shouldFix = process.argv[ 2 ] === '--fix'; const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..', '..' ); +// The `syncpack` JavaScript entry point is executed through the current Node.js binary, +// because the extensionless `node_modules/.bin` launcher does not work on Windows. +const require = createRequire( import.meta.url ); +const syncpackPackagePath = require.resolve( 'syncpack/package.json' ); +const syncpackBin = upath.join( upath.dirname( syncpackPackagePath ), require( 'syncpack/package.json' ).bin.syncpack ); + const { status } = spawnSync( - upath.join( ROOT_DIRECTORY, 'node_modules', '.bin', 'syncpack' ), + process.execPath, [ + syncpackBin, shouldFix ? 'fix' : 'lint', '--config', upath.join( ROOT_DIRECTORY, '.syncpackrc.mjs' ), '--dependency-types', 'prod,dev' From d53482138d3a4fdbd14240f6f9787d784715fff2 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:55:20 +0200 Subject: [PATCH 08/12] Remove the CSS import check, as the repository has no CSS import surface. --- package.json | 2 +- scripts/ci/check-css-imports.mjs | 38 -------------------------------- 2 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 scripts/ci/check-css-imports.mjs diff --git a/package.json b/package.json index c7dc1bed3..c05d3d61e 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "typecheck": "tsc", "precommit": "lint-staged", "reinstall": "pnpx rimraf --glob \"**/node_modules\" && pnpm install", - "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints && node ./scripts/ci/check-css-imports.mjs" + "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints" }, "lint-staged": { "**/*": [ diff --git a/scripts/ci/check-css-imports.mjs b/scripts/ci/check-css-imports.mjs deleted file mode 100644 index dfcb9fb7a..000000000 --- a/scripts/ci/check-css-imports.mjs +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env node - -/** - * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import fs from 'node:fs'; -import { styleText } from 'node:util'; -import upath from 'upath'; -import { glob } from 'glob'; - -/** - * Validates that every relative `@import` in the stylesheets of the `packages/*` directories - * points at an existing file. The dependency checker (`knip`) verifies packages imported in - * CSS, but it silently skips unresolvable relative specifiers coming from compiled sources. - */ -const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..', '..' ); - -const cssPaths = await glob( 'packages/*/theme/**/*.css', { cwd: ROOT_DIRECTORY, absolute: true } ); - -const errors = cssPaths.flatMap( cssPath => { - const content = fs.readFileSync( cssPath, 'utf-8' ); - - return [ ...content.matchAll( /@import\s+(?:url\(\s*)?["']([^"']+)["']/g ) ] - .map( ( [ , specifier ] ) => specifier ) - .filter( specifier => specifier.startsWith( './' ) || specifier.startsWith( '../' ) ) - .filter( specifier => !fs.existsSync( upath.join( upath.dirname( cssPath ), specifier ) ) ) - .map( specifier => `"${ upath.relative( ROOT_DIRECTORY, cssPath ) }" imports "${ specifier }", which does not exist.` ); -} ); - -if ( errors.length ) { - console.error( styleText( 'red', '❌ Broken CSS imports found:' ) ); - console.error( styleText( 'red', errors.join( '\n' ) ) ); - process.exit( 1 ); -} else { - console.log( styleText( 'green', '✅ All relative CSS imports point at existing files.' ) ); -} From 396253fd0bce23cad86002ed6862eca16d3b9977 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 21 Jul 2026 15:58:56 +0200 Subject: [PATCH 09/12] Add regression tests for the dependency checks. --- scripts-tests/checkdependencies.mjs | 210 ++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 scripts-tests/checkdependencies.mjs diff --git a/scripts-tests/checkdependencies.mjs b/scripts-tests/checkdependencies.mjs new file mode 100644 index 000000000..54d4f2f62 --- /dev/null +++ b/scripts-tests/checkdependencies.mjs @@ -0,0 +1,210 @@ +/** + * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { afterEach, describe, expect, it } from 'vitest'; +import { spawnSync } from 'node:child_process'; +import fs from 'node:fs'; +import upath from 'upath'; + +/** + * Regression tests for the dependency checks (`check-dependencies` and `check-versions-match`). + * + * A clean tree proves only that the current manifests pass, so each test plants a defect in + * a real file (restored afterwards), runs the relevant check in a subprocess, and asserts + * that the defect is reported. This guards against silent configuration regressions in + * `knip.ts`, `.syncpackrc.mjs`, and the ESLint setup. + */ + +const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..' ); + +const PATHS = { + devUtilsPackageJson: upath.join( ROOT_DIRECTORY, 'packages', 'ckeditor5-dev-utils', 'package.json' ), + devUtilsIndex: upath.join( ROOT_DIRECTORY, 'packages', 'ckeditor5-dev-utils', 'src', 'index.ts' ), + releaseToolsTask: upath.join( ROOT_DIRECTORY, 'packages', 'ckeditor5-dev-release-tools', 'lib', 'tasks', 'updateversions.js' ), + manualServerCss: upath.join( ROOT_DIRECTORY, 'packages', 'ckeditor5-dev-manual-server', 'theme', 'catalog.css' ), + changelogPackageJson: upath.join( ROOT_DIRECTORY, 'packages', 'ckeditor5-dev-changelog', 'package.json' ) +}; + +const KNIP_TIMEOUT = 120000; + +const originalContents = new Map(); + +function mutateFile( filePath, callback ) { + const content = fs.readFileSync( filePath, 'utf-8' ); + + if ( !originalContents.has( filePath ) ) { + originalContents.set( filePath, content ); + } + + fs.writeFileSync( filePath, callback( content ) ); +} + +afterEach( () => { + for ( const [ filePath, content ] of originalContents ) { + fs.writeFileSync( filePath, content ); + } + + originalContents.clear(); +} ); + +function runBinary( binaryName, args ) { + return spawnSync( + upath.join( ROOT_DIRECTORY, 'node_modules', '.bin', binaryName ), + args, + { + cwd: ROOT_DIRECTORY, + encoding: 'utf-8' + } + ); +} + +function runKnip( { production = false } = {} ) { + const args = [ '--dependencies', '--no-config-hints' ]; + + if ( production ) { + args.push( '--production', '--strict' ); + } + + return runBinary( 'knip', args ); +} + +function runVersionsMatch( { fix = false } = {} ) { + return spawnSync( + process.execPath, + [ + upath.join( ROOT_DIRECTORY, 'scripts', 'ci', 'check-dependencies-versions-match.mjs' ), + ...fix ? [ '--fix' ] : [] + ], + { + cwd: ROOT_DIRECTORY, + encoding: 'utf-8' + } + ); +} + +describe( 'check-dependencies', () => { + it( 'passes on a clean tree in both modes', { timeout: KNIP_TIMEOUT * 2 }, () => { + const defaultResult = runKnip(); + const productionResult = runKnip( { production: true } ); + + expect( defaultResult.status, defaultResult.stdout + defaultResult.stderr ).toEqual( 0 ); + expect( productionResult.status, productionResult.stdout + productionResult.stderr ).toEqual( 0 ); + } ); + + it( 'reports a missing production dependency', { timeout: KNIP_TIMEOUT }, () => { + // The `simple-git` package is imported in `src/` and is not declared in the root + // `package.json`, so the ancestor workspace fallback cannot mask its removal. + mutateFile( PATHS.devUtilsPackageJson, content => { + const packageJson = JSON.parse( content ); + + expect( packageJson.dependencies[ 'simple-git' ] ).toBeDefined(); + delete packageJson.dependencies[ 'simple-git' ]; + + return JSON.stringify( packageJson, null, 2 ) + '\n'; + } ); + + const { status, stdout } = runKnip(); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'simple-git' ); + } ); + + it( 'reports an unused dependency', { timeout: KNIP_TIMEOUT }, () => { + mutateFile( PATHS.devUtilsPackageJson, content => { + const packageJson = JSON.parse( content ); + + packageJson.dependencies[ 'totally-unused-package' ] = '1.0.0'; + + return JSON.stringify( packageJson, null, 2 ) + '\n'; + } ); + + const { status, stdout } = runKnip(); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'Unused' ); + expect( stdout ).toContain( 'totally-unused-package' ); + } ); + + it( 'reports a production dependency misplaced in `devDependencies`', { timeout: KNIP_TIMEOUT }, () => { + // The `simple-git` package is imported in `src/`, so it must not live in `devDependencies`. + mutateFile( PATHS.devUtilsPackageJson, content => { + const packageJson = JSON.parse( content ); + const version = packageJson.dependencies[ 'simple-git' ]; + + expect( version ).toBeDefined(); + delete packageJson.dependencies[ 'simple-git' ]; + packageJson.devDependencies[ 'simple-git' ] = version; + + return JSON.stringify( packageJson, null, 2 ) + '\n'; + } ); + + const { status, stdout } = runKnip( { production: true } ); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'simple-git' ); + } ); + + it( 'reports a package used only through a dynamic import', { timeout: KNIP_TIMEOUT }, () => { + mutateFile( PATHS.releaseToolsTask, content => { + return content + '\n\nexport async function testDynamicImportProbe() {\n' + + '\treturn import( \'totally-bogus-dynamic-package\' );\n' + + '}\n'; + } ); + + const { status, stdout } = runKnip(); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'totally-bogus-dynamic-package' ); + } ); + + it( 'reports a package imported only in CSS', { timeout: KNIP_TIMEOUT }, () => { + mutateFile( PATHS.manualServerCss, content => { + return content + '\n@import "totally-bogus-css-package";\n'; + } ); + + const { status, stdout } = runKnip(); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'totally-bogus-css-package' ); + } ); +} ); + +describe( 'self-import check (ESLint)', () => { + it( 'reports an import from a package into itself', { timeout: KNIP_TIMEOUT }, () => { + mutateFile( PATHS.devUtilsIndex, content => { + return content + '\nimport \'@ckeditor/ckeditor5-dev-utils\';\n'; + } ); + + const { status, stdout } = runBinary( 'eslint', [ '--no-cache', PATHS.devUtilsIndex ] ); + + expect( status ).not.toEqual( 0 ); + expect( stdout ).toContain( 'ckeditor5-rules/no-scoped-imports-within-package' ); + } ); +} ); + +describe( 'check-versions-match', () => { + it( 'reports and fixes a workspace package version mismatch', { timeout: KNIP_TIMEOUT }, () => { + mutateFile( PATHS.changelogPackageJson, content => { + const packageJson = JSON.parse( content ); + + expect( packageJson.dependencies[ '@ckeditor/ckeditor5-dev-utils' ] ).toEqual( 'workspace:*' ); + packageJson.dependencies[ '@ckeditor/ckeditor5-dev-utils' ] = '1.0.0'; + + return JSON.stringify( packageJson, null, 2 ) + '\n'; + } ); + + const lintResult = runVersionsMatch(); + + expect( lintResult.status ).not.toEqual( 0 ); + + const fixResult = runVersionsMatch( { fix: true } ); + + expect( fixResult.status, fixResult.stdout + fixResult.stderr ).toEqual( 0 ); + + const fixedPackageJson = JSON.parse( fs.readFileSync( PATHS.changelogPackageJson, 'utf-8' ) ); + + expect( fixedPackageJson.dependencies[ '@ckeditor/ckeditor5-dev-utils' ] ).toEqual( 'workspace:*' ); + } ); +} ); From 04acb564cf576546f38c2a51286196197afdc417 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Thu, 23 Jul 2026 15:31:27 +0200 Subject: [PATCH 10/12] Remove unused variable. --- packages/ckeditor5-dev-web-crawler/src/constants.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/ckeditor5-dev-web-crawler/src/constants.ts b/packages/ckeditor5-dev-web-crawler/src/constants.ts index 45dcb1a7a..41e3b75bf 100644 --- a/packages/ckeditor5-dev-web-crawler/src/constants.ts +++ b/packages/ckeditor5-dev-web-crawler/src/constants.ts @@ -64,8 +64,6 @@ export const DEFAULT_CONCURRENCY: number = Math.min( cpus().length, 16 ); export const DEFAULT_TIMEOUT: number = 20 * 1000; -export const DEFAULT_RESPONSIVENESS_CHECK_TIMEOUT = 1000; - export const DEFAULT_RETRIES = 3; export const DEFAULT_RETRY_DELAY = 1000; From 39d3dc90c6109d5b1974e4aab3b273c8376733b5 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Fri, 24 Jul 2026 14:02:12 +0200 Subject: [PATCH 11/12] Run Knip through pnpm and ESLint through its Node API in the regression tests, so the checks are portable across platforms. --- scripts-tests/checkdependencies.mjs | 36 ++++++++++++----------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/scripts-tests/checkdependencies.mjs b/scripts-tests/checkdependencies.mjs index 54d4f2f62..f167d4eaa 100644 --- a/scripts-tests/checkdependencies.mjs +++ b/scripts-tests/checkdependencies.mjs @@ -7,6 +7,7 @@ import { afterEach, describe, expect, it } from 'vitest'; import { spawnSync } from 'node:child_process'; import fs from 'node:fs'; import upath from 'upath'; +import { ESLint } from 'eslint'; /** * Regression tests for the dependency checks (`check-dependencies` and `check-versions-match`). @@ -49,25 +50,17 @@ afterEach( () => { originalContents.clear(); } ); -function runBinary( binaryName, args ) { - return spawnSync( - upath.join( ROOT_DIRECTORY, 'node_modules', '.bin', binaryName ), - args, - { - cwd: ROOT_DIRECTORY, - encoding: 'utf-8' - } - ); -} - +// Knip runs through `pnpm exec`, the same way CI invokes it. The command needs a shell, +// because command launchers (`pnpm` included) are `.cmd` files on Windows, which Node.js +// refuses to spawn directly. The command string is static, so shell quoting is not a concern. function runKnip( { production = false } = {} ) { - const args = [ '--dependencies', '--no-config-hints' ]; - - if ( production ) { - args.push( '--production', '--strict' ); - } + const command = `pnpm exec knip --dependencies --no-config-hints${ production ? ' --production --strict' : '' }`; - return runBinary( 'knip', args ); + return spawnSync( command, { + cwd: ROOT_DIRECTORY, + encoding: 'utf-8', + shell: true + } ); } function runVersionsMatch( { fix = false } = {} ) { @@ -172,15 +165,16 @@ describe( 'check-dependencies', () => { } ); describe( 'self-import check (ESLint)', () => { - it( 'reports an import from a package into itself', { timeout: KNIP_TIMEOUT }, () => { + it( 'reports an import from a package into itself', { timeout: KNIP_TIMEOUT }, async () => { mutateFile( PATHS.devUtilsIndex, content => { return content + '\nimport \'@ckeditor/ckeditor5-dev-utils\';\n'; } ); - const { status, stdout } = runBinary( 'eslint', [ '--no-cache', PATHS.devUtilsIndex ] ); + const eslint = new ESLint( { cwd: ROOT_DIRECTORY, cache: false } ); + const [ result ] = await eslint.lintFiles( [ PATHS.devUtilsIndex ] ); + const ruleIds = result.messages.map( message => message.ruleId ); - expect( status ).not.toEqual( 0 ); - expect( stdout ).toContain( 'ckeditor5-rules/no-scoped-imports-within-package' ); + expect( ruleIds ).toContain( 'ckeditor5-rules/no-scoped-imports-within-package' ); } ); } ); From f55944cd3f302e1ca7ab2c4e33c60998a7ee6925 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Fri, 24 Jul 2026 14:58:37 +0200 Subject: [PATCH 12/12] Move the Knip configuration to scripts/knip/dependencies.ts, matching the layout of the other repositories. --- package.json | 2 +- scripts-tests/checkdependencies.mjs | 5 +++-- knip.ts => scripts/knip/dependencies.ts | 9 +++++---- 3 files changed, 9 insertions(+), 7 deletions(-) rename knip.ts => scripts/knip/dependencies.ts (90%) diff --git a/package.json b/package.json index dcbe5232c..21ed21dc4 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "typecheck": "tsc", "precommit": "lint-staged", "reinstall": "pnpx rimraf --glob \"**/node_modules\" && pnpm install", - "check-dependencies": "knip --dependencies --no-config-hints && knip --dependencies --production --strict --no-config-hints" + "check-dependencies": "knip --config ./scripts/knip/dependencies.ts --dependencies --no-config-hints && knip --config ./scripts/knip/dependencies.ts --dependencies --production --strict --no-config-hints" }, "lint-staged": { "**/*": [ diff --git a/scripts-tests/checkdependencies.mjs b/scripts-tests/checkdependencies.mjs index f167d4eaa..e4cad5f25 100644 --- a/scripts-tests/checkdependencies.mjs +++ b/scripts-tests/checkdependencies.mjs @@ -15,7 +15,7 @@ import { ESLint } from 'eslint'; * A clean tree proves only that the current manifests pass, so each test plants a defect in * a real file (restored afterwards), runs the relevant check in a subprocess, and asserts * that the defect is reported. This guards against silent configuration regressions in - * `knip.ts`, `.syncpackrc.mjs`, and the ESLint setup. + * `scripts/knip/dependencies.ts`, `.syncpackrc.mjs`, and the ESLint setup. */ const ROOT_DIRECTORY = upath.join( import.meta.dirname, '..' ); @@ -54,7 +54,8 @@ afterEach( () => { // because command launchers (`pnpm` included) are `.cmd` files on Windows, which Node.js // refuses to spawn directly. The command string is static, so shell quoting is not a concern. function runKnip( { production = false } = {} ) { - const command = `pnpm exec knip --dependencies --no-config-hints${ production ? ' --production --strict' : '' }`; + const command = 'pnpm exec knip --config ./scripts/knip/dependencies.ts --dependencies --no-config-hints' + + ( production ? ' --production --strict' : '' ); return spawnSync( command, { cwd: ROOT_DIRECTORY, diff --git a/knip.ts b/scripts/knip/dependencies.ts similarity index 90% rename from knip.ts rename to scripts/knip/dependencies.ts index 0a9228e2e..56049e764 100644 --- a/knip.ts +++ b/scripts/knip/dependencies.ts @@ -6,10 +6,11 @@ import type { KnipConfig } from 'knip'; /** - * Configuration for the dependency checks (`pnpm run check-dependencies`), executed as: + * Configuration for the dependency checks (`pnpm run check-dependencies`), which runs Knip + * with this configuration twice: * - * knip --dependencies (unused and unlisted packages) - * knip --dependencies --production --strict (misplaced `dependencies` vs `devDependencies`) + * --dependencies (unused and unlisted packages) + * --dependencies --production --strict (misplaced `dependencies` vs `devDependencies`) * * Patterns marked with the `!` suffix describe production code. They must match the folders * that end up in the published packages (`lib`, `src`, `bin`, `theme`). @@ -33,7 +34,7 @@ const packageFiles = [ 'scripts/**/*.{js,mjs,cjs,ts}' ]; -const rootFiles = [ 'scripts/**/*.{js,mjs,cjs}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ]; +const rootFiles = [ 'scripts/**/*.{js,mjs,cjs,ts}', 'scripts-tests/**/*.{js,mjs}', '*.{js,mjs,ts}' ]; const packageWorkspace = ( ignoreDependencies: Array = [] ) => ( { // Test fixtures reference intentionally non-existent packages.