diff --git a/.gitignore b/.gitignore index 8c3323cd..ff0519e9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ apps/extension/client/scripts .DS_Store .turbo .idea +yarn-error.log diff --git a/package.json b/package.json index 19a24f2b..d8355c31 100644 --- a/package.json +++ b/package.json @@ -87,10 +87,10 @@ "@preconstruct/cli": "^2.1.0", "@types/node": "^16.0.1", "@typescript-eslint/eslint-plugin": "^4.23.0", - "@typescript-eslint/parser": "^4.23.0", + "@typescript-eslint/parser": "^5.37.0", "concurrently": "6.2.0", "esbuild": "^0.14.48", - "eslint": "^7.26.0", + "eslint": "^8.0.0", "husky": ">=6", "lint-staged": ">=10", "prettier": "^2.3.1", diff --git a/packages/eslint-plugin-xstate/jest.config.js b/packages/eslint-plugin-xstate/jest.config.js new file mode 100644 index 00000000..88fd1188 --- /dev/null +++ b/packages/eslint-plugin-xstate/jest.config.js @@ -0,0 +1,18 @@ +/** @type {import('@jest/types').Config.InitialOptions} */ +module.exports = { + testMatch: ["**/?(*.)+(spec|test).[jt]s?(x)"], + watchPathIgnorePatterns: [ + "/src/__tests__/__examples__/*.typegen.ts", + ], + watchPlugins: [ + "jest-watch-typeahead/filename", + "jest-watch-typeahead/testname", + ], + snapshotFormat: { + printBasicPrototype: false, + escapeString: false, + }, + transform: { + "^.+\\.tsx?$": ["esbuild-jest", { sourcemap: true }], + }, +}; diff --git a/packages/eslint-plugin-xstate/package.json b/packages/eslint-plugin-xstate/package.json new file mode 100644 index 00000000..6325e4c8 --- /dev/null +++ b/packages/eslint-plugin-xstate/package.json @@ -0,0 +1,32 @@ +{ + "name": "eslint-plugin-xstate", + "version": "0.0.0", + "main": "dist/eslint-plugin-xstate.cjs.js", + "author": "with-heart ", + "license": "MIT", + "keywords": [ + "eslint", + "eslintplugin" + ], + "scripts": { + "test": "jest" + }, + "dependencies": { + "@typescript-eslint/utils": "^5.37.0" + }, + "devDependencies": { + "@typescript-eslint/parser": "^5.37.0", + "eslint": "^8.0.0", + "typescript": "^4.3.5" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0", + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } +} diff --git a/packages/eslint-plugin-xstate/src/estree-utils.ts b/packages/eslint-plugin-xstate/src/estree-utils.ts new file mode 100644 index 00000000..87b1ae49 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/estree-utils.ts @@ -0,0 +1,21 @@ +import { ASTUtils, AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils"; + +const is = (type: Type) => + ASTUtils.isNodeOfType(type); + +export const isCallExpression = is(AST_NODE_TYPES.CallExpression); +export const isIdentifier = is(AST_NODE_TYPES.Identifier); +export const isImportNamespaceSpecifier = is( + AST_NODE_TYPES.ImportNamespaceSpecifier +); +export const isImportSpecifier = is(AST_NODE_TYPES.ImportSpecifier); +export const isLiteral = is(AST_NODE_TYPES.Literal); +export const isMemberExpression = is(AST_NODE_TYPES.MemberExpression); +export const isObjectExpression = is(AST_NODE_TYPES.ObjectExpression); +export const isProperty = is(AST_NODE_TYPES.Property); + +export const isIdentifierWithName = + (name: string) => + (node: TSESTree.Node): node is TSESTree.Identifier => { + return isIdentifier(node) && node.name === name; + }; diff --git a/packages/eslint-plugin-xstate/src/helpers.ts b/packages/eslint-plugin-xstate/src/helpers.ts new file mode 100644 index 00000000..bebba566 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/helpers.ts @@ -0,0 +1,25 @@ +import { TSESLint, TSESTree } from "@typescript-eslint/utils"; +import { isCallExpression, isIdentifierWithName } from "./estree-utils"; + +export const findPrevTokenMatching = ( + node: TSESTree.Node, + sourceCode: Readonly, + match: string[] +): TSESTree.Token | null => { + let prevToken = sourceCode.getTokenBefore(node); + + while (prevToken && !match.includes(prevToken.value)) { + prevToken = sourceCode.getTokenBefore(prevToken)!; + } + + return prevToken && match.includes(prevToken.value) ? prevToken : null; +}; + +export const isCreateMachineFactory = (node?: TSESTree.Node): boolean => + isCallExpression(node) && + (isIdentifierWithName("createMachine")(node.callee) || + isIdentifierWithName("createTestMachine")(node.callee)); + +export const hasCreateMachineFactoryAncestor = (ancestors: TSESTree.Node[]) => { + return ancestors.some((ancestor) => isCreateMachineFactory(ancestor)); +}; diff --git a/packages/eslint-plugin-xstate/src/index.ts b/packages/eslint-plugin-xstate/src/index.ts new file mode 100644 index 00000000..45e74683 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/index.ts @@ -0,0 +1,3 @@ +import rules from "./rules"; + +export { rules }; diff --git a/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.test.ts b/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.test.ts new file mode 100644 index 00000000..cf8cce35 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.test.ts @@ -0,0 +1,48 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./avoid-context-spread"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("avoid-context-spread", rule, { + valid: [ + { + code: outdent` + machine.withContext({ + key: 'value', + }) + `, + }, + ], + invalid: [ + { + code: outdent` + machine.withContext({ + key: 'value', + ...machine.context, + }) + `, + output: outdent` + machine.withContext({ + key: 'value', + }) + `, + errors: [{ messageId: "avoidSpread" }], + }, + { + code: outdent` + machine.withContext({ + key: 'value', ...machine.context, + }) + `, + output: outdent` + machine.withContext({ + key: 'value', + }) + `, + errors: [{ messageId: "avoidSpread" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.ts b/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.ts new file mode 100644 index 00000000..74cc1494 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/avoid-context-spread.ts @@ -0,0 +1,117 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { + isCallExpression, + isIdentifier, + isIdentifierWithName, + isMemberExpression, +} from "../estree-utils"; +import { findPrevTokenMatching } from "../helpers"; + +const isContextIdentifier = isIdentifierWithName("context"); +const isWithContextIdentifier = isIdentifierWithName("withContext"); + +const findContextMemberExpressionArgument = (node: TSESTree.SpreadElement) => { + return ( + isMemberExpression(node.argument) && + isContextIdentifier(node.argument.property) && + node.argument + ); +}; + +const findClosestCallExpression = (ancestors: TSESTree.Node[]) => { + return ancestors + .reverse() + .find((ancestor): ancestor is TSESTree.CallExpression => + isCallExpression(ancestor) + ); +}; + +const isWithContextCallExpression = ( + node: TSESTree.CallExpression +): node is TSESTree.CallExpression & { + callee: TSESTree.MemberExpression; +} => { + return ( + isMemberExpression(node.callee) && + isWithContextIdentifier(node.callee.property) + ); +}; + +const hasMatchingObjectIdentifier = ( + node1: TSESTree.MemberExpression, + node2: TSESTree.MemberExpression +) => { + return ( + isIdentifier(node1.object) && + isIdentifier(node2.object) && + node1.object.name === node2.object.name + ); +}; + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const rule = createRule({ + create(context) { + const sourceCode = context.getSourceCode(); + + return { + SpreadElement(node) { + const ancestors = context.getAncestors(); + + const contextArgument = findContextMemberExpressionArgument(node); + const parentCallExpression = findClosestCallExpression(ancestors); + + if ( + !contextArgument || + !parentCallExpression || + !isWithContextCallExpression(parentCallExpression) || + !hasMatchingObjectIdentifier( + contextArgument, + parentCallExpression.callee + ) + ) { + return; + } + + context.report({ + node, + messageId: "avoidSpread", + fix(fixer) { + const prevToken = findPrevTokenMatching(node, sourceCode, [ + ",", + "{", + ]); + + let lastToken = sourceCode.getTokenAfter(node); + if (lastToken?.value !== ",") { + lastToken = sourceCode.getTokenBefore(lastToken!); + } + + const start = prevToken?.range[1] ?? node.loc.start.line; + const end = lastToken?.range[1] ?? node.loc.end.line; + + return fixer.removeRange([start, end]); + }, + }); + }, + }; + }, + name: "avoid-context-spread", + meta: { + type: "problem", + fixable: "code", + messages: { + avoidSpread: + "`withContext` accepts partial `context`—no need to spread `machine.context`", + }, + docs: { + description: + "Since `machine.withContext` now permits partial context, no need to spread `machine.context`", + recommended: "warn", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/index.ts b/packages/eslint-plugin-xstate/src/rules/index.ts new file mode 100644 index 00000000..ba91eb16 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/index.ts @@ -0,0 +1,17 @@ +import avoidContextSpread from "./avoid-context-spread"; +import noCond from "./no-cond"; +import noEmittedFrom from "./no-emitted-from"; +import noFactoryContextArg from "./no-factory-context-arg"; +import requireObjectContext from "./require-object-context"; +import requireParameterizedActionsParams from "./require-parameterized-actions-params"; +import requireParameterizedGuardsParams from "./require-parameterized-guards-params"; + +export default { + "avoid-context-spread": avoidContextSpread, + "no-cond": noCond, + "no-emitted-from": noEmittedFrom, + "no-factory-context-arg": noFactoryContextArg, + "require-object-context": requireObjectContext, + "require-parameterized-actions-params": requireParameterizedActionsParams, + "require-parameterized-guards-params": requireParameterizedGuardsParams, +}; diff --git a/packages/eslint-plugin-xstate/src/rules/no-cond.test.ts b/packages/eslint-plugin-xstate/src/rules/no-cond.test.ts new file mode 100644 index 00000000..67499a4a --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-cond.test.ts @@ -0,0 +1,57 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./no-cond"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("no-use-cond", rule, { + valid: [ + { + code: outdent` + createMachine({ + on: { + event: { + guard: 'guard' + } + } + }) + `, + }, + { + code: outdent` + const thing = { + on: { + event: { + cond: 'guard' + } + } + } + `, + }, + ], + invalid: [ + { + code: outdent` + createMachine({ + on: { + event: { + cond: 'guard' + } + } + }) + `, + output: outdent` + createMachine({ + on: { + event: { + guard: 'guard' + } + } + }) + `, + errors: [{ messageId: "renameCond" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/no-cond.ts b/packages/eslint-plugin-xstate/src/rules/no-cond.ts new file mode 100644 index 00000000..72cfdb1e --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-cond.ts @@ -0,0 +1,61 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { + isIdentifierWithName, + isObjectExpression, + isProperty, +} from "../estree-utils"; +import { hasCreateMachineFactoryAncestor } from "../helpers"; + +const isOnIdentifier = isIdentifierWithName("on"); +const isCondIdentifier = isIdentifierWithName("cond"); + +const hasOnPropertyAncestor = (ancestors: TSESTree.Node[]) => { + return ancestors + .reverse() + .some( + (ancestor) => + isObjectExpression(ancestor) && + isProperty(ancestor.parent) && + isOnIdentifier(ancestor.parent.key) + ); +}; + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const rule = createRule({ + create(context) { + return { + Property(node) { + const ancestors = context.getAncestors(); + + if ( + isCondIdentifier(node.key) && + hasCreateMachineFactoryAncestor(ancestors) && + hasOnPropertyAncestor(ancestors) + ) { + context.report({ + node, + messageId: "renameCond", + fix: (fixer) => fixer.replaceText(node.key, "guard"), + }); + } + }, + }; + }, + name: "no-cond", + meta: { + type: "problem", + fixable: "code", + docs: { + description: "replace `cond` identifier with `guard`", + recommended: "error", + }, + messages: { + renameCond: 'Rename identifier "cond" to "guard"', + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/no-emitted-from.test.ts b/packages/eslint-plugin-xstate/src/rules/no-emitted-from.test.ts new file mode 100644 index 00000000..e2693a82 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-emitted-from.test.ts @@ -0,0 +1,92 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./no-emitted-from"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("no-emitted-from", rule, { + valid: [ + { + code: outdent` + import {SnapshotFrom} from 'xstate' + + type Snapshot = SnapshotFrom + `, + }, + { + code: outdent` + import type {SnapshotFrom} from 'xstate' + + type Snapshot = SnapshotFrom + `, + }, + { + code: outdent` + import * as XState from 'xstate' + + type Snapshot = XState.SnapshotFrom + `, + }, + ], + invalid: [ + { + code: outdent` + import {EmittedFrom} from 'xstate' + + type EmittedValue = EmittedFrom + `, + output: outdent` + import {SnapshotFrom} from 'xstate' + + type EmittedValue = SnapshotFrom + `, + errors: [{ messageId: "replaceEmittedFromImport" }], + }, + { + code: outdent` + import type {EmittedFrom} from 'xstate' + + type EmittedValue = EmittedFrom + `, + output: outdent` + import type {SnapshotFrom} from 'xstate' + + type EmittedValue = SnapshotFrom + `, + errors: [{ messageId: "replaceEmittedFromImport" }], + }, + { + code: outdent` + import {EmittedFrom as Emitted} from 'xstate' + + type EmittedValue = Emitted + `, + output: outdent` + import {SnapshotFrom as Emitted} from 'xstate' + + type EmittedValue = Emitted + `, + errors: [{ messageId: "replaceEmittedFromImport" }], + }, + { + code: outdent` + import * as XState from 'xstate' + + type EmittedActorValue = XState.EmittedFrom + type EmittedServiceValue = XState.EmittedFrom + `, + output: outdent` + import * as XState from 'xstate' + + type EmittedActorValue = XState.SnapshotFrom + type EmittedServiceValue = XState.SnapshotFrom + `, + errors: [ + { messageId: "replaceEmittedFromQualifiedIdentifier" }, + { messageId: "replaceEmittedFromQualifiedIdentifier" }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/no-emitted-from.ts b/packages/eslint-plugin-xstate/src/rules/no-emitted-from.ts new file mode 100644 index 00000000..ffbf9469 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-emitted-from.ts @@ -0,0 +1,110 @@ +import { + AST_NODE_TYPES, + ESLintUtils, + TSESLint, + TSESTree, +} from "@typescript-eslint/utils"; + +const emittedFrom = "EmittedFrom"; +const snapshotFrom = "SnapshotFrom"; + +const getQualifiedNameReferences = (variable: TSESLint.Scope.Variable) => { + const identifierReferences = []; + + for (const reference of variable.references) { + const parent = reference.identifier.parent; + + if ( + parent?.type === AST_NODE_TYPES.TSQualifiedName && + parent.right.name === emittedFrom + ) { + identifierReferences.push(parent.right); + } + } + + return identifierReferences; +}; + +function fixEmittedFromImportSpecifier( + node: TSESTree.ImportSpecifier, + variable: TSESLint.Scope.Variable +) { + return function* (fixer: TSESLint.RuleFixer) { + if (node.local.name === emittedFrom) { + // since `node.local` and `node.imported` are both + // `EmittedFrom`, replace both + yield fixer.replaceText(node, snapshotFrom); + + // replace references + for (const reference of variable.references) { + yield fixer.replaceText(reference.identifier, snapshotFrom); + } + } else { + // just update the imported name + yield fixer.replaceText(node.imported, snapshotFrom); + } + }; +} + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const rule = createRule({ + create(context) { + const variables: TSESLint.Scope.Variable[] = []; + + return { + 'ImportSpecifier[imported.name="EmittedFrom"], ImportNamespaceSpecifier[parent.source.value="xstate"]'( + node: TSESTree.ImportSpecifier | TSESTree.ImportNamespaceSpecifier + ) { + variables.push(...context.getDeclaredVariables(node)); + }, + "Program:exit"(_node) { + for (const variable of variables) { + const node = variable.defs[0].node; + + switch (node.type) { + case AST_NODE_TYPES.ImportSpecifier: + { + context.report({ + node: node.imported, + messageId: "replaceEmittedFromImport", + fix: fixEmittedFromImportSpecifier(node, variable), + }); + } + break; + case AST_NODE_TYPES.ImportNamespaceSpecifier: { + for (const identifier of getQualifiedNameReferences(variable)) { + context.report({ + node: identifier, + messageId: "replaceEmittedFromQualifiedIdentifier", + fix(fixer) { + return fixer.replaceText(identifier, snapshotFrom); + }, + }); + } + } + } + } + }, + }; + }, + name: "no-emitted-from", + meta: { + type: "problem", + fixable: "code", + messages: { + replaceEmittedFromImport: + "Replace imported type `EmittedFrom` with `SnapshotFrom`", + replaceEmittedFromQualifiedIdentifier: + "Replace identifier `EmittedFrom` with `SnapshotFrom`", + }, + docs: { + description: "Replace uses of `EmittedFrom` with `SnapshotFrom`", + recommended: "warn", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.test.ts b/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.test.ts new file mode 100644 index 00000000..7b3c3bdd --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.test.ts @@ -0,0 +1,25 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./no-factory-context-arg"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("no-factory-context-arg", rule, { + valid: [ + { + code: outdent` + createMachine({}, {}) + `, + }, + ], + invalid: [ + { + code: outdent` + createMachine({}, {}, {}) + `, + errors: [{ messageId: "removeContextArg" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.ts b/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.ts new file mode 100644 index 00000000..2a3b9cb9 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/no-factory-context-arg.ts @@ -0,0 +1,37 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import { isCreateMachineFactory } from "../helpers"; + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const rule = createRule({ + create(context) { + return { + CallExpression(node) { + if (isCreateMachineFactory(node) && node.arguments.length === 3) { + const argumentNode = node.arguments[2]; + + context.report({ + node: argumentNode, + messageId: "removeContextArg", + }); + } + }, + }; + }, + name: "no-cond", + meta: { + type: "problem", + docs: { + description: "`createMachine` accepts only two arguments", + recommended: "error", + }, + messages: { + removeContextArg: + "Move the `context` definition into `machine.context` or use `machine.withContext`", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/require-object-context.test.ts b/packages/eslint-plugin-xstate/src/rules/require-object-context.test.ts new file mode 100644 index 00000000..d88e4ad6 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-object-context.test.ts @@ -0,0 +1,58 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./require-object-context"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("require-object-context", rule, { + valid: [ + { + code: outdent` + createMachine({ + context: {} + }) + `, + }, + { + code: outdent` + createMachine({}) + `, + }, + ], + invalid: [ + { + code: outdent` + createMachine({ + context: 'string' + }) + `, + errors: [{ messageId: "mustUseContextObject" }], + }, + { + code: outdent` + createMachine({ + context: 10 + }) + `, + errors: [{ messageId: "mustUseContextObject" }], + }, + { + code: outdent` + createMachine({ + context: [] + }) + `, + errors: [{ messageId: "mustUseContextObject" }], + }, + { + code: outdent` + createMachine({ + context: undefined + }) + `, + errors: [{ messageId: "mustUseContextObject" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/require-object-context.ts b/packages/eslint-plugin-xstate/src/rules/require-object-context.ts new file mode 100644 index 00000000..c18b97d9 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-object-context.ts @@ -0,0 +1,40 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { isObjectExpression } from "../estree-utils"; +import { isCreateMachineFactory } from "../helpers"; + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const rule = createRule({ + create(context) { + return { + 'Property[key.name="context"][value.type!="ObjectExpression"]'( + node: TSESTree.Property + ) { + if ( + isObjectExpression(node.parent) && + isCreateMachineFactory(node.parent.parent) + ) { + context.report({ + node: node.value, + messageId: "mustUseContextObject", + }); + } + }, + }; + }, + name: "require-object-context", + meta: { + type: "problem", + docs: { + description: "Require `machine.context` to be an `object`", + recommended: "error", + }, + messages: { + mustUseContextObject: "`context` must be an `object`", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.test.ts b/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.test.ts new file mode 100644 index 00000000..cdc8d04d --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.test.ts @@ -0,0 +1,180 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./require-parameterized-actions-params"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("require-parameterized-actions-params", rule, { + valid: [ + { + code: outdent` + createMachine({ + on: { + event: { + action: { + type: 'someAction', + params: { + message: 'Hello', + } + } + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + on: { + event: { + action: [ + { + type: 'someAction', + params: { + message: 'Hello', + } + } + ] + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + entry: { + type: 'someAction', + params: { + message: 'Hello', + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + entry: [ + { + type: 'someAction', + params: { + message: 'Hello', + } + } + ] + }) + `, + }, + { + code: outdent` + createMachine({ + exit: { + type: 'someAction', + params: { + message: 'Hello', + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + exit: [ + { + type: 'someAction', + params: { + message: 'Hello', + } + } + ] + }) + `, + }, + ], + invalid: [ + { + code: outdent` + createMachine({ + on: { + event: { + action: { + type: 'someAction', + message: 'Hello', + } + } + } + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + { + code: outdent` + createMachine({ + on: { + event: [ + { + action: { + type: 'someAction', + message: 'Hello', + } + } + ] + } + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + { + code: outdent` + createMachine({ + entry: { + type: 'someAction', + message: 'Hello', + } + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + { + code: outdent` + createMachine({ + entry: [ + { + type: 'someAction', + message: 'Hello', + } + ] + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + { + code: outdent` + createMachine({ + exit: { + type: 'someAction', + message: 'Hello', + } + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + { + code: outdent` + createMachine({ + exit: [ + { + type: 'someAction', + message: 'Hello', + } + ] + }) + `, + errors: [{ messageId: "moveActionParamsIntoParamsObject" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.ts b/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.ts new file mode 100644 index 00000000..a7399e25 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-parameterized-actions-params.ts @@ -0,0 +1,75 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { getPropertyName } from "@typescript-eslint/utils/dist/ast-utils"; +import { isProperty } from "../estree-utils"; +import { hasCreateMachineFactoryAncestor } from "../helpers"; + +interface ParameterizedActionParamProperty extends TSESTree.ObjectExpression { + key: { + name: string; + }; +} + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const isParameterizedActionParamProperty = ( + node: TSESTree.Node +): node is ParameterizedActionParamProperty => { + return ( + isProperty(node) && + getPropertyName(node) !== "type" && + getPropertyName(node) !== "params" + ); +}; + +const propertyKey = "Property[key.name=/action|entry|exit/]"; +const propertyWithObject = `${propertyKey} > ObjectExpression`; +const propertyWithArrayOfObjects = `${propertyKey} > ArrayExpression > ObjectExpression`; + +const rule = createRule({ + create(context) { + return { + [`${propertyWithObject}, ${propertyWithArrayOfObjects}`]( + node: TSESTree.ObjectExpression + ) { + const ancestors = context.getAncestors(); + if (!hasCreateMachineFactoryAncestor(ancestors)) { + return; + } + + const params: ParameterizedActionParamProperty[] = []; + for (const property of node.properties) { + if (isParameterizedActionParamProperty(property)) { + params.push(property); + } + } + + if (params.length > 0) { + context.report({ + node, + messageId: "moveActionParamsIntoParamsObject", + data: { + keys: params.map((param) => param.key.name).join(", "), + }, + }); + } + }, + }; + }, + name: "require-parameterized-actions-params", + meta: { + type: "problem", + docs: { + description: + "Require parameterized action objects params to be in a `params` object", + recommended: "error", + }, + messages: { + moveActionParamsIntoParamsObject: + "Move keys [{{ keys }}] into an object at the `params` key", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.test.ts b/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.test.ts new file mode 100644 index 00000000..a00b2e53 --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.test.ts @@ -0,0 +1,69 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import outdent from "outdent"; +import rule from "./require-parameterized-guards-params"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", +}); + +ruleTester.run("require-parameterized-guards-params", rule, { + valid: [ + { + code: outdent` + createMachine({ + on: { + event: { + guard: 'searchValid' + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + on: { + event: { + guard: { + type: 'searchValid' + } + } + } + }) + `, + }, + { + code: outdent` + createMachine({ + on: { + event: { + guard: { + type: 'searchValid', + params: { + minQueryLength: 3 + } + } + } + } + }) + `, + }, + ], + invalid: [ + { + code: outdent` + createMachine({ + on: { + event: { + guard: { + type: 'searchValid', + minQueryLength: 3, + } + } + } + }) + `, + errors: [{ messageId: "moveGuardParamsIntoParamsObject" }], + }, + ], +}); diff --git a/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.ts b/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.ts new file mode 100644 index 00000000..0c5c62df --- /dev/null +++ b/packages/eslint-plugin-xstate/src/rules/require-parameterized-guards-params.ts @@ -0,0 +1,71 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { getPropertyName } from "@typescript-eslint/utils/dist/ast-utils"; +import { isProperty } from "../estree-utils"; +import { hasCreateMachineFactoryAncestor } from "../helpers"; + +interface ParameterizedGuardParamProperty extends TSESTree.ObjectExpression { + key: { + name: string; + }; +} + +const createRule = ESLintUtils.RuleCreator((name) => name); + +const isParameterizedGuardParamProperty = ( + node: TSESTree.Node +): node is ParameterizedGuardParamProperty => { + return ( + isProperty(node) && + getPropertyName(node) !== "type" && + getPropertyName(node) !== "params" + ); +}; + +const rule = createRule({ + create(context) { + return { + 'Property[key.name="guard"][value.type="ObjectExpression"] > ObjectExpression'( + node: TSESTree.ObjectExpression + ) { + const ancestors = context.getAncestors(); + if (!hasCreateMachineFactoryAncestor(ancestors)) { + return; + } + + const params: ParameterizedGuardParamProperty[] = []; + for (const property of node.properties) { + if (isParameterizedGuardParamProperty(property)) { + params.push(property); + } + } + + if (params.length > 0) { + context.report({ + node, + messageId: "moveGuardParamsIntoParamsObject", + data: { + keys: params.map((param) => param.key.name).join(", "), + }, + }); + } + }, + }; + }, + name: "require-parameterized-guards-params", + meta: { + type: "problem", + docs: { + description: + "Require parameterized guard objects params to be in a `params` object", + recommended: "error", + }, + messages: { + moveGuardParamsIntoParamsObject: + "Move keys [{{ keys }}] into an object on the `params` key", + }, + schema: [], + }, + defaultOptions: [], +}); + +export default rule; diff --git a/packages/eslint-plugin-xstate/tsconfig.json b/packages/eslint-plugin-xstate/tsconfig.json new file mode 100644 index 00000000..9cef5965 --- /dev/null +++ b/packages/eslint-plugin-xstate/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2019", + "lib": ["ES2019"], + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "strict": true, + "outDir": "out", + "rootDir": "src", + "noEmit": true, + "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index d2dcdd6b..8f4d47e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,13 +9,6 @@ dependencies: "@jridgewell/trace-mapping" "^0.3.0" -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.5.5": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -257,7 +250,7 @@ "@babel/traverse" "^7.17.9" "@babel/types" "^7.17.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": +"@babel/highlight@^7.16.7": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== @@ -1217,34 +1210,44 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@eslint/eslintrc@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" - integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== +"@eslint/eslintrc@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" + integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.4.0" + globals "^13.15.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@humanwhocodes/config-array@^0.10.4": + version "0.10.4" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" + integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -1795,6 +1798,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== +"@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + "@types/lz-string@^1.3.34": version "1.3.34" resolved "https://registry.yarnpkg.com/@types/lz-string/-/lz-string-1.3.34.tgz#69bfadde419314b4a374bf2c8e58659c035ed0a5" @@ -1901,15 +1909,15 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.23.0": - version "4.28.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.3.tgz#95f1d475c08268edffdcb2779993c488b6434b44" - integrity sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ== +"@typescript-eslint/parser@^5.37.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.38.0.tgz#5a59a1ff41a7b43aacd1bb2db54f6bf1c02b2ff8" + integrity sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA== dependencies: - "@typescript-eslint/scope-manager" "4.28.3" - "@typescript-eslint/types" "4.28.3" - "@typescript-eslint/typescript-estree" "4.28.3" - debug "^4.3.1" + "@typescript-eslint/scope-manager" "5.38.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/typescript-estree" "5.38.0" + debug "^4.3.4" "@typescript-eslint/scope-manager@4.28.3": version "4.28.3" @@ -1919,11 +1927,37 @@ "@typescript-eslint/types" "4.28.3" "@typescript-eslint/visitor-keys" "4.28.3" +"@typescript-eslint/scope-manager@5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz#044980e4f1516a774a418dafe701a483a6c9f9ca" + integrity sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q== + dependencies: + "@typescript-eslint/types" "5.37.0" + "@typescript-eslint/visitor-keys" "5.37.0" + +"@typescript-eslint/scope-manager@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz#8f0927024b6b24e28671352c93b393a810ab4553" + integrity sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA== + dependencies: + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" + "@typescript-eslint/types@4.28.3": version "4.28.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.3.tgz#8fffd436a3bada422c2c1da56060a0566a9506c7" integrity sha512-kQFaEsQBQVtA9VGVyciyTbIg7S3WoKHNuOp/UF5RG40900KtGqfoiETWD/v0lzRXc+euVE9NXmfer9dLkUJrkA== +"@typescript-eslint/types@5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.37.0.tgz#09e4870a5f3af7af3f84e08d792644a87d232261" + integrity sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA== + +"@typescript-eslint/types@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.0.tgz#8cd15825e4874354e31800dcac321d07548b8a5f" + integrity sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA== + "@typescript-eslint/typescript-estree@4.28.3": version "4.28.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.3.tgz#253d7088100b2a38aefe3c8dd7bd1f8232ec46fb" @@ -1937,6 +1971,44 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz#956dcf5c98363bcb97bdd5463a0a86072ff79355" + integrity sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA== + dependencies: + "@typescript-eslint/types" "5.37.0" + "@typescript-eslint/visitor-keys" "5.37.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/typescript-estree@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz#89f86b2279815c6fb7f57d68cf9b813f0dc25d98" + integrity sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg== + dependencies: + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@^5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.37.0.tgz#7784cb8e91390c4f90ccaffd24a0cf9874df81b2" + integrity sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.37.0" + "@typescript-eslint/types" "5.37.0" + "@typescript-eslint/typescript-estree" "5.37.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + "@typescript-eslint/visitor-keys@4.28.3": version "4.28.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.3.tgz#26ac91e84b23529968361045829da80a4e5251c4" @@ -1945,6 +2017,22 @@ "@typescript-eslint/types" "4.28.3" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz#7b72dd343295ea11e89b624995abc7103c554eee" + integrity sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA== + dependencies: + "@typescript-eslint/types" "5.37.0" + eslint-visitor-keys "^3.3.0" + +"@typescript-eslint/visitor-keys@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz#60591ca3bf78aa12b25002c0993d067c00887e34" + integrity sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w== + dependencies: + "@typescript-eslint/types" "5.38.0" + eslint-visitor-keys "^3.3.0" + "@xstate/inspect@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@xstate/inspect/-/inspect-0.4.1.tgz#6b00b945c03280a333de8ddf10e91830c361052d" @@ -1970,7 +2058,7 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1980,7 +2068,7 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -1990,6 +2078,11 @@ acorn@^8.2.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2015,16 +2108,6 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" - integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -2099,6 +2182,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2860,7 +2948,7 @@ date-fns@^2.16.1: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.22.1.tgz#1e5af959831ebb1d82992bf67b765052d8f0efc4" integrity sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg== -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== @@ -2874,6 +2962,13 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + debug@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" @@ -3074,7 +3169,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enquirer@^2.3.0, enquirer@^2.3.5, enquirer@^2.3.6: +enquirer@^2.3.0, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== @@ -3263,12 +3358,13 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: - eslint-visitor-keys "^1.1.0" + esrecurse "^4.3.0" + estraverse "^5.2.0" eslint-utils@^3.0.0: version "3.0.0" @@ -3277,70 +3373,69 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - eslint-visitor-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@^7.26.0: - version "7.30.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8" - integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.2" - "@humanwhocodes/config-array" "^0.5.0" +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.0.0: + version "8.23.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.1.tgz#cfd7b3f7fdd07db8d16b4ac0516a29c8d8dca5dc" + integrity sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg== + dependencies: + "@eslint/eslintrc" "^1.3.2" + "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" + find-up "^5.0.0" + glob-parent "^6.0.1" + globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-sdsl "^4.1.4" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" + regexpp "^3.2.0" + strip-ansi "^6.0.1" strip-json-comments "^3.1.0" - table "^6.0.9" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" @@ -3798,6 +3893,13 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" @@ -3832,14 +3934,14 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.6.0, globals@^13.9.0: - version "13.10.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.10.0.tgz#60ba56c3ac2ca845cfbf4faeca727ad9dd204676" - integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== +globals@^13.15.0: + version "13.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== dependencies: type-fest "^0.20.2" -globby@^11.0.0: +globby@^11.0.0, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -4035,7 +4137,7 @@ ignore-walk@^3.0.3: dependencies: minimatch "^3.0.4" -ignore@^4.0.3, ignore@^4.0.6: +ignore@^4.0.3: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== @@ -4253,7 +4355,7 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@~4.0.1: +is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -4871,6 +4973,11 @@ jest@^27.4.7: import-local "^3.0.2" jest-cli "^27.4.7" +js-sdsl@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6" + integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4884,6 +4991,13 @@ js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.6.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -4942,11 +5056,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -5109,11 +5218,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -5129,11 +5233,6 @@ lodash.startcase@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" integrity sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg= -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -5327,6 +5426,13 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist-options@4.1.0, minimist-options@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -5865,11 +5971,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -6020,7 +6121,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^3.1.0: +regexpp@^3.1.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== @@ -6083,11 +6184,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -6285,13 +6381,20 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -6606,6 +6709,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -6694,18 +6804,6 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - term-size@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" @@ -7101,7 +7199,7 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: +v8-compile-cache@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==