diff --git a/.changeset/wicked-schools-stare.md b/.changeset/wicked-schools-stare.md new file mode 100644 index 000000000..9084297bb --- /dev/null +++ b/.changeset/wicked-schools-stare.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-import-x": minor +--- + +feat!: start TypeScript migration diff --git a/.eslintrc.js b/.eslintrc.js index a577a3f41..bed02298a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,6 @@ +/** + * @type {import('eslint').Linter.Config} + */ module.exports = { root: true, plugins: ['eslint-plugin', 'import-x'], @@ -18,6 +21,7 @@ module.exports = { ecmaVersion: 2020, }, rules: { + '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-var-requires': 'off', 'eslint-plugin/consistent-output': ['error', 'always'], @@ -55,6 +59,15 @@ module.exports = { }, overrides: [ + { + files: ['*.js', '*.ts'], + excludedFiles: ['test/fixtures'], + settings: { + 'import-x/resolver': { + typescript: true, + }, + }, + }, { files: 'test/**', env: { diff --git a/.github/workflows/pkg-size.yml b/.github/workflows/pkg-size.yml deleted file mode 100644 index 1b8adbb45..000000000 --- a/.github/workflows/pkg-size.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Package Size Report - -on: - pull_request_target: - branches: - - master - -jobs: - pkg-size-report: - name: Package Size Report - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Enable Corepack - run: corepack enable - - - name: Setup Node.js LTS - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: yarn - env: - # https://github.com/actions/setup-node/issues/531#issuecomment-1819151412 - SKIP_YARN_COREPACK_CHECK: 1 - - - name: Package Size Report - uses: pkg-size/action@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/babel.config.js b/babel.config.js index f95592159..44396b262 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,6 @@ +/** + * @type {import('@babel/core').TransformOptions} + */ module.exports = { presets: [ [ @@ -22,4 +25,10 @@ module.exports = { ], sourceMaps: 'inline', retainLines: true, + overrides: [ + { + include: '**/*.ts', + presets: ['@babel/typescript'], + }, + ], } diff --git a/jest.config.js b/jest.config.js index d66621954..e5ed8aa9b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,19 +1,23 @@ +const testCompiled = process.env.TEST_COMPILED === '1' + +const srcDir = testCompiled ? 'lib' : 'src' + /** * @type {import('@jest/types').Config.InitialOptions} */ module.exports = { - collectCoverage: true, + collectCoverage: !testCompiled, modulePathIgnorePatterns: ['/test/fixtures/with-syntax-error'], moduleNameMapper: { - '^core/(.+)$': '/src/core/$1', - '^eslint-plugin-import-x$': '/src/index.js', - '^eslint-plugin-import-x/config/(.+)$': '/config/$1', + '^core/(.+)$': `/${srcDir}/core/$1`, + '^eslint-plugin-import-x$': `/${srcDir}`, '^eslint-plugin-import-x/package.json$': '/package.json', - '^eslint-plugin-import-x/(.+)$': '/src/$1', - '^rules/(.+)$': '/src/rules/$1', + '^eslint-plugin-import-x/(.+)$': `/${srcDir}/$1`, + '^rules/(.+)$': `/${srcDir}/rules/$1`, }, testMatch: [ '/test/**/*.spec.js', + '/test/**/*.spec.ts', '!/test/fixtures/**/*.js', ], } diff --git a/package.json b/package.json index 952e44165..29a871ab9 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,12 @@ "main": "lib/index.js", "exports": { ".": "./lib/index.js", - "./config/*": "./config/*", "./package.json": "./package.json", "./*": "./lib/*" }, "files": [ - "config", - "lib" + "lib", + "!lib/*.tsbuildinfo" ], "keywords": [ "eslint", @@ -31,12 +30,13 @@ "export" ], "scripts": { - "build": "babel --quiet --out-dir lib src", + "build": "rimraf lib && tsc -p src", "lint": "yarn lint:es && yarn update:eslint-docs --check", "lint:es": "eslint . --cache", - "prebuild": "rimraf lib", + "prepare": "patch-package", "release": "changeset publish", "test": "jest", + "test-compiled": "yarn build && cross-env TEST_COMPILED=1 jest", "update:eslint-docs": "yarn build && eslint-doc-generator --rule-doc-title-format prefix-name --rule-doc-section-options false --rule-list-split meta.docs.category --ignore-config stage-0 --config-emoji recommended,☑️", "watch": "yarn test --watch" }, @@ -44,6 +44,7 @@ "eslint": "^7.2.0 || ^8" }, "dependencies": { + "@typescript-eslint/utils": "^5.62.0", "debug": "^4.3.4", "doctrine": "^3.0.0", "eslint-import-resolver-node": "^0.3.9", @@ -54,8 +55,8 @@ }, "devDependencies": { "@1stg/prettier-config": "^4.0.1", + "@1stg/tsconfig": "^2.3.3", "@angular-eslint/template-parser": "^17.2.1", - "@babel/cli": "^7.23.9", "@babel/core": "^7.24.0", "@babel/eslint-parser": "^7.23.10", "@babel/plugin-proposal-decorators": "^7.24.0", @@ -63,14 +64,21 @@ "@babel/preset-env": "^7.24.0", "@babel/preset-flow": "^7.24.0", "@babel/preset-react": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", "@babel/register": "^7.23.7", "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.1", "@eslint/import-test-order-redirect-scoped": "link:./test/fixtures/order-redirect-scoped", "@test-scope/some-module": "link:./test/fixtures/symlinked-module", + "@types/eslint": "^8.56.5", "@types/jest": "^29.5.12", - "@typescript-eslint/eslint-plugin": "^7.2.0", + "@types/json-schema": "^7.0.15", + "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "@typescript-eslint/typescript-estree": "^5.62.0", + "@unts/patch-package": "^8.0.0", + "cross-env": "^7.0.3", + "enhanced-resolve": "^5.16.0", "escope": "^4.0.0", "eslint": "^7.2.0 || ^8", "eslint-config-prettier": "^9.1.0", @@ -88,6 +96,7 @@ "redux": "^5.0.1", "rimraf": "^5.0.5", "svelte": "^4.2.12", - "typescript": "^5.4.2" + "type-fest": "^4.12.0", + "typescript": "~5.1.0" } } diff --git a/patches/@typescript-eslint+utils+5.62.0.patch b/patches/@typescript-eslint+utils+5.62.0.patch new file mode 100644 index 000000000..7ae6c47d3 --- /dev/null +++ b/patches/@typescript-eslint+utils+5.62.0.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts +index 9a3a1fd..46b3961 100644 +--- a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts ++++ b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts +@@ -6,6 +6,10 @@ import type { Scope } from './Scope'; + import type { SourceCode } from './SourceCode'; + export type RuleRecommendation = 'error' | 'strict' | 'warn' | false; + interface RuleMetaDataDocs { ++ /** ++ * The category the rule falls under ++ */ ++ category?: string; + /** + * Concise description of the rule + */ diff --git a/src/ExportMap.js b/src/ExportMap.js index d76df2f5f..57cf12ccd 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -9,7 +9,7 @@ import { SourceCode } from 'eslint' import parse from './utils/parse' import visit from './utils/visit' -import resolve from './utils/resolve' +import { relative, resolve } from './utils/resolve' import isIgnored, { hasValidExtension } from './utils/ignore' import { hashObject } from './utils/hash' @@ -506,7 +506,7 @@ ExportMap.parse = function (path, content, context) { const namespaces = new Map() function remotePath(value) { - return resolve.relative(value, path, context.settings) + return relative(value, path, context.settings) } function resolveImport(value) { diff --git a/config/electron.js b/src/config/electron.ts similarity index 58% rename from config/electron.js rename to src/config/electron.ts index e1d9833db..4e1cc9cc1 100644 --- a/config/electron.js +++ b/src/config/electron.ts @@ -1,8 +1,10 @@ +import type { PluginConfig } from '../types' + /** * Default settings for Electron applications. */ -module.exports = { +export = { settings: { 'import-x/core-modules': ['electron'], }, -} +} satisfies PluginConfig diff --git a/config/errors.js b/src/config/errors.ts similarity index 77% rename from config/errors.js rename to src/config/errors.ts index 3bdc7399f..d2de611d6 100644 --- a/config/errors.js +++ b/src/config/errors.ts @@ -1,9 +1,10 @@ +import type { PluginConfig } from '../types' + /** * unopinionated config. just the things that are necessarily runtime errors * waiting to happen. - * @type {Object} */ -module.exports = { +export = { plugins: ['import-x'], rules: { 'import-x/no-unresolved': 2, @@ -12,4 +13,4 @@ module.exports = { 'import-x/default': 2, 'import-x/export': 2, }, -} +} satisfies PluginConfig diff --git a/config/react-native.js b/src/config/react-native.ts similarity index 63% rename from config/react-native.js rename to src/config/react-native.ts index ce5535223..1e5c9a90c 100644 --- a/config/react-native.js +++ b/src/config/react-native.ts @@ -1,7 +1,9 @@ +import type { PluginConfig } from '../types' + /** - * - adds platform extensions to Node resolver + * adds platform extensions to Node resolver */ -module.exports = { +export = { settings: { 'import-x/resolver': { node: { @@ -10,4 +12,4 @@ module.exports = { }, }, }, -} +} satisfies PluginConfig diff --git a/config/react.js b/src/config/react.ts similarity index 74% rename from config/react.js rename to src/config/react.ts index ed7376dd8..b28a97407 100644 --- a/config/react.js +++ b/src/config/react.ts @@ -1,3 +1,5 @@ +import type { PluginConfig } from '../types' + /** * Adds `.jsx` as an extension, and enables JSX parsing. * @@ -5,12 +7,13 @@ * define jsnext:main and have JSX internally, you may run into problems * if you don't enable these settings at the top level. */ -module.exports = { +export = { settings: { 'import-x/extensions': ['.js', '.jsx'], }, - parserOptions: { - ecmaFeatures: { jsx: true }, + ecmaFeatures: { + jsx: true, + }, }, -} +} satisfies PluginConfig diff --git a/config/recommended.js b/src/config/recommended.ts similarity index 88% rename from config/recommended.js rename to src/config/recommended.ts index b20d943ac..23b4c5198 100644 --- a/config/recommended.js +++ b/src/config/recommended.ts @@ -1,8 +1,9 @@ +import type { PluginConfig } from '../types' + /** * The basics. - * @type {Object} */ -module.exports = { +export = { plugins: ['import-x'], rules: { @@ -25,4 +26,4 @@ module.exports = { sourceType: 'module', ecmaVersion: 2018, }, -} +} satisfies PluginConfig diff --git a/config/stage-0.js b/src/config/stage-0.ts similarity index 69% rename from config/stage-0.js rename to src/config/stage-0.ts index a02945158..dcf72b462 100644 --- a/config/stage-0.js +++ b/src/config/stage-0.ts @@ -1,12 +1,13 @@ +import type { PluginConfig } from '../types' + /** * Rules in progress. * * Do not expect these to adhere to semver across releases. - * @type {Object} */ -module.exports = { +export = { plugins: ['import-x'], rules: { 'import-x/no-deprecated': 1, }, -} +} as PluginConfig diff --git a/config/typescript.js b/src/config/typescript.ts similarity index 72% rename from config/typescript.js rename to src/config/typescript.ts index f1ca42609..21269b2b4 100644 --- a/config/typescript.js +++ b/src/config/typescript.ts @@ -1,3 +1,5 @@ +import type { PluginConfig } from '../types' + /** * This config: * 1) adds `.jsx`, `.ts`, `.cts`, `.mts`, and `.tsx` as an extension @@ -7,16 +9,16 @@ // Omit `.d.ts` because 1) TypeScript compilation already confirms that // types are resolved, and 2) it would mask an unresolved // `.ts`/`.tsx`/`.js`/`.jsx` implementation. -const typeScriptExtensions = ['.ts', '.cts', '.mts', '.tsx'] +const typeScriptExtensions = ['.ts', '.tsx'] as const -const allExtensions = [...typeScriptExtensions, '.js', '.jsx'] +const allExtensions = [...typeScriptExtensions, '.js', '.jsx'] as const -module.exports = { +export = { settings: { 'import-x/extensions': allExtensions, 'import-x/external-module-folders': ['node_modules', 'node_modules/@types'], 'import-x/parsers': { - '@typescript-eslint/parser': typeScriptExtensions, + '@typescript-eslint/parser': [...typeScriptExtensions, '.cts', '.mts'], }, 'import-x/resolver': { node: { @@ -24,11 +26,10 @@ module.exports = { }, }, }, - rules: { // analysis/correctness // TypeScript compilation already ensures that named imports exist in the referenced module 'import-x/named': 'off', }, -} +} satisfies PluginConfig diff --git a/config/warnings.js b/src/config/warnings.ts similarity index 70% rename from config/warnings.js rename to src/config/warnings.ts index b323885c7..fe111e844 100644 --- a/config/warnings.js +++ b/src/config/warnings.ts @@ -1,12 +1,13 @@ +import type { PluginConfig } from '../types' + /** * more opinionated config. - * @type {Object} */ -module.exports = { +export = { plugins: ['import-x'], rules: { 'import-x/no-named-as-default': 1, 'import-x/no-named-as-default-member': 1, 'import-x/no-duplicates': 1, }, -} +} satisfies PluginConfig diff --git a/src/core/importType.js b/src/core/importType.js index 2f46f78f6..b3da97981 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -5,7 +5,7 @@ import { } from 'path' import { isCoreModule } from '../utils/is-core-module' -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import { getContextPackagePath } from './packagePath' function baseModule(name) { diff --git a/src/core/packagePath.js b/src/core/packagePath.js index 36ea6f61a..d0a360edc 100644 --- a/src/core/packagePath.js +++ b/src/core/packagePath.js @@ -1,6 +1,6 @@ import { dirname } from 'path' -import pkgUp from '../utils/pkgUp' -import readPkgUp from '../utils/readPkgUp' +import { pkgUp } from '../utils/pkgUp' +import { readPkgUp } from '../utils/readPkgUp' export function getContextPackagePath(context) { return getFilePackagePath( diff --git a/src/docs-url.ts b/src/docs-url.ts new file mode 100644 index 000000000..61e029c0a --- /dev/null +++ b/src/docs-url.ts @@ -0,0 +1,8 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore - We're using commonjs +import pkg from '../package.json' + +const repoUrl = 'https://github.com/un-es/eslint-plugin-import-x' + +export const docsUrl = (ruleName: string, commitish = `v${pkg.version}`) => + `${repoUrl}/blob/${commitish}/docs/rules/${ruleName}.md` diff --git a/src/docsUrl.js b/src/docsUrl.js deleted file mode 100644 index 5cccd938f..000000000 --- a/src/docsUrl.js +++ /dev/null @@ -1,7 +0,0 @@ -import pkg from '../package.json' - -const repoUrl = 'https://github.com/un-es/eslint-plugin-import-x' - -export default function docsUrl(ruleName, commitish = `v${pkg.version}`) { - return `${repoUrl}/blob/${commitish}/docs/rules/${ruleName}.md` -} diff --git a/src/import-declaration.ts b/src/import-declaration.ts new file mode 100644 index 000000000..eacdb4ed4 --- /dev/null +++ b/src/import-declaration.ts @@ -0,0 +1,6 @@ +import type { Rule } from 'eslint' + +export const importDeclaration = (context: Rule.RuleContext) => { + const ancestors = context.getAncestors() + return ancestors[ancestors.length - 1] +} diff --git a/src/importDeclaration.js b/src/importDeclaration.js deleted file mode 100644 index a14fbb5c7..000000000 --- a/src/importDeclaration.js +++ /dev/null @@ -1,4 +0,0 @@ -export default function importDeclaration(context) { - const ancestors = context.getAncestors() - return ancestors[ancestors.length - 1] -} diff --git a/src/index.js b/src/index.ts similarity index 81% rename from src/index.js rename to src/index.ts index 9ec76ee44..279a2b59c 100644 --- a/src/index.js +++ b/src/index.ts @@ -1,5 +1,10 @@ +import type { PluginConfig } from './types' + +import noUnresolved from './rules/no-unresolved' +import { TSESLint } from '@typescript-eslint/utils' + export const rules = { - 'no-unresolved': require('./rules/no-unresolved'), + 'no-unresolved': noUnresolved, named: require('./rules/named'), default: require('./rules/default'), namespace: require('./rules/namespace'), @@ -52,20 +57,20 @@ export const rules = { // deprecated aliases to rules 'imports-first': require('./rules/imports-first'), -} +} satisfies Record> export const configs = { - recommended: require('../config/recommended'), + recommended: require('./config/recommended'), - errors: require('../config/errors'), - warnings: require('../config/warnings'), + errors: require('./config/errors'), + warnings: require('./config/warnings'), // shhhh... work in progress "secret" rules - 'stage-0': require('../config/stage-0'), + 'stage-0': require('./config/stage-0'), // useful stuff for folks using various environments - react: require('../config/react'), - 'react-native': require('../config/react-native'), - electron: require('../config/electron'), - typescript: require('../config/typescript'), -} + react: require('./config/react'), + 'react-native': require('./config/react-native'), + electron: require('./config/electron'), + typescript: require('./config/typescript'), +} satisfies Record diff --git a/src/rules/consistent-type-specifier-style.js b/src/rules/consistent-type-specifier-style.js index cb9f5a0b7..067889138 100644 --- a/src/rules/consistent-type-specifier-style.js +++ b/src/rules/consistent-type-specifier-style.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function isComma(token) { return token.type === 'Punctuator' && token.value === ',' diff --git a/src/rules/default.js b/src/rules/default.js index 1e3e0fc53..6d345b49b 100644 --- a/src/rules/default.js +++ b/src/rules/default.js @@ -1,5 +1,5 @@ import Exports from '../ExportMap' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/dynamic-import-chunkname.js b/src/rules/dynamic-import-chunkname.js index 81e70c220..31bad3479 100644 --- a/src/rules/dynamic-import-chunkname.js +++ b/src/rules/dynamic-import-chunkname.js @@ -1,5 +1,5 @@ import vm from 'vm' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/export.js b/src/rules/export.js index e8ad7c61f..b36ad4846 100644 --- a/src/rules/export.js +++ b/src/rules/export.js @@ -1,5 +1,5 @@ import ExportMap, { recursivePatternCapture } from '../ExportMap' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' /* Notes on TypeScript namespaces aka TSModuleDeclaration: diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js index 344979e0b..0612cf32a 100644 --- a/src/rules/exports-last.js +++ b/src/rules/exports-last.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function isNonExportStatement({ type }) { return ( diff --git a/src/rules/extensions.js b/src/rules/extensions.js index b33f6f8dd..734c1a69a 100644 --- a/src/rules/extensions.js +++ b/src/rules/extensions.js @@ -1,9 +1,9 @@ import path from 'path' -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import { isBuiltIn, isExternalModule, isScoped } from '../core/importType' -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' const enumValues = { enum: ['always', 'ignorePackages', 'never'] } const patternProperties = { diff --git a/src/rules/first.js b/src/rules/first.js index 95561522d..99148b0ff 100644 --- a/src/rules/first.js +++ b/src/rules/first.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function getImportValue(node) { return node.type === 'ImportDeclaration' diff --git a/src/rules/group-exports.js b/src/rules/group-exports.js index 8ce5be342..8f32a1086 100644 --- a/src/rules/group-exports.js +++ b/src/rules/group-exports.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const meta = { type: 'suggestion', diff --git a/src/rules/imports-first.js b/src/rules/imports-first.js index 4220c3143..620d5f7e3 100644 --- a/src/rules/imports-first.js +++ b/src/rules/imports-first.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const first = require('./first') diff --git a/src/rules/max-dependencies.js b/src/rules/max-dependencies.js index 301f2eeb3..f196e66bf 100644 --- a/src/rules/max-dependencies.js +++ b/src/rules/max-dependencies.js @@ -1,5 +1,5 @@ -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' const DEFAULT_MAX = 10 const DEFAULT_IGNORE_TYPE_IMPORTS = false diff --git a/src/rules/named.js b/src/rules/named.js index c3083a8bb..afae724d4 100644 --- a/src/rules/named.js +++ b/src/rules/named.js @@ -1,6 +1,6 @@ import * as path from 'path' import Exports from '../ExportMap' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/namespace.js b/src/rules/namespace.js index 88c4289cf..b6f13f9a6 100644 --- a/src/rules/namespace.js +++ b/src/rules/namespace.js @@ -1,7 +1,7 @@ import declaredScope from '../utils/declaredScope' import Exports from '../ExportMap' -import importDeclaration from '../importDeclaration' -import docsUrl from '../docsUrl' +import { importDeclaration } from '../import-declaration' +import { docsUrl } from '../docs-url' function processBodyStatement(context, namespaces, declaration) { if (declaration.type !== 'ImportDeclaration') { diff --git a/src/rules/newline-after-import.js b/src/rules/newline-after-import.js index 4f0bed0f8..02f6dbd24 100644 --- a/src/rules/newline-after-import.js +++ b/src/rules/newline-after-import.js @@ -4,7 +4,7 @@ */ import isStaticRequire from '../core/staticRequire' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' import debug from 'debug' const log = debug('eslint-plugin-import-x:rules:newline-after-import') diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index 5781463c0..d416fbc81 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -1,7 +1,7 @@ import path from 'path' -import moduleVisitor, { makeOptionsSchema } from '../utils/moduleVisitor' +import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor' import { isAbsolute } from '../core/importType' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-amd.js b/src/rules/no-amd.js index 21199a57a..cb013685f 100644 --- a/src/rules/no-amd.js +++ b/src/rules/no-amd.js @@ -3,7 +3,7 @@ * @author Jamund Ferguson */ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' //------------------------------------------------------------------------------ // Rule Definition diff --git a/src/rules/no-anonymous-default-export.js b/src/rules/no-anonymous-default-export.js index f7f8a4702..44add0e9c 100644 --- a/src/rules/no-anonymous-default-export.js +++ b/src/rules/no-anonymous-default-export.js @@ -3,7 +3,7 @@ * @author Duncan Beevers */ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const hasOwn = Function.bind.bind(Function.prototype.call)( Object.prototype.hasOwnProperty, diff --git a/src/rules/no-commonjs.js b/src/rules/no-commonjs.js index 4f4b2df6e..c8a2b61a0 100644 --- a/src/rules/no-commonjs.js +++ b/src/rules/no-commonjs.js @@ -3,7 +3,7 @@ * @author Jamund Ferguson */ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const EXPORT_MESSAGE = 'Expected "export" or "export default"' const IMPORT_MESSAGE = 'Expected "import" instead of "require()"' diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index 73b1d446d..94bda96bb 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -3,11 +3,11 @@ * @author Ben Mosher */ -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import Exports from '../ExportMap' import { isExternalModule } from '../core/importType' -import moduleVisitor, { makeOptionsSchema } from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' const traversed = new Set() diff --git a/src/rules/no-default-export.js b/src/rules/no-default-export.js index 8ca24153e..24ad661ff 100644 --- a/src/rules/no-default-export.js +++ b/src/rules/no-default-export.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-deprecated.js b/src/rules/no-deprecated.js index eb49c05f0..b33107062 100644 --- a/src/rules/no-deprecated.js +++ b/src/rules/no-deprecated.js @@ -1,6 +1,6 @@ import declaredScope from '../utils/declaredScope' import Exports from '../ExportMap' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function message(deprecation) { return `Deprecated${deprecation.description ? `: ${deprecation.description}` : '.'}` diff --git a/src/rules/no-duplicates.js b/src/rules/no-duplicates.js index 729de7465..c24768277 100644 --- a/src/rules/no-duplicates.js +++ b/src/rules/no-duplicates.js @@ -1,7 +1,7 @@ -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import semver from 'semver' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' let typescriptPkg try { diff --git a/src/rules/no-dynamic-require.js b/src/rules/no-dynamic-require.js index 2b752e34d..229366455 100644 --- a/src/rules/no-dynamic-require.js +++ b/src/rules/no-dynamic-require.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function isRequire(node) { return ( diff --git a/src/rules/no-empty-named-blocks.js b/src/rules/no-empty-named-blocks.js index a9324c5bb..619adb1b8 100644 --- a/src/rules/no-empty-named-blocks.js +++ b/src/rules/no-empty-named-blocks.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function getEmptyBlockRange(tokens, index) { const token = tokens[index] diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index c29e73f28..467f1af40 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -1,12 +1,12 @@ import path from 'path' import fs from 'fs' -import pkgUp from '../utils/pkgUp' +import { pkgUp } from '../utils/pkgUp' import { minimatch } from 'minimatch' -import resolve from '../utils/resolve' -import moduleVisitor from '../utils/moduleVisitor' +import { resolve } from '../utils/resolve' +import { moduleVisitor } from '../utils/moduleVisitor' import importType from '../core/importType' import { getFilePackageName } from '../core/packagePath' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const depFieldCache = new Map() diff --git a/src/rules/no-import-module-exports.js b/src/rules/no-import-module-exports.js index 01b93f125..5a2995952 100644 --- a/src/rules/no-import-module-exports.js +++ b/src/rules/no-import-module-exports.js @@ -1,6 +1,6 @@ import { minimatch } from 'minimatch' import path from 'path' -import pkgUp from '../utils/pkgUp' +import { pkgUp } from '../utils/pkgUp' function getEntryPoint(context) { const pkgPath = pkgUp({ diff --git a/src/rules/no-internal-modules.js b/src/rules/no-internal-modules.js index 47007564d..e8f55eaaa 100644 --- a/src/rules/no-internal-modules.js +++ b/src/rules/no-internal-modules.js @@ -1,9 +1,9 @@ import { makeRe } from 'minimatch' -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import importType from '../core/importType' -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-mutable-exports.js b/src/rules/no-mutable-exports.js index f7c7e4300..017ec4d1f 100644 --- a/src/rules/no-mutable-exports.js +++ b/src/rules/no-mutable-exports.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-named-as-default-member.js b/src/rules/no-named-as-default-member.js index 3d4d32a71..cf3058ef2 100644 --- a/src/rules/no-named-as-default-member.js +++ b/src/rules/no-named-as-default-member.js @@ -5,8 +5,8 @@ * See LICENSE in root directory for full license. */ import Exports from '../ExportMap' -import importDeclaration from '../importDeclaration' -import docsUrl from '../docsUrl' +import { importDeclaration } from '../import-declaration' +import { docsUrl } from '../docs-url' //------------------------------------------------------------------------------ // Rule Definition diff --git a/src/rules/no-named-as-default.js b/src/rules/no-named-as-default.js index 95876496e..8a4ffbbfe 100644 --- a/src/rules/no-named-as-default.js +++ b/src/rules/no-named-as-default.js @@ -1,6 +1,6 @@ import Exports from '../ExportMap' -import importDeclaration from '../importDeclaration' -import docsUrl from '../docsUrl' +import { importDeclaration } from '../import-declaration' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-named-default.js b/src/rules/no-named-default.js index 5948eadd8..c0cbad2c4 100644 --- a/src/rules/no-named-default.js +++ b/src/rules/no-named-default.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-named-export.js b/src/rules/no-named-export.js index ceb1abfb5..8bef9c85b 100644 --- a/src/rules/no-named-export.js +++ b/src/rules/no-named-export.js @@ -1,4 +1,4 @@ -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/rules/no-namespace.js b/src/rules/no-namespace.js index 123022112..f20d41e2f 100644 --- a/src/rules/no-namespace.js +++ b/src/rules/no-namespace.js @@ -4,7 +4,7 @@ */ import { minimatch } from 'minimatch' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' //------------------------------------------------------------------------------ // Rule Definition diff --git a/src/rules/no-nodejs-modules.js b/src/rules/no-nodejs-modules.js index c8256b07b..4c3303947 100644 --- a/src/rules/no-nodejs-modules.js +++ b/src/rules/no-nodejs-modules.js @@ -1,6 +1,6 @@ import importType from '../core/importType' -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' function reportIfMissing(context, node, allowed, name) { if (allowed.indexOf(name) === -1 && importType(name, context) === 'builtin') { diff --git a/src/rules/no-relative-packages.js b/src/rules/no-relative-packages.js index 5cddc0bd7..b1f5bd7a8 100644 --- a/src/rules/no-relative-packages.js +++ b/src/rules/no-relative-packages.js @@ -1,10 +1,10 @@ import path from 'path' -import readPkgUp from '../utils/readPkgUp' +import { readPkgUp } from '../utils/readPkgUp' -import resolve from '../utils/resolve' -import moduleVisitor, { makeOptionsSchema } from '../utils/moduleVisitor' +import { resolve } from '../utils/resolve' +import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor' import importType from '../core/importType' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' /** @param {string} filePath */ function toPosixPath(filePath) { diff --git a/src/rules/no-relative-parent-imports.js b/src/rules/no-relative-parent-imports.js index db4f03d82..7b52c7a12 100644 --- a/src/rules/no-relative-parent-imports.js +++ b/src/rules/no-relative-parent-imports.js @@ -1,7 +1,7 @@ -import moduleVisitor, { makeOptionsSchema } from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' import { basename, dirname, relative } from 'path' -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import importType from '../core/importType' diff --git a/src/rules/no-restricted-paths.js b/src/rules/no-restricted-paths.js index 1c1c2f0a1..84b914ea4 100644 --- a/src/rules/no-restricted-paths.js +++ b/src/rules/no-restricted-paths.js @@ -1,10 +1,10 @@ import path from 'path' -import resolve from '../utils/resolve' -import moduleVisitor from '../utils/moduleVisitor' +import { resolve } from '../utils/resolve' +import { moduleVisitor } from '../utils/moduleVisitor' import isGlob from 'is-glob' import { Minimatch } from 'minimatch' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' import importType from '../core/importType' const containsPath = (filepath, target) => { diff --git a/src/rules/no-self-import.js b/src/rules/no-self-import.js index 9178359a5..4f43ecf32 100644 --- a/src/rules/no-self-import.js +++ b/src/rules/no-self-import.js @@ -3,9 +3,9 @@ * @author Gio d'Amelio */ -import resolve from '../utils/resolve' -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { resolve } from '../utils/resolve' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' function isImportingSelf(context, node, requireName) { const filePath = context.getPhysicalFilename diff --git a/src/rules/no-unassigned-import.js b/src/rules/no-unassigned-import.js index 23536db13..0f5423125 100644 --- a/src/rules/no-unassigned-import.js +++ b/src/rules/no-unassigned-import.js @@ -2,7 +2,7 @@ import path from 'path' import { minimatch } from 'minimatch' import isStaticRequire from '../core/staticRequire' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' function report(context, node) { context.report({ diff --git a/src/rules/no-unresolved.js b/src/rules/no-unresolved.js deleted file mode 100644 index ba11ecf13..000000000 --- a/src/rules/no-unresolved.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @fileOverview Ensures that an imported path exists, given resolution rules. - * @author Ben Mosher - */ - -import resolve, { - CASE_SENSITIVE_FS, - fileExistsWithCaseSync, -} from '../utils/resolve' -import ModuleCache from '../utils/ModuleCache' -import moduleVisitor, { makeOptionsSchema } from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' - -module.exports = { - meta: { - type: 'problem', - docs: { - category: 'Static analysis', - description: - 'Ensure imports point to a file/module that can be resolved.', - url: docsUrl('no-unresolved'), - }, - - schema: [ - makeOptionsSchema({ - caseSensitive: { type: 'boolean', default: true }, - caseSensitiveStrict: { type: 'boolean', default: false }, - }), - ], - }, - - create(context) { - const options = context.options[0] || {} - - function checkSourceValue(source, node) { - // ignore type-only imports and exports - if (node.importKind === 'type' || node.exportKind === 'type') { - return - } - - const caseSensitive = - !CASE_SENSITIVE_FS && options.caseSensitive !== false - const caseSensitiveStrict = - !CASE_SENSITIVE_FS && options.caseSensitiveStrict - - const resolvedPath = resolve(source.value, context) - - if (resolvedPath === undefined) { - context.report( - source, - `Unable to resolve path to module '${source.value}'.`, - ) - } else if (caseSensitive || caseSensitiveStrict) { - const cacheSettings = ModuleCache.getSettings(context.settings) - if ( - !fileExistsWithCaseSync( - resolvedPath, - cacheSettings, - caseSensitiveStrict, - ) - ) { - context.report( - source, - `Casing of ${source.value} does not match the underlying filesystem.`, - ) - } - } - } - - return moduleVisitor(checkSourceValue, options) - }, -} diff --git a/src/rules/no-unresolved.ts b/src/rules/no-unresolved.ts new file mode 100644 index 000000000..eb21a3bb6 --- /dev/null +++ b/src/rules/no-unresolved.ts @@ -0,0 +1,102 @@ +/** + * Ensures that an imported path exists, given resolution rules. + */ + +import { + CASE_SENSITIVE_FS, + fileExistsWithCaseSync, + resolve, +} from '../utils/resolve' +import { ModuleCache } from '../utils/ModuleCache' +import { + ModuleOptions, + makeOptionsSchema, + moduleVisitor, +} from '../utils/moduleVisitor' +import { createRule } from '../utils' + +type Options = [ + ModuleOptions & { + caseSensitive?: boolean + caseSensitiveStrict?: boolean + }, +] + +type MessageId = 'unresolved' | 'casing-mismatch' + +export = createRule({ + name: 'no-unresolved', + meta: { + type: 'problem', + docs: { + category: 'Static analysis', + description: + 'Ensure imports point to a file/module that can be resolved.', + recommended: 'error', + }, + messages: { + unresolved: "Unable to resolve path to module '{{module}}'.", + 'casing-mismatch': + "Casing of '{{module}}' does not match the underlying filesystem.", + }, + schema: [ + makeOptionsSchema({ + caseSensitive: { type: 'boolean', default: true }, + caseSensitiveStrict: { type: 'boolean' }, + }), + ], + }, + defaultOptions: [ + { + caseSensitive: true, + }, + ], + + create(context) { + const options = context.options[0] || {} + + return moduleVisitor(function checkSourceValue(source, node) { + // ignore type-only imports and exports + if ( + ('importKind' in node && node.importKind === 'type') || + ('exportKind' in node && node.exportKind === 'type') + ) { + return + } + + const caseSensitive = + !CASE_SENSITIVE_FS && options.caseSensitive !== false + const caseSensitiveStrict = + !CASE_SENSITIVE_FS && options.caseSensitiveStrict + + const resolvedPath = resolve(source.value, context) + + if (resolvedPath === undefined) { + context.report({ + node: source, + messageId: 'unresolved', + data: { + module: source.value, + }, + }) + } else if (caseSensitive || caseSensitiveStrict) { + const cacheSettings = ModuleCache.getSettings(context.settings) + if ( + !fileExistsWithCaseSync( + resolvedPath, + cacheSettings, + caseSensitiveStrict, + ) + ) { + context.report({ + node: source, + messageId: 'casing-mismatch', + data: { + module: source.value, + }, + }) + } + } + }, options) + }, +}) diff --git a/src/rules/no-unused-modules.js b/src/rules/no-unused-modules.js index 41c86fef4..34aa51d9b 100644 --- a/src/rules/no-unused-modules.js +++ b/src/rules/no-unused-modules.js @@ -5,13 +5,13 @@ */ import { getFileExtensions } from '../utils/ignore' -import resolve from '../utils/resolve' +import { resolve } from '../utils/resolve' import visit from '../utils/visit' import { dirname, join } from 'path' -import readPkgUp from '../utils/readPkgUp' +import { readPkgUp } from '../utils/readPkgUp' import Exports, { recursivePatternCapture } from '../ExportMap' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' let FileEnumerator let listFilesToProcess diff --git a/src/rules/no-useless-path-segments.js b/src/rules/no-useless-path-segments.js index 0f68401e7..35a854a77 100644 --- a/src/rules/no-useless-path-segments.js +++ b/src/rules/no-useless-path-segments.js @@ -4,10 +4,10 @@ */ import { getFileExtensions } from '../utils/ignore' -import moduleVisitor from '../utils/moduleVisitor' -import resolve from '../utils/resolve' +import { moduleVisitor } from '../utils/moduleVisitor' +import { resolve } from '../utils/resolve' import path from 'path' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' /** * convert a potentially relative path from node utils into a true diff --git a/src/rules/no-webpack-loader-syntax.js b/src/rules/no-webpack-loader-syntax.js index 9f489c113..a7f8f60d2 100644 --- a/src/rules/no-webpack-loader-syntax.js +++ b/src/rules/no-webpack-loader-syntax.js @@ -1,5 +1,5 @@ -import moduleVisitor from '../utils/moduleVisitor' -import docsUrl from '../docsUrl' +import { moduleVisitor } from '../utils/moduleVisitor' +import { docsUrl } from '../docs-url' function reportIfNonStandard(context, node, name) { if (name && name.indexOf('!') !== -1) { diff --git a/src/rules/order.js b/src/rules/order.js index 54d8c05ce..87ebc6bd6 100644 --- a/src/rules/order.js +++ b/src/rules/order.js @@ -4,7 +4,7 @@ import { minimatch } from 'minimatch' import importType from '../core/importType' import isStaticRequire from '../core/staticRequire' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' // This is a **non-spec compliant** but works in practice replacement of `object.groupby` package. const groupBy = (array, grouper) => diff --git a/src/rules/prefer-default-export.js b/src/rules/prefer-default-export.js index 0cd148c31..ee849b0ed 100644 --- a/src/rules/prefer-default-export.js +++ b/src/rules/prefer-default-export.js @@ -1,6 +1,6 @@ 'use strict' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' const SINGLE_EXPORT_ERROR_MESSAGE = 'Prefer default export on a file with single export.' diff --git a/src/rules/unambiguous.js b/src/rules/unambiguous.js index ec1d4d2d4..a7e231b54 100644 --- a/src/rules/unambiguous.js +++ b/src/rules/unambiguous.js @@ -4,7 +4,7 @@ */ import { isModule } from '../utils/unambiguous' -import docsUrl from '../docsUrl' +import { docsUrl } from '../docs-url' module.exports = { meta: { diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 000000000..c06d53146 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.base", + "compilerOptions": { + "rootDir": ".", + "outDir": "../lib" + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 000000000..c599f8e1d --- /dev/null +++ b/src/types.ts @@ -0,0 +1,51 @@ +import type { TsResolverOptions } from 'eslint-import-resolver-typescript' +import type { KebabCase, LiteralUnion } from 'type-fest' +import type { ResolveOptions } from 'enhanced-resolve' + +import type { PluginName } from './utils' +import { TSESLint } from '@typescript-eslint/utils' + +export interface NodeResolverOptions { + extensions?: readonly string[] + moduleDirectory?: string[] + paths?: string[] +} + +export interface WebpackResolverOptions { + config?: string | ResolveOptions + 'config-index'?: number + env?: Record + argv?: Record +} + +export interface ImportSettings { + cache?: { + lifetime: number | '∞' | 'Infinity' + } + coreModules?: string[] + extensions?: ReadonlyArray<`.${string}`> + externalModuleFolders?: string[] + parsers?: boolean | Record + resolve?: NodeResolverOptions + resolver?: + | LiteralUnion<'node' | 'typescript' | 'webpack', string> + | { + node?: boolean | NodeResolverOptions + typescript?: boolean | TsResolverOptions + webpack?: WebpackResolverOptions + } +} + +export type WithPluginName = T extends string + ? `${PluginName}/${KebabCase}` + : { + [K in keyof T as WithPluginName<`${KebabCase}`>]: T[K] + } + +export type PluginSettings = WithPluginName + +export interface PluginConfig extends TSESLint.Linter.Config { + plugins?: [PluginName] + settings?: PluginSettings + rules?: Record<`${PluginName}/${string}`, TSESLint.Linter.RuleEntry> +} diff --git a/src/utils/ModuleCache.d.ts b/src/utils/ModuleCache.d.ts deleted file mode 100644 index 4ea4075cb..000000000 --- a/src/utils/ModuleCache.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { ESLintSettings } from './types' - -export type CacheKey = unknown -export type CacheObject = { - result: unknown - lastSeen: ReturnType -} - -declare class ModuleCache { - map: Map - - constructor(map?: Map) - - get(cacheKey: CacheKey, settings: ESLintSettings): T | undefined - - set(cacheKey: CacheKey, result: T): T - - static getSettings( - settings: ESLintSettings, - ): { lifetime: number } & Omit -} -export default ModuleCache - -export type { ModuleCache } diff --git a/src/utils/ModuleCache.js b/src/utils/ModuleCache.js deleted file mode 100644 index 851f5d359..000000000 --- a/src/utils/ModuleCache.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict' - -exports.__esModule = true - -const log = require('debug')('eslint-plugin-import-x:utils:ModuleCache') - -/** @type {import('./ModuleCache').ModuleCache} */ -class ModuleCache { - /** @param {typeof import('./ModuleCache').ModuleCache.prototype.map} map */ - constructor(map) { - this.map = - map || - /** @type {{typeof import('./ModuleCache').ModuleCache.prototype.map} */ new Map() - } - - /** @type {typeof import('./ModuleCache').ModuleCache.prototype.set} */ - set(cacheKey, result) { - this.map.set(cacheKey, { result, lastSeen: process.hrtime() }) - log('setting entry for', cacheKey) - return result - } - - /** @type {typeof import('./ModuleCache').ModuleCache.prototype.get} */ - get(cacheKey, settings) { - if (this.map.has(cacheKey)) { - const f = this.map.get(cacheKey) - // check freshness - // @ts-expect-error TS can't narrow properly from `has` and `get` - if (process.hrtime(f.lastSeen)[0] < settings.lifetime) { - return f.result - } - } else { - log('cache miss for', cacheKey) - } - // cache miss - return undefined - } - - /** @type {typeof import('./ModuleCache').ModuleCache.getSettings} */ - static getSettings(settings) { - /** @type {ReturnType} */ - const cacheSettings = { - lifetime: 30, // seconds - ...settings['import-x/cache'], - } - - // parse infinity - // @ts-expect-error the lack of type overlap is because we're abusing `cacheSettings` as a temporary object - if ( - cacheSettings.lifetime === '∞' || - cacheSettings.lifetime === 'Infinity' - ) { - cacheSettings.lifetime = Infinity - } - - return cacheSettings - } -} - -exports.default = ModuleCache diff --git a/src/utils/ModuleCache.ts b/src/utils/ModuleCache.ts new file mode 100644 index 000000000..8d8819dff --- /dev/null +++ b/src/utils/ModuleCache.ts @@ -0,0 +1,58 @@ +import { ImportSettings, PluginSettings } from '../types' + +const log = require('debug')('eslint-plugin-import-x:utils:ModuleCache') + +export type CacheKey = unknown + +export type CacheObject = { + result: unknown + lastSeen: ReturnType +} + +export class ModuleCache { + constructor(public map: Map = new Map()) {} + + set(cacheKey: CacheKey, result: unknown) { + this.map.set(cacheKey, { + result, + lastSeen: process.hrtime(), + }) + log('setting entry for', cacheKey) + return result + } + + get(cacheKey: CacheKey, settings: ImportSettings['cache']): T | undefined { + if (this.map.has(cacheKey)) { + const f = this.map.get(cacheKey) + // check freshness + // @ts-expect-error TS can't narrow properly from `has` and `get` + if (process.hrtime(f.lastSeen)[0] < settings.lifetime) { + return f!.result as T + } + } else { + log('cache miss for', cacheKey) + } + // cache miss + } + + static getSettings(settings: PluginSettings) { + const cacheSettings = { + lifetime: 30, // seconds + ...settings['import-x/cache'], + } + + // parse infinity + if ( + (['∞', 'Infinity'] as const).includes( + // @ts-expect-error - TS can't narrow properly from `includes` + cacheSettings.lifetime, + ) + ) { + cacheSettings.lifetime = Infinity + } + + return cacheSettings as ImportSettings['cache'] & { + lifetime: number + } + } +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts new file mode 100644 index 000000000..58b684006 --- /dev/null +++ b/src/utils/constants.ts @@ -0,0 +1,3 @@ +export const pluginName = 'import-x' + +export type PluginName = typeof pluginName diff --git a/src/utils/create-rule.ts b/src/utils/create-rule.ts new file mode 100644 index 000000000..cba4799dc --- /dev/null +++ b/src/utils/create-rule.ts @@ -0,0 +1,5 @@ +import { ESLintUtils } from '@typescript-eslint/utils' + +import { docsUrl } from '../docs-url' + +export const createRule = ESLintUtils.RuleCreator(docsUrl) diff --git a/src/utils/hash.d.ts b/src/utils/hash.d.ts deleted file mode 100644 index 611a33f79..000000000 --- a/src/utils/hash.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Hash } from 'crypto' - -declare function hashArray(value: Array, hash?: Hash): Hash - -declare function hashObject(value: T, hash?: Hash): Hash - -declare function hashify( - value: Array | object | unknown, - hash?: Hash, -): Hash - -export default hashify - -export { hashArray, hashObject } diff --git a/src/utils/hash.js b/src/utils/hash.js deleted file mode 100644 index 159e05920..000000000 --- a/src/utils/hash.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * utilities for hashing config objects. - * basically iteratively updates hash with a JSON-like format - */ - -'use strict' - -exports.__esModule = true - -const createHash = require('crypto').createHash - -const stringify = JSON.stringify - -/** @type {import('./hash').default} */ -function hashify(value, hash) { - if (!hash) { - hash = createHash('sha256') - } - - if (Array.isArray(value)) { - hashArray(value, hash) - } else if (value instanceof Object) { - hashObject(value, hash) - } else { - hash.update(stringify(value) || 'undefined') - } - - return hash -} -exports.default = hashify - -/** @type {import('./hash').hashArray} */ -function hashArray(array, hash) { - if (!hash) { - hash = createHash('sha256') - } - - hash.update('[') - for (let i = 0; i < array.length; i++) { - hashify(array[i], hash) - hash.update(',') - } - hash.update(']') - - return hash -} -hashify.array = hashArray -exports.hashArray = hashArray - -/** @type {import('./hash').hashObject} */ -function hashObject(object, optionalHash) { - const hash = optionalHash || createHash('sha256') - - hash.update('{') - Object.keys(object) - .sort() - .forEach(key => { - hash.update(stringify(key)) - hash.update(':') - // @ts-expect-error the key is guaranteed to exist on the object here - hashify(object[key], hash) - hash.update(',') - }) - hash.update('}') - - return hash -} -hashify.object = hashObject -exports.hashObject = hashObject diff --git a/src/utils/hash.ts b/src/utils/hash.ts new file mode 100644 index 000000000..bc132e16c --- /dev/null +++ b/src/utils/hash.ts @@ -0,0 +1,53 @@ +/** + * utilities for hashing config objects. + * basically iteratively updates hash with a JSON-like format + */ +import type { Hash } from 'crypto' + +import { createHash } from 'crypto' + +export function hashify(value: unknown, hash?: Hash) { + hash ??= createHash('sha256') + + if (Array.isArray(value)) { + hashArray(value, hash) + } else if (value instanceof Object) { + hashObject(value, hash) + } else { + hash.update(JSON.stringify(value) || 'undefined') + } + + return hash +} + +export function hashArray(array: unknown[], hash?: Hash) { + hash ??= createHash('sha256') + + hash.update('[') + + for (let i = 0; i < array.length; i++) { + hashify(array[i], hash) + hash.update(',') + } + + hash.update(']') + + return hash +} + +export function hashObject(object: T, hash?: Hash) { + hash ??= createHash('sha256') + + hash.update('{') + + for (const key of Object.keys(object).sort()) { + hash.update(JSON.stringify(key)) + hash.update(':') + hashify(object[key as keyof T], hash) + hash.update(',') + } + + hash.update('}') + + return hash +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 000000000..b163699ef --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,2 @@ +export * from './constants' +export * from './create-rule' diff --git a/src/utils/moduleVisitor.d.ts b/src/utils/moduleVisitor.d.ts deleted file mode 100644 index 2ce668135..000000000 --- a/src/utils/moduleVisitor.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { Rule } from 'eslint' -import type { Node } from 'estree' - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type Visitor = (source: Node, importer: unknown) => any - -type Options = { - amd?: boolean - commonjs?: boolean - esmodule?: boolean - ignore?: string[] -} - -declare function moduleVisitor(visitor: Visitor, options?: Options): object - -export default moduleVisitor - -export type Schema = NonNullable - -declare function makeOptionsSchema( - additionalProperties?: Partial, -): Schema - -declare const optionsSchema: Schema - -export { makeOptionsSchema, optionsSchema } diff --git a/src/utils/moduleVisitor.js b/src/utils/moduleVisitor.ts similarity index 71% rename from src/utils/moduleVisitor.js rename to src/utils/moduleVisitor.ts index 1a96c71d2..8f1f77dbb 100644 --- a/src/utils/moduleVisitor.js +++ b/src/utils/moduleVisitor.ts @@ -1,18 +1,30 @@ -'use strict' - -exports.__esModule = true - -/** @typedef {import('estree').Node} Node */ -/** @typedef {{ arguments: import('estree').CallExpression['arguments'], callee: Node }} Call */ -/** @typedef {import('estree').ImportDeclaration | import('estree').ExportNamedDeclaration | import('estree').ExportAllDeclaration} Declaration */ +import type { TSESTree } from '@typescript-eslint/typescript-estree' +import type { TSESLint } from '@typescript-eslint/utils' +import type { JSONSchema4 } from 'json-schema' + +type Visitor = ( + source: TSESTree.StringLiteral, + importer: + | TSESTree.ImportDeclaration + | TSESTree.ExportNamedDeclaration + | TSESTree.ExportAllDeclaration + | TSESTree.CallExpression + | TSESTree.ImportExpression + | TSESTree.StringLiteral, +) => void + +export interface ModuleOptions { + amd?: boolean + commonjs?: boolean + esmodule?: boolean + ignore?: string[] +} /** * Returns an object of node visitors that will call * 'visitor' with every discovered module path. - * - * @type {(import('./moduleVisitor').default)} */ -exports.default = function visitModules(visitor, options) { +export function moduleVisitor(visitor: Visitor, options: ModuleOptions) { const ignore = options && options.ignore const amd = !!(options && options.amd) const commonjs = !!(options && options.commonjs) @@ -21,8 +33,16 @@ exports.default = function visitModules(visitor, options) { const ignoreRegExps = ignore == null ? [] : ignore.map(p => new RegExp(p)) - /** @type {(source: undefined | null | import('estree').Literal, importer: Parameters[1]) => void} */ - function checkSourceValue(source, importer) { + function checkSourceValue( + source: TSESTree.StringLiteral | null | undefined, + importer: + | TSESTree.ImportDeclaration + | TSESTree.ExportNamedDeclaration + | TSESTree.ExportAllDeclaration + | TSESTree.CallExpression + | TSESTree.ImportExpression + | TSESTree.StringLiteral, + ) { if (source == null) { return } //? @@ -37,15 +57,17 @@ exports.default = function visitModules(visitor, options) { } // for import-y declarations - /** @type {(node: Declaration) => void} */ - function checkSource(node) { + function checkSource( + node: + | TSESTree.ImportDeclaration + | TSESTree.ExportNamedDeclaration + | TSESTree.ExportAllDeclaration, + ) { checkSourceValue(node.source, node) } // for esmodule dynamic `import()` calls - /** @type {(node: import('estree').ImportExpression | import('estree').CallExpression) => void} */ - function checkImportCall(node) { - /** @type {import('estree').Expression | import('estree').Literal | import('estree').CallExpression['arguments'][0]} */ + function checkImportCall(node: TSESTree.Node) { let modulePath // refs https://github.com/estree/estree/blob/HEAD/es2020.md#importexpression if (node.type === 'ImportExpression') { @@ -67,6 +89,7 @@ exports.default = function visitModules(visitor, options) { if (modulePath.type !== 'Literal') { return } + if (typeof modulePath.value !== 'string') { return } @@ -76,8 +99,7 @@ exports.default = function visitModules(visitor, options) { // for CommonJS `require` calls // adapted from @mctep: https://git.io/v4rAu - /** @type {(call: Call) => void} */ - function checkCommon(call) { + function checkCommon(call: TSESTree.CallExpression) { if (call.callee.type !== 'Identifier') { return } @@ -89,6 +111,7 @@ exports.default = function visitModules(visitor, options) { } const modulePath = call.arguments[0] + if (modulePath.type !== 'Literal') { return } @@ -99,8 +122,7 @@ exports.default = function visitModules(visitor, options) { checkSourceValue(modulePath, call) } - /** @type {(call: Call) => void} */ - function checkAMD(call) { + function checkAMD(call: TSESTree.CallExpression) { if (call.callee.type !== 'Identifier') { return } @@ -120,9 +142,11 @@ exports.default = function visitModules(visitor, options) { if (!element) { continue } + if (element.type !== 'Literal') { continue } + if (typeof element.value !== 'string') { continue } @@ -135,7 +159,8 @@ exports.default = function visitModules(visitor, options) { } } - const visitors = {} + const visitors = {} as TSESLint.RuleListener + if (esmodule) { Object.assign(visitors, { ImportDeclaration: checkSource, @@ -148,9 +173,7 @@ exports.default = function visitModules(visitor, options) { if (commonjs || amd) { const currentCallExpression = visitors.CallExpression - visitors.CallExpression = /** @type {(call: Call) => void} */ function ( - call, - ) { + visitors.CallExpression = function (call) { if (currentCallExpression) { currentCallExpression(call) } @@ -168,11 +191,9 @@ exports.default = function visitModules(visitor, options) { /** * make an options schema for the module visitor, optionally adding extra fields. - * @type {import('./moduleVisitor').makeOptionsSchema} */ -function makeOptionsSchema(additionalProperties) { - /** @type {import('./moduleVisitor').Schema} */ - const base = { +export function makeOptionsSchema(additionalProperties?: JSONSchema4) { + const base: JSONSchema4 = { type: 'object', properties: { commonjs: { type: 'boolean' }, @@ -190,16 +211,14 @@ function makeOptionsSchema(additionalProperties) { if (additionalProperties) { for (const key in additionalProperties) { - // @ts-expect-error TS always has trouble with arbitrary object assignment/mutation - base.properties[key] = additionalProperties[key] + base.properties![key] = additionalProperties[key] } } return base } -exports.makeOptionsSchema = makeOptionsSchema /** * json schema object for options parameter. can be used to build rule options schema object. */ -exports.optionsSchema = makeOptionsSchema() +export const optionsSchema = makeOptionsSchema() diff --git a/src/utils/pkgDir.d.ts b/src/utils/pkgDir.d.ts deleted file mode 100644 index 9b05edf5f..000000000 --- a/src/utils/pkgDir.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare function pkgDir(cwd: string): string | null - -export default pkgDir diff --git a/src/utils/pkgDir.js b/src/utils/pkgDir.js deleted file mode 100644 index bcc5aa28b..000000000 --- a/src/utils/pkgDir.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -const path = require('path') -const pkgUp = require('./pkgUp').default - -exports.__esModule = true - -/** @type {import('./pkgDir').default} */ -exports.default = function (cwd) { - const fp = pkgUp({ cwd }) - return fp ? path.dirname(fp) : null -} diff --git a/src/utils/pkgDir.ts b/src/utils/pkgDir.ts new file mode 100644 index 000000000..471cc488d --- /dev/null +++ b/src/utils/pkgDir.ts @@ -0,0 +1,8 @@ +import path from 'path' + +import { pkgUp } from './pkgUp' + +export function pkgDir(cwd: string) { + const fp = pkgUp({ cwd }) + return fp ? path.dirname(fp) : null +} diff --git a/src/utils/pkgUp.d.ts b/src/utils/pkgUp.d.ts deleted file mode 100644 index 2e9e96a23..000000000 --- a/src/utils/pkgUp.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare function pkgUp(opts?: { cwd?: string }): string | null - -export default pkgUp diff --git a/src/utils/pkgUp.js b/src/utils/pkgUp.js deleted file mode 100644 index 031681d52..000000000 --- a/src/utils/pkgUp.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict' - -exports.__esModule = true - -const fs = require('fs') -const path = require('path') - -/** - * Derived significantly from package find-up@2.0.0. See license below. - * - * @copyright Sindre Sorhus - * MIT License - * - * Copyright (c) Sindre Sorhus (https://sindresorhus.com) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** @type {(filename: string | string[], cwd?: string) => string | null} */ -function findUp(filename, cwd) { - let dir = path.resolve(cwd || '') - const root = path.parse(dir).root - - /** @type {string[]} */ // @ts-expect-error TS sucks with concat - const filenames = [].concat(filename) - - // eslint-disable-next-line no-constant-condition - while (true) { - const file = filenames.find(el => fs.existsSync(path.resolve(dir, el))) - - if (file) { - return path.join(dir, file) - } - if (dir === root) { - return null - } - - dir = path.dirname(dir) - } -} - -/** @type {import('./pkgUp').default} */ -exports.default = function pkgUp(opts) { - return findUp('package.json', opts && opts.cwd) -} diff --git a/src/utils/pkgUp.ts b/src/utils/pkgUp.ts new file mode 100644 index 000000000..3dc3258ce --- /dev/null +++ b/src/utils/pkgUp.ts @@ -0,0 +1,27 @@ +import fs from 'fs' +import path from 'path' + +function findUp(filename: string | string[], cwd?: string): string | null { + let dir = path.resolve(cwd || '') + const root = path.parse(dir).root + + const filenames = [filename].flat() + + // eslint-disable-next-line no-constant-condition + while (true) { + const file = filenames.find(el => fs.existsSync(path.resolve(dir, el))) + + if (file) { + return path.join(dir, file) + } + if (dir === root) { + return null + } + + dir = path.dirname(dir) + } +} + +export function pkgUp(opts?: { cwd?: string }) { + return findUp('package.json', opts && opts.cwd) +} diff --git a/src/utils/readPkgUp.d.ts b/src/utils/readPkgUp.d.ts deleted file mode 100644 index 0323252b9..000000000 --- a/src/utils/readPkgUp.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import pkgUp from './pkgUp' - -declare function readPkgUp( - opts?: Parameters[0], - // eslint-disable-next-line @typescript-eslint/ban-types -): {} | { pkg: string; path: string } - -export default readPkgUp diff --git a/src/utils/readPkgUp.js b/src/utils/readPkgUp.js deleted file mode 100644 index 0333fcad4..000000000 --- a/src/utils/readPkgUp.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict' - -exports.__esModule = true - -const fs = require('fs') -const pkgUp = require('./pkgUp').default - -/** @type {(str: string) => string} */ -function stripBOM(str) { - return str.replace(/^\uFEFF/, '') -} - -/** - * Derived significantly from read-pkg-up@2.0.0. See license below. - * - * @copyright Sindre Sorhus - * MIT License - * - * Copyright (c) Sindre Sorhus (https://sindresorhus.com) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -/** @type {import('./readPkgUp').default} */ -exports.default = function readPkgUp(opts) { - const fp = pkgUp(opts) - - if (!fp) { - return {} - } - - try { - return { - pkg: JSON.parse(stripBOM(fs.readFileSync(fp, { encoding: 'utf-8' }))), - path: fp, - } - } catch (e) { - return {} - } -} diff --git a/src/utils/readPkgUp.ts b/src/utils/readPkgUp.ts new file mode 100644 index 000000000..69e62fb96 --- /dev/null +++ b/src/utils/readPkgUp.ts @@ -0,0 +1,28 @@ +import fs from 'fs' + +import type { PackageJson } from 'type-fest' + +import { pkgUp } from './pkgUp' + +function stripBOM(str: string) { + return str.replace(/^\uFEFF/, '') +} + +export function readPkgUp(opts?: { cwd?: string }) { + const fp = pkgUp(opts) + + if (!fp) { + return {} + } + + try { + return { + pkg: JSON.parse( + stripBOM(fs.readFileSync(fp, { encoding: 'utf-8' })), + ) as PackageJson, + path: fp, + } + } catch (e) { + return {} + } +} diff --git a/src/utils/resolve.d.ts b/src/utils/resolve.d.ts deleted file mode 100644 index aec2a4ddf..000000000 --- a/src/utils/resolve.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { Rule } from 'eslint' - -import type ModuleCache from './ModuleCache' -import type { ESLintSettings } from './types' - -export type ResultNotFound = { found: false; path?: undefined } -export type ResultFound = { found: true; path: string | null } -export type ResolvedResult = ResultNotFound | ResultFound - -export type ResolverResolve = ( - modulePath: string, - sourceFile: string, - config: unknown, -) => ResolvedResult -export type ResolverResolveImport = ( - modulePath: string, - sourceFile: string, - config: unknown, -) => string | undefined -export type Resolver = { - interfaceVersion?: 1 | 2 - resolve: ResolverResolve - resolveImport: ResolverResolveImport -} - -declare function resolve( - p: string, - context: Rule.RuleContext, -): ResolvedResult['path'] - -export default resolve - -declare function fileExistsWithCaseSync( - filepath: string | null, - cacheSettings: ESLintSettings, - strict: boolean, -): boolean | ReturnType - -declare function relative( - modulePath: string, - sourceFile: string, - settings: ESLintSettings, -): ResolvedResult['path'] - -export { fileExistsWithCaseSync, relative } diff --git a/src/utils/resolve.js b/src/utils/resolve.ts similarity index 67% rename from src/utils/resolve.js rename to src/utils/resolve.ts index 2b18bacdb..26df24693 100644 --- a/src/utils/resolve.js +++ b/src/utils/resolve.ts @@ -1,32 +1,62 @@ 'use strict' -exports.__esModule = true +import fs from 'fs' +import module from 'module' +import path from 'path' -const fs = require('fs') -const { createRequire } = require('module') -const path = require('path') +import type { TSESLint } from '@typescript-eslint/utils' -const hashObject = require('./hash').hashObject -const ModuleCache = require('./ModuleCache').default -const pkgDir = require('./pkgDir').default +import { ImportSettings, PluginSettings } from '../types' -const CASE_SENSITIVE_FS = !fs.existsSync( +import { hashObject } from './hash' +import { ModuleCache } from './ModuleCache' + +import { pkgDir } from './pkgDir' + +export type ResultNotFound = { found: false; path?: undefined } + +export type ResultFound = { found: true; path: string | null } + +export type ResolvedResult = ResultNotFound | ResultFound + +export type ResolverResolve = ( + modulePath: string, + sourceFile: string, + config: unknown, +) => ResolvedResult + +export type ResolverResolveImport = ( + modulePath: string, + sourceFile: string, + config: unknown, +) => string | undefined + +export type Resolver = { + interfaceVersion?: 1 | 2 + resolve: ResolverResolve + resolveImport: ResolverResolveImport +} + +export const CASE_SENSITIVE_FS = !fs.existsSync( path.join(__dirname.toUpperCase(), 'reSOLVE.js'), ) -exports.CASE_SENSITIVE_FS = CASE_SENSITIVE_FS const ERROR_NAME = 'EslintPluginImportResolveError' const fileExistsCache = new ModuleCache() -/** @type {(target: T, sourceFile?: string | null | undefined) => undefined | ReturnType} */ -function tryRequire(target, sourceFile) { +function tryRequire( + target: string, + sourceFile?: string | null, +): undefined | T { let resolved try { // Check if the target exists if (sourceFile != null) { try { - resolved = createRequire(path.resolve(sourceFile)).resolve(target) + resolved = module + .createRequire(path.resolve(sourceFile)) + .resolve(target) } catch (e) { resolved = require.resolve(target) } @@ -43,12 +73,11 @@ function tryRequire(target, sourceFile) { } // https://stackoverflow.com/a/27382838 -/** @type {import('./resolve').fileExistsWithCaseSync} */ -exports.fileExistsWithCaseSync = function fileExistsWithCaseSync( - filepath, - cacheSettings, - strict, -) { +export function fileExistsWithCaseSync( + filepath: string | null, + cacheSettings: ImportSettings['cache'], + strict?: boolean, +): boolean { // don't care if the FS is case-sensitive if (CASE_SENSITIVE_FS) { return true @@ -64,7 +93,7 @@ exports.fileExistsWithCaseSync = function fileExistsWithCaseSync( const parsedPath = path.parse(filepath) const dir = parsedPath.dir - let result = fileExistsCache.get(filepath, cacheSettings) + let result = fileExistsCache.get(filepath, cacheSettings) if (result != null) { return result } @@ -84,11 +113,14 @@ exports.fileExistsWithCaseSync = function fileExistsWithCaseSync( return result } -/** @type {import('./types').ESLintSettings | null} */ -let prevSettings = null +let prevSettings: PluginSettings | null = null let memoizedHash = '' -/** @type {(modulePath: string, sourceFile: string, settings: import('./types').ESLintSettings) => import('./resolve').ResolvedResult} */ -function fullResolve(modulePath, sourceFile, settings) { + +function fullResolve( + modulePath: string, + sourceFile: string, + settings: PluginSettings, +) { // check if this is a bonus core module const coreSet = new Set(settings['import-x/core-modules']) if (coreSet.has(modulePath)) { @@ -106,18 +138,16 @@ function fullResolve(modulePath, sourceFile, settings) { const cacheSettings = ModuleCache.getSettings(settings) - const cachedPath = fileExistsCache.get(cacheKey, cacheSettings) + const cachedPath = fileExistsCache.get(cacheKey, cacheSettings) if (cachedPath !== undefined) { return { found: true, path: cachedPath } } - /** @type {(resolvedPath: string | null) => void} */ - function cache(resolvedPath) { + function cache(resolvedPath: string | null) { fileExistsCache.set(cacheKey, resolvedPath) } - /** @type {(resolver: import('./resolve').Resolver, config: unknown) => import('./resolve').ResolvedResult} */ - function withResolver(resolver, config) { + function withResolver(resolver: Resolver, config: unknown) { if (resolver.interfaceVersion === 2) { return resolver.resolve(modulePath, sourceFile, config) } @@ -150,7 +180,7 @@ function fullResolve(modulePath, sourceFile, settings) { } // else, counts - cache(resolved.path) + cache(resolved.path as string | null) return resolved } @@ -160,13 +190,18 @@ function fullResolve(modulePath, sourceFile, settings) { } /** @type {import('./resolve').relative} */ -function relative(modulePath, sourceFile, settings) { +export function relative( + modulePath: string, + sourceFile: string, + settings: PluginSettings, +) { return fullResolve(modulePath, sourceFile, settings).path } -exports.relative = relative -/** @type {>(resolvers: string[] | string | { [k: string]: string }, map: T) => T} */ -function resolverReducer(resolvers, map) { +function resolverReducer( + resolvers: string[] | string | Record, + map: Map, +) { if (Array.isArray(resolvers)) { resolvers.forEach(r => resolverReducer(r, map)) return map @@ -189,13 +224,11 @@ function resolverReducer(resolvers, map) { throw err } -/** @type {(sourceFile: string) => string} */ -function getBaseDir(sourceFile) { +function getBaseDir(sourceFile: string): string { return pkgDir(sourceFile) || process.cwd() } -/** @type {(name: string, sourceFile: string) => import('./resolve').Resolver} */ -function requireResolver(name, sourceFile) { +function requireResolver(name: string, sourceFile: string) { // Try to resolve package with conventional name const resolver = tryRequire(`eslint-import-resolver-${name}`, sourceFile) || @@ -216,8 +249,7 @@ function requireResolver(name, sourceFile) { return resolver } -/** @type {(resolver: object) => resolver is import('./resolve').Resolver} */ -function isResolverValid(resolver) { +function isResolverValid(resolver: object): resolver is Resolver { if ('interfaceVersion' in resolver && resolver.interfaceVersion === 2) { return ( 'resolve' in resolver && @@ -232,17 +264,20 @@ function isResolverValid(resolver) { ) } -/** @type {Set} */ -const erroredContexts = new Set() +const erroredContexts = new Set< + TSESLint.RuleContext +>() /** * Given * @param p - module path * @param context - ESLint context * @return - the full module filesystem path; null if package is core; undefined if not found - * @type {import('./resolve').default} */ -function resolve(p, context) { +export function resolve( + p: string, + context: TSESLint.RuleContext, +) { try { return relative( p, @@ -252,17 +287,16 @@ function resolve(p, context) { context.settings, ) } catch (err) { + const error = err as Error if (!erroredContexts.has(context)) { // The `err.stack` string starts with `err.name` followed by colon and `err.message`. // We're filtering out the default `err.name` because it adds little value to the message. - // @ts-expect-error this might be an Error - let errMessage = err.message - // @ts-expect-error this might be an Error - if (err.name !== ERROR_NAME && err.stack) { - // @ts-expect-error this might be an Error - errMessage = err.stack.replace(/^Error: /, '') + let errMessage = error.message + if (error.name !== ERROR_NAME && error.stack) { + errMessage = error.stack.replace(/^Error: /, '') } context.report({ + // @ts-expect-error - report without messageId message: `Resolve error: ${errMessage}`, loc: { line: 1, column: 0 }, }) @@ -270,5 +304,3 @@ function resolve(p, context) { } } } -resolve.relative = relative -exports.default = resolve diff --git a/test/cli.spec.js b/test/cli.spec.js index b0be5f306..4cd084dd1 100644 --- a/test/cli.spec.js +++ b/test/cli.spec.js @@ -64,7 +64,9 @@ describe('CLI regression tests', () => { './test/fixtures/just-json-files/.eslintrc.json', rulePaths: ['./src/rules'], ignore: false, - plugins: { 'eslint-plugin-import': importPlugin }, + plugins: { + 'eslint-plugin-import-x': importPlugin, + }, }) } else { cli = new CLIEngine({ @@ -73,7 +75,7 @@ describe('CLI regression tests', () => { rulePaths: ['./src/rules'], ignore: false, }) - cli.addPlugin('eslint-plugin-import', importPlugin) + cli.addPlugin('eslint-plugin-import-x', importPlugin) } } }) diff --git a/test/core/docsUrl.spec.js b/test/core/docs-url.spec.ts similarity index 91% rename from test/core/docsUrl.spec.js rename to test/core/docs-url.spec.ts index 4250747d7..cded08926 100644 --- a/test/core/docsUrl.spec.js +++ b/test/core/docs-url.spec.ts @@ -1,5 +1,6 @@ import pkg from '../../package.json' -import docsUrl from '../../src/docsUrl' + +import { docsUrl } from '../../src/docs-url' describe('docsUrl', () => { it('returns the rule documentation URL when given a rule name', () => { diff --git a/test/core/getExports.spec.js b/test/core/getExports.spec.js index f64e47930..c4793d877 100644 --- a/test/core/getExports.spec.js +++ b/test/core/getExports.spec.js @@ -34,7 +34,7 @@ describe('ExportMap', () => { let imports expect(function () { imports = ExportMap.get('./export-all', fakeContext) - }).not.toThrow(Error) + }).not.toThrow() expect(imports).toBeDefined() expect(imports.has('foo')).toBe(true) @@ -77,7 +77,7 @@ describe('ExportMap', () => { let imports expect(function () { imports = ExportMap.get('./does-not-exist', fakeContext) - }).not.toThrow(Error) + }).not.toThrow() expect(imports).toBeFalsy() }) @@ -86,7 +86,7 @@ describe('ExportMap', () => { let imports expect(function () { imports = ExportMap.get('./exports-missing', fakeContext) - }).not.toThrow(Error) + }).not.toThrow() expect(imports).toBeDefined() expect(imports.has('bar')).toBe(true) diff --git a/test/core/hash.spec.js b/test/core/hash.spec.ts similarity index 93% rename from test/core/hash.spec.js rename to test/core/hash.spec.ts index ca82445e7..ec0f5b61e 100644 --- a/test/core/hash.spec.js +++ b/test/core/hash.spec.ts @@ -1,8 +1,8 @@ -import hashify, { hashArray, hashObject } from '../../src/utils/hash' +import { type Hash, createHash } from 'crypto' -const createHash = require('crypto').createHash +import { hashify, hashArray, hashObject } from '../../src/utils/hash' -function expectHash(actualHash, expectedString) { +function expectHash(actualHash: Hash, expectedString: string) { const expectedHash = createHash('sha256') expectedHash.update(expectedString) // to be a hex digest of sha256 hash of string <${expectedString}> diff --git a/test/core/parse.spec.js b/test/core/parse.spec.js index e5fc2f59b..54a3404b3 100644 --- a/test/core/parse.spec.js +++ b/test/core/parse.spec.js @@ -23,7 +23,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { }) it("doesn't support JSX by default", () => { - expect(() => parse(path, content, { parserPath: 'espree' })).toThrow(Error) + expect(() => parse(path, content, { parserPath: 'espree' })).toThrow() }) it('infers jsx from ecmaFeatures when using stock parser', () => { @@ -37,7 +37,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { ecmaFeatures: { jsx: true }, }, }), - ).not.toThrow(Error) + ).not.toThrow() }) it('passes expected parserOptions to custom parser', () => { @@ -85,13 +85,13 @@ describe('parse(content, { settings, ecmaFeatures })', () => { }) it('throws on context == null', () => { - expect(parse.bind(null, path, content, null)).toThrow(Error) + expect(parse.bind(null, path, content, null)).toThrow() }) it('throws on unable to resolve parserPath', () => { expect( parse.bind(null, path, content, { settings: {}, parserPath: null }), - ).toThrow(Error) + ).toThrow() }) it('takes the alternate parser specified in settings', () => { @@ -104,7 +104,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, parserOptions, }), - ).not.toThrow(Error) + ).not.toThrow() // custom parser to be called once expect(parseSpy).toHaveBeenCalledTimes(1) }) @@ -116,7 +116,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: null, }), - ).toThrow(Error) + ).toThrow() }) it('throws on non-object languageOptions.parser', () => { @@ -126,7 +126,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: 'espree' }, }), - ).toThrow(Error) + ).toThrow() }) it('throws on null languageOptions.parser', () => { @@ -136,7 +136,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: null }, }), - ).toThrow(Error) + ).toThrow() }) it('throws on empty languageOptions.parser', () => { @@ -146,7 +146,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: {} }, }), - ).toThrow(Error) + ).toThrow() }) it('throws on non-function languageOptions.parser.parse', () => { @@ -156,7 +156,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: { parse: 'espree' } }, }), - ).toThrow(Error) + ).toThrow() }) it('throws on non-function languageOptions.parser.parse', () => { @@ -166,7 +166,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: { parseForESLint: 'espree' } }, }), - ).toThrow(Error) + ).toThrow() }) it('requires only one of the parse methods', () => { @@ -176,7 +176,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parserPath: null, languageOptions: { parser: { parseForESLint: () => ({ ast: {} }) } }, }), - ).not.toThrow(Error) + ).not.toThrow() }) it('uses parse from languageOptions.parser', () => { @@ -186,7 +186,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { settings: {}, languageOptions: { parser: { parse: parseSpy } }, }), - ).not.toThrow(Error) + ).not.toThrow() // passed parser to be called once expect(parseSpy).toHaveBeenCalledTimes(1) }) @@ -198,7 +198,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { settings: {}, languageOptions: { parser: { parseForESLint: parseSpy } }, }), - ).not.toThrow(Error) + ).not.toThrow() // passed parser to be called once expect(parseSpy).toHaveBeenCalledTimes(1) }) @@ -210,9 +210,15 @@ describe('parse(content, { settings, ecmaFeatures })', () => { parse.bind(null, path, content, { settings: { 'import-x/parsers': { [parseStubParserPath]: ['.js'] } }, parserPath: null, - languageOptions: { parser: { parse() {} } }, + languageOptions: { + parser: { + parse() { + // + }, + }, + }, }), - ).not.toThrow(Error) + ).not.toThrow() // custom parser to be called once expect(parseSpy).toHaveBeenCalledTimes(1) }) @@ -231,7 +237,7 @@ describe('parse(content, { settings, ecmaFeatures })', () => { ecmaFeatures: { jsx: true }, }, }), - ).not.toThrow(Error) + ).not.toThrow() }) it('prefers languageOptions.parserOptions over parserOptions', () => { @@ -250,6 +256,6 @@ describe('parse(content, { settings, ecmaFeatures })', () => { }, parserOptions: { sourceType: 'script' }, }), - ).not.toThrow(Error) + ).not.toThrow() }) }) diff --git a/test/core/parseStubParser.js b/test/core/parseStubParser.js index a123672ab..10c8e3feb 100644 --- a/test/core/parseStubParser.js +++ b/test/core/parseStubParser.js @@ -1,4 +1,6 @@ // this stub must be in a separate file to require from parse via moduleRequire module.exports = { - parse() {}, + parse() { + // + }, } diff --git a/test/core/resolve.spec.js b/test/core/resolve.spec.js index c19ed5512..c7481363d 100644 --- a/test/core/resolve.spec.js +++ b/test/core/resolve.spec.js @@ -1,18 +1,19 @@ import eslintPkg from 'eslint/package.json' import semver from 'semver' -import resolve, { +import { CASE_SENSITIVE_FS, fileExistsWithCaseSync, + resolve, } from '../../src/utils/resolve' -import * as path from 'path' -import * as fs from 'fs' +import path from 'path' +import fs from 'fs' import * as utils from '../utils' describe('resolve', () => { it('throws on bad parameters', () => { - expect(resolve.bind(null, null, null)).toThrow(Error) + expect(resolve.bind(null, null, null)).toThrow() }) it('resolves via a custom resolver with interface version 1', () => { diff --git a/test/fixtures/typescript-d-ts/.eslintrc b/test/fixtures/typescript-d-ts/.eslintrc index cffd58331..0c9a578a1 100644 --- a/test/fixtures/typescript-d-ts/.eslintrc +++ b/test/fixtures/typescript-d-ts/.eslintrc @@ -3,7 +3,7 @@ { "files": "**.ts", "parser": "@typescript-eslint/parser", - "extends": "../../../config/typescript", + "extends": "../../../lib/config/typescript", "rules": { "import-x/export": "error" } diff --git a/test/package.spec.js b/test/package.spec.js index aff5e50de..e413b8876 100644 --- a/test/package.spec.js +++ b/test/package.spec.js @@ -1,12 +1,20 @@ const path = require('path') const fs = require('fs') -function isJSFile(f) { - return path.extname(f) === '.js' +import { srcDir } from './utils' + +/** + * @param {string} f + * @returns {boolean} + */ +function isSourceFile(f) { + const ext = path.extname(f) + return ext === '.js' || (ext === '.ts' && !f.endsWith('.d.ts')) } describe('package', () => { - const pkg = path.join(process.cwd(), 'src') + const pkg = path.resolve(srcDir) + let module beforeAll(() => { @@ -21,8 +29,8 @@ describe('package', () => { fs.readdir(path.join(pkg, 'rules'), function (err, files) { expect(err).toBeFalsy() - files.filter(isJSFile).forEach(function (f) { - expect(module.rules).toHaveProperty(path.basename(f, '.js')) + files.filter(isSourceFile).forEach(function (f) { + expect(module.rules).toHaveProperty(path.basename(f, path.extname(f))) }) done() @@ -30,16 +38,15 @@ describe('package', () => { }) it('exports all configs', done => { - fs.readdir(path.join(process.cwd(), 'config'), function (err, files) { + fs.readdir(path.resolve(srcDir, 'config'), function (err, files) { if (err) { done(err) return } - files.filter(isJSFile).forEach(file => { - if (file[0] === '.') { - return - } - expect(module.configs).toHaveProperty(path.basename(file, '.js')) + files.filter(isSourceFile).forEach(file => { + expect(module.configs).toHaveProperty( + path.basename(file, path.extname(file)), + ) }) done() }) @@ -52,7 +59,7 @@ describe('package', () => { for (const rule in module.configs[configFile].rules) { expect(() => require(getRulePath(rule.slice(preamble.length))), - ).not.toThrow(Error) + ).not.toThrow() } } diff --git a/test/rules/no-duplicates.spec.js b/test/rules/no-duplicates.spec.js index 10fa599ba..4725135bd 100644 --- a/test/rules/no-duplicates.spec.js +++ b/test/rules/no-duplicates.spec.js @@ -5,7 +5,7 @@ import { tsVersionSatisfies, typescriptEslintParserSatisfies, } from '../utils' -import jsxConfig from '../../config/react' +import jsxConfig from '../../src/config/react' import { RuleTester } from 'eslint' import eslintPkg from 'eslint/package.json' diff --git a/test/rules/no-extraneous-dependencies.spec.js b/test/rules/no-extraneous-dependencies.spec.js index 3500fb8c9..82f621596 100644 --- a/test/rules/no-extraneous-dependencies.spec.js +++ b/test/rules/no-extraneous-dependencies.spec.js @@ -1,5 +1,5 @@ import { parsers, test, testFilePath } from '../utils' -import typescriptConfig from '../../config/typescript' +import typescriptConfig from '../../src/config/typescript' import path from 'path' import fs from 'fs' diff --git a/test/rules/no-unused-modules.spec.js b/test/rules/no-unused-modules.spec.js index ff979efa9..99d395ca1 100644 --- a/test/rules/no-unused-modules.spec.js +++ b/test/rules/no-unused-modules.spec.js @@ -1,6 +1,6 @@ import { test, testVersion, testFilePath, parsers } from '../utils' -import jsxConfig from '../../config/react' -import typescriptConfig from '../../config/typescript' +import jsxConfig from '../../src/config/react' +import typescriptConfig from '../../src/config/typescript' import { RuleTester } from 'eslint' import fs from 'fs' diff --git a/test/utils.js b/test/utils.js index d7d2bf925..16249b400 100644 --- a/test/utils.js +++ b/test/utils.js @@ -136,3 +136,7 @@ export const SYNTAX_CASES = [ code: 'import { foo } from "./ignore.invalid.extension"', }), ] + +export const testCompiled = process.env.TEST_COMPILED === '1' + +export const srcDir = testCompiled ? 'lib' : 'src' diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 000000000..631a3f1ae --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,9 @@ +{ + "extends": "@1stg/tsconfig/node", + "compilerOptions": { + "allowJs": true, + "paths": { + "eslint-plugin-import-x": ["./src"] + } + } +} diff --git a/yarn.lock b/yarn.lock index 639ab9a02..6715333a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,6 +24,11 @@ prettier-plugin-svelte "^3.1.2" prettier-plugin-toml "^2.0.1" +"@1stg/tsconfig@^2.3.3": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@1stg/tsconfig/-/tsconfig-2.3.3.tgz#dc598fea2f75bf24a6da6039827679ca0213ece3" + integrity sha512-JHXiryRSs4w/ho/Uf3lDMlrYIf2p8+2gMgp23/j/HJfGF2+XwgRCnPgLA2VZ+LtGdqYX8ZJ4EmMgjFDdEdTMbg== + "@aashutoshrathi/word-wrap@^1.2.3": version "1.2.6" resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" @@ -50,22 +55,6 @@ "@angular-eslint/bundled-angular-compiler" "17.2.1" eslint-scope "^8.0.0" -"@babel/cli@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.23.9.tgz#06b3e76376ee53f14ac8ac422c884950c69e1b9e" - integrity sha512-vB1UXmGDNEhcf1jNAHKT9IlYk1R+hehVTLFlCLHBi8gfuHQGP6uRjgXVYU0EVlI/qwAWpstqkBdf2aez3/z/5Q== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - commander "^4.0.1" - convert-source-map "^2.0.0" - fs-readdir-recursive "^1.1.0" - glob "^7.2.0" - make-dir "^2.1.0" - slash "^2.0.0" - optionalDependencies: - "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.3" - chokidar "^3.4.0" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" @@ -144,7 +133,7 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.24.0": +"@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.6", "@babel/helper-create-class-features-plugin@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz#fc7554141bdbfa2d17f7b4b80153b9b090e5d158" integrity sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g== @@ -533,7 +522,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.7.2": +"@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== @@ -946,6 +935,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-typescript@^7.23.3": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" + integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.23.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" + "@babel/plugin-transform-unicode-escapes@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" @@ -1093,6 +1092,17 @@ "@babel/plugin-transform-react-jsx-development" "^7.22.5" "@babel/plugin-transform-react-pure-annotations" "^7.23.3" +"@babel/preset-typescript@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" + "@babel/register@^7.23.7": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038" @@ -1371,14 +1381,14 @@ human-id "^1.0.2" prettier "^2.7.1" -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": +"@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== @@ -1700,11 +1710,6 @@ globby "^11.0.0" read-yaml-file "^1.1.0" -"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3": - version "2.1.8-no-fsevents.3" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b" - integrity sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ== - "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" @@ -1830,6 +1835,14 @@ dependencies: "@babel/types" "^7.20.7" +"@types/eslint@^8.56.5": + version "8.56.5" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.5.tgz#94b88cab77588fcecdd0771a6d576fa1c0af9d02" + integrity sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + "@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.1": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" @@ -1869,7 +1882,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1911,22 +1924,21 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz#5a5fcad1a7baed85c10080d71ad901f98c38d5b7" - integrity sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/type-utils" "7.2.0" - "@typescript-eslint/utils" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" +"@typescript-eslint/eslint-plugin@^5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" "@typescript-eslint/parser@^5.62.0": version "5.62.0" @@ -1946,35 +1958,22 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/scope-manager@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz#cfb437b09a84f95a0930a76b066e89e35d94e3da" - integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - -"@typescript-eslint/type-utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz#7be5c30e9b4d49971b79095a1181324ef6089a19" - integrity sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/typescript-estree" "7.2.0" - "@typescript-eslint/utils" "7.2.0" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" - ts-api-utils "^1.0.1" + tsutils "^3.21.0" "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" - integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== - -"@typescript-eslint/typescript-estree@5.62.0": +"@typescript-eslint/typescript-estree@5.62.0", "@typescript-eslint/typescript-estree@^5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== @@ -1987,34 +1986,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz#5beda2876c4137f8440c5a84b4f0370828682556" - integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.2.0.tgz#fc8164be2f2a7068debb4556881acddbf0b7ce2a" - integrity sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/typescript-estree" "7.2.0" - semver "^7.5.4" - -"@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.38.1": +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.38.1", "@typescript-eslint/utils@^5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== @@ -2036,19 +2008,32 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz#5035f177752538a5750cca1af6044b633610bf9e" - integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== - dependencies: - "@typescript-eslint/types" "7.2.0" - eslint-visitor-keys "^3.4.1" - "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@unts/patch-package@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@unts/patch-package/-/patch-package-8.0.0.tgz#c57a3ad184b76899d486d76f7dd5ad4f09ed600a" + integrity sha512-iR1QSMMxt3fGgoQjyV4H9s26GXRLO93oFPrU3qSgioLC7AMAOvc9AkJOV8RrfCU4mlac/LGQh98m+AO4OFqoBQ== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^2.2.2" + "@xml-tools/parser@^1.0.11": version "1.0.11" resolved "https://registry.yarnpkg.com/@xml-tools/parser/-/parser-1.0.11.tgz#a118a14099ea5c3c537e4781fad2fc195b57f8ff" @@ -2056,6 +2041,11 @@ dependencies: chevrotain "7.1.1" +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -2137,7 +2127,7 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== -anymatch@^3.0.3, anymatch@~3.1.2: +anymatch@^3.0.3: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -2216,6 +2206,11 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -2331,11 +2326,6 @@ better-path-resolve@1.0.0: dependencies: is-windows "^1.0.0" -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - boolean@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" @@ -2356,7 +2346,7 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2473,21 +2463,6 @@ chevrotain@7.1.1: dependencies: regexp-to-ast "0.5.0" -chokidar@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - ci-info@^3.2.0, ci-info@^3.7.0: version "3.9.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" @@ -2580,11 +2555,6 @@ commander@^10.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== -commander@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2630,6 +2600,13 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2639,7 +2616,7 @@ cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2852,7 +2829,7 @@ enhanced-resolve@^0.9.1: memory-fs "^0.2.0" tapable "^0.1.8" -enhanced-resolve@^5.12.0: +enhanced-resolve@^5.12.0, enhanced-resolve@^5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787" integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA== @@ -3369,6 +3346,13 @@ find-yarn-workspace-root2@1.2.16: micromatch "^4.0.2" pkg-dir "^4.2.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + flat-cache@^3.0.4: version "3.2.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" @@ -3416,17 +3400,22 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-readdir-recursive@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2, fsevents@~2.3.2: +fsevents@^2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -3498,7 +3487,7 @@ get-tsconfig@^4.5.0, get-tsconfig@^4.7.3: dependencies: resolve-pkg-maps "^1.0.0" -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -3523,7 +3512,7 @@ glob@^10.3.7: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-scurry "^1.10.1" -glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: +glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -3573,7 +3562,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3666,7 +3655,7 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -3744,13 +3733,6 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -3778,6 +3760,11 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-expression@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" @@ -3801,7 +3788,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -3909,6 +3896,13 @@ is-windows@^1.0.0: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -4399,6 +4393,16 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stable-stringify@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" + integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== + dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -4416,6 +4420,20 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -4428,6 +4446,13 @@ kind-of@^6.0.2, kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -4646,13 +4671,6 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@9.0.3, minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4660,6 +4678,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.1, minimatch@^9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist-options@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -4669,6 +4694,11 @@ minimist-options@^4.0.2: is-plain-obj "^1.1.0" kind-of "^6.0.3" +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "7.0.4" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" @@ -4689,6 +4719,11 @@ mvdan-sh@^0.10.1: resolved "https://registry.yarnpkg.com/mvdan-sh/-/mvdan-sh-0.10.1.tgz#5b3a4462a89cf20739b12d851589342c875f4d1f" integrity sha512-kMbrH0EObaKmK3nVRKUIIya1dpASHIEusM13S4V1ViHFuxuNxCo+arxoa6j/dbV22YBGjl7UKJm9QQKJ2Crzhg== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4729,7 +4764,7 @@ normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^3.0.0, normalize-path@~3.0.0: +normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -4780,6 +4815,14 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -4923,7 +4966,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -5125,13 +5168,6 @@ read-yaml-file@^1.1.0: pify "^4.0.1" strip-bom "^3.0.0" -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -5268,6 +5304,13 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -5762,11 +5805,6 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -ts-api-utils@^1.0.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== - tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -5844,6 +5882,11 @@ type-fest@^3.0.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== +type-fest@^4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.12.0.tgz#00ae70d02161b81ecd095158143c4bb8c879760d" + integrity sha512-5Y2/pp2wtJk8o08G0CMkuFPCO354FGwk/vbidxrdhRGZfd0tFnb4Qb8anp9XxXriwBgVPjdWbKpGl4J9lJY2jQ== + typed-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" @@ -5888,10 +5931,10 @@ typed-array-length@^1.0.5: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript@^5.4.2: - version "5.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" - integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== +typescript@~5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== unbox-primitive@^1.0.2: version "1.0.2" @@ -5931,6 +5974,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -6135,6 +6183,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^2.2.2: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" + integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== + yargs-parser@^18.1.2, yargs-parser@^18.1.3: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"