From 548e5f318e44d7a96f29bf939c5b6cdd49795432 Mon Sep 17 00:00:00 2001 From: Jason Weinzierl Date: Mon, 4 Nov 2024 11:22:32 -0600 Subject: [PATCH] fix: remove tsutils and tsutils-etc --- package.json | 8 +- src/etc/could-be-function.ts | 11 ++ src/etc/could-be-type.ts | 110 ++++++++++++++ src/etc/get-type-services.ts | 16 +- src/etc/index.ts | 2 + src/rules/no-unsafe-subject-next.ts | 8 +- src/rules/throw-error.ts | 8 +- tests/etc/could-be-type.test.ts | 137 ++++++++++++++++++ .../create-source-file-and-type-checker.ts | 42 ++++++ yarn.lock | 131 +++-------------- 10 files changed, 342 insertions(+), 131 deletions(-) create mode 100644 src/etc/could-be-function.ts create mode 100644 src/etc/could-be-type.ts create mode 100644 tests/etc/could-be-type.test.ts create mode 100644 tests/etc/create-source-file-and-type-checker.ts diff --git a/package.json b/package.json index 489c0223..268f38ff 100644 --- a/package.json +++ b/package.json @@ -53,14 +53,13 @@ "@typescript-eslint/utils": "^8.12.2", "common-tags": "^1.8.0", "decamelize": "^5.0.0 || ^6.0.0", - "tslib": "^2.0.0", - "tsutils": "^3.0.0", - "tsutils-etc": "^1.4.2" + "ts-api-utils": "^1.3.0", + "tslib": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "rxjs": ">=7.0.0", - "typescript": ">=4.0.0" + "typescript": ">=4.2.0" }, "devDependencies": { "@eslint/js": "^9.13.0", @@ -68,6 +67,7 @@ "@types/common-tags": "^1.8.4", "@types/node": "^18.18.0", "@typescript-eslint/rule-tester": "^8.12.2", + "@typescript/vfs": "^1.6.0", "@vitest/coverage-v8": "^2.1.4", "@vitest/eslint-plugin": "^1.1.7", "bumpp": "^9.8.0", diff --git a/src/etc/could-be-function.ts b/src/etc/could-be-function.ts new file mode 100644 index 00000000..3f66a524 --- /dev/null +++ b/src/etc/could-be-function.ts @@ -0,0 +1,11 @@ +import * as ts from 'typescript'; +import { couldBeType } from './could-be-type'; + +export function couldBeFunction(type: ts.Type): boolean { + return ( + type.getCallSignatures().length > 0 + || couldBeType(type, 'Function') + || couldBeType(type, 'ArrowFunction') + || couldBeType(type, ts.InternalSymbolName.Function) + ); +} diff --git a/src/etc/could-be-type.ts b/src/etc/could-be-type.ts new file mode 100644 index 00000000..2e73dab2 --- /dev/null +++ b/src/etc/could-be-type.ts @@ -0,0 +1,110 @@ +import * as tsutils from 'ts-api-utils'; +import * as ts from 'typescript'; + +export function couldBeType( + type: ts.Type, + name: string | RegExp, + qualified?: { + name: RegExp; + typeChecker: ts.TypeChecker; + }, +): boolean { + if (tsutils.isTypeReference(type)) { + type = type.target; + } + + if (isType(type, name, qualified)) { + return true; + } + + if (tsutils.isUnionOrIntersectionType(type)) { + return type.types.some(t => couldBeType(t, name, qualified)); + } + + const baseTypes = type.getBaseTypes(); + if (baseTypes?.some(t => couldBeType(t, name, qualified))) { + return true; + } + + if (couldImplement(type, name, qualified)) { + return true; + } + + return false; +} + +function isType( + type: ts.Type, + name: string | RegExp, + qualified?: { + name: RegExp; + typeChecker: ts.TypeChecker; + }, +): boolean { + if (!type.symbol) { + return false; + } + if ( + qualified + && !qualified.name.test( + qualified.typeChecker.getFullyQualifiedName(type.symbol), + ) + ) { + return false; + } + return typeof name === 'string' + ? type.symbol.name === name + : Boolean(type.symbol.name.match(name)); +} + +function couldImplement( + type: ts.Type, + name: string | RegExp, + qualified?: { + name: RegExp; + typeChecker: ts.TypeChecker; + }, +): boolean { + const { symbol } = type; + if (symbol) { + const { valueDeclaration } = symbol; + if (valueDeclaration && ts.isClassDeclaration(valueDeclaration)) { + const { heritageClauses } = valueDeclaration; + if (heritageClauses) { + const implemented = heritageClauses.some( + ({ token, types }) => + token === ts.SyntaxKind.ImplementsKeyword + && types.some(node => isMatchingNode(node, name, qualified)), + ); + if (implemented) { + return true; + } + } + } + } + return false; +} + +function isMatchingNode( + node: ts.ExpressionWithTypeArguments, + name: string | RegExp, + qualified?: { + name: RegExp; + typeChecker: ts.TypeChecker; + }, +): boolean { + const { expression } = node; + if (qualified) { + const type = qualified.typeChecker.getTypeAtLocation(expression); + if (type) { + const qualifiedName = qualified.typeChecker.getFullyQualifiedName( + type.symbol, + ); + if (!qualified.name.test(qualifiedName)) { + return false; + } + } + } + const text = expression.getText(); + return typeof name === 'string' ? text === name : Boolean(text.match(name)); +} diff --git a/src/etc/get-type-services.ts b/src/etc/get-type-services.ts index 8d6652d2..0c3e7eb8 100644 --- a/src/etc/get-type-services.ts +++ b/src/etc/get-type-services.ts @@ -1,6 +1,8 @@ import { ESLintUtils, TSESLint, TSESTree } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils-etc'; +import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; +import { couldBeFunction } from './could-be-function'; +import { couldBeType as tsutilsEtcCouldBeType } from './could-be-type'; import { isArrowFunctionExpression, isFunctionDeclaration } from './is'; export function getTypeServices< @@ -17,7 +19,7 @@ export function getTypeServices< qualified?: { name: RegExp }, ): boolean => { const type = getType(node); - return tsutils.couldBeType( + return tsutilsEtcCouldBeType( type, name, qualified ? { ...qualified, typeChecker } : undefined, @@ -46,7 +48,7 @@ export function getTypeServices< } return Boolean( tsTypeNode - && tsutils.couldBeType( + && tsutilsEtcCouldBeType( typeChecker.getTypeAtLocation(tsTypeNode), name, qualified ? { ...qualified, typeChecker } : undefined, @@ -66,7 +68,7 @@ export function getTypeServices< if (isArrowFunctionExpression(node) || isFunctionDeclaration(node)) { return true; } - return tsutils.couldBeFunction(getType(node)); + return couldBeFunction(getType(node)); }, couldBeMonoTypeOperatorFunction: (node: TSESTree.Node) => couldBeType(node, 'MonoTypeOperatorFunction'), @@ -78,9 +80,9 @@ export function getTypeServices< couldReturnType(node, 'Observable'), couldReturnType, getType, - isAny: (node: TSESTree.Node) => tsutils.isAny(getType(node)), - isReferenceType: (node: TSESTree.Node) => tsutils.isReferenceType(getType(node)), - isUnknown: (node: TSESTree.Node) => tsutils.isUnknown(getType(node)), + isAny: (node: TSESTree.Node) => tsutils.isIntrinsicAnyType(getType(node)), + isReferenceType: (node: TSESTree.Node) => tsutils.isTypeReference(getType(node)), + isUnknown: (node: TSESTree.Node) => tsutils.isIntrinsicUnknownType(getType(node)), typeChecker, }; } diff --git a/src/etc/index.ts b/src/etc/index.ts index aca244c8..d66808aa 100644 --- a/src/etc/index.ts +++ b/src/etc/index.ts @@ -1,3 +1,5 @@ +export * from './could-be-function'; +export * from './could-be-type'; export * from './find-parent'; export * from './get-loc'; export * from './get-type-services'; diff --git a/src/rules/no-unsafe-subject-next.ts b/src/rules/no-unsafe-subject-next.ts index 511a8e67..28685a01 100644 --- a/src/rules/no-unsafe-subject-next.ts +++ b/src/rules/no-unsafe-subject-next.ts @@ -1,8 +1,8 @@ import { TSESTree as es } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; -import { couldBeType, isReferenceType, isUnionType } from 'tsutils-etc'; +import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; import { + couldBeType, getTypeServices, isMemberExpression } from '../etc'; import { ruleCreator } from '../utils'; @@ -30,7 +30,7 @@ export const noUnsafeSubjectNext = ruleCreator({ ) => { if (node.arguments.length === 0 && isMemberExpression(node.callee)) { const type = getType(node.callee.object); - if (isReferenceType(type) && couldBeType(type, 'Subject')) { + if (tsutils.isTypeReference(type) && couldBeType(type, 'Subject')) { const [typeArg] = typeChecker.getTypeArguments(type); if (tsutils.isTypeFlagSet(typeArg, ts.TypeFlags.Any)) { return; @@ -42,7 +42,7 @@ export const noUnsafeSubjectNext = ruleCreator({ return; } if ( - isUnionType(typeArg) + tsutils.isUnionType(typeArg) && typeArg.types.some((t) => tsutils.isTypeFlagSet(t, ts.TypeFlags.Void), ) diff --git a/src/rules/throw-error.ts b/src/rules/throw-error.ts index cc7cb43d..3f7fec48 100644 --- a/src/rules/throw-error.ts +++ b/src/rules/throw-error.ts @@ -1,7 +1,7 @@ import { TSESTree as es, ESLintUtils } from '@typescript-eslint/utils'; -import { couldBeFunction, couldBeType, isAny, isUnknown } from 'tsutils-etc'; +import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { getTypeServices } from '../etc'; +import { couldBeFunction, couldBeType, getTypeServices } from '../etc'; import { ruleCreator } from '../utils'; export const throwErrorRule = ruleCreator({ @@ -32,8 +32,8 @@ export const throwErrorRule = ruleCreator({ type = program.getTypeChecker().getTypeAtLocation(annotation ?? body); } if ( - !isAny(type) - && !isUnknown(type) + !tsutils.isIntrinsicAnyType(type) + && !tsutils.isIntrinsicUnknownType(type) && !couldBeType(type, /^(Error|DOMException)$/) ) { context.report({ diff --git a/tests/etc/could-be-type.test.ts b/tests/etc/could-be-type.test.ts new file mode 100644 index 00000000..3b24f698 --- /dev/null +++ b/tests/etc/could-be-type.test.ts @@ -0,0 +1,137 @@ +import * as ts from 'typescript'; +import { couldBeType } from '../../src/etc/could-be-type'; +import { createSourceFileAndTypeChecker } from './create-source-file-and-type-checker'; + +describe('couldBeType', () => { + it('should match a specific type', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + class A {} + let a: A; + `, + ); + const node = (sourceFile.statements[1] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + }); + + it('should not match different types', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + class A {} + class B {} + let b: B; + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(false); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it('should match a base type', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + class A {} + class B extends A {} + let b: B; + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it('should match an implemented interface', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + interface A { name: string; } + class B implements A { name = ""; } + let b: B; + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it('should match an implemented generic interface', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + interface A { value: T; } + class B implements A { constructor(public value: T) {} } + let b = new B("B"); + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it('should match an intersection type', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + class A {} + class B {} + let ab: A & B; + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it('should match a union type', () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + class A {} + class B {} + let ab: A | B; + `, + ); + const node = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const type = typeChecker.getTypeAtLocation(node); + + expect(couldBeType(type, 'A')).toBe(true); + expect(couldBeType(type, 'B')).toBe(true); + }); + + it.todo('should support fully-qualified types', () => { + // TODO: This test is disabled because we're failing to import from other files using @typescript/vfs. See env.languageService.getSemanticDiagnostics(fileName) for error message. + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker( + ` + import { A } from "./a"; + class B {} + let a: A; + let b: B; + `, + ); + const nodeA = (sourceFile.statements[2] as ts.VariableStatement).declarationList.declarations[0]; + const nodeB = (sourceFile.statements[3] as ts.VariableStatement).declarationList.declarations[0]; + const typeA = typeChecker.getTypeAtLocation(nodeA); + const typeB = typeChecker.getTypeAtLocation(nodeB); + + expect( + couldBeType(typeA, 'A', { + name: /"a"/, + typeChecker, + }), + ).toBe(true); + expect( + couldBeType(typeB, 'B', { + name: /"b"/, + typeChecker, + }), + ).toBe(false); + }); +}); diff --git a/tests/etc/create-source-file-and-type-checker.ts b/tests/etc/create-source-file-and-type-checker.ts new file mode 100644 index 00000000..3b2d8063 --- /dev/null +++ b/tests/etc/create-source-file-and-type-checker.ts @@ -0,0 +1,42 @@ +import * as tsvfs from '@typescript/vfs'; +import * as ts from 'typescript'; + +interface SourceFileAndTypeChecker { + sourceFile: ts.SourceFile; + typeChecker: ts.TypeChecker; +} + +export function createSourceFileAndTypeChecker( + sourceText: string, + fileName = 'file.tsx', +): SourceFileAndTypeChecker { + const compilerOptions: ts.CompilerOptions = { + lib: ['ES2018'], + target: ts.ScriptTarget.ES2018, + module: ts.ModuleKind.CommonJS, + }; + + const fsMap = tsvfs.createDefaultMapFromNodeModules(compilerOptions, ts); + fsMap.set(fileName, sourceText); + fsMap.set('a.ts', 'export class A {}'); + fsMap.set('b.ts', 'export class B {}'); + + const system = tsvfs.createSystem(fsMap); + const env = tsvfs.createVirtualTypeScriptEnvironment( + system, + [fileName, 'a.ts', 'b.ts'], + ts, + compilerOptions, + ); + + const program = env.languageService.getProgram(); + if (program === undefined) { + throw new Error('Failed to get program'); + } + + return { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + sourceFile: program.getSourceFile(fileName)!, + typeChecker: program.getTypeChecker(), + }; +} diff --git a/yarn.lock b/yarn.lock index 3bd78aae..8a043617 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1391,22 +1391,6 @@ __metadata: languageName: node linkType: hard -"@types/yargs-parser@npm:*": - version: 21.0.0 - resolution: "@types/yargs-parser@npm:21.0.0" - checksum: 10c0/cb89f3bb2e8002f1479a65a934e825be4cc18c50b350bbc656405d41cf90b8a299b105e7da497d7eb1aa460472a07d1e5a389f3af0862f1d1252279cfcdd017c - languageName: node - linkType: hard - -"@types/yargs@npm:^17.0.0": - version: 17.0.10 - resolution: "@types/yargs@npm:17.0.10" - dependencies: - "@types/yargs-parser": "npm:*" - checksum: 10c0/eb46d2c0dc7b3e1ccbf5a06ac217dc761ec8b9817c1fe6a15474476f86e90abc29c693f33221c28b0f20fa5f3028f44a0b1f040fc9f91f0124b9a88a7d2462a7 - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:8.12.2": version: 8.12.2 resolution: "@typescript-eslint/eslint-plugin@npm:8.12.2" @@ -1539,6 +1523,17 @@ __metadata: languageName: node linkType: hard +"@typescript/vfs@npm:^1.6.0": + version: 1.6.0 + resolution: "@typescript/vfs@npm:1.6.0" + dependencies: + debug: "npm:^4.1.1" + peerDependencies: + typescript: "*" + checksum: 10c0/35e17d92f0d4f33c4be12fc4468196788794bc2edc1a371f1023c42314f6d1e0e851f07b45732a634ef750e61e2ef8769e8ab4f6a6c511cea8da397fa87852ff + languageName: node + linkType: hard + "@vitest/coverage-v8@npm:^2.1.4": version: 2.1.4 resolution: "@vitest/coverage-v8@npm:2.1.4" @@ -2037,17 +2032,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: "npm:^4.2.0" - strip-ansi: "npm:^6.0.0" - wrap-ansi: "npm:^7.0.0" - checksum: 10c0/6035f5daf7383470cef82b3d3db00bec70afb3423538c50394386ffbbab135e26c3689c41791f911fa71b62d13d3863c712fdd70f0fbdffd938a1e6fd09aac00 - languageName: node - linkType: hard - "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -2779,7 +2763,7 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1, escalade@npm:^3.2.0": +"escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 @@ -2926,6 +2910,7 @@ __metadata: "@typescript-eslint/rule-tester": "npm:^8.12.2" "@typescript-eslint/scope-manager": "npm:^8.12.2" "@typescript-eslint/utils": "npm:^8.12.2" + "@typescript/vfs": "npm:^1.6.0" "@vitest/coverage-v8": "npm:^2.1.4" "@vitest/eslint-plugin": "npm:^1.1.7" bumpp: "npm:^9.8.0" @@ -2937,9 +2922,8 @@ __metadata: eslint-plugin-import-x: "npm:^4.4.0" eslint-plugin-n: "npm:^17.12.0" rxjs: "npm:^7.0.0" - tslib: "npm:^2.0.0" - tsutils: "npm:^3.0.0" - tsutils-etc: "npm:^1.4.2" + ts-api-utils: "npm:^1.3.0" + tslib: "npm:^2.1.0" tsx: "npm:^4.19.2" typescript: "npm:~5.6.3" typescript-eslint: "npm:^8.12.2" @@ -2948,7 +2932,7 @@ __metadata: peerDependencies: eslint: ^8.57.0 || ^9.0.0 rxjs: ">=7.0.0" - typescript: ">=4.0.0" + typescript: ">=4.2.0" languageName: unknown linkType: soft @@ -3298,13 +3282,6 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.5": - version: 2.0.5 - resolution: "get-caller-file@npm:2.0.5" - checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde - languageName: node - linkType: hard - "get-stream@npm:^8.0.1": version: 8.0.1 resolution: "get-stream@npm:8.0.1" @@ -4883,13 +4860,6 @@ __metadata: languageName: node linkType: hard -"require-directory@npm:^2.1.1": - version: 2.1.1 - resolution: "require-directory@npm:2.1.1" - checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 - languageName: node - linkType: hard - "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -5216,7 +5186,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -5417,47 +5387,13 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1": - version: 1.14.1 - resolution: "tslib@npm:1.14.1" - checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 - languageName: node - linkType: hard - -"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.6.3": +"tslib@npm:^2.1.0, tslib@npm:^2.6.3": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 languageName: node linkType: hard -"tsutils-etc@npm:^1.4.2": - version: 1.4.2 - resolution: "tsutils-etc@npm:1.4.2" - dependencies: - "@types/yargs": "npm:^17.0.0" - yargs: "npm:^17.0.0" - peerDependencies: - tsutils: ^3.0.0 - typescript: ">=4.0.0" - bin: - ts-flags: bin/ts-flags - ts-kind: bin/ts-kind - checksum: 10c0/7b07273627f2f4af2a785a073d0fead7c0c0d1133fee68e5de19f2aca4b01ea35a08de2c97e75f58fb6ba6ddb03ad490abf056bb8b71fb01e84bfed1b8a24a0d - languageName: node - linkType: hard - -"tsutils@npm:^3.0.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 - languageName: node - linkType: hard - "tsx@npm:^4.19.2": version: 4.19.2 resolution: "tsx@npm:4.19.2" @@ -5790,7 +5726,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -5819,13 +5755,6 @@ __metadata: languageName: node linkType: hard -"y18n@npm:^5.0.5": - version: 5.0.8 - resolution: "y18n@npm:5.0.8" - checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 - languageName: node - linkType: hard - "yallist@npm:^3.0.2": version: 3.1.1 resolution: "yallist@npm:3.1.1" @@ -5840,28 +5769,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^21.0.0": - version: 21.0.1 - resolution: "yargs-parser@npm:21.0.1" - checksum: 10c0/384ca19e113a053bb7858cf47f891e630c10ea6ad91f9ad7cae84ea1cdfb09b155a2d0fa97b51116ee6f01e038faaa6c46964953afecd453fa64a761bb87475f - languageName: node - linkType: hard - -"yargs@npm:^17.0.0": - version: 17.5.1 - resolution: "yargs@npm:17.5.1" - dependencies: - cliui: "npm:^7.0.2" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.3" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^21.0.0" - checksum: 10c0/349c823b772bc5383d56684bca8615020ae5cc0b81bacafe1ef268b281ade93528da1982b0f2dd898e0c678932d9147b8a2e93e341733622773caf7048196de4 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0"