From 0637a6f643673f3bfd7c303a4fbc5f2316da2244 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Mon, 14 Aug 2023 23:11:27 +0200 Subject: [PATCH 01/43] feat: add support for xstate v5 XState version can be specified in ESLint config with settings.xstate.version item. Default shareable config now support xstate v5. The old v4 is supported by "all_v4" and "recommended_v4". BREAKING CHANGE: The default configs are no longer compatible with xstate v4. To continue working with xstate v4, use new shareable configs "all_v4" or "recommended_v4". --- package.json | 10 +++------- tests/lib/utils/settings.js | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 tests/lib/utils/settings.js diff --git a/package.json b/package.json index ebd96b2..46da9f7 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,7 @@ "name": "eslint-plugin-xstate", "version": "0.0.0-semantically-released", "description": "ESLint rules for XState", - "keywords": [ - "eslint", - "eslintplugin", - "eslint-plugin" - ], + "keywords": ["eslint", "eslintplugin", "eslint-plugin"], "author": "Richard Laffers", "main": "lib/index.js", "scripts": { @@ -40,10 +36,10 @@ "semantic-release": "^21.0.7" }, "peerDependencies": { - "eslint": "^7.1.0||^8.17.0" + "eslint": "^8.17.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=16.0.0" }, "license": "MIT", "repository": { diff --git a/tests/lib/utils/settings.js b/tests/lib/utils/settings.js new file mode 100644 index 0000000..2e6376c --- /dev/null +++ b/tests/lib/utils/settings.js @@ -0,0 +1,22 @@ +module.exports = { + withVersion(version, testCase) { + if (typeof testCase === 'string') { + return { + code: testCase, + settings: { + xstate: { + version, + }, + }, + } + } + return { + ...testCase, + settings: { + xstate: { + version, + }, + }, + } + }, +} From 4aecdff9a8a80641f8080fcc8b87ae9d0f233b32 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Mon, 14 Aug 2023 23:19:30 +0200 Subject: [PATCH 02/43] feat(no-invalid-state-props): modify the rule to accept new xstate@5 state props Newly accepted props: types, output. No longer valid props: activities, tsTypes, schema, preserveActionOrder, predictableActionArguments, strict, data. --- lib/index.js | 61 +++++++++ lib/rules/no-invalid-state-props.js | 146 +++++++++++++++------- lib/utils/getSettings.js | 19 +++ tests/lib/rules/no-invalid-state-props.js | 123 ++++++++++++++++-- 4 files changed, 290 insertions(+), 59 deletions(-) create mode 100644 lib/utils/getSettings.js diff --git a/lib/index.js b/lib/index.js index 956c90f..3ccca74 100644 --- a/lib/index.js +++ b/lib/index.js @@ -29,7 +29,13 @@ module.exports = { 'no-async-guard': require('./rules/no-async-guard'), }, configs: { + // Requires: xstate@5 recommended: { + settings: { + xstate: { + version: 5, + }, + }, plugins: ['xstate'], rules: { 'xstate/spawn-usage': 'error', @@ -46,7 +52,62 @@ module.exports = { 'xstate/no-async-guard': 'error', }, }, + // Requires: xstate@5 all: { + settings: { + xstate: { + version: 5, + }, + }, + plugins: ['xstate'], + rules: { + 'xstate/spawn-usage': 'error', + 'xstate/no-infinite-loop': 'error', + 'xstate/no-imperative-action': 'error', + 'xstate/no-ondone-outside-compound-state': 'error', + 'xstate/invoke-usage': 'error', + 'xstate/entry-exit-action': 'error', + 'xstate/event-names': ['warn', 'macroCase'], + 'xstate/state-names': ['warn', 'camelCase'], + 'xstate/no-inline-implementation': 'warn', + 'xstate/no-auto-forward': 'warn', + 'xstate/prefer-always': 'error', + 'xstate/no-misplaced-on-transition': 'error', + 'xstate/no-invalid-transition-props': 'error', + 'xstate/no-invalid-state-props': 'error', + 'xstate/no-async-guard': 'error', + }, + }, + // Requires: xstate@4 + recommended_v4: { + settings: { + xstate: { + version: 4, + }, + }, + plugins: ['xstate'], + rules: { + 'xstate/spawn-usage': 'error', + 'xstate/no-infinite-loop': 'error', + 'xstate/no-imperative-action': 'error', + 'xstate/no-ondone-outside-compound-state': 'error', + 'xstate/invoke-usage': 'error', + 'xstate/entry-exit-action': 'error', + 'xstate/prefer-always': 'error', + 'xstate/prefer-predictable-action-arguments': 'warn', + 'xstate/no-misplaced-on-transition': 'error', + 'xstate/no-invalid-transition-props': 'error', + 'xstate/no-invalid-state-props': 'error', + 'xstate/no-async-guard': 'error', + }, + }, + // Requires: xstate@4 + all_v4: { + settings: { + xstate: { + version: 4, + }, + }, plugins: ['xstate'], rules: { 'xstate/spawn-usage': 'error', diff --git a/lib/rules/no-invalid-state-props.js b/lib/rules/no-invalid-state-props.js index c24e61b..96bf71e 100644 --- a/lib/rules/no-invalid-state-props.js +++ b/lib/rules/no-invalid-state-props.js @@ -8,55 +8,104 @@ const { hasProperty, } = require('../utils/predicates') const { allPass } = require('../utils/combinators') +const getSettings = require('../utils/getSettings') -const validProperties = [ - 'after', - 'always', - 'entry', - 'exit', - 'history', // only when type=history - 'id', - 'initial', - 'invoke', - 'meta', - 'on', - 'onDone', - 'states', - 'tags', - 'target', // only when type=history - 'type', - 'data', - 'description', - 'activities', -] -function isValidStateProperty(property) { - return validProperties.includes(property.key.name) +const validProperties = { + 4: [ + 'after', + 'always', + 'entry', + 'exit', + 'history', // only when type=history + 'id', + 'initial', + 'invoke', + 'meta', + 'on', + 'onDone', + 'states', + 'tags', + 'target', // only when type=history + 'type', + 'data', + 'description', + 'activities', + ], + 5: [ + 'after', + 'always', + 'entry', + 'exit', + 'history', // only when type=history + 'id', + 'initial', + 'invoke', + 'meta', + 'on', + 'onDone', + 'states', + 'tags', + 'target', // only when type=history + 'type', + 'description', + 'output', + ], } -const validRootProperties = [ - 'after', - 'context', - 'description', - 'entry', - 'exit', - 'history', // only when type=history - 'id', - 'initial', - 'invoke', - 'meta', - 'on', - 'predictableActionArguments', - 'preserveActionOrder', - 'schema', - 'states', - 'strict', - 'tags', - 'target', // only when type=history - 'tsTypes', - 'type', -] -function isValidRootStateProperty(property) { - return validRootProperties.includes(property.key.name) +function isValidStateProperty(property, version) { + return ( + validRootProperties[version] && + validProperties[version].includes(property.key.name) + ) +} + +const validRootProperties = { + 4: [ + 'after', + 'context', + 'description', + 'entry', + 'exit', + 'history', // only when type=history + 'id', + 'initial', + 'invoke', + 'meta', + 'on', + 'predictableActionArguments', + 'preserveActionOrder', + 'schema', + 'states', + 'strict', + 'tags', + 'target', // only when type=history + 'tsTypes', + 'type', + ], + 5: [ + 'after', + 'context', + 'description', + 'entry', + 'exit', + 'history', // only when type=history + 'id', + 'initial', + 'invoke', + 'meta', + 'on', + 'states', + 'tags', + 'target', // only when type=history + 'types', + 'type', + ], +} +function isValidRootStateProperty(property, version) { + return ( + validRootProperties[version] && + validRootProperties[version].includes(property.key.name) + ) } function hasHistoryTypeProperty(node) { @@ -156,6 +205,7 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) return { [stateDeclaration]: function (node) { const isHistoryNode = hasHistoryTypeProperty(node) @@ -189,7 +239,7 @@ module.exports = { return } - if (!isValidStateProperty(prop)) { + if (!isValidStateProperty(prop, version)) { context.report({ node: prop, messageId: 'invalidStateProperty', @@ -230,7 +280,7 @@ module.exports = { return } - if (!isValidRootStateProperty(prop)) { + if (!isValidRootStateProperty(prop, version)) { context.report({ node: prop, messageId: 'invalidRootStateProperty', diff --git a/lib/utils/getSettings.js b/lib/utils/getSettings.js new file mode 100644 index 0000000..cb39ccb --- /dev/null +++ b/lib/utils/getSettings.js @@ -0,0 +1,19 @@ +'use strict' + +const defaults = { + version: 5 +} + +const supportedVersions = [4, 5] + +module.exports = function getSettings(context) { + const settings = { + ...defaults, + ...(context.settings ? context.settings.xstate : undefined) + } + + if (!supportedVersions.includes(settings.version)) { + throw new Error(`XState version "${settings.version}" is not supported. Check "settings.xstate.version" in your ESLint config.`) + } + return settings +} diff --git a/tests/lib/rules/no-invalid-state-props.js b/tests/lib/rules/no-invalid-state-props.js index 3991f90..badd072 100644 --- a/tests/lib/rules/no-invalid-state-props.js +++ b/tests/lib/rules/no-invalid-state-props.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-invalid-state-props') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ context: {}, // valid in the root node initial: 'idle', @@ -30,7 +33,8 @@ const tests = { on: {}, tags: ['off'], invoke: { src: 'someService' }, - description: 'this is an idle state' + description: 'this is an idle state', + activities: ['beeping'] }, busy: { type: 'compound', @@ -55,11 +59,61 @@ const tests = { }, }, }) - `, + ` + ), + withVersion( + 5, + ` + createMachine({ + context: {}, // valid in the root node + initial: 'idle', + description: 'This is my root node', + types: {}, + entry: 'log', + exit: 'log', + states: { + idle: { + type: 'parallel', + entry: 'log', + exit: 'log', + always: [], + after: {}, + states: {}, + onDone: {}, + on: {}, + tags: ['off'], + invoke: { src: 'someService' }, + description: 'this is an idle state' + }, + busy: { + type: 'compound', + initial: 'reading', + states: { + hist: { + type: 'history', + history: 'deep', + target: 'writing', + }, + reading: { + meta: { + value: 42, + }, + }, + writing: {}, + }, + }, + done: { + type: 'final', + output: {}, + }, + }, + }) + ` + ), ], invalid: [ // unrecognized prop names - { + withVersion(4, { code: ` createMachine({ intial: 'idle', @@ -75,9 +129,56 @@ const tests = { { messageId: 'invalidRootStateProperty', data: { propName: 'intial' } }, { messageId: 'invalidStateProperty', data: { propName: 'enter' } }, ], - }, + }), + // unrecognized prop names + withVersion(5, { + code: ` + createMachine({ + intial: 'idle', + strict: true, + preserveActionOrder: true, + predictableActionArguments: true, + schema: { + context: {}, + events: {}, + }, + tsTypes: {}, + states: { + idle: { + id: 'idle-state', + enter: 'log', + activities: ['beeping'], + }, + finished: { + type: 'final', + data: {}, + }, + }, + }) + `, + errors: [ + { messageId: 'invalidRootStateProperty', data: { propName: 'intial' } }, + { messageId: 'invalidRootStateProperty', data: { propName: 'strict' } }, + { + messageId: 'invalidRootStateProperty', + data: { propName: 'preserveActionOrder' }, + }, + { + messageId: 'invalidRootStateProperty', + data: { propName: 'predictableActionArguments' }, + }, + { messageId: 'invalidRootStateProperty', data: { propName: 'schema' } }, + { + messageId: 'invalidRootStateProperty', + data: { propName: 'tsTypes' }, + }, + { messageId: 'invalidStateProperty', data: { propName: 'enter' } }, + { messageId: 'invalidStateProperty', data: { propName: 'activities' } }, + { messageId: 'invalidStateProperty', data: { propName: 'data' } }, + ], + }), // certain props are valid only in specific contexts - { + withVersion(4, { code: ` createMachine({ initial: 'idle', @@ -108,9 +209,9 @@ const tests = { data: { propName: 'target' }, }, ], - }, + }), // some recognized props cannot be on the root node - { + withVersion(4, { code: ` createMachine({ onDone: 'idle', @@ -122,10 +223,10 @@ const tests = { errors: [ { messageId: 'invalidRootStateProperty', data: { propName: 'onDone' } }, ], - }, + }), // invalid type values // invalid history values - { + withVersion(4, { code: ` createMachine({ states: { @@ -147,7 +248,7 @@ const tests = { { messageId: 'invalidTypeValue', data: { value: 'done' } }, { messageId: 'invalidHistoryValue', data: { value: 'shallowish' } }, ], - }, + }), ], } From c9a2b9c821480fcd28731f4357dc960a5e5bc419 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Tue, 15 Aug 2023 12:46:16 +0200 Subject: [PATCH 03/43] feat(no-invalid-transition-props): support new transition props from xstate v5 Newly accepted props in transitions: guard, reenter. No longer valid props: cond, in, internal. --- lib/rules/no-invalid-transition-props.js | 31 +-- .../lib/rules/no-invalid-transition-props.js | 192 +++++++++++++++++- 2 files changed, 203 insertions(+), 20 deletions(-) diff --git a/lib/rules/no-invalid-transition-props.js b/lib/rules/no-invalid-transition-props.js index e3f8500..be10b3d 100644 --- a/lib/rules/no-invalid-transition-props.js +++ b/lib/rules/no-invalid-transition-props.js @@ -2,17 +2,18 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isObjectExpression, isArrayExpression } = require('../utils/predicates') +const getSettings = require('../utils/getSettings') -const validProperties = [ - 'target', - 'cond', - 'actions', - 'in', - 'internal', - 'description', -] -function isValidTransitionProperty(property) { - return validProperties.includes(property.key.name) +const validProperties = { + 4: ['target', 'cond', 'actions', 'in', 'internal', 'description'], + 5: ['target', 'guard', 'actions', 'reenter', 'description'], +} + +function isValidTransitionProperty(property, version) { + return ( + validProperties[version] && + validProperties[version].includes(property.key.name) + ) } // e.g. @@ -52,11 +53,12 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) function checkTransitionDeclaration(node) { const transitionValue = node.value if (isObjectExpression(transitionValue)) { transitionValue.properties.forEach((prop) => { - if (!isValidTransitionProperty(prop)) { + if (!isValidTransitionProperty(prop, version)) { context.report({ node: prop, messageId: 'invalidTransitionProperty', @@ -73,7 +75,7 @@ module.exports = { return } transitionObject.properties.forEach((prop) => { - if (!isValidTransitionProperty(prop)) { + if (!isValidTransitionProperty(prop, version)) { context.report({ node: prop, messageId: 'invalidTransitionProperty', @@ -91,7 +93,10 @@ module.exports = { return } transitionObject.properties.forEach((prop) => { - if (prop.key.name !== 'event' && !isValidTransitionProperty(prop)) { + if ( + prop.key.name !== 'event' && + !isValidTransitionProperty(prop, version) + ) { context.report({ node: prop, messageId: 'invalidTransitionProperty', diff --git a/tests/lib/rules/no-invalid-transition-props.js b/tests/lib/rules/no-invalid-transition-props.js index 5af906c..5c2dc04 100644 --- a/tests/lib/rules/no-invalid-transition-props.js +++ b/tests/lib/rules/no-invalid-transition-props.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-invalid-transition-props') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ states: { idle: { @@ -18,15 +21,57 @@ const tests = { }, }, }, + ready: { + on: [ + { event: "*", target: "elsewhere", internal: false }, + { event: "SOME_EVENT", target: "here", cond: () => true }, + ], + }, }, on: { EVENT: [{ + cond: () => true, target: 'active', }], }, }) - `, ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + idle: { + on: { + EVENT: { + guard: () => true, + target: 'active', + actions: [], + reenter: true, + description: 'some text', + }, + }, + }, + ready: { + on: [ + { event: "*", target: "elsewhere", reenter: true }, + { event: "SOME_EVENT", target: "here", guard: () => true }, + ], + }, + }, + on: { + EVENT: [{ + guard: () => true, + target: 'active', + }], + }, + }) + ` + ), + withVersion( + 4, + ` createMachine({ states: { idle: { @@ -55,10 +100,43 @@ const tests = { }, }, }) - `, + ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + idle: { + invoke: { + src: 'someService', + onDone: { + guard: () => true, + target: 'active', + actions: [], + reenter: true, + description: 'some text', + }, + onError: [ + { + guard: () => false, + target: 'failed', + description: 'some text', + }, + { + target: 'failed', + description: 'some text', + }, + ], + }, + }, + }, + }) + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { @@ -70,6 +148,12 @@ const tests = { }, }, }, + ready: { + on: [ + { event: "*", target: "elsewhere", beeep: '???' }, + { event: "SOME_EVENT", target: "here", guard: () => true }, + ], + }, }, on: { EVENT: [{ @@ -80,13 +164,99 @@ const tests = { `, errors: [ { messageId: 'invalidTransitionProperty', data: { propName: 'foo' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'beeep' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'guard' } }, { messageId: 'invalidTransitionProperty', data: { propName: 'invoke' }, }, ], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + idle: { + on: { + EVENT: { + target: 'active', + foo: '???', + cond: () => true, + in: 'otherState.ready', + internal: false, + }, + }, + }, + ready: { + on: [ + { event: "*", target: "elsewhere", internal: '???' }, + { event: "SOME_EVENT", target: "here", cond: () => true }, + ], + }, + }, + on: { + EVENT: [{ + invoke: '???', + }], + }, + }) + `, + errors: [ + { messageId: 'invalidTransitionProperty', data: { propName: 'foo' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'cond' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'in' } }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'internal' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'internal' }, + }, + { messageId: 'invalidTransitionProperty', data: { propName: 'cond' } }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'invoke' }, + }, + ], + }), + withVersion(4, { + code: ` + createMachine({ + states: { + idle: { + invoke: { + src: 'someService', + onDone: { + target: 'active', + always: '???', + }, + onError: [ + { + cond: () => false, + target: 'failed', + after: 1000, + }, + { + target: 'failed', + entry: '???', + }, + ], + }, + }, + }, + }) + `, + errors: [ + { + messageId: 'invalidTransitionProperty', + data: { propName: 'always' }, + }, + { messageId: 'invalidTransitionProperty', data: { propName: 'after' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'entry' } }, + ], + }), + withVersion(5, { code: ` createMachine({ states: { @@ -96,12 +266,14 @@ const tests = { onDone: { target: 'active', always: '???', + in: 'otherState.ready', }, onError: [ { cond: () => false, target: 'failed', after: 1000, + internal: false, }, { target: 'failed', @@ -118,10 +290,16 @@ const tests = { messageId: 'invalidTransitionProperty', data: { propName: 'always' }, }, + { messageId: 'invalidTransitionProperty', data: { propName: 'in' } }, + { messageId: 'invalidTransitionProperty', data: { propName: 'cond' } }, { messageId: 'invalidTransitionProperty', data: { propName: 'after' } }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'internal' }, + }, { messageId: 'invalidTransitionProperty', data: { propName: 'entry' } }, ], - }, + }), ], } From ffa717eb3b4d2dc7a80a847103d751cc70730fe0 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Tue, 15 Aug 2023 13:06:29 +0200 Subject: [PATCH 04/43] feat(no-auto-forward): report error if autoForward is found with XState v5 --- docs/rules/no-auto-forward.md | 4 ++- lib/index.js | 3 +- lib/rules/no-auto-forward.js | 18 ++++++++++++ tests/lib/rules/no-auto-forward.js | 47 +++++++++++++++++++++++++----- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/docs/rules/no-auto-forward.md b/docs/rules/no-auto-forward.md index b1161c0..58b2985 100644 --- a/docs/rules/no-auto-forward.md +++ b/docs/rules/no-auto-forward.md @@ -6,6 +6,8 @@ Prefer sending events explicitly to child actors/services. Avoid blindly forwarding all events to invoked services or spawned actors - it may lead to unexpected behavior or infinite loops. The official documentation [suggests sending events explicitly](https://xstate.js.org/docs/guides/communication.html#the-invoke-property) with the [`forwardTo`](https://xstate.js.org/docs/guides/actions.html#forward-to-action) or `send` action creators. +**XState v5 removed the `autoForward` option. This rule will report errors if `autoForward` is used with XState v5.** + Examples of **incorrect** code for this rule: ```javascript @@ -33,7 +35,7 @@ createMachine({ }) ``` -Examples of **correct** code for this rule: +Examples of **correct** code for this rule (XState v4 only): ```javascript // ✅ no auto-forward diff --git a/lib/index.js b/lib/index.js index 3ccca74..9f19d11 100644 --- a/lib/index.js +++ b/lib/index.js @@ -50,6 +50,7 @@ module.exports = { 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', 'xstate/no-async-guard': 'error', + 'xstate/no-auto-forward': 'error', }, }, // Requires: xstate@5 @@ -70,7 +71,7 @@ module.exports = { 'xstate/event-names': ['warn', 'macroCase'], 'xstate/state-names': ['warn', 'camelCase'], 'xstate/no-inline-implementation': 'warn', - 'xstate/no-auto-forward': 'warn', + 'xstate/no-auto-forward': 'error', 'xstate/prefer-always': 'error', 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', diff --git a/lib/rules/no-auto-forward.js b/lib/rules/no-auto-forward.js index c594971..a2ba7cb 100644 --- a/lib/rules/no-auto-forward.js +++ b/lib/rules/no-auto-forward.js @@ -1,6 +1,7 @@ 'use strict' const getDocsUrl = require('../utils/getDocsUrl') +const getSettings = require('../utils/getSettings') module.exports = { meta: { @@ -15,13 +16,23 @@ module.exports = { messages: { noAutoForward: 'Forwarding all events may lead to unexpected behavior and/or infinite loops. Prefer using `forwardTo` action creator to send events explicitly.', + autoForwardDeprecated: + 'The autoForward option has been removed in v5. Use `forwardTo` action creator to send events explicitly.', }, }, create: function (context) { + const { version } = getSettings(context) return { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="invoke"] > ObjectExpression > Property[key.name="autoForward"]': function (node) { + if (version !== 4) { + context.report({ + node, + messageId: 'autoForwardDeprecated', + }) + return + } if (node.value.value === true) { context.report({ node, @@ -32,6 +43,13 @@ module.exports = { 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="spawn"] > ObjectExpression > Property[key.name="autoForward"]': function (node) { + if (version !== 4) { + context.report({ + node, + messageId: 'autoForwardDeprecated', + }) + return + } if (node.value.value === true) { context.report({ node, diff --git a/tests/lib/rules/no-auto-forward.js b/tests/lib/rules/no-auto-forward.js index 9eacebb..4a21ee0 100644 --- a/tests/lib/rules/no-auto-forward.js +++ b/tests/lib/rules/no-auto-forward.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-auto-forward') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ states: { playing: { @@ -14,7 +17,7 @@ const tests = { }, }) `, - ` + ` createMachine({ states: { initializing: { @@ -24,10 +27,11 @@ const tests = { }, }, }) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { @@ -41,8 +45,23 @@ const tests = { }) `, errors: [{ messageId: 'noAutoForward' }], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + playing: { + invoke: { + src: 'game', + autoForward: true, + }, + }, + }, + }) + `, + errors: [{ messageId: 'autoForwardDeprecated' }], + }), + withVersion(4, { code: ` createMachine({ states: { @@ -55,7 +74,21 @@ const tests = { }) `, errors: [{ messageId: 'noAutoForward' }], - }, + }), + withVersion(5, { + code: ` + createMachine({ + states: { + initializing: { + entry: assign({ + gameRef: () => spawn(game, { autoForward: true }), + }), + }, + }, + }) + `, + errors: [{ messageId: 'autoForwardDeprecated' }], + }), ], } From 6043ff33bf17ce9ca31dd1646dd8e94bd72dff11 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Tue, 15 Aug 2023 13:16:36 +0200 Subject: [PATCH 05/43] docs(no-invalid-state-props): add docs about new state node props in xstate v5 --- docs/rules/no-invalid-state-props.md | 70 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-invalid-state-props.md b/docs/rules/no-invalid-state-props.md index 9ea7c32..c0b6249 100644 --- a/docs/rules/no-invalid-state-props.md +++ b/docs/rules/no-invalid-state-props.md @@ -18,6 +18,20 @@ Certain properties accept specific values only: - `type` can be one of: "atomic", "compound", "parallel", "history", "final". - `history` can be one of: "shallow", "deep". +### XState v5 + +In XState v5 some props are no longer valid on state nodes: + +- `activities` +- `data`: removed in favor of a new prop `output` +- `strict` +- `schema`: removed in favor of a new prop `types` +- `tsTypes`: removed in favor of a new prop `types` +- `preserveActionOrder` +- `predictableActionArguments` + +If the above props are used with XState v5, this rule will report an error. + Examples of **incorrect** code for this rule: ```javascript @@ -71,13 +85,61 @@ createMachine({ Examples of **correct** code for this rule: ```javascript -// ✅ all state props are valid +// ✅ all state props are valid (XState v4) createMachine({ id: 'root', + strict: true, description: 'this is the main machine', predictableActionArguments: true, + preserveActionOrder: true, + tsTypes: {}, + schema: {}, + context: {}, // valid in the root node + initial: 'idle', + states: { + idle: { + type: 'parallel', + entry: 'log', + exit: 'log', + always: [], + after: {}, + states: {}, + onDone: {}, + on: {}, + tags: ['off'], + activities: ['beeping'], + }, + busy: { + type: 'compound', + initial: 'reading', + states: { + hist: { + type: 'history', + history: 'deep', + target: 'writing', + }, + reading: { + meta: { + value: 42, + }, + }, + writing: {}, + }, + }, + done: { + type: 'final', + data: { answer: 42 }, + }, + }, +}) + +// ✅ all state props are valid (XState v5) +createMachine({ + id: 'root', + types: {}, + description: 'this is the main machine', context: {}, // valid in the root node - initial: 'idle' + initial: 'idle', states: { idle: { type: 'parallel', @@ -107,6 +169,10 @@ createMachine({ writing: {}, }, }, + done: { + type: 'final', + output: { answer: 42 }, + }, }, }) ``` From 5440a0d7b22d51ead46ba84a5df25dd19f3fad44 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Tue, 15 Aug 2023 14:50:15 +0200 Subject: [PATCH 06/43] docs(no-invalid-transition-props): update docs about new transition props in xstate v5 --- docs/rules/no-invalid-transition-props.md | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-invalid-transition-props.md b/docs/rules/no-invalid-transition-props.md index 647d608..4f05f97 100644 --- a/docs/rules/no-invalid-transition-props.md +++ b/docs/rules/no-invalid-transition-props.md @@ -6,6 +6,14 @@ Forbid unrecognized properties in `on`, `onDone` and `onError` transition declar Transition declarations should not contain properties which are not recognized by XState. +### XState v5 + +In XState v5, the following transition properties are no longer valid: + +- `cond`: removed in favor of `guard` +- `in`: removed in favor of the `stateIn` guard +- `internal`: removed in favor of `reenter` + Examples of **incorrect** code for this rule: ```javascript @@ -61,7 +69,7 @@ createMachine({ Examples of **correct** code for this rule: ```javascript -// ✅ only recognized properties inside transitions +// ✅ only recognized properties inside transitions (XState v4) createMachine({ states: { idle: { @@ -78,6 +86,28 @@ createMachine({ }, }, }) + +// ✅ only recognized properties inside transitions (XState v5) +createMachine({ + states: { + idle: { + on: { + EVENT: { + guard: () => true, + target: 'active', + actions: [], + reenter: true, + description: 'some text', + }, + OTHER_EVENT: { + // "stateIn" instead of the "in" guard + guard: stateIn('otherState.ready'), + target: 'active', + }, + }, + }, + }, +}) ``` ## Further Reading From bee4ad56bb1b15fe5cb82422882fa4805410a29e Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 08:07:03 +0200 Subject: [PATCH 07/43] feat(no-inline-implementation): allow built-in higher level guards with xstate v5 Parse "guard" as the guard declaration in xstate v5. Always allow the built-in higher level guards to be inlined. Change the option "serviceCreatorRegex" to "actorCreatorRegex". BREAKING CHANGE: Option "serviceCreatorRegex" has been renamed to "actorCreatorRegex". --- docs/rules/no-inline-implementation.md | 48 ++- lib/rules/no-inline-implementation.js | 114 ++++-- lib/utils/predicates.js | 47 ++- tests/lib/rules/no-inline-implementation.js | 380 ++++++++++++++++++-- 4 files changed, 498 insertions(+), 91 deletions(-) diff --git a/docs/rules/no-inline-implementation.md b/docs/rules/no-inline-implementation.md index b13b992..8e1b480 100644 --- a/docs/rules/no-inline-implementation.md +++ b/docs/rules/no-inline-implementation.md @@ -7,6 +7,16 @@ Suggest moving implementations of actions, guards, activities and services into Action/guard/activity/service implementation can be quickly prototyped by specifying inline functions directly in the machine config. Although this is convenient, this makes it difficult to debug, test, serialize and accurately visualize actions. It is recommended to refactor inline implementations into the machine options object. +### XState v5 + +In XState v5 some built-in action creators were removed, so this rule will report an error when they are inlined: +- `respond` +- `send`: removed in favor of `raise` and `sendParent` +- `sendUpdate` +- `start` + +XState v5 provides some built-in higher level guards: `and`, `or`, `not`, `stateIn`. These are always fine to use. + Examples of **incorrect** code for this rule: ```javascript @@ -104,13 +114,13 @@ createMachine({ }) // ✅ inlined guard creator calls are ok if they match guardCreatorRegex -/* eslint no-inline-implementation: [ "warn", { "guardCreatorRegex": "^(and|or|not)$" } ] */ +/* eslint no-inline-implementation: [ "warn", { "guardCreatorRegex": "^customGuard$" } ] */ createMachine({ states: { inactive: { on: { BUTTON_CLICKED: { - cond: and(['isStartButton', 'isReady']) + cond: customGuard(['isStartButton', 'isReady']), target: 'active' } } @@ -118,14 +128,34 @@ createMachine({ } }) -// ✅ inlined guard creator calls are ok if they match actionCreatorRegex +// ✅ inlined built-in guards are ok with XState v5 +createMachine({ + states: { + inactive: { + on: { + BUTTON_CLICKED: [ + { + guard: and(['isStartButton', 'isDoubleClick']), + target: 'active' + }, + { + guard: stateIn('mode.active'), + target: 'inactive' + }, + ] + } + } + } +}) + +// ✅ inlined action creator calls are ok if they match actionCreatorRegex /* eslint no-inline-implementation: [ "warn", { "actionCreatorRegex": "^customAction$" } ] */ createMachine({ states: { inactive: { on: { BUTTON_CLICKED: { - target: 'active' + target: 'active', actions: customAction(), } } @@ -133,13 +163,13 @@ createMachine({ } }) -// ✅ inlined service creator calls are ok if they match serviceCreatorRegex -/* eslint no-inline-implementation: [ "warn", { "serviceCreatorRegex": "^customService$" } ] */ +// ✅ inlined actor creator calls are ok if they match actorCreatorRegex +/* eslint no-inline-implementation: [ "warn", { "actorCreatorRegex": "^customActor" } ] */ createMachine({ states: { inactive: { invoke: { - src: createService() + src: customActor() } } } @@ -153,7 +183,7 @@ createMachine({ | `allowKnownActionCreators` | No | `false` | Inlined action creators are visualized properly (but still difficult to test, debug and serialize). Setting this option to `true` will turn off the rule for [known action creators](https://xstate.js.org/docs/guides/actions.html) used inline. | | `guardCreatorRegex` | No | `''` | Use a regular expression to allow custom guard creators. | | `actionCreatorRegex` | No | `''` | Use a regular expression to allow custom action creators. | -| `serviceCreatorRegex` | No | `''` | Use a regular expression to allow custom service creators. | +| `actorCreatorRegex` | No | `''` | Use a regular expression to allow custom actor creators. | ## Example @@ -182,7 +212,7 @@ createMachine({ { "xstate/no-inline-implementation": [ "warn", - { "serviceCreatorRegex": "^customService$" } + { "actorCreatorRegex": "^customActor$" } ] } ``` diff --git a/lib/rules/no-inline-implementation.js b/lib/rules/no-inline-implementation.js index e057e04..63532a7 100644 --- a/lib/rules/no-inline-implementation.js +++ b/lib/rules/no-inline-implementation.js @@ -12,6 +12,7 @@ const { } = require('../utils/predicates') const { getTypeProperty } = require('../utils/selectors') const { anyPass } = require('../utils/combinators') +const getSettings = require('../utils/getSettings') function isArrayWithFunctionExpressionOrIdentifier(node) { return ( @@ -20,20 +21,25 @@ function isArrayWithFunctionExpressionOrIdentifier(node) { ) } -function isInlineAction(node, allowKnownActionCreators, actionCreatorRegex) { +function isInlineAction( + node, + allowKnownActionCreators, + actionCreatorRegex, + version +) { return ( isFunctionExpression(node) || isIdentifier(node) || (isCallExpression(node) && !( - (allowKnownActionCreators && isKnownActionCreatorCall(node)) || + (allowKnownActionCreators && isKnownActionCreatorCall(node, version)) || isValidCallExpression(node, actionCreatorRegex) )) ) } function isValidCallExpression(node, pattern = '') { - if (pattern === '') { + if (pattern === '' || node.callee.type !== 'Identifier') { return false } return new RegExp(pattern).test(node.callee.name) @@ -81,7 +87,22 @@ const defaultOptions = { allowKnownActionCreators: false, actionCreatorRegex: '', guardCreatorRegex: '', - serviceCreatorRegex: '', + actorCreatorRegex: '', +} + +const guardPropName = { + 4: 'cond', + 5: 'guard', +} + +const knownGuards = ['and', 'or', 'not', 'stateIn'] + +function isKnownGuard(node) { + return ( + node.type === 'CallExpression' && + node.callee.type === 'Identifier' && + knownGuards.includes(node.callee.name) + ) } module.exports = { @@ -112,10 +133,10 @@ module.exports = { format: 'regex', default: defaultOptions.guardCreatorRegex, }, - serviceCreatorRegex: { + actorCreatorRegex: { type: 'string', format: 'regex', - default: defaultOptions.serviceCreatorRegex, + default: defaultOptions.actorCreatorRegex, }, }, additionalProperties: false, @@ -128,26 +149,24 @@ module.exports = { 'Move the action implementation into machine options and refer it by its name here.', moveActivityToOptions: 'Move the activity implementation into machine options and refer it by its name here.', - moveServiceToOptions: - 'Move the service implementation into machine options and refer it by its name here.', + moveActorToOptions: + 'Move the actor implementation into machine options and refer it by its name here.', }, }, create: function (context) { + const { version } = getSettings(context) const options = context.options[0] || defaultOptions - function checkServiceSrc(node) { + + // TODO also check what is passed to spawn + function checkActorSrc(node) { + if (isStringLiteral(node.value)) { + return + } if ( - !isStringLiteral(node.value) && - !isObjectExpression(node.value) && - !( - isCallExpression(node.value) && - isValidCallExpression(node.value, options.serviceCreatorRegex) - ) + isCallExpression(node.value) && + isValidCallExpression(node.value, options.actorCreatorRegex) ) { - context.report({ - node, - messageId: 'moveServiceToOptions', - }) return } if (node.value.type === 'ObjectExpression') { @@ -155,26 +174,40 @@ module.exports = { if (typeProperty && !isStringLiteral(typeProperty.value)) { context.report({ node: typeProperty, - messageId: 'moveServiceToOptions', + messageId: 'moveActorToOptions', }) } } + + context.report({ + node, + messageId: 'moveActorToOptions', + }) } function checkTransitionProperty(node) { - if (node.key.name === 'cond') { + if (node.key.name === guardPropName[version]) { + if (isStringLiteral(node.value)) { + return + } if ( - isFunctionExpression(node.value) || - isIdentifier(node.value) || - (isCallExpression(node.value) && - !isValidCallExpression(node.value, options.guardCreatorRegex)) + version >= 5 && + isCallExpression(node.value) && + isKnownGuard(node.value) + ) { + return + } + if ( + isCallExpression(node.value) && + isValidCallExpression(node.value, options.guardCreatorRegex) ) { - context.report({ - node, - messageId: 'moveGuardToOptions', - }) return } + context.report({ + node, + messageId: 'moveGuardToOptions', + }) + return } if (node.key.name === 'actions') { @@ -182,20 +215,24 @@ module.exports = { isInlineAction( node.value, options.allowKnownActionCreators, - options.actionCreatorRegex + options.actionCreatorRegex, + version ) ) { context.report({ node, messageId: 'moveActionToOptions', }) - } else if (isArrayExpression(node.value)) { + return + } + if (isArrayExpression(node.value)) { node.value.elements.forEach((element) => { if ( isInlineAction( element, options.allowKnownActionCreators, - options.actionCreatorRegex + options.actionCreatorRegex, + version ) ) { context.report({ @@ -217,14 +254,13 @@ module.exports = { [propertyOfChoosableActionObject]: checkTransitionProperty, [propertyOfChoosableActionObjectAlt]: checkTransitionProperty, - // TODO deprecated in xstate v5 [activitiesProperty]: function (node) { if ( isFunctionExpression(node.value) || isIdentifier(node.value) || isArrayWithFunctionExpressionOrIdentifier(node.value) || (isCallExpression(node.value) && - !isValidCallExpression(node.value, options.serviceCreatorRegex)) + !isValidCallExpression(node.value, options.actorCreatorRegex)) ) { context.report({ node, @@ -233,16 +269,17 @@ module.exports = { } }, - [srcPropertyInsideInvoke]: checkServiceSrc, + [srcPropertyInsideInvoke]: checkActorSrc, - [srcPropertyInsideInvokeArray]: checkServiceSrc, + [srcPropertyInsideInvokeArray]: checkActorSrc, [entryExitProperty]: function (node) { if ( isInlineAction( node.value, options.allowKnownActionCreators, - options.actionCreatorRegex + options.actionCreatorRegex, + version ) ) { context.report({ @@ -255,7 +292,8 @@ module.exports = { isInlineAction( element, options.allowKnownActionCreators, - options.actionCreatorRegex + options.actionCreatorRegex, + version ) ) { context.report({ diff --git a/lib/utils/predicates.js b/lib/utils/predicates.js index 6229556..95d052d 100644 --- a/lib/utils/predicates.js +++ b/lib/utils/predicates.js @@ -72,34 +72,57 @@ function isObjectExpression(node) { return node.type === 'ObjectExpression' } -function isKnownActionCreatorName(name) { - return [ +const actionCreators = { + 4: [ 'assign', 'cancel', + 'choose', + 'done', + 'doneInvoke', + 'error', + 'escalate', + 'forwardTo', + 'log', + 'pure', + 'raise', + 'respond', 'send', 'sendParent', 'sendTo', + 'sendUpdate', + 'start', + 'stop', + ], + 5: [ + 'assign', + 'cancel', + 'choose', + 'done', + 'doneInvoke', + 'error', + 'escalate', 'forwardTo', - 'respond', - 'raise', 'log', - 'choose', 'pure', - 'escalate', - 'sendUpdate', - 'start', + 'raise', + 'sendParent', + 'sendTo', 'stop', - ].includes(name) + ], +} + +function isKnownActionCreatorName(name, version) { + return actionCreators[version] && actionCreators[version].includes(name) } -function isKnownActionCreatorCall(node) { +function isKnownActionCreatorCall(node, version) { return ( (node.type === 'CallExpression' && - isKnownActionCreatorName(node.callee.name)) || + isKnownActionCreatorName(node.callee.name, version)) || (node.type === 'CallExpression' && node.callee.type === 'MemberExpression' && node.callee.object.name === 'actions' && - isKnownActionCreatorName(node.callee.property.name)) + isKnownActionCreatorName(node.callee.property.name, version)) ) } diff --git a/tests/lib/rules/no-inline-implementation.js b/tests/lib/rules/no-inline-implementation.js index 86082b4..c77ece0 100644 --- a/tests/lib/rules/no-inline-implementation.js +++ b/tests/lib/rules/no-inline-implementation.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-inline-implementation') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ states: { active: { @@ -22,9 +25,34 @@ const tests = { }, }, }) - `, - // inlined action creators are ok with allowKnownActionCreators=true ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + active: { + invoke: { + src: 'myService', + }, + entry: 'myAction', + on: { + OFF: { + guard: 'myGuard', + target: 'inactive', + actions: ['myAction1', 'myAction2'], + }, + }, + }, + }, + }) + ` + ), + // inlined action creators are ok with allowKnownActionCreators=true + withVersion( + 4, + ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ createMachine({ states: { @@ -38,9 +66,61 @@ const tests = { }, }, }) - `, + ` + ), + withVersion( + 5, + ` + /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + createMachine({ + states: { + active: { + entry: assign(), + on: { + OFF: { + actions: [sendParent('EVENT'), assign()], + }, + }, + }, + }, + }) + ` + ), // onDone, onError, array of transitions + withVersion( + 4, + ` + createMachine({ + states: { + active: { + invoke: { + src: 'myService', + onDone: { + cond: 'myGuard', + actions: 'myAction1', + }, + onError: { + cond: 'myGuard', + actions: ['myAction1', 'myAction2'], + }, + }, + on: { + OFF: [ + { + cond: 'myGuard', + target: 'inactive', + actions: ['myAction1', 'myAction2'], + }, + ], + }, + }, + }, + }) ` + ), + withVersion( + 5, + ` createMachine({ states: { active: { @@ -67,9 +147,12 @@ const tests = { }, }, }) - `, - // inlined guard creators are ok if they match guardCreatorRegex ` + ), + // inlined guard creators are ok if they match guardCreatorRegex + withVersion( + 4, + ` /* eslint no-inline-implementation: [ "warn", { "guardCreatorRegex": "and|or|not" } ] */ createMachine({ states: { @@ -83,9 +166,81 @@ const tests = { }, }, }) - `, + ` + ), + // inlined guard creators are ok if they match guardCreatorRegex + withVersion( + 5, + ` + /* eslint no-inline-implementation: [ "warn", { "guardCreatorRegex": "^createGuard$" } ] */ + createMachine({ + states: { + active: { + on: { + OFF: { + guard: createGuard('param'), + target: 'inactive', + }, + }, + }, + }, + }) + ` + ), + // built in higher level guards are valid with xstate v5 + withVersion( + 5, + ` + createMachine({ + states: { + active: { + on: { + OFF: [ + { + guard: and(['guard1', 'guard2']), + target: 'inactive', + }, + { + guard: or(['guard1', 'guard2']), + target: 'active', + }, + { + guard: not('guard1'), + target: 'hibernating', + }, + { + guard: stateIn('mode.active'), + target: 'hibernating', + }, + ], + }, + }, + }, + }) + ` + ), // inlined action creators are ok if they match actionCreatorRegex + withVersion( + 4, + ` + /* eslint no-inline-implementation: [ "warn", { "actionCreatorRegex": "^customAction$" } ] */ + createMachine({ + states: { + active: { + on: { + OFF: { + target: 'inactive', + actions: customAction(), + }, + }, + }, + }, + }) ` + ), + withVersion( + 5, + ` /* eslint no-inline-implementation: [ "warn", { "actionCreatorRegex": "^customAction$" } ] */ createMachine({ states: { @@ -99,24 +254,43 @@ const tests = { }, }, }) - `, - // inlined service creators are ok if they match serviceCreatorRegex ` - /* eslint no-inline-implementation: [ "warn", { "serviceCreatorRegex": "^customService$" } ] */ + ), + // inlined service creators are ok if they match actorCreatorRegex + withVersion( + 4, + ` + /* eslint no-inline-implementation: [ "warn", { "actorCreatorRegex": "^createChildMachine|createBeeper$" } ] */ + createMachine({ + states: { + active: { + invoke: { + src: createChildMachine(), + }, + activities: createBeeper(), + }, + }, + }) + ` + ), + withVersion( + 5, + ` + /* eslint no-inline-implementation: [ "warn", { "actorCreatorRegex": "^createChildMachine$" } ] */ createMachine({ states: { active: { invoke: { - src: customService(), + src: createChildMachine(), }, - activities: customService(), }, }, }) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { @@ -138,14 +312,41 @@ const tests = { }) `, errors: [ - { messageId: 'moveServiceToOptions' }, + { messageId: 'moveActorToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveGuardToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveActivityToOptions' }, ], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + invoke: { + src: () => {}, + }, + entry: () => {}, + on: { + OFF: { + guard: () => {}, + target: 'inactive', + actions: () => {}, + }, + }, + }, + }, + }) + `, + errors: [ + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + ], + }), + withVersion(4, { code: ` createMachine({ states: { @@ -167,29 +368,70 @@ const tests = { }) `, errors: [ - { messageId: 'moveServiceToOptions' }, + { messageId: 'moveActorToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveGuardToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveActivityToOptions' }, ], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + invoke: { + src: myService, + }, + entry: myAction, + on: { + OFF: { + guard: myGuard, + target: 'inactive', + actions: myAction, + }, + }, + }, + }, + }) + `, + errors: [ + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + ], + }), + withVersion(4, { code: ` createMachine({ invoke: [ { src: () => {} }, - { src: myService }, + { src: myActor }, ] }) `, errors: [ - { messageId: 'moveServiceToOptions' }, - { messageId: 'moveServiceToOptions' }, + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActorToOptions' }, ], - }, + }), + withVersion(5, { + code: ` + createMachine({ + invoke: [ + { src: () => {} }, + { src: myActor }, + ] + }) + `, + errors: [ + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActorToOptions' }, + ], + }), // actions arrays with some valid, some invalid items - { + withVersion(4, { code: ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ createMachine({ @@ -212,9 +454,31 @@ const tests = { { messageId: 'moveActionToOptions' }, { messageId: 'moveActivityToOptions' }, ], - }, + }), + withVersion(5, { + code: ` + /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + createMachine({ + states: { + active: { + entry: ['someAction', assign(), () => {}], + on: { + OFF: { + actions: ['someAction', someAction, () => {}, sendTo()], + }, + }, + }, + }, + }) + `, + errors: [ + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, + ], + }), // inline implementations inside array of transitions - { + withVersion(4, { code: ` createMachine({ states: { @@ -223,7 +487,7 @@ const tests = { OFF: [{ cond: () => {}, target: 'inactive', - actions: [someAction, () => {}], + actions: [someAction, () => {}, foo()], }], }, }, @@ -234,10 +498,34 @@ const tests = { { messageId: 'moveGuardToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, ], - }, + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + on: { + OFF: [{ + guard: () => {}, + target: 'inactive', + actions: [someAction, () => {}, foo()], + }], + }, + }, + }, + }) + `, + errors: [ + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, + ], + }), // inline implementations inside onDone, onError transitions - { + withVersion(4, { code: ` createMachine({ states: { @@ -249,7 +537,35 @@ const tests = { actions: () => {}, }, onError: { - cond: () => {}, + cond: foo(), + actions: [myAction, () => {}], + }, + }, + }, + }, + }) + `, + errors: [ + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActionToOptions' }, + ], + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + invoke: { + src: 'myService', + onDone: { + guard: myGuard, + actions: () => {}, + }, + onError: { + guard: foo(), actions: [myAction, () => {}], }, }, @@ -264,7 +580,7 @@ const tests = { { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, ], - }, + }), ], } From 9654443d4cc71ecb8805a3b6f7b2d4501ffed87f Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 10:55:55 +0200 Subject: [PATCH 08/43] feat(no-inline-implementation): detect inline implementation inside spawn calls with xstate v4 Also prevent false positives on inline implementations within the second argument to createMachine. --- docs/rules/no-inline-implementation.md | 25 ++- lib/rules/no-inline-implementation.js | 26 ++- lib/rules/spawn-usage.js | 122 +----------- lib/utils/XStateDetector.js | 111 +++++++++++ tests/lib/rules/no-inline-implementation.js | 207 +++++++++++++++----- 5 files changed, 324 insertions(+), 167 deletions(-) create mode 100644 lib/utils/XStateDetector.js diff --git a/docs/rules/no-inline-implementation.md b/docs/rules/no-inline-implementation.md index 8e1b480..27279f2 100644 --- a/docs/rules/no-inline-implementation.md +++ b/docs/rules/no-inline-implementation.md @@ -34,7 +34,12 @@ createMachine({ actions: () => {} // inlined action } }, - activities: () => {} // inlined activity + activities: () => {}, // inlined activity + entry: assign({ + childActor: () => spawn( + () => {}, // inlined actor + ) + }), } } }) @@ -53,7 +58,12 @@ createMachine({ actions: huffAndPuff // defined elsewhere } }, - activities: beep // defined elsewhere + activities: beep, // defined elsewhere + entry: assign({ + childActor: () => spawn( + childMachine, // inlined actor + ) + }), } } }) @@ -77,11 +87,17 @@ createMachine( actions: ['huffAndPuff', 'log'] // arrays are ok too } }, - activities: 'beep' + activities: 'beep', + entry: assign({ + childActor: () => spawn( + 'childMachine', + ) + }), } } }, { + // "services" in XState v4, renamed to "actors" in XState v5 services: { someMachine: () => {} }, @@ -92,6 +108,7 @@ createMachine( huffAndPuff: () => {}, log: () => {} }, + // only in XState v4 activities: { beep: () => {} } @@ -106,7 +123,7 @@ createMachine({ entry: assign({ count: 1 }), on: { TRIGGER: { - actions: [assign({ count: 0 }), send('EVENT')] // arrays are ok too + actions: [assign({ count: 0 }), raise({ type: 'EVENT' })] // arrays are ok too } } } diff --git a/lib/rules/no-inline-implementation.js b/lib/rules/no-inline-implementation.js index 63532a7..d159860 100644 --- a/lib/rules/no-inline-implementation.js +++ b/lib/rules/no-inline-implementation.js @@ -6,13 +6,13 @@ const { isIdentifier, isStringLiteral, isCallExpression, - isObjectExpression, isKnownActionCreatorCall, isArrayExpression, } = require('../utils/predicates') const { getTypeProperty } = require('../utils/selectors') const { anyPass } = require('../utils/combinators') const getSettings = require('../utils/getSettings') +const XStateDetector = require('../utils/XStateDetector') function isArrayWithFunctionExpressionOrIdentifier(node) { return ( @@ -78,10 +78,10 @@ const activitiesProperty = 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="activities"]' const propertyOfChoosableActionObject = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' + 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' const propertyOfChoosableActionObjectAlt = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property' + 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property' const defaultOptions = { allowKnownActionCreators: false, @@ -110,7 +110,7 @@ module.exports = { type: 'suggestion', docs: { description: - 'Suggest refactoring actions, guards, services, activities into options', + 'Suggest refactoring actions, guards, actors, activities into options', category: 'Best Practices', url: getDocsUrl('no-inline-implementation'), recommended: 'warn', @@ -158,7 +158,8 @@ module.exports = { const { version } = getSettings(context) const options = context.options[0] || defaultOptions - // TODO also check what is passed to spawn + const xstateDetector = new XStateDetector() + function checkActorSrc(node) { if (isStringLiteral(node.value)) { return @@ -246,6 +247,7 @@ module.exports = { } return { + ...xstateDetector.visitors, [propertyOfEventTransition]: checkTransitionProperty, [propertyOfEventTransitionInArray]: checkTransitionProperty, [propertyOfAltEventTransitionInArray]: checkTransitionProperty, @@ -304,6 +306,20 @@ module.exports = { }) } }, + + 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression': + function (node) { + if (!xstateDetector.isSpawnCallExpression(node)) { + return + } + + if (node.arguments[0] && !isStringLiteral(node.arguments[0])) { + context.report({ + node: node.arguments[0], + messageId: 'moveActorToOptions', + }) + } + }, } }, } diff --git a/lib/rules/spawn-usage.js b/lib/rules/spawn-usage.js index 0e70df8..697b6fd 100644 --- a/lib/rules/spawn-usage.js +++ b/lib/rules/spawn-usage.js @@ -1,8 +1,8 @@ 'use strict' const getDocsUrl = require('../utils/getDocsUrl') - const { isFunctionExpression, isIIFE } = require('../utils/predicates') +const XStateDetector = require('../utils/XStateDetector') function isAssignCall(node) { return node.type === 'CallExpression' && node.callee.name === 'assign' @@ -54,124 +54,22 @@ module.exports = { }, create: function (context) { - // This will remain empty unless spawn is imported from the XState library - const spawnIdentifiers = [] - // This may get populated if the whole xstate module is imported - let xstateIdentifier = null - - function captureSpawnIdentifierFromXStateMemberExpression(node) { - if ( - xstateIdentifier != null && - node.init.object.name === xstateIdentifier - ) { - spawnIdentifiers.push(node.id.name) - } - } + const xstateDetector = new XStateDetector() return { - 'ImportDeclaration[source.value="xstate"]': function (node) { - const importSpecifier = node.specifiers.find( - (s) => s.type === 'ImportSpecifier' && s.imported.name === 'spawn' - ) - if (importSpecifier) { - spawnIdentifiers.push(importSpecifier.local.name) - return - } - const importDefaultSpecifier = node.specifiers.find( - (s) => s.type === 'ImportDefaultSpecifier' - ) - if (importDefaultSpecifier) { - xstateIdentifier = importDefaultSpecifier.local.name - return - } - const importNamespaceSpecifier = node.specifiers.find( - (s) => s.type === 'ImportNamespaceSpecifier' - ) - if (importNamespaceSpecifier) { - xstateIdentifier = importNamespaceSpecifier.local.name - } - }, - // commonjs imports - // const { spawn } = require('xstate') - // const { spawn: xspawn } = require('xstate') - // const xstate = require('xstate') - 'VariableDeclarator[init.callee.name="require"][init.arguments.0.value="xstate"]': - function (node) { - if (xstateIdentifier !== null || spawnIdentifiers.length > 0) { - return - } - if (node.id.type === 'ObjectPattern') { - const spawnProperty = node.id.properties.find( - (p) => p.key.name === 'spawn' - ) - if (spawnProperty) { - spawnIdentifiers.push(spawnProperty.value.name) - } - return - } - if (node.id.type === 'Identifier') { - xstateIdentifier = node.id.name - } - }, - // const spawn = require('xstate').spawn - // const spawn = require('xstate')['spawn'] - 'VariableDeclarator[init.object.callee.name="require"][init.object.arguments.0.value="xstate"]': - function (node) { - if ( - node.init.property.name === 'spawn' || - node.init.property.value === 'spawn' - ) { - spawnIdentifiers.push(node.id.name) - } - }, - // const { spawn } = xstate - // Ignores it if the xstateIdentifier has not been previously resolved - 'VariableDeclarator[id.type="ObjectPattern"] > ObjectPattern > Property[key.name="spawn"]': - function (node) { - const varDeclarator = node.parent.parent - if ( - xstateIdentifier != null && - xstateIdentifier === varDeclarator.init.name - ) { - spawnIdentifiers.push(node.value.name) - } - }, - // const spawn = xstate.spawn - // const spawn = xstate['spawn'] - 'VariableDeclarator[init.type="MemberExpression"][init.property.name="spawn"]': - captureSpawnIdentifierFromXStateMemberExpression, - 'VariableDeclarator[init.type="MemberExpression"][init.property.value="spawn"]': - captureSpawnIdentifierFromXStateMemberExpression, + ...xstateDetector.visitors, + // Ignores it if the spawnIdentifier has not been previously resolved to "spawn" (imported from xstate) CallExpression: function (node) { - if (spawnIdentifiers.length < 1 && xstateIdentifier == null) { + if (!xstateDetector.isSpawnCallExpression(node)) { return } - if ( - node.callee.type === 'Identifier' && - spawnIdentifiers.includes(node.callee.name) - ) { - if (!isInsideAssignerFunction(node)) { - context.report({ - node, - messageId: 'invalidCallContext', - }) - } - return - } - if ( - node.callee.type === 'MemberExpression' && - node.callee.object.name === xstateIdentifier && - (node.callee.property.name === 'spawn' || - node.callee.property.value === 'spawn') - ) { - if (!isInsideAssignerFunction(node)) { - context.report({ - node, - messageId: 'invalidCallContext', - }) - } + if (!isInsideAssignerFunction(node)) { + context.report({ + node, + messageId: 'invalidCallContext', + }) } }, } diff --git a/lib/utils/XStateDetector.js b/lib/utils/XStateDetector.js new file mode 100644 index 0000000..6441967 --- /dev/null +++ b/lib/utils/XStateDetector.js @@ -0,0 +1,111 @@ +/** + * XStateDetector can be used to capture information about xstate imports. + */ +module.exports = class XStateDetector { + constructor() { + this.xstateIdentifier = null + this.spawnIdentifiers = [] + + const captureSpawnIdentifierFromXStateMemberExpression = (node) => { + if ( + this.xstateIdentifier != null && + node.init.object.name === this.xstateIdentifier + ) { + this.spawnIdentifiers.push(node.id.name) + } + } + + this.visitors = { + 'ImportDeclaration[source.value="xstate"]': (node) => { + const importSpecifier = node.specifiers.find( + (s) => s.type === 'ImportSpecifier' && s.imported.name === 'spawn' + ) + if (importSpecifier) { + this.spawnIdentifiers.push(importSpecifier.local.name) + return + } + const importDefaultSpecifier = node.specifiers.find( + (s) => s.type === 'ImportDefaultSpecifier' + ) + if (importDefaultSpecifier) { + this.xstateIdentifier = importDefaultSpecifier.local.name + return + } + const importNamespaceSpecifier = node.specifiers.find( + (s) => s.type === 'ImportNamespaceSpecifier' + ) + if (importNamespaceSpecifier) { + this.xstateIdentifier = importNamespaceSpecifier.local.name + } + }, + // commonjs imports + // const { spawn } = require('xstate') + // const { spawn: xspawn } = require('xstate') + // const xstate = require('xstate') + 'VariableDeclarator[init.callee.name="require"][init.arguments.0.value="xstate"]': + (node) => { + if ( + this.xstateIdentifier !== null || + this.spawnIdentifiers.length > 0 + ) { + return + } + if (node.id.type === 'ObjectPattern') { + const spawnProperty = node.id.properties.find( + (p) => p.key.name === 'spawn' + ) + if (spawnProperty) { + this.spawnIdentifiers.push(spawnProperty.value.name) + } + return + } + if (node.id.type === 'Identifier') { + this.xstateIdentifier = node.id.name + } + }, + // const spawn = require('xstate').spawn + // const spawn = require('xstate')['spawn'] + 'VariableDeclarator[init.object.callee.name="require"][init.object.arguments.0.value="xstate"]': + (node) => { + if ( + node.init.property.name === 'spawn' || + node.init.property.value === 'spawn' + ) { + this.spawnIdentifiers.push(node.id.name) + } + }, + // const { spawn } = xstate + // Ignores it if the xstateIdentifier has not been previously resolved + 'VariableDeclarator[id.type="ObjectPattern"] > ObjectPattern > Property[key.name="spawn"]': + (node) => { + const varDeclarator = node.parent.parent + if ( + this.xstateIdentifier != null && + this.xstateIdentifier === varDeclarator.init.name + ) { + this.spawnIdentifiers.push(node.value.name) + } + }, + // const spawn = xstate.spawn + // const spawn = xstate['spawn'] + 'VariableDeclarator[init.type="MemberExpression"][init.property.name="spawn"]': + captureSpawnIdentifierFromXStateMemberExpression, + 'VariableDeclarator[init.type="MemberExpression"][init.property.value="spawn"]': + captureSpawnIdentifierFromXStateMemberExpression, + } + } + + isSpawnCallExpression(node) { + if (this.spawnIdentifiers.length < 1 && this.xstateIdentifier == null) { + return false + } + return ( + (node.callee.type === 'Identifier' && + this.spawnIdentifiers.includes(node.callee.name)) || + (node.callee.type === 'MemberExpression' && + node.callee.object.name === this.xstateIdentifier && + (node.callee.property.name === 'spawn' || + node.callee.property.value === 'spawn')) + ) + } +} diff --git a/tests/lib/rules/no-inline-implementation.js b/tests/lib/rules/no-inline-implementation.js index c77ece0..338cf3d 100644 --- a/tests/lib/rules/no-inline-implementation.js +++ b/tests/lib/rules/no-inline-implementation.js @@ -7,46 +7,79 @@ const tests = { withVersion( 4, ` - createMachine({ - states: { - active: { - invoke: { - src: 'myService', - }, - entry: 'myAction', - on: { - OFF: { - cond: 'myGuard', - target: 'inactive', - actions: ['myAction1', 'myAction2'], + createMachine( + { + states: { + active: { + invoke: { + src: 'myService', }, + entry: 'myAction', + on: { + OFF: { + cond: 'myGuard', + target: 'inactive', + actions: ['myAction1', 'myAction2'], + }, + }, + activities: 'myActivity', }, - activities: 'myActivity', }, - }, - }) + }, + { + services: { + myService: () => {}, + }, + actions: { + myAction: () => {}, + myAction1: () => {}, + myAction2: () => {}, + }, + guards: { + myGuard: () => {}, + }, + activities: { + myActivity: () => {}, + }, + } + ) ` ), withVersion( 5, ` - createMachine({ - states: { - active: { - invoke: { - src: 'myService', - }, - entry: 'myAction', - on: { - OFF: { - guard: 'myGuard', - target: 'inactive', - actions: ['myAction1', 'myAction2'], + createMachine( + { + states: { + active: { + invoke: { + src: 'myActor', + }, + entry: 'myAction', + on: { + OFF: { + guard: 'myGuard', + target: 'inactive', + actions: ['myAction1', 'myAction2'], + }, }, }, }, }, - }) + { + actors: { + myActor: () => {}, + }, + actions: { + myAction: () => {}, + myAction1: () => {}, + myAction2: () => {}, + }, + guards: { + myGuard: () => {}, + }, + } + ) ` ), // inlined action creators are ok with allowKnownActionCreators=true @@ -54,36 +87,82 @@ const tests = { 4, ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ - createMachine({ - states: { - active: { - entry: assign(), - on: { - OFF: { - actions: [send('EVENT'), assign()], + createMachine( + { + states: { + active: { + entry: assign({ + childActor: () => spawn('childActor'), + }), + on: { + OFF: { + actions: [send('EVENT'), assign()], + }, }, + exit: choose([{ + cond: 'myGuard', + actions: 'myAction', + }]), }, }, }, - }) + { + services: { + childActor: () => {}, + }, + guards: { + myGuard: () => {}, + }, + actions: { + myAction: () => {}, + choosableAction: choose([{ + cond: () => {}, + actions: () => {}, + }]), + }, + } + ) ` ), withVersion( 5, ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ - createMachine({ - states: { - active: { - entry: assign(), - on: { - OFF: { - actions: [sendParent('EVENT'), assign()], + createMachine( + { + states: { + active: { + entry: assign({ + childActor: () => spawn('childActor'), + }), + on: { + OFF: { + actions: [sendParent('EVENT'), assign()], + }, }, + exit: choose([{ + guard: 'myGuard', + actions: 'myAction', + }]), }, }, }, - }) + { + actors: { + childActor: () => {}, + }, + guards: { + myGuard: () => {}, + }, + actions: { + myAction: () => {}, + choosableAction: choose([{ + guard: () => {}, + actions: () => {}, + }]), + }, + } + ) ` ), // onDone, onError, array of transitions @@ -434,16 +513,30 @@ const tests = { withVersion(4, { code: ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + const { createMachine, spawn } = require('xstate') createMachine({ states: { active: { entry: ['someAction', assign(), () => {}], on: { OFF: { - actions: ['someAction', someAction, () => {}, send()], + actions: [ + 'someAction', + someAction, + () => {}, + send(), + choose([{ + cond: () => {}, + actions: () => {}, + }]), + ], }, }, activities: [myActivity, 'myActivity'], + exit: assign({ + childActor1: () => spawn(() => {}), + childActor2: () => spawn(childActor), + }), }, }, }) @@ -452,21 +545,39 @@ const tests = { { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, { messageId: 'moveActivityToOptions' }, + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActorToOptions' }, ], }), withVersion(5, { code: ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + const { createMachine, spawn } = require('xstate') createMachine({ states: { active: { entry: ['someAction', assign(), () => {}], on: { OFF: { - actions: ['someAction', someAction, () => {}, sendTo()], + actions: [ + 'someAction', + someAction, + () => {}, + sendParent(), + choose([{ + guard: () => {}, + actions: () => {}, + }]), + ], }, }, + exit: assign({ + childActor1: () => spawn(() => {}), + childActor2: () => spawn(childActor), + }), }, }, }) @@ -475,6 +586,10 @@ const tests = { { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActorToOptions' }, ], }), // inline implementations inside array of transitions From b95101d760be93f94f5b64962e88656708870ae6 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 13:12:22 +0200 Subject: [PATCH 09/43] feat(no-inline-implementation): detect inline implementations inside spawn call with xstate v5 --- lib/rules/no-inline-implementation.js | 20 +++++++++- .../isSpawnFromParametersCallExpression.js | 40 +++++++++++++++++++ lib/utils/selectors.js | 17 ++++++++ tests/lib/rules/no-inline-implementation.js | 8 ++-- 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 lib/utils/isSpawnFromParametersCallExpression.js diff --git a/lib/rules/no-inline-implementation.js b/lib/rules/no-inline-implementation.js index d159860..794b490 100644 --- a/lib/rules/no-inline-implementation.js +++ b/lib/rules/no-inline-implementation.js @@ -13,6 +13,7 @@ const { getTypeProperty } = require('../utils/selectors') const { anyPass } = require('../utils/combinators') const getSettings = require('../utils/getSettings') const XStateDetector = require('../utils/XStateDetector') +const isSpawnFromParametersCallExpresion = require('../utils/isSpawnFromParametersCallExpression') function isArrayWithFunctionExpressionOrIdentifier(node) { return ( @@ -247,7 +248,7 @@ module.exports = { } return { - ...xstateDetector.visitors, + ...(version === 4 ? xstateDetector.visitors : {}), [propertyOfEventTransition]: checkTransitionProperty, [propertyOfEventTransitionInArray]: checkTransitionProperty, [propertyOfAltEventTransitionInArray]: checkTransitionProperty, @@ -309,7 +310,22 @@ module.exports = { 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression': function (node) { - if (!xstateDetector.isSpawnCallExpression(node)) { + if (version === 4) { + if ( + xstateDetector.isSpawnCallExpression(node) && + node.arguments[0] && + !isStringLiteral(node.arguments[0]) + ) { + context.report({ + node: node.arguments[0], + messageId: 'moveActorToOptions', + }) + } + return + } + + // In XState v5, spawn comes from arguments passed to the callback within assign() + if (!isSpawnFromParametersCallExpresion(node)) { return } diff --git a/lib/utils/isSpawnFromParametersCallExpression.js b/lib/utils/isSpawnFromParametersCallExpression.js new file mode 100644 index 0000000..e65aa92 --- /dev/null +++ b/lib/utils/isSpawnFromParametersCallExpression.js @@ -0,0 +1,40 @@ +const { getParentFunctionExpression } = require('./selectors') + +module.exports = function isSpawnFromParametersCallExpresion(node) { + const functionNode = getParentFunctionExpression(node) + if (!functionNode) { + return false + } + + if (!functionNode.params[0]) { + return false + } + + // populated when there is a destructured object for params + let spawnIdentifier = null + // populated when the whole first arg object is grabbed + let firstArgIdentifier = null + + if (functionNode.params[0].type === 'Identifier') { + firstArgIdentifier = functionNode.params[0].name + } else if (functionNode.params[0].type === 'ObjectPattern') { + const spawnProperty = functionNode.params[0].properties.find( + (property) => property.key.name === 'spawn' + ) + if (!spawnProperty) { + return false + } + spawnIdentifier = spawnProperty.value.name + } else { + return false + } + + return ( + (node.callee.type === 'Identifier' && + node.callee.name === spawnIdentifier) || + (node.callee.type === 'MemberExpression' && + node.callee.object.name === firstArgIdentifier && + (node.callee.property.name === 'spawn' || + node.callee.property.value === 'spawn')) + ) +} diff --git a/lib/utils/selectors.js b/lib/utils/selectors.js index 3d32778..36d9bc0 100644 --- a/lib/utils/selectors.js +++ b/lib/utils/selectors.js @@ -7,6 +7,23 @@ function getTypeProperty(node) { return node.properties.find(propertyHasName('type')) } +function getParentFunctionExpression(node) { + let current = node.parent + while (true) { + if (!current) { + return null + } + if ( + current.type === 'FunctionExpression' || + current.type === 'ArrowFunctionExpression' + ) { + return current + } + current = current.parent + } +} + module.exports = { getTypeProperty, + getParentFunctionExpression, } diff --git a/tests/lib/rules/no-inline-implementation.js b/tests/lib/rules/no-inline-implementation.js index 338cf3d..2cbfa6d 100644 --- a/tests/lib/rules/no-inline-implementation.js +++ b/tests/lib/rules/no-inline-implementation.js @@ -133,7 +133,7 @@ const tests = { states: { active: { entry: assign({ - childActor: () => spawn('childActor'), + childActor: ({ spawn }) => spawn('childActor'), }), on: { OFF: { @@ -555,7 +555,7 @@ const tests = { withVersion(5, { code: ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ - const { createMachine, spawn } = require('xstate') + const { createMachine } = require('xstate') createMachine({ states: { active: { @@ -575,8 +575,8 @@ const tests = { }, }, exit: assign({ - childActor1: () => spawn(() => {}), - childActor2: () => spawn(childActor), + childActor1: ({ spawn }) => spawn(() => {}), + childActor2: ({ spawn }) => spawn(childActor), }), }, }, From 7678a5b3c08f0f5da2fd8ba408328d84e774faa6 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 15:08:42 +0200 Subject: [PATCH 10/43] feat(prefer-always): add message about deprecated eventless empty string transitions for xstate v5 --- lib/rules/prefer-always.js | 11 +++++++++ tests/lib/rules/prefer-always.js | 42 +++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lib/rules/prefer-always.js b/lib/rules/prefer-always.js index 7423d68..3537306 100644 --- a/lib/rules/prefer-always.js +++ b/lib/rules/prefer-always.js @@ -1,6 +1,7 @@ 'use strict' const getDocsUrl = require('../utils/getDocsUrl') +const getSettings = require('../utils/getSettings') module.exports = { meta: { @@ -15,13 +16,23 @@ module.exports = { messages: { preferAlways: 'The empty string syntax for transient transitions will be deprecated in XState v5. Prefer using the new "always" syntax available since XState v4.11+.', + eventlessTransitionsDeprecated: + 'The empty string syntax for transient (eventless) transitions was removed in v5. Use the "always" syntax.', }, }, create: function (context) { + const { version } = getSettings(context) return { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property[key.value=""]': function (node) { + if (version !== 4) { + context.report({ + node, + messageId: 'eventlessTransitionsDeprecated', + }) + return + } context.report({ node, messageId: 'preferAlways', diff --git a/tests/lib/rules/prefer-always.js b/tests/lib/rules/prefer-always.js index 9652bd2..9c54379 100644 --- a/tests/lib/rules/prefer-always.js +++ b/tests/lib/rules/prefer-always.js @@ -1,9 +1,27 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/prefer-always') +const { withVersion } = require('../utils/settings') const tests = { valid: [ + withVersion( + 4, + ` + createMachine({ + states: { + playing: { + always: [ + { target: 'win', cond: 'didPlayerWin' }, + { target: 'lose', cond: 'didPlayerLose' }, + ], + }, + }, + }) ` + ), + withVersion( + 5, + ` createMachine({ states: { playing: { @@ -14,10 +32,11 @@ const tests = { }, }, }) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { @@ -33,7 +52,24 @@ const tests = { }) `, errors: [{ messageId: 'preferAlways' }], - }, + }), + withVersion(5, { + code: ` + createMachine({ + states: { + playing: { + on: { + '': [ + { target: 'win', cond: 'didPlayerWin' }, + { target: 'lose', cond: 'didPlayerLose' }, + ], + }, + }, + }, + }) + `, + errors: [{ messageId: 'eventlessTransitionsDeprecated' }], + }), ], } From feb763c2ba65056c3934c45ed4f94b75d3e56d5a Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 15:10:01 +0200 Subject: [PATCH 11/43] test(no-auto-forward): fix ignored test case in no-auto-forward test --- lib/rules/no-auto-forward.js | 2 +- tests/lib/rules/no-auto-forward.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/rules/no-auto-forward.js b/lib/rules/no-auto-forward.js index a2ba7cb..3f60ceb 100644 --- a/lib/rules/no-auto-forward.js +++ b/lib/rules/no-auto-forward.js @@ -17,7 +17,7 @@ module.exports = { noAutoForward: 'Forwarding all events may lead to unexpected behavior and/or infinite loops. Prefer using `forwardTo` action creator to send events explicitly.', autoForwardDeprecated: - 'The autoForward option has been removed in v5. Use `forwardTo` action creator to send events explicitly.', + 'The autoForward option was removed in v5. Use `forwardTo` action creator to send events explicitly.', }, }, diff --git a/tests/lib/rules/no-auto-forward.js b/tests/lib/rules/no-auto-forward.js index 4a21ee0..22c6678 100644 --- a/tests/lib/rules/no-auto-forward.js +++ b/tests/lib/rules/no-auto-forward.js @@ -16,7 +16,10 @@ const tests = { }, }, }) - `, + ` + ), + withVersion( + 4, ` createMachine({ states: { From 409fd6765383f3c9e2f0c3f0a579c5a696e2d5d6 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 15:41:15 +0200 Subject: [PATCH 12/43] feat(no-imperative-actions): add support for xstate v5 action creators --- lib/rules/no-imperative-action.js | 10 +- tests/lib/rules/no-imperative-action.js | 434 +++++++++++++++++++----- 2 files changed, 363 insertions(+), 81 deletions(-) diff --git a/lib/rules/no-imperative-action.js b/lib/rules/no-imperative-action.js index 444a78f..4e3697b 100644 --- a/lib/rules/no-imperative-action.js +++ b/lib/rules/no-imperative-action.js @@ -1,6 +1,7 @@ 'use strict' const getDocsUrl = require('../utils/getDocsUrl') +const getSettings = require('../utils/getSettings') const { isKnownActionCreatorCall, @@ -59,11 +60,12 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) return { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^entry$|^exit$/] ArrowFunctionExpression CallExpression': function (node) { if ( - isKnownActionCreatorCall(node) && + isKnownActionCreatorCall(node, version) && !isWithinPureActionCreator(node) ) { context.report({ @@ -77,7 +79,7 @@ module.exports = { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^entry$|^exit$/] FunctionExpression CallExpression': function (node) { if ( - isKnownActionCreatorCall(node) && + isKnownActionCreatorCall(node, version) && !isWithinPureActionCreator(node) ) { context.report({ @@ -91,7 +93,7 @@ module.exports = { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="actions"] ArrowFunctionExpression CallExpression': function (node) { if ( - isKnownActionCreatorCall(node) && + isKnownActionCreatorCall(node, version) && !isWithinPureActionCreator(node) ) { context.report({ @@ -105,7 +107,7 @@ module.exports = { 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="actions"] FunctionExpression CallExpression': function (node) { if ( - isKnownActionCreatorCall(node) && + isKnownActionCreatorCall(node, version) && !isWithinPureActionCreator(node) ) { context.report({ diff --git a/tests/lib/rules/no-imperative-action.js b/tests/lib/rules/no-imperative-action.js index 20a8b86..0b9343c 100644 --- a/tests/lib/rules/no-imperative-action.js +++ b/tests/lib/rules/no-imperative-action.js @@ -1,100 +1,168 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-imperative-action') +const { withVersion } = require('../utils/settings') const tests = { valid: [ + withVersion( + 4, + ` + createMachine({ + states: { + active: { + entry: assign({}), + exit: [ + assign(), + cancel(), + choose(), + done(), + doneInvoke(), + error(), + escalate(), + forwardTo(), + log(), + pure(), + raise(), + respond(), + send(), + sendParent(), + sendTo(), + sendUpdate(), + start(), + stop(), + ], + on: { + TRIGGER1: { + actions: assign(), + }, + TRIGGER2: { + actions: [ + assign(), + send(), + sendParent(), + ], + }, + }, + }, + }, + }) ` + ), + withVersion( + 5, + ` createMachine({ states: { active: { entry: assign({}), exit: [ - assign({}), - send('EVENT'), - sendParent('EVENT'), - respond('EVENT'), - raise('EVENT'), - forwardTo('someActor'), - choose([]), - pure(() => {}), - log('message'), - escalate('error'), - pure(() => send('EVENT')), - actions.pure(() => send('EVENT')), - pure(() => actions.send('EVENT')), + assign(), + cancel(), + choose(), + done(), + doneInvoke(), + error(), + escalate(), + forwardTo(), + log(), + pure(), + raise(), + sendParent(), + sendTo(), + stop(), ], on: { TRIGGER1: { - actions: assign({}), + actions: assign(), }, TRIGGER2: { actions: [ - assign({}), - send(['EVENT']), - sendParent('EVENT'), - pure(() => send('EVENT')), - actions.pure(() => send('EVENT')), - pure(() => actions.send('EVENT')), + assign(), + sendTo(), + sendParent(), + pure(), ], }, }, }, }, }) - `, ` + ), + withVersion( + 4, + ` + createMachine( + {}, + { + actions: { + myAction1: assign(), + myAction2: send(), + myAction3: sendParent(), + myAction4: respond(), + myAction5: raise(), + myAction6: pure(), + myAction7: actions.pure(), + }, + } + ) + ` + ), + withVersion( + 5, + ` createMachine( {}, { actions: { - myAction1: assign({}), - myAction2: send('EVENT'), - myAction3: sendParent('EVENT'), - myAction4: respond('EVENT'), - myAction5: raise('EVENT'), - myAction6: pure(() => send('EVENT')), - myAction6: actions.pure(() => send('EVENT')), + myAction1: assign(), + myAction2: sendTo(), + myAction3: sendParent(), + myAction4: raise(), + myAction5: pure(), + myAction6: actions.pure(), }, } ) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { active: { - entry: () => assign({}), + entry: () => assign(), exit: [ () => { - assign({}) + assign() }, function() { - send('EVENT') + assign() }, - () => actions.send('EVENT'), - () => sendParent('EVENT'), - () => respond('EVENT'), - () => raise('EVENT'), - () => forwardTo('someActor'), - () => choose([]), - () => pure(() => {}), - () => log('message'), - () => escalate('error'), + () => send(), + () => actions.send(), + () => sendParent(), + () => respond(), + () => raise(), + () => forwardTo(), + () => choose(), + () => pure(), + () => log(), ], on: { TRIGGER1: { - actions: () => assign({}), + actions: () => assign(), }, TRIGGER2: { - actions: function() { assign({}) }, + actions: function() { assign() }, }, TRIGGER3: { actions: [ - () => assign({}), - () => { send(['EVENT']) }, - function() { sendParent(['EVENT']) }, + () => assign(), + () => { assign() }, + function() { assign() }, ], }, }, @@ -103,48 +171,260 @@ const tests = { }) `, errors: [ - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'send' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'actions.send' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'respond' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'forwardTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'choose' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'pure' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'log' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, ], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + entry: () => assign(), + exit: [ + () => { + assign() + }, + function() { + assign() + }, + () => sendTo(), + () => actions.sendTo(), + () => sendParent(), + () => forwardTo(), + () => raise(), + () => choose(), + () => pure(), + () => log(), + ], + on: { + TRIGGER1: { + actions: () => assign(), + }, + TRIGGER2: { + actions: function() { assign() }, + }, + TRIGGER3: { + actions: [ + () => assign(), + () => { assign() }, + function() { assign() }, + ], + }, + }, + }, + }, + }) + `, + errors: [ + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'actions.sendTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'forwardTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'choose' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'pure' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'log' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + ], + }), + withVersion(4, { code: ` createMachine( {}, { actions: { - myAction1: () => assign({}), - myAction2: () => { send('EVENT') }, - myAction3: function() { sendParent('EVENT') }, - myAction4: () => respond('EVENT'), - myAction5: () => raise('EVENT'), + myAction1: () => assign(), + myAction2: () => { send() }, + myAction3: function() { sendParent() }, + myAction4: () => respond(), + myAction5: () => raise(), }, } ) `, errors: [ - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, - { messageId: 'imperativeActionCreator' }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'send' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'respond' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, + ], + }), + withVersion(5, { + code: ` + createMachine( + {}, + { + actions: { + myAction1: () => assign(), + myAction2: () => { sendTo() }, + myAction3: function() { sendParent() }, + myAction4: () => choose(), + myAction5: () => raise(), + }, + } + ) + `, + errors: [ + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'choose' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, ], - }, + }), ], } From 2b0346d0182ce56b47eea5820ab5a701041f00ef Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 15:52:15 +0200 Subject: [PATCH 13/43] feat(no-async-guard): support the "guard" prop with xstate v5 --- docs/rules/no-async-guard.md | 46 ++++++++---- lib/rules/no-async-guard.js | 10 ++- tests/lib/rules/no-async-guards.js | 115 +++++++++++++++++++++++++---- 3 files changed, 143 insertions(+), 28 deletions(-) diff --git a/docs/rules/no-async-guard.md b/docs/rules/no-async-guard.md index b4c3d69..3499ebb 100644 --- a/docs/rules/no-async-guard.md +++ b/docs/rules/no-async-guard.md @@ -4,12 +4,12 @@ ## Rule Details -Async functions return a promise which is a truthy value. Therefore, async guard functions always pass. Transitions guarded by such functions will always be taken as if no `cond` was specified. +Async functions return a promise which is a truthy value. Therefore, async guard functions always pass. Transitions guarded by such functions will always be taken as if no `cond` (XState v4) or `guard` (XState v5) was specified. Examples of **incorrect** code for this rule: ```javascript -// ❌ async guard in an event transition +// ❌ async guard in an event transition (XState v4) createMachine({ on: { EVENT: { @@ -19,14 +19,24 @@ createMachine({ }, }) -// ❌ async guard in an onDone transition +// ❌ async guard in an event transition (XState v5) +createMachine({ + on: { + EVENT: { + guard: async () => {}, + target: 'active', + }, + }, +}) + +// ❌ async guard in an onDone transition (XState v5) createMachine({ states: { active: { invoke: { src: 'myService', onDone: { - cond: async function () {}, + guard: async function () {}, target: 'finished', }, }, @@ -34,22 +44,22 @@ createMachine({ }, }) -// ❌ async guard in the choose action creator +// ❌ async guard in the choose action creator (XState v5) createMachine({ entry: choose([ { - cond: async () => {}, + guard: async () => {}, actions: 'myAction', }, ]), }) -// ❌ async guards in machine options +// ❌ async guards in machine options (XState v5) createMachine( { on: { EVENT: { - cond: 'myGuard', + guard: 'myGuard', target: 'active', }, }, @@ -67,7 +77,7 @@ createMachine( Examples of **correct** code for this rule: ```javascript -// ✅ guard is synchronous +// ✅ guard is synchronous (XState v4) createMachine({ on: { EVENT: { @@ -77,14 +87,24 @@ createMachine({ }, }) -// ✅ guard is synchronous +// ✅ guard is synchronous (XState v5) +createMachine({ + on: { + EVENT: { + guard: () => {}, + target: 'active', + }, + }, +}) + +// ✅ guard is synchronous (XState v5) createMachine({ states: { active: { invoke: { src: 'myService', onDone: { - cond: function () {}, + guard: function () {}, target: 'finished', }, }, @@ -92,12 +112,12 @@ createMachine({ }, }) -// ✅ all guards in machine options are synchronous +// ✅ all guards in machine options are synchronous (XState v5) createMachine( { on: { EVENT: { - cond: 'myGuard', + guard: 'myGuard', target: 'active', }, }, diff --git a/lib/rules/no-async-guard.js b/lib/rules/no-async-guard.js index 6b6858c..a814e5f 100644 --- a/lib/rules/no-async-guard.js +++ b/lib/rules/no-async-guard.js @@ -2,6 +2,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isFunctionExpression } = require('../utils/predicates') +const getSettings = require('../utils/getSettings') function isAsyncFunctionExpression(node) { return isFunctionExpression(node) && node.async @@ -23,9 +24,16 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="cond"]': + 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child Property[key.name=/^cond|guard$/]': function (node) { + if (version === 4 && node.key.name !== 'cond') { + return + } + if (version > 4 && node.key.name !== 'guard') { + return + } if (isAsyncFunctionExpression(node.value)) { context.report({ node: node.value, diff --git a/tests/lib/rules/no-async-guards.js b/tests/lib/rules/no-async-guards.js index 609f124..730df2a 100644 --- a/tests/lib/rules/no-async-guards.js +++ b/tests/lib/rules/no-async-guards.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-async-guard') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ on: { EVENT: { @@ -12,8 +15,24 @@ const tests = { }, }, }) - `, ` + ), + withVersion( + 5, + ` + createMachine({ + on: { + EVENT: { + guard: () => {}, + target: 'active', + }, + }, + }) + ` + ), + withVersion( + 4, + ` createMachine({ states: { active: { @@ -27,17 +46,31 @@ const tests = { }, }, }) - `, ` - createMachine( - { - on: { - EVENT: { - cond: 'myGuard', - target: 'active', + ), + withVersion( + 5, + ` + createMachine({ + states: { + active: { + invoke: { + src: 'myService', + onDone: { + guard: function () {}, + target: 'finished', + }, }, }, }, + }) + ` + ), + withVersion( + 4, + ` + createMachine( + {}, { guards: { myGuard: () => {}, @@ -46,10 +79,11 @@ const tests = { }, } ) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ entry: choose([ @@ -82,9 +116,43 @@ const tests = { { messageId: 'guardCannotBeAsync' }, { messageId: 'guardCannotBeAsync' }, ], - }, + }), + withVersion(5, { + code: ` + createMachine({ + entry: choose([ + { + guard: async () => {}, + actions: 'myAction', + }, + ]), + states: { + active: { + invoke: { + src: 'myService', + onDone: { + guard: async function () {}, + target: 'finished', + }, + }, + }, + }, + on: { + EVENT: { + guard: async () => {}, + target: 'active', + }, + }, + }) + `, + errors: [ + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + ], + }), // async guard in machine options - { + withVersion(4, { code: ` createMachine( { @@ -109,7 +177,26 @@ const tests = { { messageId: 'guardCannotBeAsync' }, { messageId: 'guardCannotBeAsync' }, ], - }, + }), + withVersion(5, { + code: ` + createMachine( + {}, + { + guards: { + myGuard: async () => {}, + myGuard2: async function () {}, + async myGuard3() {}, + }, + } + ) + `, + errors: [ + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + ], + }), ], } From 15f778c632490fc18b77f794ac5c9b50a53c8211 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 16:59:15 +0200 Subject: [PATCH 14/43] feat(prefer-predictable-action-arguments): add a deprecation error for this rule with xstate v5 --- README.md | 19 ++++++ .../prefer-predictable-action-arguments.md | 16 +++-- lib/index.js | 4 +- .../prefer-predictable-action-arguments.js | 53 +++++++++++++-- .../prefer-predictable-action-arguments.js | 67 ++++++++++++++++--- 5 files changed, 140 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 0544a01..3247234 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # eslint-plugin-xstate +TODO add prefer-predictable, no-auto-forward + their docs + ESLint plugin to check for common mistakes and enforce good practices when using [XState library](https://xstate.js.org/). [![npm version](https://img.shields.io/npm/v/eslint-plugin-xstate)](https://npmjs.com/package/eslint-plugin-xstate) @@ -42,6 +44,7 @@ Then configure the rules you want to use under the rules section. "xstate/invoke-usage": "error", "xstate/entry-exit-action": "error", "xstate/prefer-always": "error", + "xstate/prefer-predictable-action-arguments": "error", "xstate/no-misplaced-on-transition": "error", "xstate/no-invalid-transition-props": "error", "xstate/no-invalid-state-props": "error", @@ -72,6 +75,21 @@ There is also an `all` configuration which includes every available rule. It enf } ``` +### XState v4 +The default shareable configurations are for XState v5. If you use the older XState v4, append `_v4` to the name of the configuration you want to use. + +```json +{ + "extends": ["plugin:xstate/recommended_v4"] +} +``` + +```json +{ + "extends": ["plugin:xstate/all_v4"] +} +``` + ## Supported Rules ### Possible Errors @@ -95,6 +113,7 @@ There is also an `all` configuration which includes every available rule. It enf | ------------------------------------------------------------------ | ----------------------------------------------------------------------- | ------------------ | | [no-inline-implementation](docs/rules/no-inline-implementation.md) | Suggest refactoring guards, actions and services into machine options | | | [prefer-always](docs/rules/prefer-always.md) | Suggest using the `always` syntax for transient (eventless) transitions | :heavy_check_mark: | +| [prefer-predictable-action-arguments](docs/rules/prefer-predictable-action-arguments.md) | Suggest turning on the `predictableActionArguments` option | :heavy_check_mark: | | [no-auto-forward](docs/rules/no-auto-forward.md) | Forbid auto-forwarding events to invoked services or spawned actors | | ### Stylistic Issues diff --git a/docs/rules/prefer-predictable-action-arguments.md b/docs/rules/prefer-predictable-action-arguments.md index c86ebbc..907907a 100644 --- a/docs/rules/prefer-predictable-action-arguments.md +++ b/docs/rules/prefer-predictable-action-arguments.md @@ -1,6 +1,6 @@ # Use `predictableActionArguments: true` at the top-level of your machine config -Suggest using setting `predictableActionArguments` to `true` at the top-level of your machine config, like this: +Suggest using setting `predictableActionArguments` to `true` at the top-level of your machine config (with XState v4), like this: ```javascript createMachine({ @@ -15,6 +15,10 @@ With this flag XState will always call an action with the event directly respons Source from docs: https://xstate.js.org/docs/guides/actions.html#api +### XState v5 + +In XState v5 the `predictableActionArguments` was removed. This rule will report an error if the option is used in your machine config. + Examples of **incorrect** code for this rule: ```javascript @@ -24,8 +28,7 @@ createMachine({ // ... }) -// ❌ predictableActionArguments is omitted - +// ❌ predictableActionArguments is omitted (XState v4) createMachine({ states: { // ... @@ -36,9 +39,14 @@ createMachine({ Examples of **correct** code for this rule: ```javascript -// ✅ predictableActionArguments is enabled +// ✅ predictableActionArguments is enabled (XState v4) createMachine({ predictableActionArguments: true, // ... }) + +// ✅ predictableActionArguments is not used (XState v5) +createMachine({ + // ... +}) ``` diff --git a/lib/index.js b/lib/index.js index 9f19d11..7a86f8a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -45,7 +45,7 @@ module.exports = { 'xstate/invoke-usage': 'error', 'xstate/entry-exit-action': 'error', 'xstate/prefer-always': 'error', - 'xstate/prefer-predictable-action-arguments': 'warn', + 'xstate/prefer-predictable-action-arguments': 'error', 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', @@ -73,6 +73,7 @@ module.exports = { 'xstate/no-inline-implementation': 'warn', 'xstate/no-auto-forward': 'error', 'xstate/prefer-always': 'error', + 'xstate/prefer-predictable-action-arguments': 'error', 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', @@ -122,6 +123,7 @@ module.exports = { 'xstate/no-inline-implementation': 'warn', 'xstate/no-auto-forward': 'warn', 'xstate/prefer-always': 'error', + 'xstate/prefer-predictable-action-arguments': 'warn', 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', diff --git a/lib/rules/prefer-predictable-action-arguments.js b/lib/rules/prefer-predictable-action-arguments.js index 08af85f..2c3f49d 100644 --- a/lib/rules/prefer-predictable-action-arguments.js +++ b/lib/rules/prefer-predictable-action-arguments.js @@ -1,6 +1,7 @@ 'use strict' const getDocsUrl = require('../utils/getDocsUrl') +const getSettings = require('../utils/getSettings') module.exports = { meta: { @@ -12,14 +13,18 @@ module.exports = { url: getDocsUrl('prefer-predictable-action-arguments'), recommended: 'warn', }, + fixable: 'code', schema: [], messages: { preferPredictableActionArguments: 'It is advised to configure predictableActionArguments: true at the top-level of your machine config', + deprecatedPredictableActionArguments: + 'The predictableActionArguments prop was removed in XState v5 so it has no effect. Please remove it.', }, }, create: function (context) { + const { version } = getSettings(context) return { 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child': function (node) { @@ -28,22 +33,60 @@ module.exports = { return prop.key.name === 'predictableActionArguments' } ) - - if (!predictableActionArgumentsProperty) { + if (version > 4) { + if (!predictableActionArgumentsProperty) { + return + } context.report({ - node, - messageId: 'preferPredictableActionArguments', + node: predictableActionArgumentsProperty, + messageId: 'deprecatedPredictableActionArguments', + fix(fixer) { + return fixer.remove(predictableActionArgumentsProperty) + }, }) return } + if (!predictableActionArgumentsProperty) { + if (node.properties.length === 0) { + context.report({ + node, + messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.replaceText( + node, + '{ predictableActionArguments: true }' + ) + }, + }) + } else { + context.report({ + node, + messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.insertTextBefore( + node.properties[0], + 'predictableActionArguments: true,\n' + ) + }, + }) + } + return + } + if ( !predictableActionArgumentsProperty.value || predictableActionArgumentsProperty.value.value !== true ) { context.report({ - node, + node: predictableActionArgumentsProperty, messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.replaceText( + predictableActionArgumentsProperty.value, + 'true' + ) + }, }) } }, diff --git a/tests/lib/rules/prefer-predictable-action-arguments.js b/tests/lib/rules/prefer-predictable-action-arguments.js index 40aa99f..9499a7b 100644 --- a/tests/lib/rules/prefer-predictable-action-arguments.js +++ b/tests/lib/rules/prefer-predictable-action-arguments.js @@ -1,32 +1,75 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/prefer-predictable-action-arguments') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ predictableActionArguments: true }) - `, + ` + ), + withVersion( + 5, + ` + createMachine({}) + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ predictableActionArguments: false }) `, errors: [{ messageId: 'preferPredictableActionArguments' }], - }, - { + output: ` + createMachine({ + predictableActionArguments: true + }) + `, + }), + withVersion(5, { code: ` createMachine({ - states: {}, + predictableActionArguments: false + }) + `, + errors: [{ messageId: 'deprecatedPredictableActionArguments' }], + output: ` + createMachine({ + + }) + `, + }), + withVersion(4, { + code: ` + createMachine({}) + `, + errors: [{ messageId: 'preferPredictableActionArguments' }], + output: ` + createMachine({ predictableActionArguments: true }) + `, + }), + withVersion(4, { + code: ` + createMachine({ + initial: 'ready' }) `, errors: [{ messageId: 'preferPredictableActionArguments' }], - }, - { + output: ` + createMachine({ + predictableActionArguments: true, +initial: 'ready' + }) + `, + }), + withVersion(4, { code: ` createMachine({ states: {}, @@ -34,7 +77,13 @@ const tests = { }) `, errors: [{ messageId: 'preferPredictableActionArguments' }], - }, + output: ` + createMachine({ + states: {}, + predictableActionArguments: true + }) + `, + }), ], } From 360b609f7b5f5b6090e188abbfd4fc9aace90c86 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 16 Aug 2023 22:12:43 +0200 Subject: [PATCH 15/43] feat(no-infinite-loop): add detection of incorrect eventless transitions in xstate v5 --- docs/rules/no-infinite-loop.md | 89 +++++++++++- lib/rules/no-infinite-loop.js | 57 +++++--- tests/lib/rules/no-infinite-loop.js | 212 +++++++++++++++++++++++++--- 3 files changed, 319 insertions(+), 39 deletions(-) diff --git a/docs/rules/no-infinite-loop.md b/docs/rules/no-infinite-loop.md index 59d082b..a303b1b 100644 --- a/docs/rules/no-infinite-loop.md +++ b/docs/rules/no-infinite-loop.md @@ -43,6 +43,7 @@ createMachine({ // ❌ The action on the 2nd transition does not update the context, // so executing it will not make the 1st transition valid on the next evaluation. // (or the 1st transition is always taken, so the 2nd transition is useless) +// XState v4 createMachine({ states: { deciding: { @@ -60,6 +61,24 @@ createMachine({ }, }) +// ❌ Same as above with XState v5 +createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + target: 'idle', + }, + // no guard, no target, no assign action + { + actions: () => console.log('hello'), + }, + ], + }, + }, +}) + // ❌ No guard, no target. Even though it updates the context, // it is the first transition in sequence, so it will be taken ad infinitum. createMachine({ @@ -90,6 +109,7 @@ createMachine({ // ❌ No target. The action does not update the context. This transition is // either useless (never taken because of its guard), or guarantees an // infinite loop error (if its guard is passed once then it will always be passed). +// XState v4 createMachine({ states: { deciding: { @@ -102,12 +122,26 @@ createMachine({ }, }, }) + +// ❌ Same as above with XState v5 +createMachine({ + states: { + deciding: { + always: [ + { + guard: () => {}, + actions: () => console.log('hello'), + }, + ], + }, + }, +}) ``` Examples of **correct** code for this rule: ```javascript -// ✅ Has target +// ✅ Has target (XState v4) createMachine({ states: { deciding: { @@ -124,8 +158,26 @@ createMachine({ }, }) +// ✅ Has target (XState v5) +createMachine({ + states: { + deciding: { + always: [ + { + guard: () => {}, + target: 'busy', + }, + { + target: 'idle', + }, + ], + }, + }, +}) + // ✅ The second transition updates the context, so there's a chance // that the first transition will eventually become valid. +// XState v4 createMachine({ states: { deciding: { @@ -142,8 +194,26 @@ createMachine({ }, }) +// ✅ XState v5 +createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + target: 'idle', + }, + { + actions: assign({ count: ({ context }) => context.count + 1 }), + }, + ], + }, + }, +}) + // ✅ We are optimistic about the 2nd transition action updating the context. // Therefore there's a chance that the first transition will eventually become valid. +// XState v4 createMachine({ states: { deciding: { @@ -159,4 +229,21 @@ createMachine({ }, }, }) + +// XState v5 +createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + target: 'idle', + }, + { + actions: 'someAction', // hopefully an assign() action + }, + ], + }, + }, +}) ``` diff --git a/lib/rules/no-infinite-loop.js b/lib/rules/no-infinite-loop.js index aa01796..38f702e 100644 --- a/lib/rules/no-infinite-loop.js +++ b/lib/rules/no-infinite-loop.js @@ -11,6 +11,7 @@ const { isFunctionExpression, isStringLiteralOrIdentifier, } = require('../utils/predicates') +const getSettings = require('../utils/getSettings') function isEventlessTransitionDeclaration(node) { return node.type === 'Property' && node.key.name === 'always' @@ -56,6 +57,11 @@ function isTransitionToItself(transition) { return targetStateNodeNameOrID === parentStateNodeNameOrID } +function isConditionalTransition(node, version) { + const guardPropName = version === 4 ? 'cond' : 'guard' + return hasProperty(guardPropName, node) +} + function isAssignCall(node) { return node.type === 'CallExpression' && node.callee.name === 'assign' } @@ -90,25 +96,33 @@ function actionsContainStringLiteralOrIdentifier(transition) { ) } -function getGuard(transition) { - if (!hasProperty('cond', transition)) { +const getGuard = (version) => (transition) => { + const guardPropName = version === 4 ? 'cond' : 'guard' + if (!hasProperty(guardPropName, transition)) { return Nothing } - const guard = transition.properties.find(propertyHasName('cond')).value + const guard = transition.properties.find(propertyHasName(guardPropName)).value if (!guard) { return Nothing } return Just(guard) } -const guardUsesContext = (guardFunctionExpression) => - guardFunctionExpression.params.length > 0 +const guardUsesContext = (version) => (guardFunctionExpression) => + version === 4 + ? guardFunctionExpression.params.length > 0 + : guardFunctionExpression.params[0]?.type === 'ObjectPattern' && + guardFunctionExpression.params[0].properties.some( + propertyHasName('context') + ) -const guardIsFunctionAndNotCheckingContext = pipe([ - getGuard, - map(allPass([isFunctionExpression, complement(guardUsesContext)])), - fromMaybe(false), -]) +function guardIsFunctionAndNotCheckingContext(node, version) { + return pipe([ + getGuard(version), + map(allPass([isFunctionExpression, complement(guardUsesContext(version))])), + fromMaybe(false), + ])(node) +} module.exports = { meta: { @@ -145,6 +159,7 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) return { // always: {} // always: { actions: whatever} @@ -152,7 +167,10 @@ module.exports = { if (!isInsideMachineDeclaration(node)) { return } - if (!hasProperty('target', node) && !hasProperty('cond', node)) { + if ( + !hasProperty('target', node) && + !isConditionalTransition(node, version) + ) { context.report({ node, messageId: 'noTargetNoGuardIsSingle', @@ -167,7 +185,10 @@ module.exports = { if (!isInsideMachineDeclaration(node)) { return } - if (!hasProperty('target', node) && !hasProperty('cond', node)) { + if ( + !hasProperty('target', node) && + !isConditionalTransition(node, version) + ) { if (isFirstArrayItem(node)) { context.report({ node, @@ -214,7 +235,7 @@ module.exports = { // always: { target: 'idle' } // }] const targetsItself = isTransitionToItself(node) - if (!hasProperty('cond', node) && targetsItself) { + if (!isConditionalTransition(node, version) && targetsItself) { if (isFirstArrayItem(node)) { context.report({ node, @@ -232,7 +253,7 @@ module.exports = { } if ( - hasProperty('cond', node) && + isConditionalTransition(node, version) && targetsItself && !hasAssignAction(node) && !actionsContainStringLiteralOrIdentifier(node) @@ -245,9 +266,9 @@ module.exports = { } if ( - hasProperty('cond', node) && + isConditionalTransition(node, version) && targetsItself && - guardIsFunctionAndNotCheckingContext(node) && + guardIsFunctionAndNotCheckingContext(node, version) && isFirstArrayItem(node) ) { context.report({ @@ -260,7 +281,7 @@ module.exports = { // always: [{ cond: something, actions: something }] if ( - hasProperty('cond', node) && + isConditionalTransition(node, version) && hasProperty('actions', node) && !hasProperty('target', node) ) { @@ -280,7 +301,7 @@ module.exports = { // or an infinite loop. if ( isFirstArrayItem(node) && - guardIsFunctionAndNotCheckingContext(node) + guardIsFunctionAndNotCheckingContext(node, version) ) { context.report({ node, diff --git a/tests/lib/rules/no-infinite-loop.js b/tests/lib/rules/no-infinite-loop.js index 359c85a..a7784e7 100644 --- a/tests/lib/rules/no-infinite-loop.js +++ b/tests/lib/rules/no-infinite-loop.js @@ -1,9 +1,12 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/no-infinite-loop') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ states: { deciding: { @@ -13,9 +16,12 @@ const tests = { }, }, }) - `, - // unconditional assign actions if they are not first ` + ), + // unconditional assign actions if they are not first + withVersion( + 4, + ` createMachine({ states: { deciding: { @@ -31,9 +37,32 @@ const tests = { }, }, }) - `, - // conditional assign actions ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + target: 'idle', + }, + { + actions: assign({ count: ({ context }) => context.count + 1 }), + }, + ], + }, + }, + }) + ` + ), + // conditional assign actions + withVersion( + 4, + ` createMachine({ states: { deciding: { @@ -46,9 +75,29 @@ const tests = { }, }, }) - `, - // conditional self transition with assign action ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + actions: assign({ count: ({ context }) => context.count + 1 }), + }, + ], + }, + }, + }) + ` + ), + // conditional self transition with assign action + withVersion( + 4, + ` createMachine({ states: { deciding: { @@ -62,9 +111,30 @@ const tests = { }, }, }) - `, - // unconditional self transition with assign actions if they are not first ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => context.count > 5, + target: 'deciding', + actions: assign({ count: ({ context }) => context.count + 1 }), + }, + ], + }, + }, + }) + ` + ), + // unconditional self transition with assign actions if they are not first + withVersion( + 4, + ` createMachine({ states: { deciding: { @@ -81,10 +151,32 @@ const tests = { }, }, }) - `, + ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ context }) => ctx.count > 5, + target: 'idle', + }, + { + target: 'deciding', + actions: assign({ count: ({ context }) => context.count + 1 }), + }, + ], + }, + }, + }) + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ states: { @@ -95,8 +187,8 @@ const tests = { }) `, errors: [{ messageId: 'noTargetNoGuardIsSingle' }], - }, - { + }), + withVersion(4, { code: ` createMachine({ states: { @@ -118,9 +210,9 @@ const tests = { { messageId: 'emptyTransitionNotFirst' }, { messageId: 'unconditionalTransitionNoTargetActionsWithoutAssign' }, ], - }, + }), // self transitions - { + withVersion(4, { code: ` createMachine({ states: { @@ -153,8 +245,42 @@ const tests = { { messageId: 'unconditionalSelfTransitionNotFirstNoAssign' }, { messageId: 'conditionalSelfTransitionNoAssign' }, ], - }, - { + }), + withVersion(5, { + code: ` + createMachine({ + states: { + deciding: { + id: '#foo', + always: [ + { target: 'deciding' }, + { target: 'deciding' }, + { + target: '#foo', + actions: () => {}, + }, + { + guard: () => {}, + target: 'deciding', + }, + { + guard: () => {}, + target: 'deciding', + actions: assign({}), + }, + ], + }, + }, + }) + `, + errors: [ + { messageId: 'unconditionalSelfTransitionIsFirst' }, + { messageId: 'unconditionalSelfTransitionNotFirstNoAssign' }, + { messageId: 'unconditionalSelfTransitionNotFirstNoAssign' }, + { messageId: 'conditionalSelfTransitionNoAssign' }, + ], + }), + withVersion(4, { code: ` createMachine({ states: { @@ -175,9 +301,31 @@ const tests = { messageId: 'firstConditionalSelfTransitionAndGuardNotCheckingContext', }, ], - }, + }), + withVersion(5, { + code: ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ event }) => event.type === 'EVENT', + target: 'deciding', + actions: assign({}), + }, + ], + }, + }, + }) + `, + errors: [ + { + messageId: 'firstConditionalSelfTransitionAndGuardNotCheckingContext', + }, + ], + }), // potential loops or useless - { + withVersion(4, { code: ` createMachine({ states: { @@ -200,7 +348,31 @@ const tests = { { messageId: 'noTargetAndGuardNotCheckingContextIsFirst' }, { messageId: 'noTargetHasGuardNoAssign' }, ], - }, + }), + withVersion(5, { + code: ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: ({ event }) => event.type === 'EVENT', + actions: assign({ count: 1 }), + }, + { + guard: () => {}, + actions: () => {}, + }, + ], + }, + }, + }) + `, + errors: [ + { messageId: 'noTargetAndGuardNotCheckingContextIsFirst' }, + { messageId: 'noTargetHasGuardNoAssign' }, + ], + }), ], } From 8bfa60ea6138305f6c2c19aa071c2a4e851b1bf6 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 10:35:21 +0200 Subject: [PATCH 16/43] docs(event-names): fix typo in docs --- docs/rules/event-names.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/event-names.md b/docs/rules/event-names.md index 83dfc66..2bd654d 100644 --- a/docs/rules/event-names.md +++ b/docs/rules/event-names.md @@ -11,7 +11,7 @@ While the XState library neither enforces nor recommends any particular format f - camelCase - regular expression -The default MACRO*CASE for event names is an \_unofficial* convention, typically used within the XState community. +The default MACRO*CASE for event names is an *unofficial* convention, typically used within the XState community. Examples of **incorrect** code for this rule: From d8f7ca1a8f2ded76d3e9057d21683036bf60c402 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 10:42:06 +0200 Subject: [PATCH 17/43] test(tests): make the tests run only from the rules dir --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 762f953..68ff25a 100644 --- a/jest.config.js +++ b/jest.config.js @@ -150,7 +150,7 @@ module.exports = { // "**/__tests__/**/*.[jt]s?(x)", // "**/?(*.)+(spec|test).[tj]s?(x)" // ], - testMatch: ['/tests/**/*.js'], + testMatch: ['/tests/lib/rules/**/*.js'], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped // testPathIgnorePatterns: [ From d461b42bbbc7121f62e262f47d3609d8d970f019 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 11:04:38 +0200 Subject: [PATCH 18/43] build(eslint): force eslint to use es2021 parser --- .eslintrc.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2669e15..d944933 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,5 +4,9 @@ "env": { "node": true, "jest": true - } + }, + "parserOptions": { + "ecmaVersion": 2021 + }, + "plugins": ["node"] } From 02976f269b408502fca65b9c8de66ff404858f8d Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 11:37:55 +0200 Subject: [PATCH 19/43] feat(spawn-usage): throw error if spawn-usage is used with xstate > 4 Using the rule no longer makes sense in XState v5 since the new API makes it impossible to call it outside of an assign function. --- README.md | 2 +- docs/rules/spawn-usage.md | 6 ++ lib/index.js | 2 - lib/rules/spawn-usage.js | 23 +++++- tests/lib/rules/spawn-usage.js | 133 +++++++++++++++++++-------------- 5 files changed, 105 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 3247234..d16a5c0 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ The default shareable configurations are for XState v5. If you use the older XSt | Rule | Description | Recommended | | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ------------------ | -| [spawn-usage](docs/rules/spawn-usage.md) | Enforce correct usage of `spawn` | :heavy_check_mark: | +| [spawn-usage](docs/rules/spawn-usage.md) | Enforce correct usage of `spawn`. **Only for XState v4!** | :heavy_check_mark: | | [no-infinite-loop](docs/rules/no-infinite-loop.md) | Detect infinite loops with eventless transitions | :heavy_check_mark: | | [no-imperative-action](docs/rules/no-imperative-action.md) | Forbid using action creators imperatively | :heavy_check_mark: | | [no-ondone-outside-compound-state](docs/rules/no-ondone-outside-compound-state.md) | Forbid onDone transitions on `atomic`, `history` and `final` nodes | :heavy_check_mark: | diff --git a/docs/rules/spawn-usage.md b/docs/rules/spawn-usage.md index 2103110..f4f5cfc 100644 --- a/docs/rules/spawn-usage.md +++ b/docs/rules/spawn-usage.md @@ -2,10 +2,16 @@ Ensure that the `spawn` function imported from xstate is used correctly. +** This rule is compatible with XState v4 only! ** + ## Rule Details The `spawn` function has to be used in the context of an assignment function. Failing to do so creates an orphaned actor which has no effect. +### XState v5 + +XState v5 changed the way the `spawn` function is accessed. This effectively eliminated the possibility of using the `spawn` function outside of the `assign` function. Therefore, this rule becomes obsolete in XState v5. Do not use it with XState v5. + Examples of **incorrect** code for this rule: ```javascript diff --git a/lib/index.js b/lib/index.js index 7a86f8a..409beb8 100644 --- a/lib/index.js +++ b/lib/index.js @@ -38,7 +38,6 @@ module.exports = { }, plugins: ['xstate'], rules: { - 'xstate/spawn-usage': 'error', 'xstate/no-infinite-loop': 'error', 'xstate/no-imperative-action': 'error', 'xstate/no-ondone-outside-compound-state': 'error', @@ -62,7 +61,6 @@ module.exports = { }, plugins: ['xstate'], rules: { - 'xstate/spawn-usage': 'error', 'xstate/no-infinite-loop': 'error', 'xstate/no-imperative-action': 'error', 'xstate/no-ondone-outside-compound-state': 'error', diff --git a/lib/rules/spawn-usage.js b/lib/rules/spawn-usage.js index 697b6fd..ab6c78c 100644 --- a/lib/rules/spawn-usage.js +++ b/lib/rules/spawn-usage.js @@ -1,8 +1,17 @@ 'use strict' +/** + * This rule is relevant only for XState v4. + * + */ const getDocsUrl = require('../utils/getDocsUrl') const { isFunctionExpression, isIIFE } = require('../utils/predicates') const XStateDetector = require('../utils/XStateDetector') +const getSettings = require('../utils/getSettings') + +// TODO instead of the detector, consider using: +// context.getDeclaredVariables(node) +// context.sourceCode.getScope(node).variables function isAssignCall(node) { return node.type === 'CallExpression' && node.callee.name === 'assign' @@ -30,8 +39,6 @@ function isInsideAssignerFunction(node) { if (isAssignCall(parent)) { return false } - // TODO it's possible that a function expression inside assigner function - // does not get called, so nothing is ever spawned parent = parent.parent } return false @@ -55,6 +62,18 @@ module.exports = { create: function (context) { const xstateDetector = new XStateDetector() + const { version } = getSettings(context) + if (version !== 4) { + throw new Error(`Rule "spawn-usage" should be used with XState v4 only! Your XState version: ${version}. Either remove this rule from your ESLint config or set the correct version of XState in the config: + { + "settings": { + "xstate": { + "version": 4 + } + } + } +`) + } return { ...xstateDetector.visitors, diff --git a/tests/lib/rules/spawn-usage.js b/tests/lib/rules/spawn-usage.js index a846696..58f7b7c 100644 --- a/tests/lib/rules/spawn-usage.js +++ b/tests/lib/rules/spawn-usage.js @@ -1,45 +1,66 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/spawn-usage') +const { withVersion } = require('../utils/settings') const tests = { valid: [ // not imported from xstate - ignore the rule - ` + withVersion( + 4, + ` spawn(x) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign({ ref: () => spawn(x) }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign({ ref: () => spawn(x) }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign({ ref: () => spawn(x) }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign(() => ({ ref: spawn(x, 'id') })) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign(() => { return { ref: spawn(x) } }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign(() => { const ref = spawn(x) @@ -47,8 +68,11 @@ const tests = { ref, } }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign(() => { const start = () => spawn(x) @@ -56,29 +80,41 @@ const tests = { ref: start() } }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign({ ref: function() { return spawn(x) } }) - `, ` + ), + withVersion( + 4, + ` import { spawn } from 'xstate' assign(function() { return { ref: spawn(x, 'id') } }) - `, - // other import types ` + ), + // other import types + withVersion( + 4, + ` import { spawn as foo } from 'xstate' assign({ ref: () => foo(x) }) - `, ` + ), + withVersion( + 4, + ` import xs from 'xstate' const { spawn } = xs const foo = xs.spawn @@ -89,8 +125,11 @@ const tests = { ref3: () => xs.spawn(x), ref4: () => xs['spawn'](x), }) - `, ` + ), + withVersion( + 4, + ` import * as xs from 'xstate' const { spawn } = xs const foo = xs.spawn @@ -101,24 +140,25 @@ const tests = { ref3: () => xs.spawn(x), ref4: () => xs['spawn'](x), }) - `, + ` + ), ], invalid: [ - { + withVersion(4, { code: ` import { spawn } from 'xstate' spawn(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` import { spawn } from 'xstate' assign(spawn(x)) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` import { spawn } from 'xstate' assign({ @@ -126,8 +166,8 @@ const tests = { }) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` import { spawn } from 'xstate' assign((() => ({ @@ -135,16 +175,16 @@ const tests = { }))()) `, errors: [{ messageId: 'invalidCallContext' }], - }, + }), // test other import types with a single invalid call - { + withVersion(4, { code: ` import { spawn as foo } from 'xstate' foo(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` import xs from 'xstate' const { spawn } = xs @@ -162,8 +202,8 @@ const tests = { { messageId: 'invalidCallContext' }, { messageId: 'invalidCallContext' }, ], - }, - { + }), + withVersion(4, { code: ` import * as xs from 'xstate' const { spawn } = xs @@ -181,54 +221,35 @@ const tests = { { messageId: 'invalidCallContext' }, { messageId: 'invalidCallContext' }, ], - }, - { + }), + withVersion(4, { code: ` const { spawn } = require('xstate') spawn(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` const spawn = require('xstate').spawn spawn(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` const spawn = require('xstate')['spawn'] spawn(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - { + }), + withVersion(4, { code: ` const xs = require('xstate') xs.spawn(x) `, errors: [{ messageId: 'invalidCallContext' }], - }, - // { - // code: ` - // import xs from 'xstate' - // xs.spawn(x) - // `, - // errors: [{ messageId: 'invalidCallContext' }], - // }, - // TODO extend the rule to catch this use case - // { - // code: ` - // assign(() => { - // const start = () => spawn(x) - // return { - // ref: start - // } - // }) - // `, - // errors: [{ messageId: 'spawnNeverCalled' }], - // }, + }), ], } From ff8b7c85574fa6c8077bc256d69433433bc16480 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 13:07:29 +0200 Subject: [PATCH 20/43] ci(github): trigger build on the next branch --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16f3b96..853c3c1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,7 @@ name: Release on: push: branches: + - next - master permissions: From 7de8da8c16546b77dccdec3ff815bb8134f07e3c Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 17 Aug 2023 13:24:41 +0200 Subject: [PATCH 21/43] docs: update the README --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d16a5c0..5ead5bc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # eslint-plugin-xstate -TODO add prefer-predictable, no-auto-forward + their docs - ESLint plugin to check for common mistakes and enforce good practices when using [XState library](https://xstate.js.org/). [![npm version](https://img.shields.io/npm/v/eslint-plugin-xstate)](https://npmjs.com/package/eslint-plugin-xstate) @@ -75,8 +73,8 @@ There is also an `all` configuration which includes every available rule. It enf } ``` -### XState v4 -The default shareable configurations are for XState v5. If you use the older XState v4, append `_v4` to the name of the configuration you want to use. +### XState Version +The default shareable configurations are for XState v5. If you use XState version 4, append `_v4` to the name of the configuration you want to use. ```json { @@ -90,6 +88,17 @@ The default shareable configurations are for XState v5. If you use the older XSt } ``` +If you do not use shareable configs, you need to manually specify the XState version in the ESLint config (defaults to 5): +```json +{ + "settings": { + "xstate": { + "version": 4 + } + } +} +``` + ## Supported Rules ### Possible Errors From 69ff4241433f76f27df087f87cccc2bbe9ea3a52 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Mon, 21 Aug 2023 12:35:44 +0200 Subject: [PATCH 22/43] feat(no-invalid-transition-props): add error for invalid props within "always" transitions --- lib/rules/no-invalid-transition-props.js | 10 +- .../lib/rules/no-invalid-transition-props.js | 106 ++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/lib/rules/no-invalid-transition-props.js b/lib/rules/no-invalid-transition-props.js index be10b3d..ab9037d 100644 --- a/lib/rules/no-invalid-transition-props.js +++ b/lib/rules/no-invalid-transition-props.js @@ -4,15 +4,15 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isObjectExpression, isArrayExpression } = require('../utils/predicates') const getSettings = require('../utils/getSettings') -const validProperties = { +const validTransitionProperties = { 4: ['target', 'cond', 'actions', 'in', 'internal', 'description'], 5: ['target', 'guard', 'actions', 'reenter', 'description'], } function isValidTransitionProperty(property, version) { return ( - validProperties[version] && - validProperties[version].includes(property.key.name) + validTransitionProperties[version] && + validTransitionProperties[version].includes(property.key.name) ) } @@ -36,6 +36,9 @@ const globalEventTransitionArrayDeclaration = const onDoneOrOnErrorTransitionDeclaration = 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^onDone$|^onError$/]' +const alwaysTransitionDeclaration = + 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property > ObjectExpression > Property[key.name="always"] > ArrayExpression' + module.exports = { meta: { type: 'problem', @@ -115,6 +118,7 @@ module.exports = { [globalEventTransitionArrayDeclaration]: checkTransitionArrayDeclaration, [onDoneOrOnErrorTransitionDeclaration]: checkTransitionDeclaration, + [alwaysTransitionDeclaration]: checkTransitionArrayDeclaration, } }, } diff --git a/tests/lib/rules/no-invalid-transition-props.js b/tests/lib/rules/no-invalid-transition-props.js index 5c2dc04..671bd06 100644 --- a/tests/lib/rules/no-invalid-transition-props.js +++ b/tests/lib/rules/no-invalid-transition-props.js @@ -134,6 +134,43 @@ const tests = { }) ` ), + // transitions within the "always" block + withVersion( + 4, + ` + createMachine({ + states: { + deciding: { + always: [ + { + cond: 'myGuard', + target: 'active', + actions: [], + } + ] + } + } + }) + ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + deciding: { + always: [ + { + guard: 'myGuard', + target: 'active', + actions: [], + } + ] + } + } + }) + ` + ), ], invalid: [ withVersion(4, { @@ -300,6 +337,75 @@ const tests = { { messageId: 'invalidTransitionProperty', data: { propName: 'entry' } }, ], }), + // transitions within the "always" block + withVersion(4, { + code: ` + createMachine({ + states: { + deciding: { + always: [ + { + unknown: '???', + cond: 'myGuard', + guard: '???', + invoke: '???', + target: 'active', + actions: [], + } + ] + } + } + }) + `, + errors: [ + { + messageId: 'invalidTransitionProperty', + data: { propName: 'unknown' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'guard' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'invoke' }, + }, + ], + }), + withVersion(5, { + code: ` + createMachine({ + states: { + deciding: { + always: [ + { + unknown: '???', + cond: '???', + guard: 'myGuard', + invoke: '???', + target: 'active', + actions: [], + } + ] + } + } + }) + `, + errors: [ + { + messageId: 'invalidTransitionProperty', + data: { propName: 'unknown' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'cond' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'invoke' }, + }, + ], + }), ], } From 4c7c201a7df7af69cac6ac28d5deb1e409927525 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Mon, 21 Aug 2023 12:54:13 +0200 Subject: [PATCH 23/43] feat(no-invalid-conditional-action): add a new rule for linting conditional actions Add a rule for linting conditional actions declared with the `choose` action creator. --- README.md | 4 +- docs/rules/no-invalid-conditional-action.md | 142 ++++++++++ lib/index.js | 5 + lib/rules/no-invalid-conditional-action.js | 122 +++++++++ .../rules/no-invalid-conditional-action.js | 247 ++++++++++++++++++ 5 files changed, 519 insertions(+), 1 deletion(-) create mode 100644 docs/rules/no-invalid-conditional-action.md create mode 100644 lib/rules/no-invalid-conditional-action.js create mode 100644 tests/lib/rules/no-invalid-conditional-action.js diff --git a/README.md b/README.md index 5ead5bc..b122d80 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ Then configure the rules you want to use under the rules section. "xstate/no-misplaced-on-transition": "error", "xstate/no-invalid-transition-props": "error", "xstate/no-invalid-state-props": "error", + "xstate/no-invalid-conditional-action": "error", "xstate/no-async-guard": "error", "xstate/event-names": ["warn", "macroCase"], "xstate/state-names": ["warn", "camelCase"], @@ -105,7 +106,7 @@ If you do not use shareable configs, you need to manually specify the XState ver | Rule | Description | Recommended | | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ------------------ | -| [spawn-usage](docs/rules/spawn-usage.md) | Enforce correct usage of `spawn`. **Only for XState v4!** | :heavy_check_mark: | +| [spawn-usage](docs/rules/spawn-usage.md) | Enforce correct usage of `spawn`. **Only for XState v4!** | :heavy_check_mark: | | [no-infinite-loop](docs/rules/no-infinite-loop.md) | Detect infinite loops with eventless transitions | :heavy_check_mark: | | [no-imperative-action](docs/rules/no-imperative-action.md) | Forbid using action creators imperatively | :heavy_check_mark: | | [no-ondone-outside-compound-state](docs/rules/no-ondone-outside-compound-state.md) | Forbid onDone transitions on `atomic`, `history` and `final` nodes | :heavy_check_mark: | @@ -115,6 +116,7 @@ If you do not use shareable configs, you need to manually specify the XState ver | [no-invalid-transition-props](docs/rules/no-invalid-transition-props.md) | Forbid invalid properties in transition declarations | :heavy_check_mark: | | [no-invalid-state-props](docs/rules/no-invalid-state-props.md) | Forbid invalid properties in state node declarations | :heavy_check_mark: | | [no-async-guard](docs/rules/no-async-guard.md) | Forbid asynchronous guard functions | :heavy_check_mark: | +| [no-invalid-conditional-action](docs/rules/no-invalid-conditional-action.md) | Forbid invalid declarations inside the `choose` action creator | :heavy_check_mark: | ### Best Practices diff --git a/docs/rules/no-invalid-conditional-action.md b/docs/rules/no-invalid-conditional-action.md new file mode 100644 index 0000000..2587347 --- /dev/null +++ b/docs/rules/no-invalid-conditional-action.md @@ -0,0 +1,142 @@ +# Forbid invalid properties in conditional actions + +Forbid unrecognized properties in conditional actions passed to the `choose` action creator. + +## Rule Details + +Conditional action declarations may contains only `cond` and `actions` props. + +### XState v5 + +In XState v5, the `cond` propery has been renamed to `guard`. + +Examples of **incorrect** code for this rule: + +```javascript +// ❌ (XState v4) +createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([ + { + cond: 'myGuard', + actions: [], + foo: 'bar', // ??? + guard: 'myGuard', // ??? + invoke: 'myService', // ??? + }, + ]), + }, + }, + entry: choose([ + { + cond: 'myGuard', + actions: [], + foo: 'bar', // ??? + guard: 'myGuard', // ??? + invoke: 'myService', // ??? + }, + ]), + }, + }, +}) + +// ❌ (XState v5) +createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([ + { + guard: 'myGuard', + actions: [], + cond: 'myGuard', // ??? + }, + ]), + }, + }, + entry: choose([ + { + guard: 'myGuard', + actions: [], + cond: 'myGuard', // ??? + }, + ]), + }, + }, +}) + +// ❌ The first argument passed to "choose" must be an array +createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: [ + choose(), // ??? + choose({}), // ??? + choose(() => []), // ??? + ], + }, + }, + entry: choose(''), // ??? + exit: choose(null), // ??? + }, + }, +}) +``` + +Examples of **correct** code for this rule: + +```javascript +// ✅ only recognized properties inside conditional actions (XState v4) +createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([ + { + cond: 'myGuard', + actions: [], + }, + ]), + }, + }, + entry: choose([ + { + cond: 'myGuard', + actions: [], + }, + ]), + }, + }, +}) + +// ✅ only recognized properties inside conditional actions (XState v5) +createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([ + { + guard: 'myGuard', + actions: [], + }, + ]), + }, + }, + entry: choose([ + { + guard: 'myGuard', + actions: [], + }, + ]), + }, + }, +}) +``` diff --git a/lib/index.js b/lib/index.js index 409beb8..b680df0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -27,6 +27,7 @@ module.exports = { 'no-invalid-transition-props': require('./rules/no-invalid-transition-props'), 'no-invalid-state-props': require('./rules/no-invalid-state-props'), 'no-async-guard': require('./rules/no-async-guard'), + 'no-invalid-conditional-action': require('./rules/no-invalid-conditional-action'), }, configs: { // Requires: xstate@5 @@ -48,6 +49,7 @@ module.exports = { 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', + 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', 'xstate/no-auto-forward': 'error', }, @@ -75,6 +77,7 @@ module.exports = { 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', + 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', }, }, @@ -98,6 +101,7 @@ module.exports = { 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', + 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', }, }, @@ -125,6 +129,7 @@ module.exports = { 'xstate/no-misplaced-on-transition': 'error', 'xstate/no-invalid-transition-props': 'error', 'xstate/no-invalid-state-props': 'error', + 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', }, }, diff --git a/lib/rules/no-invalid-conditional-action.js b/lib/rules/no-invalid-conditional-action.js new file mode 100644 index 0000000..71f437c --- /dev/null +++ b/lib/rules/no-invalid-conditional-action.js @@ -0,0 +1,122 @@ +'use strict' + +const getDocsUrl = require('../utils/getDocsUrl') +const { + isFunctionExpression, + isArrayExpression, + isObjectExpression, +} = require('../utils/predicates') +const getSettings = require('../utils/getSettings') + +const validChooseActionProperty = { + 4: ['cond', 'actions'], + 5: ['guard', 'actions'], +} +function isValidChooseActionProperty(property, version) { + return ( + validChooseActionProperty[version] && + validChooseActionProperty[version].includes(property.key.name) + ) +} + +const propertyOfChoosableActionObject = + 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' +const chooseFunctionCall = + 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"]' + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'forbid invalid usage of the "choose" action creator', + category: 'Possible Errors', + url: getDocsUrl('no-invalid-conditional-action'), + recommended: true, + }, + schema: [], + messages: { + invalidConditionalActionProperty: + '"{{propName}}" is not a valid property for a conditional action.', + invalidArgumentForChoose: + '"{{argType}}" cannot be passed to the "choose" action creator. Pass an array instead.', + missingFirstArgumentForChoose: + 'The "choose" action creator requires an argument.', + }, + }, + + create: function (context) { + const { version } = getSettings(context) + + return { + [propertyOfChoosableActionObject]: + function checkChooseActionObjectProperty(node) { + if (!isValidChooseActionProperty(node, version)) { + context.report({ + node, + messageId: 'invalidConditionalActionProperty', + data: { propName: node.key.name }, + }) + } + }, + [chooseFunctionCall]: function checkChooseFirstArgument(node) { + if (node.arguments.length < 1) { + context.report({ + node, + messageId: 'missingFirstArgumentForChoose', + }) + return + } + const firstArgument = node.arguments[0] + if (isArrayExpression(firstArgument)) { + return + } + if (isObjectExpression(firstArgument)) { + context.report({ + node, + messageId: 'invalidArgumentForChoose', + data: { argType: 'object' }, + }) + return + } + if (firstArgument.type === 'Literal') { + context.report({ + node, + messageId: 'invalidArgumentForChoose', + data: { + argType: + firstArgument.value === null + ? 'null' + : typeof firstArgument.value, + }, + }) + return + } + if (isFunctionExpression(firstArgument)) { + context.report({ + node, + messageId: 'invalidArgumentForChoose', + data: { argType: 'function' }, + }) + return + } + if (firstArgument.type === 'Identifier') { + context.report({ + node, + messageId: 'invalidArgumentForChoose', + data: { + argType: + firstArgument.name === 'undefined' ? 'undefined' : 'identifier', + }, + }) + return + } + + context.report({ + node, + messageId: 'invalidArgumentForChoose', + data: { argType: firstArgument.type }, + }) + }, + } + }, +} diff --git a/tests/lib/rules/no-invalid-conditional-action.js b/tests/lib/rules/no-invalid-conditional-action.js new file mode 100644 index 0000000..6c11a3b --- /dev/null +++ b/tests/lib/rules/no-invalid-conditional-action.js @@ -0,0 +1,247 @@ +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-invalid-conditional-action') +const { withVersion } = require('../utils/settings') + +const tests = { + valid: [ + // transitions within the choose action creator + withVersion( + 4, + ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + cond: 'myGuard', + actions: [], + }]), + }, + }, + entry: choose([{ + cond: 'myGuard', + actions: [], + }]), + } + } + }) + ` + ), + withVersion( + 5, + ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + guard: 'myGuard', + actions: [], + }]), + }, + }, + entry: choose([{ + guard: 'myGuard', + actions: [], + }]), + } + } + }) + ` + ), + ], + invalid: [ + // transitions within the choose action creator + withVersion(4, { + code: ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + } + } + }) + `, + errors: [ + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'guard' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'guard' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + ], + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + cond: '???', + guard: 'myGuard', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + cond: '???', + guard: 'myGuard', + invoke: '???', + actions: [], + }]), + } + } + }) + `, + errors: [ + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'cond' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'cond' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + ], + }), + withVersion(4, { + code: ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: [ + choose(), + choose({}), + choose(() => []), + choose(undefined), + ], + }, + }, + entry: choose(''), + exit: choose(null), + } + } + }) + `, + errors: [ + { + messageId: 'missingFirstArgumentForChoose', + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'object' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'function' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'undefined' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'string' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'null' }, + }, + ], + }), + withVersion(5, { + code: ` + createMachine({ + states: { + active: { + on: { + EVENT1: { + actions: [ + choose(), + choose({}), + choose(() => []), + choose(undefined), + ], + }, + }, + entry: choose(''), + exit: choose(null), + } + } + }) + `, + errors: [ + { + messageId: 'missingFirstArgumentForChoose', + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'object' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'function' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'undefined' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'string' }, + }, + { + messageId: 'invalidArgumentForChoose', + data: { argType: 'null' }, + }, + ], + }), + ], +} + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 6, + }, +}) +ruleTester.run('no-invalid-conditional-action', rule, tests) From 3136344364d11635266ea1b64f2053a859bf0fb6 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 24 Aug 2023 21:52:16 +0200 Subject: [PATCH 24/43] fix(entry-exit-action): recognize "guard" in entry/exit actions with xstate v5 --- lib/rules/entry-exit-action.js | 49 ++++++++++------ lib/utils/getSelectorPrefix.js | 7 +++ lib/utils/isXStateLintingEnforced.js | 3 + tests/lib/rules/entry-exit-action.js | 88 +++++++++++++++++++++++++--- 4 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 lib/utils/getSelectorPrefix.js create mode 100644 lib/utils/isXStateLintingEnforced.js diff --git a/lib/rules/entry-exit-action.js b/lib/rules/entry-exit-action.js index 4b3fcec..2b84252 100644 --- a/lib/rules/entry-exit-action.js +++ b/lib/rules/entry-exit-action.js @@ -7,9 +7,14 @@ const { isFunctionExpression, isCallExpression, } = require('../utils/predicates') +const getSelectorPrefix = require('../utils/getSelectorPrefix') +const getSettings = require('../utils/getSettings') -function isObjectWithGuard(node) { - return node.type === 'ObjectExpression' && hasProperty('cond', node) +function isObjectWithGuard(node, version) { + return ( + node.type === 'ObjectExpression' && + hasProperty(version > 4 ? 'guard' : 'cond', node) + ) } function isValidAction(node) { @@ -21,17 +26,25 @@ function isValidAction(node) { ) } -const entryActionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name!="states"] > ObjectExpression > Property[key.name="entry"]' +const entryActionDeclaration = (prefix) => + prefix === '' + ? 'Property[key.name!="states"] > ObjectExpression > Property[key.name="entry"]' + : `${prefix}Property[key.name!="states"] > ObjectExpression > Property[key.name="entry"]` -const rootEntryActionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:nth-child(1) > Property[key.name="entry"]' +const rootEntryActionDeclaration = (prefix) => + prefix === '' + ? 'Property[key.name="entry"]' + : `${prefix}> ObjectExpression:nth-child(1) > Property[key.name="entry"]` -const exitActionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name!="states"] > ObjectExpression > Property[key.name="exit"]' +const exitActionDeclaration = (prefix) => + prefix === '' + ? 'Property[key.name!="states"] > ObjectExpression > Property[key.name="exit"]' + : `${prefix}Property[key.name!="states"] > ObjectExpression > Property[key.name="exit"]` -const rootExitActionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:nth-child(1) > Property[key.name="exit"]' +const rootExitActionDeclaration = (prefix) => + prefix === '' + ? 'Property[key.name="exit"]' + : `${prefix}> ObjectExpression:nth-child(1) > Property[key.name="exit"]` module.exports = { meta: { @@ -48,7 +61,7 @@ module.exports = { invalidGuardedEntryAction: 'Invalid declaration of an "entry" action. Use the "choose" or "pure" action creators to specify a conditional entry action.', invalidGuardedExitAction: - 'Invalid declaration of an "entry" action. Use the "choose" or "pure" action creators to specify a conditional entry action.', + 'Invalid declaration of an "exit" action. Use the "choose" or "pure" action creators to specify a conditional exit action.', invalidEntryAction: 'The "entry" action has an invalid value. Specify a function, string, variable, action creator call, action object, or an array of those.', invalidExitAction: @@ -57,8 +70,10 @@ module.exports = { }, create: function (context) { + const { version } = getSettings(context) + const prefix = getSelectorPrefix(context.sourceCode) const validateAction = (actionType) => (node) => { - if (isObjectWithGuard(node.value)) { + if (isObjectWithGuard(node.value, version)) { context.report({ node, messageId: @@ -80,7 +95,7 @@ module.exports = { if (node.value.type === 'ArrayExpression') { node.value.elements.forEach((element) => { - if (isObjectWithGuard(element)) { + if (isObjectWithGuard(element, version)) { context.report({ node: element, messageId: @@ -101,10 +116,10 @@ module.exports = { } } return { - [entryActionDeclaration]: validateAction('entry'), - [rootEntryActionDeclaration]: validateAction('entry'), - [exitActionDeclaration]: validateAction('exit'), - [rootExitActionDeclaration]: validateAction('exit'), + [entryActionDeclaration(prefix)]: validateAction('entry'), + [rootEntryActionDeclaration(prefix)]: validateAction('entry'), + [exitActionDeclaration(prefix)]: validateAction('exit'), + [rootExitActionDeclaration(prefix)]: validateAction('exit'), } }, } diff --git a/lib/utils/getSelectorPrefix.js b/lib/utils/getSelectorPrefix.js new file mode 100644 index 0000000..859e667 --- /dev/null +++ b/lib/utils/getSelectorPrefix.js @@ -0,0 +1,7 @@ +const isXStateLintingEnforced = require('./isXStateLintingEnforced') + +module.exports = function getSelectorPrefix(sourceCode) { + return isXStateLintingEnforced(sourceCode) + ? '' + : 'CallExpression[callee.name=/^createMachine$|^Machine$/] ' +} diff --git a/lib/utils/isXStateLintingEnforced.js b/lib/utils/isXStateLintingEnforced.js new file mode 100644 index 0000000..0944842 --- /dev/null +++ b/lib/utils/isXStateLintingEnforced.js @@ -0,0 +1,3 @@ +module.exports = function isXStateLintingEnforced(sourceCode) { + return sourceCode.getAllComments().some(x => x.type === 'Block' && x.value === ' eslint-plugin-xstate-include ') +} diff --git a/tests/lib/rules/entry-exit-action.js b/tests/lib/rules/entry-exit-action.js index 353f7a1..1389d45 100644 --- a/tests/lib/rules/entry-exit-action.js +++ b/tests/lib/rules/entry-exit-action.js @@ -1,15 +1,21 @@ const RuleTester = require('eslint').RuleTester const rule = require('../../../lib/rules/entry-exit-action') +const { withVersion } = require('../utils/settings') const tests = { valid: [ - ` + withVersion( + 4, + ` createMachine({ entry: 'someAction', exit: ['someAction', () => {}, assign({ foo: true }), someAction], }) - `, ` + ), + withVersion( + 4, + ` createMachine({ entry: choose([ { @@ -21,10 +27,36 @@ const tests = { }, ]), }) - `, + ` + ), + withVersion( + 5, + ` + createMachine({ + entry: 'someAction', + exit: ['someAction', () => {}, assign({ foo: true }), someAction], + }) + ` + ), + withVersion( + 5, + ` + createMachine({ + entry: choose([ + { + guard: 'someGuard', + actions: 'someAction', + }, + { + actions: 'defaultAction', + }, + ]), + }) + ` + ), ], invalid: [ - { + withVersion(4, { code: ` createMachine({ entry: [ @@ -53,8 +85,50 @@ const tests = { { messageId: 'invalidGuardedExitAction' }, { messageId: 'invalidExitAction' }, ], - }, - { + }), + withVersion(4, { + code: ` + createMachine({ + entry: 123, // numbers are invalid + exit: {}, // objects without a "type" property are invalid + }) + `, + errors: [ + { messageId: 'invalidEntryAction' }, + { messageId: 'invalidExitAction' }, + ], + }), + withVersion(5, { + code: ` + createMachine({ + entry: [ + { + guard: 'someGuard', + actions: 'someAction', + }, + { + actions: 'defaultAction', + }, + ], + exit: [ + { + guard: 'someGuard', + actions: 'someAction', + }, + { + actions: 'defaultAction', + }, + ], + }) + `, + errors: [ + { messageId: 'invalidGuardedEntryAction' }, + { messageId: 'invalidEntryAction' }, + { messageId: 'invalidGuardedExitAction' }, + { messageId: 'invalidExitAction' }, + ], + }), + withVersion(5, { code: ` createMachine({ entry: 123, // numbers are invalid @@ -65,7 +139,7 @@ const tests = { { messageId: 'invalidEntryAction' }, { messageId: 'invalidExitAction' }, ], - }, + }), ], } From 48cd08956bfadea19094970f382a12ad6db10f5f Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Sat, 26 Aug 2023 16:47:23 +0200 Subject: [PATCH 25/43] feat: add a comment directive tu enforce this plugin By default, this plugin does not lint code outside of createMachine call epxressions. This commit add a comment direective eslint-plugin-xstate-include which enforces these rules over any file. fix #20 --- README.md | 14 ++ lib/rules/event-names.js | 12 +- lib/rules/invoke-usage.js | 18 ++- lib/rules/no-async-guard.js | 63 +++++--- lib/rules/no-auto-forward.js | 6 +- lib/rules/no-imperative-action.js | 10 +- lib/rules/no-infinite-loop.js | 15 +- lib/rules/no-inline-implementation.js | 125 +++++++------- lib/rules/no-invalid-conditional-action.js | 14 +- lib/rules/no-invalid-state-props.js | 113 ++++++++----- lib/rules/no-invalid-transition-props.js | 36 ++--- lib/rules/no-misplaced-on-transition.js | 33 ++-- lib/rules/no-ondone-outside-compound-state.js | 69 ++++---- lib/rules/prefer-always.js | 4 +- .../prefer-predictable-action-arguments.js | 152 +++++++++++------- lib/rules/state-names.js | 32 ++-- lib/utils/isInsideMachineDeclaration.js | 12 -- tests/lib/rules/event-names.js | 37 +++++ tests/lib/rules/no-async-guards.js | 76 +++++++++ tests/lib/rules/no-auto-forward.js | 25 +++ tests/lib/rules/no-imperative-action.js | 92 +++++++++++ tests/lib/rules/no-infinite-loop.js | 29 +++- tests/lib/rules/no-inline-implementation.js | 101 ++++++++++++ .../rules/no-invalid-conditional-action.js | 146 +++++++++++++++++ tests/lib/rules/no-invalid-state-props.js | 74 +++++++++ .../lib/rules/no-invalid-transition-props.js | 128 +++++++++++++++ tests/lib/rules/no-misplaced-on-transition.js | 37 +++++ .../rules/no-ondone-outside-compound-state.js | 57 +++++++ tests/lib/rules/prefer-always.js | 72 +++++++++ .../prefer-predictable-action-arguments.js | 70 ++++++++ tests/lib/rules/state-names.js | 98 +++++++++++ 31 files changed, 1454 insertions(+), 316 deletions(-) delete mode 100644 lib/utils/isInsideMachineDeclaration.js diff --git a/README.md b/README.md index b122d80..5856c2f 100644 --- a/README.md +++ b/README.md @@ -133,3 +133,17 @@ If you do not use shareable configs, you need to manually specify the XState ver | ---------------------------------------- | ------------------------------------------------------------------------ | ----------- | | [event-names](docs/rules/event-names.md) | Suggest consistent formatting of event names | | | [state-names](docs/rules/state-names.md) | Suggest consistent formatting of state names and prevent confusing names | | + +## Comment Directives + +By default, the plugin lints only code within the `createMachine` or `Machine` calls. However, if your machine configuration is imported from another file, you will need to enable this plugin's rules by adding a comment directive to the top of the file: + +```js +/* eslint-plugin-xstate-include */ +// 💡 This machine config will no w be linted too. +export machine = { + initial: 'active', + context: {}, + // etc +} +``` diff --git a/lib/rules/event-names.js b/lib/rules/event-names.js index 6497aee..2074be5 100644 --- a/lib/rules/event-names.js +++ b/lib/rules/event-names.js @@ -6,6 +6,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isStringLiteral } = require('../utils/predicates') const { getTypeProperty } = require('../utils/selectors') const { init, last } = require('../utils/arrays') +const getSelectorPrefix = require('../utils/getSelectorPrefix') const toMacroCase = (string) => { const words = string.split('.').filter(Boolean) @@ -61,8 +62,10 @@ function containsWildcardOrDot(name) { return wildcardOrDot.test(name) } -const selectorSendEvent = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name=/^send$|^sendParent$|^respond$|^raise$/]' +const selectorSendEvent = (prefix) => + prefix === '' + ? 'CallExpression[callee.name=/^send$|^sendTo$|^sendParent$|^respond$|^raise$|^forwardTo$/]' + : `${prefix}CallExpression[callee.name=/^send$|^sendTo$|^sendParent$|^respond$|^raise$|^forwardTo$/]` /** * Default regular expression for the regex option. @@ -107,6 +110,7 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const mode = context.options[0] || 'macroCase' const regexOption = mode === 'regex' @@ -115,7 +119,7 @@ module.exports = { const regex = regexOption !== null ? new RegExp(regexOption) : null return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property': + [`${prefix}Property[key.name="on"] > ObjectExpression > Property`]: function (node) { // key names [varName] are dynamic values and cannot be linted if (node.computed) { @@ -156,7 +160,7 @@ module.exports = { } }, - [selectorSendEvent]: function (node) { + [selectorSendEvent(prefix)]: function (node) { const eventArg = node.arguments[0] if (!eventArg) { return diff --git a/lib/rules/invoke-usage.js b/lib/rules/invoke-usage.js index 07fd565..89bc130 100644 --- a/lib/rules/invoke-usage.js +++ b/lib/rules/invoke-usage.js @@ -9,6 +9,7 @@ const { isCreateMachineCall, isCallExpression, } = require('../utils/predicates') +const getSelectorPrefix = require('../utils/getSelectorPrefix') module.exports = { meta: { @@ -30,15 +31,16 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) + return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="invoke"]': - function (node) { - if (node.value.type === 'ArrayExpression') { - node.value.elements.forEach((node) => testInvokeDefinition(node)) - } else { - testInvokeDefinition(node.value) - } - }, + [`${prefix}Property[key.name="invoke"]`]: function (node) { + if (node.value.type === 'ArrayExpression') { + node.value.elements.forEach((node) => testInvokeDefinition(node)) + } else { + testInvokeDefinition(node.value) + } + }, } function testInvokeDefinition(node) { diff --git a/lib/rules/no-async-guard.js b/lib/rules/no-async-guard.js index a814e5f..2dbae00 100644 --- a/lib/rules/no-async-guard.js +++ b/lib/rules/no-async-guard.js @@ -3,6 +3,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isFunctionExpression } = require('../utils/predicates') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function isAsyncFunctionExpression(node) { return isFunctionExpression(node) && node.async @@ -25,31 +26,43 @@ module.exports = { create: function (context) { const { version } = getSettings(context) - return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child Property[key.name=/^cond|guard$/]': - function (node) { - if (version === 4 && node.key.name !== 'cond') { - return - } - if (version > 4 && node.key.name !== 'guard') { - return - } - if (isAsyncFunctionExpression(node.value)) { - context.report({ - node: node.value, - messageId: 'guardCannotBeAsync', - }) - } - }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:nth-child(2) > Property[key.name="guards"] > ObjectExpression > Property': - function (node) { - if (isAsyncFunctionExpression(node.value)) { - context.report({ - node: node.value, - messageId: 'guardCannotBeAsync', - }) - } - }, + const prefix = getSelectorPrefix(context.sourceCode) + + function checkInlineGuard(node) { + if (version === 4 && node.key.name !== 'cond') { + return + } + if (version > 4 && node.key.name !== 'guard') { + return + } + if (isAsyncFunctionExpression(node.value)) { + context.report({ + node: node.value, + messageId: 'guardCannotBeAsync', + }) + } + } + + function checkGuardImplementation(node) { + if (isAsyncFunctionExpression(node.value)) { + context.report({ + node: node.value, + messageId: 'guardCannotBeAsync', + }) + } } + + return prefix === '' + ? { + 'Property[key.name=/^cond|guard$/]': checkInlineGuard, + 'Property[key.name="guards"] > ObjectExpression > Property': + checkGuardImplementation, + } + : { + [`${prefix}> ObjectExpression:first-child Property[key.name=/^cond|guard$/]`]: + checkInlineGuard, + [`${prefix}> ObjectExpression:nth-child(2) > Property[key.name="guards"] > ObjectExpression > Property`]: + checkGuardImplementation, + } }, } diff --git a/lib/rules/no-auto-forward.js b/lib/rules/no-auto-forward.js index 3f60ceb..466fcee 100644 --- a/lib/rules/no-auto-forward.js +++ b/lib/rules/no-auto-forward.js @@ -2,6 +2,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') module.exports = { meta: { @@ -22,9 +23,10 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="invoke"] > ObjectExpression > Property[key.name="autoForward"]': + [`${prefix}Property[key.name="invoke"] > ObjectExpression > Property[key.name="autoForward"]`]: function (node) { if (version !== 4) { context.report({ @@ -41,7 +43,7 @@ module.exports = { } }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="spawn"] > ObjectExpression > Property[key.name="autoForward"]': + [`${prefix}CallExpression[callee.name="spawn"] > ObjectExpression > Property[key.name="autoForward"]`]: function (node) { if (version !== 4) { context.report({ diff --git a/lib/rules/no-imperative-action.js b/lib/rules/no-imperative-action.js index 4e3697b..532a19a 100644 --- a/lib/rules/no-imperative-action.js +++ b/lib/rules/no-imperative-action.js @@ -2,6 +2,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') const { isKnownActionCreatorCall, @@ -60,9 +61,10 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^entry$|^exit$/] ArrowFunctionExpression CallExpression': + [`${prefix}Property[key.name=/^entry$|^exit$/] ArrowFunctionExpression CallExpression`]: function (node) { if ( isKnownActionCreatorCall(node, version) && @@ -76,7 +78,7 @@ module.exports = { } }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^entry$|^exit$/] FunctionExpression CallExpression': + [`${prefix}Property[key.name=/^entry$|^exit$/] FunctionExpression CallExpression`]: function (node) { if ( isKnownActionCreatorCall(node, version) && @@ -90,7 +92,7 @@ module.exports = { } }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="actions"] ArrowFunctionExpression CallExpression': + [`${prefix}Property[key.name="actions"] ArrowFunctionExpression CallExpression`]: function (node) { if ( isKnownActionCreatorCall(node, version) && @@ -104,7 +106,7 @@ module.exports = { } }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="actions"] FunctionExpression CallExpression': + [`${prefix}Property[key.name="actions"] FunctionExpression CallExpression`]: function (node) { if ( isKnownActionCreatorCall(node, version) && diff --git a/lib/rules/no-infinite-loop.js b/lib/rules/no-infinite-loop.js index 38f702e..7235a5d 100644 --- a/lib/rules/no-infinite-loop.js +++ b/lib/rules/no-infinite-loop.js @@ -3,7 +3,6 @@ const { pipe, map, fromMaybe, Just, Nothing } = require('sanctuary') const { allPass, complement } = require('../utils/combinators') const getDocsUrl = require('../utils/getDocsUrl') -const isInsideMachineDeclaration = require('../utils/isInsideMachineDeclaration') const { isFirstArrayItem, propertyHasName, @@ -12,6 +11,7 @@ const { isStringLiteralOrIdentifier, } = require('../utils/predicates') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function isEventlessTransitionDeclaration(node) { return node.type === 'Property' && node.key.name === 'always' @@ -159,14 +159,14 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { // always: {} // always: { actions: whatever} - 'Property[key.name="always"] > ObjectExpression': function (node) { - if (!isInsideMachineDeclaration(node)) { - return - } + [`${prefix}Property[key.name="always"] > ObjectExpression`]: function ( + node + ) { if ( !hasProperty('target', node) && !isConditionalTransition(node, version) @@ -180,11 +180,8 @@ module.exports = { // always: [{}] // always: [{ actions: whatever }] - 'Property[key.name="always"] > ArrayExpression > ObjectExpression': + [`${prefix}Property[key.name="always"] > ArrayExpression > ObjectExpression`]: function (node) { - if (!isInsideMachineDeclaration(node)) { - return - } if ( !hasProperty('target', node) && !isConditionalTransition(node, version) diff --git a/lib/rules/no-inline-implementation.js b/lib/rules/no-inline-implementation.js index 794b490..2d51d48 100644 --- a/lib/rules/no-inline-implementation.js +++ b/lib/rules/no-inline-implementation.js @@ -14,6 +14,7 @@ const { anyPass } = require('../utils/combinators') const getSettings = require('../utils/getSettings') const XStateDetector = require('../utils/XStateDetector') const isSpawnFromParametersCallExpresion = require('../utils/isSpawnFromParametersCallExpression') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function isArrayWithFunctionExpressionOrIdentifier(node) { return ( @@ -47,42 +48,46 @@ function isValidCallExpression(node, pattern = '') { } // states: { idle: { on: { EVENT: { target: 'active' }}}} -const propertyOfEventTransition = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property > ObjectExpression > Property' +const propertyOfEventTransition = (prefix) => + `${prefix}Property[key.name="on"] > ObjectExpression > Property > ObjectExpression > Property` // states: { idle: { on: { EVENT: [{ target: 'active' }]}}} -const propertyOfEventTransitionInArray = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property > ArrayExpression > ObjectExpression > Property' +const propertyOfEventTransitionInArray = (prefix) => + `${prefix}Property[key.name="on"] > ObjectExpression > Property > ArrayExpression > ObjectExpression > Property` // states: { idle: { on: [ { event: 'EVENT', target: 'active' } ]}} -const propertyOfAltEventTransitionInArray = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ArrayExpression > ObjectExpression > Property' +const propertyOfAltEventTransitionInArray = (prefix) => + `${prefix}Property[key.name="on"] > ArrayExpression > ObjectExpression > Property` -const srcPropertyInsideInvoke = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="invoke"] > ObjectExpression > Property[key.name="src"]' +const srcPropertyInsideInvoke = (prefix) => + `${prefix}Property[key.name="invoke"] > ObjectExpression > Property[key.name="src"]` -const srcPropertyInsideInvokeArray = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="invoke"] > ArrayExpression > ObjectExpression > Property[key.name="src"]' +const srcPropertyInsideInvokeArray = (prefix) => + `${prefix}Property[key.name="invoke"] > ArrayExpression > ObjectExpression > Property[key.name="src"]` -const entryExitProperty = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^entry$|^exit$/]' +const entryExitProperty = (prefix) => + `${prefix}Property[key.name=/^entry$|^exit$/]` // invoke: { onDone: { target: 'active' }} -const propertyOfOnDoneOnErrorTransition = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^onDone$|^onError$/] > ObjectExpression > Property' +const propertyOfOnDoneOnErrorTransition = (prefix) => + `${prefix}Property[key.name=/^onDone$|^onError$/] > ObjectExpression > Property` // invoke: { onDone: [{ target: 'active' }] } -const propertyOfOnDoneOnErrorTransitionInArray = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^onDone$|^onError$/] > ArrayExpression > ObjectExpression > Property' +const propertyOfOnDoneOnErrorTransitionInArray = (prefix) => + `${prefix}Property[key.name=/^onDone$|^onError$/] > ArrayExpression > ObjectExpression > Property` -const activitiesProperty = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="activities"]' +const activitiesProperty = (prefix) => + `${prefix}Property[key.name="activities"]` -const propertyOfChoosableActionObject = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' +const propertyOfChoosableActionObject = (prefix) => + prefix === '' + ? 'CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' + : `${prefix}> ObjectExpression:first-child CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property` -const propertyOfChoosableActionObjectAlt = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property' +const propertyOfChoosableActionObjectAlt = (prefix) => + prefix === '' + ? 'CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property' + : `${prefix}> ObjectExpression:first-child CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property` const defaultOptions = { allowKnownActionCreators: false, @@ -156,6 +161,7 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) const options = context.options[0] || defaultOptions @@ -247,17 +253,23 @@ module.exports = { } } + const spawnCall = (prefix) => + prefix === '' + ? 'CallExpression' + : `${prefix}> ObjectExpression:first-child CallExpression` + return { ...(version === 4 ? xstateDetector.visitors : {}), - [propertyOfEventTransition]: checkTransitionProperty, - [propertyOfEventTransitionInArray]: checkTransitionProperty, - [propertyOfAltEventTransitionInArray]: checkTransitionProperty, - [propertyOfOnDoneOnErrorTransition]: checkTransitionProperty, - [propertyOfOnDoneOnErrorTransitionInArray]: checkTransitionProperty, - [propertyOfChoosableActionObject]: checkTransitionProperty, - [propertyOfChoosableActionObjectAlt]: checkTransitionProperty, - - [activitiesProperty]: function (node) { + [propertyOfEventTransition(prefix)]: checkTransitionProperty, + [propertyOfEventTransitionInArray(prefix)]: checkTransitionProperty, + [propertyOfAltEventTransitionInArray(prefix)]: checkTransitionProperty, + [propertyOfOnDoneOnErrorTransition(prefix)]: checkTransitionProperty, + [propertyOfOnDoneOnErrorTransitionInArray(prefix)]: + checkTransitionProperty, + [propertyOfChoosableActionObject(prefix)]: checkTransitionProperty, + [propertyOfChoosableActionObjectAlt(prefix)]: checkTransitionProperty, + + [activitiesProperty(prefix)]: function (node) { if ( isFunctionExpression(node.value) || isIdentifier(node.value) || @@ -272,11 +284,11 @@ module.exports = { } }, - [srcPropertyInsideInvoke]: checkActorSrc, + [srcPropertyInsideInvoke(prefix)]: checkActorSrc, - [srcPropertyInsideInvokeArray]: checkActorSrc, + [srcPropertyInsideInvokeArray(prefix)]: checkActorSrc, - [entryExitProperty]: function (node) { + [entryExitProperty(prefix)]: function (node) { if ( isInlineAction( node.value, @@ -308,34 +320,33 @@ module.exports = { } }, - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child CallExpression': - function (node) { - if (version === 4) { - if ( - xstateDetector.isSpawnCallExpression(node) && - node.arguments[0] && - !isStringLiteral(node.arguments[0]) - ) { - context.report({ - node: node.arguments[0], - messageId: 'moveActorToOptions', - }) - } - return - } - - // In XState v5, spawn comes from arguments passed to the callback within assign() - if (!isSpawnFromParametersCallExpresion(node)) { - return - } - - if (node.arguments[0] && !isStringLiteral(node.arguments[0])) { + [spawnCall(prefix)]: function (node) { + if (version === 4) { + if ( + xstateDetector.isSpawnCallExpression(node) && + node.arguments[0] && + !isStringLiteral(node.arguments[0]) + ) { context.report({ node: node.arguments[0], messageId: 'moveActorToOptions', }) } - }, + return + } + + // In XState v5, spawn comes from arguments passed to the callback within assign() + if (!isSpawnFromParametersCallExpresion(node)) { + return + } + + if (node.arguments[0] && !isStringLiteral(node.arguments[0])) { + context.report({ + node: node.arguments[0], + messageId: 'moveActorToOptions', + }) + } + }, } }, } diff --git a/lib/rules/no-invalid-conditional-action.js b/lib/rules/no-invalid-conditional-action.js index 71f437c..97b747e 100644 --- a/lib/rules/no-invalid-conditional-action.js +++ b/lib/rules/no-invalid-conditional-action.js @@ -7,6 +7,7 @@ const { isObjectExpression, } = require('../utils/predicates') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') const validChooseActionProperty = { 4: ['cond', 'actions'], @@ -19,10 +20,10 @@ function isValidChooseActionProperty(property, version) { ) } -const propertyOfChoosableActionObject = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' -const chooseFunctionCall = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"]' +const propertyOfChoosableActionObject = (prefix) => + `${prefix}CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property` +const chooseFunctionCall = (prefix) => + `${prefix}CallExpression[callee.name="choose"]` module.exports = { meta: { @@ -45,10 +46,11 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { - [propertyOfChoosableActionObject]: + [propertyOfChoosableActionObject(prefix)]: function checkChooseActionObjectProperty(node) { if (!isValidChooseActionProperty(node, version)) { context.report({ @@ -58,7 +60,7 @@ module.exports = { }) } }, - [chooseFunctionCall]: function checkChooseFirstArgument(node) { + [chooseFunctionCall(prefix)]: function checkChooseFirstArgument(node) { if (node.arguments.length < 1) { context.report({ node, diff --git a/lib/rules/no-invalid-state-props.js b/lib/rules/no-invalid-state-props.js index 96bf71e..305fb56 100644 --- a/lib/rules/no-invalid-state-props.js +++ b/lib/rules/no-invalid-state-props.js @@ -9,6 +9,7 @@ const { } = require('../utils/predicates') const { allPass } = require('../utils/combinators') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') const validProperties = { 4: [ @@ -170,11 +171,12 @@ function validateHistoryPropertyValue(prop, context) { return true } -const stateDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property > ObjectExpression' +const stateDeclaration = (prefix) => + `${prefix}Property[key.name="states"] > ObjectExpression > Property > ObjectExpression` -const rootStateDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child' +// Without createMachine we have no way of checking whether an ObjectExpression is root state node +const rootStateDeclaration = (prefix) => + `${prefix}> ObjectExpression:first-child` module.exports = { meta: { @@ -205,9 +207,10 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { - [stateDeclaration]: function (node) { + [stateDeclaration(prefix)]: function (node) { const isHistoryNode = hasHistoryTypeProperty(node) const isCompoundStateNode = isCompoundState(node) node.properties.forEach((prop) => { @@ -256,46 +259,76 @@ module.exports = { }) }, - [rootStateDeclaration]: function (node) { - const isHistoryNode = hasHistoryTypeProperty(node) - const isCompoundStateNode = isCompoundState(node) - node.properties.forEach((prop) => { - if ( - !isHistoryNode && - (prop.key.name === 'history' || prop.key.name === 'target') - ) { - context.report({ - node: prop, - messageId: 'propAllowedOnHistoryStateOnly', - data: { propName: prop.key.name }, - }) - return + ...(prefix !== '' + ? { + [rootStateDeclaration(prefix)]: checkRootNode, } + : { + // If the createMachine prefix cannot be considered, we search for + // root state nodes by some tell-tale props: context, types + // In case of XState v4: context, tsTypes, schema + ObjectExpression(node) { + // check if it is a root state node config + if ( + version === 4 && + !( + hasProperty('context', node) || + hasProperty('tsTypes', node) || + hasProperty('schema', node) + ) + ) { + return false + } + if ( + version === 5 && + !(hasProperty('context', node) || hasProperty('types', node)) + ) { + return false + } + return checkRootNode(node) + }, + }), + } - if (prop.key.name === 'initial' && !isCompoundStateNode) { - context.report({ - node: prop, - messageId: 'initialAllowedOnlyOnCompoundNodes', - }) - return - } + function checkRootNode(node) { + const isHistoryNode = hasHistoryTypeProperty(node) + const isCompoundStateNode = isCompoundState(node) + node.properties.forEach((prop) => { + if ( + !isHistoryNode && + (prop.key.name === 'history' || prop.key.name === 'target') + ) { + context.report({ + node: prop, + messageId: 'propAllowedOnHistoryStateOnly', + data: { propName: prop.key.name }, + }) + return + } - if (!isValidRootStateProperty(prop, version)) { - context.report({ - node: prop, - messageId: 'invalidRootStateProperty', - data: { propName: prop.key.name }, - }) - return - } + if (prop.key.name === 'initial' && !isCompoundStateNode) { + context.report({ + node: prop, + messageId: 'initialAllowedOnlyOnCompoundNodes', + }) + return + } - if (!validateTypePropertyValue(prop, context)) { - return - } + if (!isValidRootStateProperty(prop, version)) { + context.report({ + node: prop, + messageId: 'invalidRootStateProperty', + data: { propName: prop.key.name }, + }) + return + } - validateHistoryPropertyValue(prop, context) - }) - }, + if (!validateTypePropertyValue(prop, context)) { + return + } + + validateHistoryPropertyValue(prop, context) + }) } }, } diff --git a/lib/rules/no-invalid-transition-props.js b/lib/rules/no-invalid-transition-props.js index ab9037d..5ef24c2 100644 --- a/lib/rules/no-invalid-transition-props.js +++ b/lib/rules/no-invalid-transition-props.js @@ -3,6 +3,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isObjectExpression, isArrayExpression } = require('../utils/predicates') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') const validTransitionProperties = { 4: ['target', 'cond', 'actions', 'in', 'internal', 'description'], @@ -19,25 +20,19 @@ function isValidTransitionProperty(property, version) { // e.g. // states: { idle: { on: { EVENT: { target: 'active' }}}} // states: { idle: { on: { EVENT: [{ target: 'active' }]}}} -const eventTransitionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property > ObjectExpression > Property[key.name="on"] > ObjectExpression > Property' - -const globalEventTransitionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression > Property[key.name="on"] > ObjectExpression > Property' +const eventTransitionDeclaration = (prefix) => + `${prefix}ObjectExpression > Property[key.name="on"] > ObjectExpression > Property` // e.g. // states: { idle: { on: [ { event: 'EVENT', target: 'active' } ]}} -const eventTransitionArrayDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property > ObjectExpression > Property[key.name="on"] > ArrayExpression' - -const globalEventTransitionArrayDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression > Property[key.name="on"] > ArrayExpression' +const eventTransitionArrayDeclaration = (prefix) => + `${prefix}ObjectExpression > Property[key.name="on"] > ArrayExpression` -const onDoneOrOnErrorTransitionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name=/^onDone$|^onError$/]' +const onDoneOrOnErrorTransitionDeclaration = (prefix) => + `${prefix}Property[key.name=/^onDone$|^onError$/]` -const alwaysTransitionDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property > ObjectExpression > Property[key.name="always"] > ArrayExpression' +const alwaysTransitionDeclaration = (prefix) => + `${prefix}Property[key.name="states"] > ObjectExpression > Property > ObjectExpression > Property[key.name="always"] > ArrayExpression` module.exports = { meta: { @@ -56,6 +51,7 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) function checkTransitionDeclaration(node) { const transitionValue = node.value @@ -111,14 +107,14 @@ module.exports = { } return { - [eventTransitionDeclaration]: checkTransitionDeclaration, - [globalEventTransitionDeclaration]: checkTransitionDeclaration, + [eventTransitionDeclaration(prefix)]: checkTransitionDeclaration, - [eventTransitionArrayDeclaration]: checkTransitionArrayDeclaration, - [globalEventTransitionArrayDeclaration]: checkTransitionArrayDeclaration, + [eventTransitionArrayDeclaration(prefix)]: + checkTransitionArrayDeclaration, - [onDoneOrOnErrorTransitionDeclaration]: checkTransitionDeclaration, - [alwaysTransitionDeclaration]: checkTransitionArrayDeclaration, + [onDoneOrOnErrorTransitionDeclaration(prefix)]: + checkTransitionDeclaration, + [alwaysTransitionDeclaration(prefix)]: checkTransitionArrayDeclaration, } }, } diff --git a/lib/rules/no-misplaced-on-transition.js b/lib/rules/no-misplaced-on-transition.js index ab6936c..cf2581f 100644 --- a/lib/rules/no-misplaced-on-transition.js +++ b/lib/rules/no-misplaced-on-transition.js @@ -2,6 +2,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { isWithinInvoke } = require('../utils/predicates') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function isWithinStatesDeclaration(node) { const parentProp = node.parent.parent @@ -27,23 +28,23 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"]': - function (node) { - if (isWithinInvoke(node)) { - context.report({ - node, - messageId: 'onTransitionInsideInvokeForbidden', - }) - return - } - if (isWithinStatesDeclaration(node)) { - context.report({ - node, - messageId: 'onTransitionInsideStatesForbidden', - }) - } - }, + [`${prefix}Property[key.name="on"]`]: function (node) { + if (isWithinInvoke(node)) { + context.report({ + node, + messageId: 'onTransitionInsideInvokeForbidden', + }) + return + } + if (isWithinStatesDeclaration(node)) { + context.report({ + node, + messageId: 'onTransitionInsideStatesForbidden', + }) + } + }, } }, } diff --git a/lib/rules/no-ondone-outside-compound-state.js b/lib/rules/no-ondone-outside-compound-state.js index f468f28..f95dcbf 100644 --- a/lib/rules/no-ondone-outside-compound-state.js +++ b/lib/rules/no-ondone-outside-compound-state.js @@ -3,6 +3,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const { getTypeProperty } = require('../utils/selectors') const { hasProperty, isWithinInvoke } = require('../utils/predicates') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function isWithinCompoundStateNode(node) { const stateNode = node.parent @@ -61,44 +62,44 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="onDone"]': - function (node) { - if (isWithinInvoke(node)) { - return - } - if (isWithinCompoundStateNode(node)) { - return - } - if (isWithinParallelStateNode(node)) { - return - } - if (isWithinAtomicStateNode(node)) { - context.report({ - node, - messageId: 'onDoneOnAtomicStateForbidden', - }) - return - } - if (isWithinHistoryStateNode(node)) { - context.report({ - node, - messageId: 'onDoneOnHistoryStateForbidden', - }) - return - } - if (isWithinFinalStateNode(node)) { - context.report({ - node, - messageId: 'onDoneOnFinalStateForbidden', - }) - return - } + [`${prefix}Property[key.name="onDone"]`]: function (node) { + if (isWithinInvoke(node)) { + return + } + if (isWithinCompoundStateNode(node)) { + return + } + if (isWithinParallelStateNode(node)) { + return + } + if (isWithinAtomicStateNode(node)) { context.report({ node, - messageId: 'onDoneUsedIncorrectly', + messageId: 'onDoneOnAtomicStateForbidden', }) - }, + return + } + if (isWithinHistoryStateNode(node)) { + context.report({ + node, + messageId: 'onDoneOnHistoryStateForbidden', + }) + return + } + if (isWithinFinalStateNode(node)) { + context.report({ + node, + messageId: 'onDoneOnFinalStateForbidden', + }) + return + } + context.report({ + node, + messageId: 'onDoneUsedIncorrectly', + }) + }, } }, } diff --git a/lib/rules/prefer-always.js b/lib/rules/prefer-always.js index 3537306..e3c5ea2 100644 --- a/lib/rules/prefer-always.js +++ b/lib/rules/prefer-always.js @@ -2,6 +2,7 @@ const getDocsUrl = require('../utils/getDocsUrl') const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') module.exports = { meta: { @@ -22,9 +23,10 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property[key.value=""]': + [`${prefix}Property[key.name="on"] > ObjectExpression > Property[key.value=""]`]: function (node) { if (version !== 4) { context.report({ diff --git a/lib/rules/prefer-predictable-action-arguments.js b/lib/rules/prefer-predictable-action-arguments.js index 2c3f49d..dd520b0 100644 --- a/lib/rules/prefer-predictable-action-arguments.js +++ b/lib/rules/prefer-predictable-action-arguments.js @@ -2,6 +2,8 @@ const getDocsUrl = require('../utils/getDocsUrl') const getSettings = require('../utils/getSettings') +const { hasProperty } = require('../utils/predicates') +const getSelectorPrefix = require('../utils/getSelectorPrefix') module.exports = { meta: { @@ -24,72 +26,98 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const { version } = getSettings(context) - return { - 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child': - function (node) { - const predictableActionArgumentsProperty = node.properties.find( - (prop) => { - return prop.key.name === 'predictableActionArguments' - } - ) - if (version > 4) { - if (!predictableActionArgumentsProperty) { - return - } - context.report({ - node: predictableActionArgumentsProperty, - messageId: 'deprecatedPredictableActionArguments', - fix(fixer) { - return fixer.remove(predictableActionArgumentsProperty) - }, - }) - return - } - if (!predictableActionArgumentsProperty) { - if (node.properties.length === 0) { - context.report({ - node, - messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.replaceText( - node, - '{ predictableActionArguments: true }' - ) - }, - }) - } else { - context.report({ + function check(node) { + const predictableActionArgumentsProperty = node.properties.find( + (prop) => { + return prop.key.name === 'predictableActionArguments' + } + ) + if (version > 4) { + if (!predictableActionArgumentsProperty) { + return + } + context.report({ + node: predictableActionArgumentsProperty, + messageId: 'deprecatedPredictableActionArguments', + fix(fixer) { + return fixer.remove(predictableActionArgumentsProperty) + }, + }) + return + } + + if (!predictableActionArgumentsProperty) { + if (node.properties.length === 0) { + context.report({ + node, + messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.replaceText( node, - messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.insertTextBefore( - node.properties[0], - 'predictableActionArguments: true,\n' - ) - }, - }) - } - return - } + '{ predictableActionArguments: true }' + ) + }, + }) + } else { + context.report({ + node, + messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.insertTextBefore( + node.properties[0], + 'predictableActionArguments: true,\n' + ) + }, + }) + } + return + } - if ( - !predictableActionArgumentsProperty.value || - predictableActionArgumentsProperty.value.value !== true - ) { - context.report({ - node: predictableActionArgumentsProperty, - messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.replaceText( - predictableActionArgumentsProperty.value, - 'true' - ) - }, - }) - } - }, + if ( + !predictableActionArgumentsProperty.value || + predictableActionArgumentsProperty.value.value !== true + ) { + context.report({ + node: predictableActionArgumentsProperty, + messageId: 'preferPredictableActionArguments', + fix(fixer) { + return fixer.replaceText( + predictableActionArgumentsProperty.value, + 'true' + ) + }, + }) + } } + + return prefix !== '' + ? { + [`${prefix}> ObjectExpression:first-child`]: check, + } + : { + ObjectExpression(node) { + // check if it is a root state node config + if ( + version === 4 && + !( + hasProperty('context', node) || + hasProperty('tsTypes', node) || + hasProperty('schema', node) + ) + ) { + return false + } + if ( + version === 5 && + !(hasProperty('context', node) || hasProperty('types', node)) + ) { + return false + } + return check(node) + }, + } }, } diff --git a/lib/rules/state-names.js b/lib/rules/state-names.js index b3941ba..7efbb67 100644 --- a/lib/rules/state-names.js +++ b/lib/rules/state-names.js @@ -5,6 +5,7 @@ const { isReservedXStateWord } = require('../utils/predicates') const snakeCase = require('lodash.snakecase') const camelCase = require('lodash.camelcase') const upperFirst = require('lodash.upperfirst') +const getSelectorPrefix = require('../utils/getSelectorPrefix') function fixName(name, mode) { switch (mode) { @@ -33,16 +34,16 @@ function mustBeQuoted(string) { */ const defaultRegex = '^[a-z]*$' -const stateNodeDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] > ObjectExpression > Property' -const targetDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] Property[key.name="target"][value.type="Literal"]' -const targetArrayStringDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="states"] Property[key.name="target"][value.type="ArrayExpression"] > ArrayExpression > Literal' -const simpleEventTargetDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="on"] > ObjectExpression > Property[value.type="Literal"]' -const simpleOnDoneOnErrorTargetDeclaration = - 'CallExpression[callee.name=/^createMachine$|^Machine$/] Property:matches([key.name="onDone"], [key.name="onError"])[value.type="Literal"]' +const stateNodeDeclaration = (prefix) => + `${prefix}Property[key.name="states"] > ObjectExpression > Property` +const targetDeclaration = (prefix) => + `${prefix}Property[key.name="states"] Property[key.name="target"][value.type="Literal"]` +const targetArrayStringDeclaration = (prefix) => + `${prefix}Property[key.name="states"] Property[key.name="target"][value.type="ArrayExpression"] > ArrayExpression > Literal` +const simpleEventTargetDeclaration = (prefix) => + `${prefix}Property[key.name="on"] > ObjectExpression > Property[value.type="Literal"]` +const simpleOnDoneOnErrorTargetDeclaration = (prefix) => + `${prefix}Property:matches([key.name="onDone"], [key.name="onError"])[value.type="Literal"]` module.exports = { meta: { @@ -81,6 +82,7 @@ module.exports = { }, create: function (context) { + const prefix = getSelectorPrefix(context.sourceCode) const mode = context.options[0] || 'camelCase' const regexOption = mode === 'regex' @@ -165,7 +167,7 @@ module.exports = { } return { - [stateNodeDeclaration]: function (node) { + [stateNodeDeclaration(prefix)]: function (node) { if (node.computed) { return } @@ -182,10 +184,10 @@ module.exports = { return validate(name, node.key) }, - [targetDeclaration]: validateTarget, - [simpleEventTargetDeclaration]: validateTarget, - [simpleOnDoneOnErrorTargetDeclaration]: validateTarget, - [targetArrayStringDeclaration]: validateTargetLiteral, + [targetDeclaration(prefix)]: validateTarget, + [simpleEventTargetDeclaration(prefix)]: validateTarget, + [simpleOnDoneOnErrorTargetDeclaration(prefix)]: validateTarget, + [targetArrayStringDeclaration(prefix)]: validateTargetLiteral, } }, } diff --git a/lib/utils/isInsideMachineDeclaration.js b/lib/utils/isInsideMachineDeclaration.js deleted file mode 100644 index 47bb3fa..0000000 --- a/lib/utils/isInsideMachineDeclaration.js +++ /dev/null @@ -1,12 +0,0 @@ -const { isCreateMachineCall } = require('./predicates') - -module.exports = function isInsideMachineDeclaration(node) { - let parent = node.parent - while (parent) { - if (isCreateMachineCall(parent)) { - return true - } - parent = parent.parent - } - return false -} diff --git a/tests/lib/rules/event-names.js b/tests/lib/rules/event-names.js index 2bc5a3b..7b832a7 100644 --- a/tests/lib/rules/event-names.js +++ b/tests/lib/rules/event-names.js @@ -345,6 +345,43 @@ const tests = { }, ], }, + { + // If xstate linting is enforced over the entire file, errors are reported even outside of createMachine calls + code: ` + /* eslint-plugin-xstate-include */ + const obj = { + on: { + thisIsNotEvent: 'foo', + 'neither.is.this': 'foo', + } + } + `, + errors: [ + { + messageId: 'invalidEventName', + data: { + eventName: 'thisIsNotEvent', + fixedEventName: 'THIS_IS_NOT_EVENT', + }, + }, + { + messageId: 'invalidEventName', + data: { + eventName: 'neither.is.this', + fixedEventName: 'NEITHER.IS.THIS', + }, + }, + ], + output: ` + /* eslint-plugin-xstate-include */ + const obj = { + on: { + THIS_IS_NOT_EVENT: 'foo', + 'NEITHER.IS.THIS': 'foo', + } + } + `, + }, ], } diff --git a/tests/lib/rules/no-async-guards.js b/tests/lib/rules/no-async-guards.js index 730df2a..0ac276c 100644 --- a/tests/lib/rules/no-async-guards.js +++ b/tests/lib/rules/no-async-guards.js @@ -81,6 +81,21 @@ const tests = { ) ` ), + withVersion( + 5, + ` + createMachine( + {}, + { + guards: { + myGuard: () => {}, + myGuard2: function () {}, + myGuard3() {}, + }, + } + ) + ` + ), ], invalid: [ withVersion(4, { @@ -197,6 +212,67 @@ const tests = { { messageId: 'guardCannotBeAsync' }, ], }), + // lint code outside of createMachine if it is enforced + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const obj = { + on: { + EVENT: { + cond: async () => {}, + }, + }, + invoke: { + src: 'myActor', + onDone: { + cond: async () => {}, + }, + }, + } + `, + errors: [ + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + ], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const obj = { + on: { + EVENT: { + guard: async () => {}, + }, + }, + invoke: { + src: 'myActor', + onDone: { + guard: async () => {}, + }, + }, + } + `, + errors: [ + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + ], + }), + // check implementations outside of createMachine + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const implementations = { + guards: { + guard1: async () => {}, + guard2: async function () {}, + } + } + `, + errors: [ + { messageId: 'guardCannotBeAsync' }, + { messageId: 'guardCannotBeAsync' }, + ], + }), ], } diff --git a/tests/lib/rules/no-auto-forward.js b/tests/lib/rules/no-auto-forward.js index 22c6678..5a06b42 100644 --- a/tests/lib/rules/no-auto-forward.js +++ b/tests/lib/rules/no-auto-forward.js @@ -92,6 +92,31 @@ const tests = { `, errors: [{ messageId: 'autoForwardDeprecated' }], }), + // check the code outside of createMachine if the rule is enforced + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + invoke: { + src: 'myActorLogic', + autoForward: true, + } + } + `, + errors: [{ messageId: 'noAutoForward' }], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + invoke: { + src: 'myActorLogic', + autoForward: true, + } + } + `, + errors: [{ messageId: 'autoForwardDeprecated' }], + }), ], } diff --git a/tests/lib/rules/no-imperative-action.js b/tests/lib/rules/no-imperative-action.js index 0b9343c..4e83038 100644 --- a/tests/lib/rules/no-imperative-action.js +++ b/tests/lib/rules/no-imperative-action.js @@ -425,6 +425,98 @@ const tests = { }, ], }), + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + actions: { + myAction1: () => assign(), + myAction2: () => { send() }, + myAction3: function() { sendParent() }, + myAction4: () => respond(), + myAction5: () => raise(), + }, + entry: () => send(), + exit: () => send(), + } + `, + errors: [ + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'send' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'respond' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'send' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'send' }, + }, + ], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + actions: { + myAction1: () => assign(), + myAction2: () => { sendTo() }, + myAction3: function() { sendParent() }, + myAction4: () => choose(), + myAction5: () => raise(), + }, + entry: () => sendTo(), + exit: () => sendTo(), + } + `, + errors: [ + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'assign' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendParent' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'choose' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'raise' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendTo' }, + }, + { + messageId: 'imperativeActionCreator', + data: { actionCreator: 'sendTo' }, + }, + ], + }), ], } diff --git a/tests/lib/rules/no-infinite-loop.js b/tests/lib/rules/no-infinite-loop.js index a7784e7..aad925e 100644 --- a/tests/lib/rules/no-infinite-loop.js +++ b/tests/lib/rules/no-infinite-loop.js @@ -174,6 +174,19 @@ const tests = { }) ` ), + // outside of createMachine it is not linted by default + withVersion( + 4, + ` + const config = { + states: { + deciding: { + always: {}, + }, + }, + } + ` + ), ], invalid: [ withVersion(4, { @@ -373,6 +386,20 @@ const tests = { { messageId: 'noTargetHasGuardNoAssign' }, ], }), + // outside of createMachine it is not linted by default + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + deciding: { + always: {}, + }, + }, + } + `, + errors: [{ messageId: 'noTargetNoGuardIsSingle' }], + }), ], } @@ -381,4 +408,4 @@ const ruleTester = new RuleTester({ ecmaVersion: 6, }, }) -ruleTester.run('no-infnite-loop', rule, tests) +ruleTester.run('no-infinite-loop', rule, tests) diff --git a/tests/lib/rules/no-inline-implementation.js b/tests/lib/rules/no-inline-implementation.js index 2cbfa6d..f7613ad 100644 --- a/tests/lib/rules/no-inline-implementation.js +++ b/tests/lib/rules/no-inline-implementation.js @@ -87,6 +87,7 @@ const tests = { 4, ` /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + const { spawn } = require('xstate') createMachine( { states: { @@ -367,6 +368,30 @@ const tests = { }) ` ), + // code outside of createMachine is ignored by default + withVersion( + 4, + ` + const config = { + states: { + active: { + invoke: { + src: () => {}, + }, + entry: () => {}, + on: { + OFF: { + cond: () => {}, + target: 'inactive', + actions: () => {}, + }, + }, + activities: () => {}, + }, + }, + } + ` + ), ], invalid: [ withVersion(4, { @@ -696,6 +721,82 @@ const tests = { { messageId: 'moveActionToOptions' }, ], }), + // reports error ourside of createMachine if there is the include directive + withVersion(4, { + code: ` + /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + /* eslint-plugin-xstate-include */ + const { spawn } = require('xstate') + const config = { + states: { + active: { + invoke: { + src: () => {}, + }, + entry: () => {}, + on: { + OFF: { + cond: () => {}, + target: 'inactive', + actions: [ + () => {}, + assign({ + ref: () => spawn(() => {}), + }) + ] + }, + }, + activities: () => {}, + }, + }, + } + `, + errors: [ + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActivityToOptions' }, + ], + }), + withVersion(5, { + code: ` + /* eslint no-inline-implementation: [ "warn", { "allowKnownActionCreators": true } ] */ + /* eslint-plugin-xstate-include */ + const config = { + states: { + active: { + invoke: { + src: () => {}, + }, + entry: () => {}, + on: { + OFF: { + guard: () => {}, + target: 'inactive', + actions: [ + () => {}, + assign({ + ref: ({ spawn }) => spawn(() => {}), + }) + ] + }, + }, + activities: () => {}, + }, + }, + } + `, + errors: [ + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveGuardToOptions' }, + { messageId: 'moveActionToOptions' }, + { messageId: 'moveActorToOptions' }, + { messageId: 'moveActivityToOptions' }, + ], + }), ], } diff --git a/tests/lib/rules/no-invalid-conditional-action.js b/tests/lib/rules/no-invalid-conditional-action.js index 6c11a3b..e6fb9ff 100644 --- a/tests/lib/rules/no-invalid-conditional-action.js +++ b/tests/lib/rules/no-invalid-conditional-action.js @@ -51,6 +51,61 @@ const tests = { }) ` ), + // no errors outside ofc reateMachine by default + withVersion( + 4, + ` + const config = { + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + } + } + } + ` + ), + withVersion( + 5, + ` + const config = { + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + guard: 'myGuard', + cond: '???', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + guard: 'myGuard', + cond: '???', + invoke: '???', + actions: [], + }]), + } + } + } + ` + ), ], invalid: [ // transitions within the choose action creator @@ -236,6 +291,97 @@ const tests = { }, ], }), + // should report errors outside of createMachine with the directive + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + cond: 'myGuard', + guard: '???', + invoke: '???', + actions: [], + }]), + } + } + } + `, + errors: [ + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'guard' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'guard' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + ], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + active: { + on: { + EVENT1: { + actions: choose([{ + guard: 'myGuard', + cond: '???', + invoke: '???', + actions: [], + }]), + }, + }, + entry: choose([{ + guard: 'myGuard', + cond: '???', + invoke: '???', + actions: [], + }]), + } + } + } + `, + errors: [ + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'cond' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'cond' }, + }, + { + messageId: 'invalidConditionalActionProperty', + data: { propName: 'invoke' }, + }, + ], + }), ], } diff --git a/tests/lib/rules/no-invalid-state-props.js b/tests/lib/rules/no-invalid-state-props.js index badd072..e1f8893 100644 --- a/tests/lib/rules/no-invalid-state-props.js +++ b/tests/lib/rules/no-invalid-state-props.js @@ -110,6 +110,37 @@ const tests = { }) ` ), + // no errors reported outside of createMachine by default + withVersion( + 4, + ` + const config = { + id: 'myMachine', + context: {}, + foo: '???', + states: { + idle: { + foo: '???', + }, + }, + } + ` + ), + withVersion( + 5, + ` + const config = { + id: 'myMachine', + context: {}, + foo: '???', + states: { + idle: { + foo: '???', + }, + }, + } + ` + ), ], invalid: [ // unrecognized prop names @@ -249,6 +280,49 @@ const tests = { { messageId: 'invalidHistoryValue', data: { value: 'shallowish' } }, ], }), + // should report errors outside of createMachine if there is the comment directive + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + id: 'myMachine', + context: { + simpson: 10, + }, + foo: '???', + states: { + idle: { + boo: '???', + }, + }, + } + `, + errors: [ + { messageId: 'invalidRootStateProperty', data: { propName: 'foo' } }, + { messageId: 'invalidStateProperty', data: { propName: 'boo' } }, + ], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + id: 'myMachine', + context: { + simpson: 10, + }, + foo: '???', + states: { + idle: { + boo: '???', + }, + }, + } + `, + errors: [ + { messageId: 'invalidRootStateProperty', data: { propName: 'foo' } }, + { messageId: 'invalidStateProperty', data: { propName: 'boo' } }, + ], + }), ], } diff --git a/tests/lib/rules/no-invalid-transition-props.js b/tests/lib/rules/no-invalid-transition-props.js index 671bd06..96d7827 100644 --- a/tests/lib/rules/no-invalid-transition-props.js +++ b/tests/lib/rules/no-invalid-transition-props.js @@ -171,6 +171,55 @@ const tests = { }) ` ), + // no errors outside of the createMachine calls by default + withVersion( + 4, + ` + const config = { + states: { + idle: { + always: [ + { + foo: '???', + }, + ], + on: { + EVENT: { + foo: '???' + } + }, + }, + }, + onDone: { + foo: '???' + }, + } + ` + ), + withVersion( + 5, + ` + const config = { + states: { + idle: { + always: [ + { + foo: '???', + }, + ], + on: { + EVENT: { + foo: '???' + } + }, + }, + }, + onDone: { + foo: '???' + }, + } + ` + ), ], invalid: [ withVersion(4, { @@ -406,6 +455,85 @@ const tests = { }, ], }), + // errors reported outside of createMachine if there is a comment directive + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + idle: { + always: [ + { + foo: '???', + }, + ], + on: { + EVENT: { + cond: 'myGuard', + boo: '???', + }, + }, + }, + }, + onDone: { + unknown: '???' + }, + } + `, + errors: [ + { + messageId: 'invalidTransitionProperty', + data: { propName: 'foo' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'boo' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'unknown' }, + }, + ], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + idle: { + always: [ + { + foo: '???', + }, + ], + on: { + EVENT: { + guard: 'myGuard', + boo: '???', + }, + }, + }, + }, + onDone: { + unknown: '???' + }, + } + `, + errors: [ + { + messageId: 'invalidTransitionProperty', + data: { propName: 'foo' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'boo' }, + }, + { + messageId: 'invalidTransitionProperty', + data: { propName: 'unknown' }, + }, + ], + }), ], } diff --git a/tests/lib/rules/no-misplaced-on-transition.js b/tests/lib/rules/no-misplaced-on-transition.js index a9bee0a..1d60a64 100644 --- a/tests/lib/rules/no-misplaced-on-transition.js +++ b/tests/lib/rules/no-misplaced-on-transition.js @@ -38,6 +38,21 @@ const tests = { }, }) `, + // no errors outside of createmachine by default + ` + const config = { + states: { + on: { + EVENT: 'passive', + }, + }, + invoke: { + on: { + EVENT: 'passive', + }, + } + } + `, ], invalid: [ { @@ -70,6 +85,28 @@ const tests = { `, errors: [{ messageId: 'onTransitionInsideInvokeForbidden' }], }, + // errors reported outside of createMachine if there is the comment directive + { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + on: { + EVENT: 'passive', + }, + }, + invoke: { + on: { + EVENT: 'passive', + }, + } + } + `, + errors: [ + { messageId: 'onTransitionInsideStatesForbidden' }, + { messageId: 'onTransitionInsideInvokeForbidden' }, + ], + }, ], } diff --git a/tests/lib/rules/no-ondone-outside-compound-state.js b/tests/lib/rules/no-ondone-outside-compound-state.js index 980f248..63e7676 100644 --- a/tests/lib/rules/no-ondone-outside-compound-state.js +++ b/tests/lib/rules/no-ondone-outside-compound-state.js @@ -59,6 +59,30 @@ const tests = { }, }) `, + // no errors outside of createMachine by default + ` + const config = { + states: { + active: { + type: 'atomic', + onDone: 'idle', + }, + hist: { + type: 'history', + onDone: 'idle', + }, + idle: { + onDone: 'active', + }, + finished: { + type: 'final', + onDone: { + actions: () => {}, + }, + } + }, + } + `, ], invalid: [ { @@ -124,6 +148,39 @@ const tests = { `, errors: [{ messageId: 'onDoneUsedIncorrectly' }], }, + // errors reported outside of createMachine if there is the comment directive + { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + active: { + type: 'atomic', + onDone: 'idle', + }, + hist: { + type: 'history', + onDone: 'idle', + }, + idle: { + onDone: 'active', + }, + finished: { + type: 'final', + onDone: { + actions: () => {}, + }, + } + }, + } + `, + errors: [ + { messageId: 'onDoneOnAtomicStateForbidden' }, + { messageId: 'onDoneOnHistoryStateForbidden' }, + { messageId: 'onDoneUsedIncorrectly' }, + { messageId: 'onDoneOnFinalStateForbidden' }, + ], + }, ], } diff --git a/tests/lib/rules/prefer-always.js b/tests/lib/rules/prefer-always.js index 9c54379..3434421 100644 --- a/tests/lib/rules/prefer-always.js +++ b/tests/lib/rules/prefer-always.js @@ -34,6 +34,41 @@ const tests = { }) ` ), + // no errors outside of createMachine by default + withVersion( + 4, + ` + const config = { + states: { + playing: { + on: { + '': [ + { target: 'win', cond: 'didPlayerWin' }, + { target: 'lose', cond: 'didPlayerLose' }, + ], + }, + }, + }, + } + ` + ), + withVersion( + 5, + ` + const config = { + states: { + playing: { + on: { + '': [ + { target: 'win', guard: 'didPlayerWin' }, + { target: 'lose', guard: 'didPlayerLose' }, + ], + }, + }, + }, + } + ` + ), ], invalid: [ withVersion(4, { @@ -70,6 +105,43 @@ const tests = { `, errors: [{ messageId: 'eventlessTransitionsDeprecated' }], }), + // errors reported outside of createMachine if there is the comment directive + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + playing: { + on: { + '': [ + { target: 'win', cond: 'didPlayerWin' }, + { target: 'lose', cond: 'didPlayerLose' }, + ], + }, + }, + }, + } + `, + errors: [{ messageId: 'preferAlways' }], + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + playing: { + on: { + '': [ + { target: 'win', guard: 'didPlayerWin' }, + { target: 'lose', guard: 'didPlayerLose' }, + ], + }, + }, + }, + } + `, + errors: [{ messageId: 'eventlessTransitionsDeprecated' }], + }), ], } diff --git a/tests/lib/rules/prefer-predictable-action-arguments.js b/tests/lib/rules/prefer-predictable-action-arguments.js index 9499a7b..0119284 100644 --- a/tests/lib/rules/prefer-predictable-action-arguments.js +++ b/tests/lib/rules/prefer-predictable-action-arguments.js @@ -18,6 +18,25 @@ const tests = { createMachine({}) ` ), + // no errors outside of createMachine by default + withVersion( + 4, + ` + const config = { + predictableActionArguments: false, + context: {}, + } + ` + ), + withVersion( + 5, + ` + const config = { + predictableActionArguments: false, + context: {}, + } + ` + ), ], invalid: [ withVersion(4, { @@ -84,6 +103,57 @@ initial: 'ready' }) `, }), + // errors reported outside of createMachine if there is the comment directive + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + context: {}, + } + `, + errors: [{ messageId: 'preferPredictableActionArguments' }], + output: ` + /* eslint-plugin-xstate-include */ + const config = { + predictableActionArguments: true, +context: {}, + } + `, + }), + withVersion(4, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + predictableActionArguments: false, + context: {}, + } + `, + errors: [{ messageId: 'preferPredictableActionArguments' }], + output: ` + /* eslint-plugin-xstate-include */ + const config = { + predictableActionArguments: true, + context: {}, + } + `, + }), + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + context: {}, + predictableActionArguments: false + } + `, + errors: [{ messageId: 'deprecatedPredictableActionArguments' }], + output: ` + /* eslint-plugin-xstate-include */ + const config = { + context: {}, + + } + `, + }), ], } diff --git a/tests/lib/rules/state-names.js b/tests/lib/rules/state-names.js index 57bbce7..7e70bc2 100644 --- a/tests/lib/rules/state-names.js +++ b/tests/lib/rules/state-names.js @@ -55,6 +55,25 @@ const tests = { }, }) `, + // no errors outside of createMachine by default + ` + const config = { + states: { + PowerOn: {}, + power_on: {}, + 'power:on': {}, + 'power.on': {}, + entry: {}, + }, + onDone: 'power_on', + on: { + CLICK: 'power_on', + BUMP: { + target: 'power_on', + } + } + } + `, ], invalid: [ @@ -277,6 +296,85 @@ const tests = { }) `, }, + // report errors outside of createMachine if there is the comment directive + { + code: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + PowerOn: {}, + power_on: {}, + 'power:on': {}, + 'power.on': {}, + entry: {}, + someState: { + on: { + CLICK: 'power_shut', + BUMP: { + target: 'power_kill', + }, + }, + }, + }, + onDone: 'power_off', + } + `, + errors: [ + { + messageId: 'invalidStateName', + data: { name: 'PowerOn', fixedName: 'powerOn' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power_on', fixedName: 'powerOn' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power:on', fixedName: 'powerOn' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power.on', fixedName: 'powerOn' }, + }, + { + messageId: 'stateNameIsReservedWord', + data: { name: 'entry' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power_shut', fixedName: 'powerShut' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power_kill', fixedName: 'powerKill' }, + }, + { + messageId: 'invalidStateName', + data: { name: 'power_off', fixedName: 'powerOff' }, + }, + ], + output: ` + /* eslint-plugin-xstate-include */ + const config = { + states: { + powerOn: {}, + powerOn: {}, + powerOn: {}, + powerOn: {}, + entry: {}, + someState: { + on: { + CLICK: 'powerShut', + BUMP: { + target: 'powerKill', + }, + }, + }, + }, + onDone: 'powerOff', + } + `, + }, ], } From e768c8600b34273e6b0b8c696a5d46b32aea2c38 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Sat, 26 Aug 2023 16:59:04 +0200 Subject: [PATCH 26/43] test(eslint): upgrade eslint dev dep --- package-lock.json | 449 ++-- package.json | 8 +- pnpm-lock.yaml | 6497 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 6710 insertions(+), 244 deletions(-) create mode 100644 pnpm-lock.yaml diff --git a/package-lock.json b/package-lock.json index 2856ba8..9fb5194 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@commitlint/config-conventional": "^17.0.3", "commitizen": "^4.2.3", "cz-conventional-changelog": "^3.3.0", - "eslint": "^8.17.0", + "eslint": "^8.48.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", @@ -31,10 +31,19 @@ "semantic-release": "^21.0.7" }, "engines": { - "node": ">=8.0.0" + "node": ">=16.0.0" }, "peerDependencies": { - "eslint": "^7.1.0||^8.17.0" + "eslint": "^8.17.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { @@ -948,16 +957,40 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -971,30 +1004,29 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2486,9 +2518,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2684,15 +2716,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/array.prototype.flat": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", @@ -4015,49 +4038,47 @@ } }, "node_modules/eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4432,9 +4453,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -4442,6 +4463,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-utils": { @@ -4469,39 +4493,15 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/glob-parent": { @@ -4517,14 +4517,14 @@ } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4547,9 +4547,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4693,7 +4693,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { @@ -5099,9 +5099,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5113,36 +5113,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/handlebars": { @@ -5707,6 +5687,15 @@ "node": ">=8" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -6513,12 +6502,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10396,17 +10379,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -12927,6 +12910,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -13630,16 +13619,31 @@ } } }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -13647,23 +13651,23 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -14799,9 +14803,9 @@ "dev": true }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -14941,12 +14945,6 @@ "is-string": "^1.0.7" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, "array.prototype.flat": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", @@ -15909,69 +15907,50 @@ "dev": true }, "eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -16241,9 +16220,9 @@ "requires": {} }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -16268,20 +16247,20 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -16291,9 +16270,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -16404,7 +16383,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { @@ -16725,38 +16704,24 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, "graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "handlebars": { @@ -17135,6 +17100,12 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -17742,12 +17713,6 @@ } } }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -20405,17 +20370,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "ora": { diff --git a/package.json b/package.json index 46da9f7..41c3d6b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,11 @@ "name": "eslint-plugin-xstate", "version": "0.0.0-semantically-released", "description": "ESLint rules for XState", - "keywords": ["eslint", "eslintplugin", "eslint-plugin"], + "keywords": [ + "eslint", + "eslintplugin", + "eslint-plugin" + ], "author": "Richard Laffers", "main": "lib/index.js", "scripts": { @@ -24,7 +28,7 @@ "@commitlint/config-conventional": "^17.0.3", "commitizen": "^4.2.3", "cz-conventional-changelog": "^3.3.0", - "eslint": "^8.17.0", + "eslint": "^8.48.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..3875146 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,6497 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + lodash.camelcase: + specifier: ^4.3.0 + version: 4.3.0 + lodash.snakecase: + specifier: ^4.1.1 + version: 4.1.1 + lodash.upperfirst: + specifier: ^4.3.1 + version: 4.3.1 + sanctuary: + specifier: ^3.1.0 + version: 3.1.0 + +devDependencies: + '@commitlint/cli': + specifier: ^17.0.3 + version: 17.0.3 + '@commitlint/config-conventional': + specifier: ^17.0.3 + version: 17.0.3 + commitizen: + specifier: ^4.2.3 + version: 4.2.3 + cz-conventional-changelog: + specifier: ^3.3.0 + version: 3.3.0 + eslint: + specifier: ^8.48.0 + version: 8.48.0 + eslint-config-prettier: + specifier: ^8.5.0 + version: 8.5.0(eslint@8.48.0) + eslint-config-standard: + specifier: ^17.0.0 + version: 17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.48.0) + eslint-plugin-import: + specifier: ^2.26.0 + version: 2.26.0(eslint@8.48.0) + eslint-plugin-node: + specifier: ^11.1.0 + version: 11.1.0(eslint@8.48.0) + eslint-plugin-promise: + specifier: ^6.0.0 + version: 6.0.0(eslint@8.48.0) + husky: + specifier: ^8.0.1 + version: 8.0.1 + jest: + specifier: ^29.0.0 + version: 29.0.0(@types/node@20.4.7)(ts-node@10.9.1) + prettier: + specifier: ^2.6.2 + version: 2.6.2 + semantic-release: + specifier: ^21.0.7 + version: 21.0.7 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@babel/code-frame@7.22.10: + resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.10 + chalk: 2.4.2 + dev: true + + /@babel/compat-data@7.22.9: + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.22.11: + resolution: {integrity: sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.10 + '@babel/generator': 7.22.10 + '@babel/helper-compilation-targets': 7.22.10 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.11) + '@babel/helpers': 7.22.11 + '@babel/parser': 7.22.11 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.11 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.22.10: + resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.11 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets@7.22.10: + resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/helper-validator-option': 7.22.5 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/types': 7.22.11 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@babel/helper-module-imports@7.22.5: + resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.11): + resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.5 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.5: + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.22.5: + resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.22.11: + resolution: {integrity: sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.11 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.22.10: + resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.22.11: + resolution: {integrity: sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.11): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.11): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.11): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.11): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.11): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.11): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.11): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.11): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.11): + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/template@7.22.5: + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.10 + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + dev: true + + /@babel/traverse@7.22.11: + resolution: {integrity: sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.10 + '@babel/generator': 7.22.10 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.22.11: + resolution: {integrity: sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + + /@commitlint/cli@17.0.3: + resolution: {integrity: sha512-oAo2vi5d8QZnAbtU5+0cR2j+A7PO8zuccux65R/EycwvsZrDVyW518FFrnJK2UQxbRtHFFIG+NjQ6vOiJV0Q8A==} + engines: {node: '>=v14'} + hasBin: true + dependencies: + '@commitlint/format': 17.4.4 + '@commitlint/lint': 17.7.0 + '@commitlint/load': 17.7.1 + '@commitlint/read': 17.5.1 + '@commitlint/types': 17.4.4 + execa: 5.1.1 + lodash: 4.17.21 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + dev: true + + /@commitlint/config-conventional@17.0.3: + resolution: {integrity: sha512-HCnzTm5ATwwwzNVq5Y57poS0a1oOOcd5pc1MmBpLbGmSysc4i7F/++JuwtdFPu16sgM3H9J/j2zznRLOSGVO2A==} + engines: {node: '>=v14'} + dependencies: + conventional-changelog-conventionalcommits: 5.0.0 + dev: true + + /@commitlint/config-validator@17.6.7: + resolution: {integrity: sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/types': 17.4.4 + ajv: 8.12.0 + dev: true + + /@commitlint/ensure@17.6.7: + resolution: {integrity: sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/types': 17.4.4 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + dev: true + + /@commitlint/execute-rule@17.4.0: + resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==} + engines: {node: '>=v14'} + dev: true + + /@commitlint/format@17.4.4: + resolution: {integrity: sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/types': 17.4.4 + chalk: 4.1.2 + dev: true + + /@commitlint/is-ignored@17.7.0: + resolution: {integrity: sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/types': 17.4.4 + semver: 7.5.4 + dev: true + + /@commitlint/lint@17.7.0: + resolution: {integrity: sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/is-ignored': 17.7.0 + '@commitlint/parse': 17.7.0 + '@commitlint/rules': 17.7.0 + '@commitlint/types': 17.4.4 + dev: true + + /@commitlint/load@17.7.1: + resolution: {integrity: sha512-S/QSOjE1ztdogYj61p6n3UbkUvweR17FQ0zDbNtoTLc+Hz7vvfS7ehoTMQ27hPSjVBpp7SzEcOQu081RLjKHJQ==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/config-validator': 17.6.7 + '@commitlint/execute-rule': 17.4.0 + '@commitlint/resolve-extends': 17.6.7 + '@commitlint/types': 17.4.4 + '@types/node': 20.4.7 + chalk: 4.1.2 + cosmiconfig: 8.2.0 + cosmiconfig-typescript-loader: 4.4.0(@types/node@20.4.7)(cosmiconfig@8.2.0)(ts-node@10.9.1)(typescript@5.2.2) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 + resolve-from: 5.0.0 + ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + dev: true + + /@commitlint/message@17.4.2: + resolution: {integrity: sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==} + engines: {node: '>=v14'} + dev: true + + /@commitlint/parse@17.7.0: + resolution: {integrity: sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/types': 17.4.4 + conventional-changelog-angular: 6.0.0 + conventional-commits-parser: 4.0.0 + dev: true + + /@commitlint/read@17.5.1: + resolution: {integrity: sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/top-level': 17.4.0 + '@commitlint/types': 17.4.4 + fs-extra: 11.1.1 + git-raw-commits: 2.0.11 + minimist: 1.2.8 + dev: true + + /@commitlint/resolve-extends@17.6.7: + resolution: {integrity: sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/config-validator': 17.6.7 + '@commitlint/types': 17.4.4 + import-fresh: 3.3.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + dev: true + + /@commitlint/rules@17.7.0: + resolution: {integrity: sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==} + engines: {node: '>=v14'} + dependencies: + '@commitlint/ensure': 17.6.7 + '@commitlint/message': 17.4.2 + '@commitlint/to-lines': 17.4.0 + '@commitlint/types': 17.4.4 + execa: 5.1.1 + dev: true + + /@commitlint/to-lines@17.4.0: + resolution: {integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==} + engines: {node: '>=v14'} + dev: true + + /@commitlint/top-level@17.4.0: + resolution: {integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==} + engines: {node: '>=v14'} + dependencies: + find-up: 5.0.0 + dev: true + + /@commitlint/types@17.4.4: + resolution: {integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==} + engines: {node: '>=v14'} + dependencies: + chalk: 4.1.2 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.48.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.8.0: + resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.21.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.48.0: + resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.10: + resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@29.6.4: + resolution: {integrity: sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + chalk: 4.1.2 + jest-message-util: 29.6.3 + jest-util: 29.6.3 + slash: 3.0.0 + dev: true + + /@jest/core@29.6.4(ts-node@10.9.1): + resolution: {integrity: sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.6.4 + '@jest/reporters': 29.6.4 + '@jest/test-result': 29.6.4 + '@jest/transform': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.6.3 + jest-config: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1) + jest-haste-map: 29.6.4 + jest-message-util: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.4 + jest-resolve-dependencies: 29.6.4 + jest-runner: 29.6.4 + jest-runtime: 29.6.4 + jest-snapshot: 29.6.4 + jest-util: 29.6.3 + jest-validate: 29.6.3 + jest-watcher: 29.6.4 + micromatch: 4.0.5 + pretty-format: 29.6.3 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /@jest/environment@29.6.4: + resolution: {integrity: sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + jest-mock: 29.6.3 + dev: true + + /@jest/expect-utils@29.6.4: + resolution: {integrity: sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + dev: true + + /@jest/expect@29.6.4: + resolution: {integrity: sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.6.4 + jest-snapshot: 29.6.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@29.6.4: + resolution: {integrity: sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.5.6 + jest-message-util: 29.6.3 + jest-mock: 29.6.3 + jest-util: 29.6.3 + dev: true + + /@jest/globals@29.6.4: + resolution: {integrity: sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.4 + '@jest/expect': 29.6.4 + '@jest/types': 29.6.3 + jest-mock: 29.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@29.6.4: + resolution: {integrity: sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.6.4 + '@jest/test-result': 29.6.4 + '@jest/transform': 29.6.4 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.19 + '@types/node': 20.5.6 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 6.0.0 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + jest-message-util: 29.6.3 + jest-util: 29.6.3 + jest-worker: 29.6.4 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@29.6.4: + resolution: {integrity: sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.6.4 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@29.6.4: + resolution: {integrity: sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.6.4 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.4 + slash: 3.0.0 + dev: true + + /@jest/transform@29.6.4: + resolution: {integrity: sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.11 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.19 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.4 + jest-regex-util: 29.6.3 + jest-util: 29.6.3 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 20.5.6 + '@types/yargs': 17.0.24 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@octokit/auth-token@4.0.0: + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} + dev: true + + /@octokit/core@5.0.0: + resolution: {integrity: sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==} + engines: {node: '>= 18'} + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.0.1 + '@octokit/request': 8.1.1 + '@octokit/request-error': 5.0.0 + '@octokit/types': 11.1.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.0 + dev: true + + /@octokit/endpoint@9.0.0: + resolution: {integrity: sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==} + engines: {node: '>= 18'} + dependencies: + '@octokit/types': 11.1.0 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.0 + dev: true + + /@octokit/graphql@7.0.1: + resolution: {integrity: sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==} + engines: {node: '>= 18'} + dependencies: + '@octokit/request': 8.1.1 + '@octokit/types': 11.1.0 + universal-user-agent: 6.0.0 + dev: true + + /@octokit/openapi-types@18.0.0: + resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==} + dev: true + + /@octokit/plugin-paginate-rest@8.0.0(@octokit/core@5.0.0): + resolution: {integrity: sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=5' + dependencies: + '@octokit/core': 5.0.0 + '@octokit/types': 11.1.0 + dev: true + + /@octokit/plugin-retry@6.0.0(@octokit/core@5.0.0): + resolution: {integrity: sha512-a1/A4A+PB1QoAHQfLJxGHhLfSAT03bR1jJz3GgQJZvty2ozawFWs93MiBQXO7SL2YbO7CIq0Goj4qLOBj8JeMQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=5' + dependencies: + '@octokit/core': 5.0.0 + '@octokit/request-error': 5.0.0 + '@octokit/types': 11.1.0 + bottleneck: 2.19.5 + dev: true + + /@octokit/plugin-throttling@7.0.0(@octokit/core@5.0.0): + resolution: {integrity: sha512-KL2k/d0uANc8XqP5S64YcNFCudR3F5AaKO39XWdUtlJIjT9Ni79ekWJ6Kj5xvAw87udkOMEPcVf9xEge2+ahew==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^5.0.0 + dependencies: + '@octokit/core': 5.0.0 + '@octokit/types': 11.1.0 + bottleneck: 2.19.5 + dev: true + + /@octokit/request-error@5.0.0: + resolution: {integrity: sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==} + engines: {node: '>= 18'} + dependencies: + '@octokit/types': 11.1.0 + deprecation: 2.3.1 + once: 1.4.0 + dev: true + + /@octokit/request@8.1.1: + resolution: {integrity: sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==} + engines: {node: '>= 18'} + dependencies: + '@octokit/endpoint': 9.0.0 + '@octokit/request-error': 5.0.0 + '@octokit/types': 11.1.0 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.0 + dev: true + + /@octokit/types@11.1.0: + resolution: {integrity: sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==} + dependencies: + '@octokit/openapi-types': 18.0.0 + dev: true + + /@pnpm/config.env-replace@1.1.0: + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + dev: true + + /@pnpm/network.ca-file@1.0.2: + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + dependencies: + graceful-fs: 4.2.10 + dev: true + + /@pnpm/npm-conf@2.2.2: + resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} + engines: {node: '>=12'} + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + dev: true + + /@semantic-release/commit-analyzer@10.0.1(semantic-release@21.0.7): + resolution: {integrity: sha512-9ejHzTAijYs9z246sY/dKBatmOPcd0GQ7lH4MgLCkv1q4GCiDZRkjHJkaQZXZVaK7mJybS+sH3Ng6G8i3pYMGQ==} + engines: {node: '>=18'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + conventional-changelog-angular: 6.0.0 + conventional-commits-filter: 3.0.0 + conventional-commits-parser: 4.0.0 + debug: 4.3.4 + import-from: 4.0.0 + lodash-es: 4.17.21 + micromatch: 4.0.5 + semantic-release: 21.0.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@semantic-release/error@4.0.0: + resolution: {integrity: sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==} + engines: {node: '>=18'} + dev: true + + /@semantic-release/github@9.0.4(semantic-release@21.0.7): + resolution: {integrity: sha512-kQCGFAsBErvCR6hzNuzu63cj4erQN2krm9zQlg8vl4j5X0mL0d/Ras0wmL5Gkr1TuSS2lweME7M4J5zvtDDDSA==} + engines: {node: '>=18'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + '@octokit/core': 5.0.0 + '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.0) + '@octokit/plugin-retry': 6.0.0(@octokit/core@5.0.0) + '@octokit/plugin-throttling': 7.0.0(@octokit/core@5.0.0) + '@semantic-release/error': 4.0.0 + aggregate-error: 4.0.1 + debug: 4.3.4 + dir-glob: 3.0.1 + globby: 13.2.2 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.1 + issue-parser: 6.0.0 + lodash-es: 4.17.21 + mime: 3.0.0 + p-filter: 3.0.0 + semantic-release: 21.0.7 + url-join: 5.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@semantic-release/npm@10.0.5(semantic-release@21.0.7): + resolution: {integrity: sha512-cJnQ2M5pxJRwZEkb0A/+U3TG4UNmjrrLwV2PxJKljn5OPT0yJB8GzGgWbbKACayvxrT06YdTa4Amtq/piJcOIA==} + engines: {node: '>=18'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + '@semantic-release/error': 4.0.0 + aggregate-error: 4.0.1 + execa: 8.0.1 + fs-extra: 11.1.1 + lodash-es: 4.17.21 + nerf-dart: 1.0.0 + normalize-url: 8.0.0 + npm: 9.8.1 + rc: 1.2.8 + read-pkg: 8.1.0 + registry-auth-token: 5.0.2 + semantic-release: 21.0.7 + semver: 7.5.4 + tempy: 3.1.0 + dev: true + + /@semantic-release/release-notes-generator@11.0.4(semantic-release@21.0.7): + resolution: {integrity: sha512-j0Znnwq9IdWTCGzqSlkLv4MpALTsVDZxcVESzJCNN8pK2BYQlYaKsdZ1Ea/+7RlppI3vjhEi33ZKmjSGY1FLKw==} + engines: {node: '>=18'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + conventional-changelog-angular: 6.0.0 + conventional-changelog-writer: 6.0.1 + conventional-commits-filter: 3.0.0 + conventional-commits-parser: 4.0.0 + debug: 4.3.4 + get-stream: 7.0.1 + import-from: 4.0.0 + into-stream: 7.0.0 + lodash-es: 4.17.21 + read-pkg-up: 10.1.0 + semantic-release: 21.0.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.0 + dev: true + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/babel__core@7.20.1: + resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} + dependencies: + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.20.1 + dev: true + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + dev: true + + /@types/babel__traverse@7.20.1: + resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} + dependencies: + '@babel/types': 7.22.11 + dev: true + + /@types/graceful-fs@4.1.6: + resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} + dependencies: + '@types/node': 20.5.6 + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report@3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports@3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/minimist@1.2.2: + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + dev: true + + /@types/node@20.4.7: + resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==} + dev: true + + /@types/node@20.5.6: + resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==} + dev: true + + /@types/normalize-package-data@2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + + /@types/stack-utils@2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + + /@types/yargs-parser@21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs@17.0.24: + resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /aggregate-error@4.0.1: + resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} + engines: {node: '>=12'} + dependencies: + clean-stack: 4.2.0 + indent-string: 5.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-escapes@6.2.0: + resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} + engines: {node: '>=14.16'} + dependencies: + type-fest: 3.13.1 + dev: true + + /ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + dev: true + + /ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /argv-formatter@1.0.0: + resolution: {integrity: sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==} + dev: true + + /arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + + /array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + dev: true + + /array-includes@3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + dev: true + + /array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + dev: true + + /array.prototype.flat@1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + es-shim-unscopables: 1.0.0 + dev: true + + /arraybuffer.prototype.slice@1.0.1: + resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.0 + get-intrinsic: 1.2.1 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + + /arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + + /assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + dev: true + + /atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /babel-jest@29.6.4(@babel/core@7.22.11): + resolution: {integrity: sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.22.11 + '@jest/transform': 29.6.4 + '@types/babel__core': 7.20.1 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.22.11) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.22.5 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.22.5 + '@babel/types': 7.22.11 + '@types/babel__core': 7.20.1 + '@types/babel__traverse': 7.20.1 + dev: true + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.11): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.11 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.11) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.11) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.11) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.11) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.11) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.11) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.11) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.22.11): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.11 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11) + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + dev: true + + /before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + dev: true + + /bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browserslist@4.21.10: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001523 + electron-to-chromium: 1.4.503 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.10) + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + + /cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + dev: true + + /cachedir@2.2.0: + resolution: {integrity: sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==} + engines: {node: '>=6'} + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001523: + resolution: {integrity: sha512-I5q5cisATTPZ1mc588Z//pj/Ox80ERYDfR71YnvY7raS/NOk8xXlZcB0sF7JdqaV//kOaa6aus7lRfpdnt1eBA==} + dev: true + + /cardinal@2.1.1: + resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} + hasBin: true + dependencies: + ansicolors: 0.3.2 + redeyed: 2.1.1 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + dev: true + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + dev: true + + /class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + dev: true + + /clean-stack@4.2.0: + resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} + engines: {node: '>=12'} + dependencies: + escape-string-regexp: 5.0.0 + dev: true + + /cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + dependencies: + restore-cursor: 2.0.0 + dev: true + + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + + /cli-width@2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + dev: true + + /collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /commitizen@4.2.3: + resolution: {integrity: sha512-pYlYEng7XMV2TW4xtjDKBGqeJ0Teq2zyRSx2S3Ml1XAplHSlJZK8vm1KdGclpMEZuGafbS5TeHXIVnHk8RWIzQ==} + engines: {node: '>= 10'} + hasBin: true + dependencies: + cachedir: 2.2.0 + cz-conventional-changelog: 3.2.0 + dedent: 0.7.0 + detect-indent: 6.0.0 + find-node-modules: 2.0.0 + find-root: 1.1.0 + fs-extra: 8.1.0 + glob: 7.1.4 + inquirer: 6.5.2 + is-utf8: 0.2.1 + lodash: 4.17.21 + minimist: 1.2.5 + strip-bom: 4.0.0 + strip-json-comments: 3.0.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - supports-color + dev: true + + /compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + dev: true + + /component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + dev: true + + /conventional-changelog-angular@6.0.0: + resolution: {integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==} + engines: {node: '>=14'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-changelog-conventionalcommits@5.0.0: + resolution: {integrity: sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==} + engines: {node: '>=10'} + dependencies: + compare-func: 2.0.0 + lodash: 4.17.21 + q: 1.5.1 + dev: true + + /conventional-changelog-writer@6.0.1: + resolution: {integrity: sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==} + engines: {node: '>=14'} + hasBin: true + dependencies: + conventional-commits-filter: 3.0.0 + dateformat: 3.0.3 + handlebars: 4.7.8 + json-stringify-safe: 5.0.1 + meow: 8.1.2 + semver: 7.5.4 + split: 1.0.1 + dev: true + + /conventional-commit-types@3.0.0: + resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} + dev: true + + /conventional-commits-filter@3.0.0: + resolution: {integrity: sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==} + engines: {node: '>=14'} + dependencies: + lodash.ismatch: 4.4.0 + modify-values: 1.0.1 + dev: true + + /conventional-commits-parser@4.0.0: + resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==} + engines: {node: '>=14'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + is-text-path: 1.0.1 + meow: 8.1.2 + split2: 3.2.2 + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cosmiconfig-typescript-loader@4.4.0(@types/node@20.4.7)(cosmiconfig@8.2.0)(ts-node@10.9.1)(typescript@5.2.2): + resolution: {integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==} + engines: {node: '>=v14.21.3'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=7' + ts-node: '>=10' + typescript: '>=4' + dependencies: + '@types/node': 20.4.7 + cosmiconfig: 8.2.0 + ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2) + typescript: 5.2.2 + dev: true + + /cosmiconfig@8.2.0: + resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==} + engines: {node: '>=14'} + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: true + + /cz-conventional-changelog@3.2.0: + resolution: {integrity: sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==} + engines: {node: '>= 10'} + dependencies: + chalk: 2.4.2 + commitizen: 4.2.3 + conventional-commit-types: 3.0.0 + lodash.map: 4.6.0 + longest: 2.0.1 + word-wrap: 1.2.5 + optionalDependencies: + '@commitlint/load': 17.7.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - supports-color + dev: true + + /cz-conventional-changelog@3.3.0: + resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} + engines: {node: '>= 10'} + dependencies: + chalk: 2.4.2 + commitizen: 4.2.3 + conventional-commit-types: 3.0.0 + lodash.map: 4.6.0 + longest: 2.0.1 + word-wrap: 1.2.5 + optionalDependencies: + '@commitlint/load': 17.7.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - supports-color + dev: true + + /dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + dev: true + + /dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + dev: true + + /dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + + /dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /define-properties@1.2.0: + resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 0.1.6 + dev: true + + /define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + dev: true + + /define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + isobject: 3.0.1 + dev: true + + /deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dev: true + + /detect-file@1.0.0: + resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} + engines: {node: '>=0.10.0'} + dev: true + + /detect-indent@6.0.0: + resolution: {integrity: sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==} + engines: {node: '>=8'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dependencies: + is-obj: 2.0.0 + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.8 + dev: true + + /electron-to-chromium@1.4.503: + resolution: {integrity: sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==} + dev: true + + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /env-ci@9.1.1: + resolution: {integrity: sha512-Im2yEWeF4b2RAMAaWvGioXk6m0UNaIjD8hj28j2ij5ldnIFrDQT0+pzDvpbRkcjurhXhf/AsBKv8P2rtmGi9Aw==} + engines: {node: ^16.14 || >=18} + dependencies: + execa: 7.2.0 + java-properties: 1.0.2 + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.22.1: + resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.1 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + safe-array-concat: 1.0.0 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.7 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.11 + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: true + + /eslint-config-prettier@8.5.0(eslint@8.48.0): + resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.48.0 + dev: true + + /eslint-config-standard@17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.48.0): + resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==} + peerDependencies: + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: ^15.0.0 + eslint-plugin-promise: ^6.0.0 + dependencies: + eslint: 8.48.0 + eslint-plugin-import: 2.26.0(eslint@8.48.0) + eslint-plugin-n: 15.7.0(eslint@8.48.0) + eslint-plugin-promise: 6.0.0(eslint@8.48.0) + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.0 + resolve: 1.22.4 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.48.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + debug: 3.2.7 + eslint: 8.48.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-es@3.0.1(eslint@8.48.0): + resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.48.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-es@4.1.0(eslint@8.48.0): + resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.48.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-import@2.26.0(eslint@8.48.0): + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.48.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.48.0) + has: 1.0.3 + is-core-module: 2.13.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.4 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-n@15.7.0(eslint@8.48.0): + resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==} + engines: {node: '>=12.22.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + builtins: 5.0.1 + eslint: 8.48.0 + eslint-plugin-es: 4.1.0(eslint@8.48.0) + eslint-utils: 3.0.0(eslint@8.48.0) + ignore: 5.2.4 + is-core-module: 2.13.0 + minimatch: 3.1.2 + resolve: 1.22.4 + semver: 7.5.4 + dev: true + + /eslint-plugin-node@11.1.0(eslint@8.48.0): + resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=5.16.0' + dependencies: + eslint: 8.48.0 + eslint-plugin-es: 3.0.1(eslint@8.48.0) + eslint-utils: 2.1.0 + ignore: 5.2.4 + minimatch: 3.1.2 + resolve: 1.22.4 + semver: 6.3.1 + dev: true + + /eslint-plugin-promise@6.0.0(eslint@8.48.0): + resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.48.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils@3.0.0(eslint@8.48.0): + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.48.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.48.0: + resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@eslint-community/regexpp': 4.8.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.48.0 + '@humanwhocodes/config-array': 0.11.10 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.21.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.3 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /expand-tilde@2.0.2: + resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} + engines: {node: '>=0.10.0'} + dependencies: + homedir-polyfill: 1.0.3 + dev: true + + /expect@29.6.4: + resolution: {integrity: sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.6.4 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.6.4 + jest-message-util: 29.6.3 + jest-util: 29.6.3 + dev: true + + /extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 0.1.1 + dev: true + + /extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.1.0 + dev: true + + /fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-node-modules@2.0.0: + resolution: {integrity: sha512-8MWIBRgJi/WpjjfVXumjPKCtmQ10B+fjx6zmSA+770GMJirLhWIzg8l763rhjl9xaeaHbnxPNRQKq2mgMhr+aw==} + dependencies: + findup-sync: 3.0.0 + merge: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: true + + /find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: true + + /find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + dependencies: + locate-path: 2.0.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + dev: true + + /find-versions@5.1.0: + resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} + engines: {node: '>=12'} + dependencies: + semver-regex: 4.0.5 + dev: true + + /findup-sync@3.0.0: + resolution: {integrity: sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==} + engines: {node: '>= 0.10'} + dependencies: + detect-file: 1.0.0 + is-glob: 4.0.3 + micromatch: 3.1.10 + resolve-dir: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /flat-cache@3.1.0: + resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} + engines: {node: '>=12.0.0'} + dependencies: + flatted: 3.2.7 + keyv: 4.5.3 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + dev: true + + /fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + dependencies: + map-cache: 0.2.2 + dev: true + + /from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + dev: true + + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-stream@7.0.1: + resolution: {integrity: sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==} + engines: {node: '>=16'} + dev: true + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + + /get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + dev: true + + /git-log-parser@1.2.0: + resolution: {integrity: sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==} + dependencies: + argv-formatter: 1.0.0 + spawn-error-forwarder: 1.0.0 + split2: 1.0.0 + stream-combiner2: 1.1.1 + through2: 2.0.5 + traverse: 0.6.7 + dev: true + + /git-raw-commits@2.0.11: + resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + dargs: 7.0.0 + lodash: 4.17.21 + meow: 8.1.2 + split2: 3.2.2 + through2: 4.0.2 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.1.4: + resolution: {integrity: sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /global-dirs@0.1.1: + resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} + engines: {node: '>=4'} + dependencies: + ini: 1.3.8 + dev: true + + /global-modules@1.0.0: + resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} + engines: {node: '>=0.10.0'} + dependencies: + global-prefix: 1.0.2 + is-windows: 1.0.2 + resolve-dir: 1.0.1 + dev: true + + /global-prefix@1.0.2: + resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} + engines: {node: '>=0.10.0'} + dependencies: + expand-tilde: 2.0.2 + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 1.0.2 + which: 1.3.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.0 + dev: true + + /globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 4.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + dev: true + + /hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + dev: true + + /has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + dev: true + + /has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + dev: true + + /has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + dependencies: + parse-passwd: 1.0.0 + dev: true + + /hook-std@3.0.0: + resolution: {integrity: sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + dependencies: + lru-cache: 6.0.0 + dev: true + + /hosted-git-info@6.1.1: + resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + lru-cache: 7.18.3 + dev: true + + /hosted-git-info@7.0.0: + resolution: {integrity: sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==} + engines: {node: ^16.14.0 || >=18.0.0} + dependencies: + lru-cache: 10.0.1 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@7.0.1: + resolution: {integrity: sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: true + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /husky@8.0.1: + resolution: {integrity: sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-from@4.0.0: + resolution: {integrity: sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==} + engines: {node: '>=12.2'} + dev: true + + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /inquirer@6.5.2: + resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==} + engines: {node: '>=6.0.0'} + dependencies: + ansi-escapes: 3.2.0 + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 3.1.0 + figures: 2.0.0 + lodash: 4.17.21 + mute-stream: 0.0.7 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 2.1.1 + strip-ansi: 5.2.0 + through: 2.3.8 + dev: true + + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /into-stream@7.0.0: + resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} + engines: {node: '>=12'} + dependencies: + from2: 2.3.0 + p-is-promise: 3.0.0 + dev: true + + /is-accessor-descriptor@0.1.6: + resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-accessor-descriptor@1.0.0: + resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + dependencies: + has: 1.0.3 + dev: true + + /is-data-descriptor@0.1.4: + resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-data-descriptor@1.0.0: + resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-descriptor@0.1.6: + resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 0.1.6 + is-data-descriptor: 0.1.4 + kind-of: 5.1.0 + dev: true + + /is-descriptor@1.0.2: + resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 1.0.0 + is-data-descriptor: 1.0.0 + kind-of: 6.0.3 + dev: true + + /is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-text-path@1.0.1: + resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} + engines: {node: '>=0.10.0'} + dependencies: + text-extensions: 1.9.0 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.11 + dev: true + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + + /is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /issue-parser@6.0.0: + resolution: {integrity: sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==} + engines: {node: '>=10.13'} + dependencies: + lodash.capitalize: 4.2.1 + lodash.escaperegexp: 4.1.2 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.uniqby: 4.7.0 + dev: true + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.22.11 + '@babel/parser': 7.22.11 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument@6.0.0: + resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.22.11 + '@babel/parser': 7.22.11 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /java-properties@1.0.2: + resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} + engines: {node: '>= 0.6.0'} + dev: true + + /jest-changed-files@29.6.3: + resolution: {integrity: sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + jest-util: 29.6.3 + p-limit: 3.1.0 + dev: true + + /jest-circus@29.6.4: + resolution: {integrity: sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.4 + '@jest/expect': 29.6.4 + '@jest/test-result': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.1 + is-generator-fn: 2.1.0 + jest-each: 29.6.3 + jest-matcher-utils: 29.6.4 + jest-message-util: 29.6.3 + jest-runtime: 29.6.4 + jest-snapshot: 29.6.4 + jest-util: 29.6.3 + p-limit: 3.1.0 + pretty-format: 29.6.3 + pure-rand: 6.0.2 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-cli@29.6.4(@types/node@20.4.7)(ts-node@10.9.1): + resolution: {integrity: sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.6.4(ts-node@10.9.1) + '@jest/test-result': 29.6.4 + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.1.0 + jest-config: 29.6.4(@types/node@20.4.7)(ts-node@10.9.1) + jest-util: 29.6.3 + jest-validate: 29.6.3 + prompts: 2.4.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-config@29.6.4(@types/node@20.4.7)(ts-node@10.9.1): + resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.22.11 + '@jest/test-sequencer': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.4.7 + babel-jest: 29.6.4(@babel/core@7.22.11) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.6.4 + jest-environment-node: 29.6.4 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.4 + jest-runner: 29.6.4 + jest-util: 29.6.3 + jest-validate: 29.6.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.6.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-config@29.6.4(@types/node@20.5.6)(ts-node@10.9.1): + resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.22.11 + '@jest/test-sequencer': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + babel-jest: 29.6.4(@babel/core@7.22.11) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.6.4 + jest-environment-node: 29.6.4 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.4 + jest-runner: 29.6.4 + jest-util: 29.6.3 + jest-validate: 29.6.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.6.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-diff@29.6.4: + resolution: {integrity: sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.6.3 + dev: true + + /jest-docblock@29.6.3: + resolution: {integrity: sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@29.6.3: + resolution: {integrity: sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.6.3 + pretty-format: 29.6.3 + dev: true + + /jest-environment-node@29.6.4: + resolution: {integrity: sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.4 + '@jest/fake-timers': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + jest-mock: 29.6.3 + jest-util: 29.6.3 + dev: true + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map@29.6.4: + resolution: {integrity: sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.6 + '@types/node': 20.5.6 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.6.3 + jest-worker: 29.6.4 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-leak-detector@29.6.3: + resolution: {integrity: sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.6.3 + dev: true + + /jest-matcher-utils@29.6.4: + resolution: {integrity: sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.6.4 + jest-get-type: 29.6.3 + pretty-format: 29.6.3 + dev: true + + /jest-message-util@29.6.3: + resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.22.10 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.6.3 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@29.6.3: + resolution: {integrity: sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + jest-util: 29.6.3 + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@29.6.4): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.6.4 + dev: true + + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies@29.6.4: + resolution: {integrity: sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.6.4 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@29.6.4: + resolution: {integrity: sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.4 + jest-pnp-resolver: 1.2.3(jest-resolve@29.6.4) + jest-util: 29.6.3 + jest-validate: 29.6.3 + resolve: 1.22.4 + resolve.exports: 2.0.2 + slash: 3.0.0 + dev: true + + /jest-runner@29.6.4: + resolution: {integrity: sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.6.4 + '@jest/environment': 29.6.4 + '@jest/test-result': 29.6.4 + '@jest/transform': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.6.3 + jest-environment-node: 29.6.4 + jest-haste-map: 29.6.4 + jest-leak-detector: 29.6.3 + jest-message-util: 29.6.3 + jest-resolve: 29.6.4 + jest-runtime: 29.6.4 + jest-util: 29.6.3 + jest-watcher: 29.6.4 + jest-worker: 29.6.4 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@29.6.4: + resolution: {integrity: sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.4 + '@jest/fake-timers': 29.6.4 + '@jest/globals': 29.6.4 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.6.4 + '@jest/transform': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + chalk: 4.1.2 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.4 + jest-message-util: 29.6.3 + jest-mock: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.4 + jest-snapshot: 29.6.4 + jest-util: 29.6.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot@29.6.4: + resolution: {integrity: sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.11 + '@babel/generator': 7.22.10 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.11) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.11) + '@babel/types': 7.22.11 + '@jest/expect-utils': 29.6.4 + '@jest/transform': 29.6.4 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11) + chalk: 4.1.2 + expect: 29.6.4 + graceful-fs: 4.2.11 + jest-diff: 29.6.4 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.6.4 + jest-message-util: 29.6.3 + jest-util: 29.6.3 + natural-compare: 1.4.0 + pretty-format: 29.6.3 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@29.6.3: + resolution: {integrity: sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + chalk: 4.1.2 + ci-info: 3.8.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@29.6.3: + resolution: {integrity: sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.6.3 + dev: true + + /jest-watcher@29.6.4: + resolution: {integrity: sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.6.4 + '@jest/types': 29.6.3 + '@types/node': 20.5.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.6.3 + string-length: 4.0.2 + dev: true + + /jest-worker@29.6.4: + resolution: {integrity: sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 20.5.6 + jest-util: 29.6.3 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@29.0.0(@types/node@20.4.7)(ts-node@10.9.1): + resolution: {integrity: sha512-9uz4Tclskb8WrfRXqu66FsFCFoyYctwWXpruKwnD95FZqkyoEAA1oGH53HUn7nQx7uEgZTKdNl/Yo6DqqU+XMg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.6.4(ts-node@10.9.1) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.6.4(@types/node@20.4.7)(ts-node@10.9.1) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-parse-even-better-errors@3.0.0: + resolution: {integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /keyv@4.5.3: + resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of@5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lines-and-columns@2.0.3: + resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + /lodash.capitalize@4.2.1: + resolution: {integrity: sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==} + dev: true + + /lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + dev: true + + /lodash.ismatch@4.4.0: + resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + + /lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + dev: true + + /lodash.map@4.6.0: + resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + dev: true + + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /lodash.uniqby@4.7.0: + resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} + dev: true + + /lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /longest@2.0.1: + resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} + engines: {node: '>=0.10.0'} + dev: true + + /lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: true + + /map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + dependencies: + object-visit: 1.0.1 + dev: true + + /marked-terminal@5.2.0(marked@5.1.2): + resolution: {integrity: sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==} + engines: {node: '>=14.13.1 || >=16.0.0'} + peerDependencies: + marked: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + dependencies: + ansi-escapes: 6.2.0 + cardinal: 2.1.1 + chalk: 5.3.0 + cli-table3: 0.6.3 + marked: 5.1.2 + node-emoji: 1.11.0 + supports-hyperlinks: 2.3.0 + dev: true + + /marked@5.1.2: + resolution: {integrity: sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==} + engines: {node: '>= 16'} + hasBin: true + dev: true + + /meow@8.1.2: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} + engines: {node: '>=10'} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /merge@1.2.1: + resolution: {integrity: sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==} + dev: true + + /micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: true + + /mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + + /minimist@1.2.5: + resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + dev: true + + /modify-values@1.0.1: + resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} + engines: {node: '>=0.10.0'} + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mute-stream@0.0.7: + resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + dev: true + + /nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /nerf-dart@1.0.0: + resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} + dev: true + + /node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + dependencies: + lodash: 4.17.21 + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.4 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.13.0 + semver: 7.5.4 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-package-data@6.0.0: + resolution: {integrity: sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==} + engines: {node: ^16.14.0 || >=18.0.0} + dependencies: + hosted-git-info: 7.0.0 + is-core-module: 2.13.0 + semver: 7.5.4 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url@8.0.0: + resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} + engines: {node: '>=14.16'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /npm@9.8.1: + resolution: {integrity: sha512-AfDvThQzsIXhYgk9zhbk5R+lh811lKkLAeQMMhSypf1BM7zUafeIIBzMzespeuVEJ0+LvY36oRQYf7IKLzU3rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + dev: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/run-script' + - abbrev + - archy + - cacache + - chalk + - ci-info + - cli-columns + - cli-table3 + - columnify + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - npmlog + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - sigstore + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic + + /object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /object.values@1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + dependencies: + mimic-fn: 1.2.0 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /p-each-series@3.0.0: + resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} + engines: {node: '>=12'} + dev: true + + /p-filter@3.0.0: + resolution: {integrity: sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-map: 5.5.0 + dev: true + + /p-is-promise@3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + dev: true + + /p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + dependencies: + p-try: 1.0.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + dependencies: + p-limit: 1.3.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + dev: true + + /p-map@5.5.0: + resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} + engines: {node: '>=12'} + dependencies: + aggregate-error: 4.0.1 + dev: true + + /p-reduce@3.0.0: + resolution: {integrity: sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==} + engines: {node: '>=12'} + dev: true + + /p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.22.10 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse-json@7.0.0: + resolution: {integrity: sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==} + engines: {node: '>=16'} + dependencies: + '@babel/code-frame': 7.22.10 + error-ex: 1.3.2 + json-parse-even-better-errors: 3.0.0 + lines-and-columns: 2.0.3 + type-fest: 3.13.1 + dev: true + + /parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + dev: true + + /pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + dependencies: + find-up: 2.1.0 + load-json-file: 4.0.0 + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.6.2: + resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-format@29.6.3: + resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /pure-rand@6.0.2: + resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} + dev: true + + /q@1.5.1: + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} + engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: true + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: true + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + + /read-pkg-up@10.1.0: + resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==} + engines: {node: '>=16'} + dependencies: + find-up: 6.3.0 + read-pkg: 8.1.0 + type-fest: 4.2.0 + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /read-pkg@8.1.0: + resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} + engines: {node: '>=16'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 6.0.0 + parse-json: 7.0.0 + type-fest: 4.2.0 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /redeyed@2.1.1: + resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + dependencies: + esprima: 4.0.1 + dev: true + + /regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + dev: true + + /regexp.prototype.flags@1.5.0: + resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + functions-have-names: 1.2.3 + dev: true + + /regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + dependencies: + '@pnpm/npm-conf': 2.2.2 + dev: true + + /repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + dev: true + + /repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-dir@1.0.1: + resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} + engines: {node: '>=0.10.0'} + dependencies: + expand-tilde: 2.0.2 + global-modules: 1.0.0 + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-global@1.0.0: + resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} + engines: {node: '>=8'} + dependencies: + global-dirs: 0.1.1 + dev: true + + /resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + dev: true + + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.4: + resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + dev: true + + /ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + dependencies: + tslib: 1.14.1 + dev: true + + /safe-array-concat@1.0.0: + resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + dev: true + + /safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + dependencies: + ret: 0.1.15 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /sanctuary-def@0.22.0: + resolution: {integrity: sha512-lywS27TfuPHzelMh6M1YWBcB//Lom4Gko/tGjKYbDPkPet1B5KplsSdjY+5sF4mwp6+PDUodsk/Y3Uskrc/ebw==} + dependencies: + sanctuary-either: 2.1.0 + sanctuary-show: 2.0.0 + sanctuary-type-classes: 12.1.0 + sanctuary-type-identifiers: 3.0.0 + dev: false + + /sanctuary-either@2.1.0: + resolution: {integrity: sha512-AsQCma2yGAVS7Dlxme/09NZWQfcXBNylVmkuvarp8uOe9otSwClOgQyyePN2OxO4hTf3Au1Ck4ggm+97Je06kA==} + dependencies: + sanctuary-show: 2.0.0 + sanctuary-type-classes: 12.1.0 + dev: false + + /sanctuary-maybe@2.1.0: + resolution: {integrity: sha512-xCmvaEkYaIz5klWUrsgvgORKTL3bVYxATp7HyGBY0ZCu9tHJtSYDTpwnqMkRknHFIU986Kr2M/dJdiFvuc6UCQ==} + dependencies: + sanctuary-show: 2.0.0 + sanctuary-type-classes: 12.1.0 + dev: false + + /sanctuary-pair@2.1.0: + resolution: {integrity: sha512-yY1JzzIJ/Ex7rjN8NmQLB7yv6GVzNeaMvxoYSW8w1ReLQI0n2sGOVCnAVipZuCv7wmfd+BavSXp59rklJeYytw==} + dependencies: + sanctuary-show: 2.0.0 + sanctuary-type-classes: 12.1.0 + dev: false + + /sanctuary-show@2.0.0: + resolution: {integrity: sha512-REj4ZiioUXnDLj6EpJ9HcYDIEGaEexmB9Fg5o6InZR9f0x5PfnnC21QeU9SZ9E7G8zXSZPNjy8VRUK4safbesw==} + dev: false + + /sanctuary-type-classes@12.1.0: + resolution: {integrity: sha512-oWP071Q88dEgJwxHLZp8tc7DoS+mWmYhYOuhP85zznPpIxV1ZjJfyRvcR59YCazyFxyFeBif7bJx1giLhDZW0Q==} + dependencies: + sanctuary-type-identifiers: 3.0.0 + dev: false + + /sanctuary-type-identifiers@3.0.0: + resolution: {integrity: sha512-YFXYcG0Ura1dSPd/1xLYtE2XAWUEsBHhMTZvYBOvwT8MeFQwdUOCMm2DC+r94z6H93FVq0qxDac8/D7QpJj6Mg==} + dev: false + + /sanctuary@3.1.0: + resolution: {integrity: sha512-yTpWmslb5Q2jXcHYeIfCzJksIpe3pngBaFBDpjdPXONWyVSB3hBVDZZ8EmitohaMZqjLB+JREeEL0YOVtdxILA==} + dependencies: + sanctuary-def: 0.22.0 + sanctuary-either: 2.1.0 + sanctuary-maybe: 2.1.0 + sanctuary-pair: 2.1.0 + sanctuary-show: 2.0.0 + sanctuary-type-classes: 12.1.0 + sanctuary-type-identifiers: 3.0.0 + dev: false + + /semantic-release@21.0.7: + resolution: {integrity: sha512-peRDSXN+hF8EFSKzze90ff/EnAmgITHQ/a3SZpRV3479ny0BIZWEJ33uX6/GlOSKdaSxo9hVRDyv2/u2MuF+Bw==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@semantic-release/commit-analyzer': 10.0.1(semantic-release@21.0.7) + '@semantic-release/error': 4.0.0 + '@semantic-release/github': 9.0.4(semantic-release@21.0.7) + '@semantic-release/npm': 10.0.5(semantic-release@21.0.7) + '@semantic-release/release-notes-generator': 11.0.4(semantic-release@21.0.7) + aggregate-error: 4.0.1 + cosmiconfig: 8.2.0 + debug: 4.3.4 + env-ci: 9.1.1 + execa: 7.2.0 + figures: 5.0.0 + find-versions: 5.1.0 + get-stream: 6.0.1 + git-log-parser: 1.2.0 + hook-std: 3.0.0 + hosted-git-info: 6.1.1 + lodash-es: 4.17.21 + marked: 5.1.2 + marked-terminal: 5.2.0(marked@5.1.2) + micromatch: 4.0.5 + p-each-series: 3.0.0 + p-reduce: 3.0.0 + read-pkg-up: 10.1.0 + resolve-from: 5.0.0 + semver: 7.5.4 + semver-diff: 4.0.0 + signale: 1.4.0 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + dev: true + + /semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + dependencies: + semver: 7.5.4 + dev: true + + /semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + dependencies: + chalk: 2.4.2 + figures: 2.0.0 + pkg-conf: 2.1.0 + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + + /snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + dev: true + + /snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + dev: true + + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + dev: true + + /source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spawn-error-forwarder@1.0.0: + resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + dev: true + + /split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + dev: true + + /split2@1.0.0: + resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} + dependencies: + through2: 2.0.5 + dev: true + + /split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + dependencies: + readable-stream: 3.6.2 + dev: true + + /split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + dependencies: + through: 2.3.8 + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + dev: true + + /stream-combiner2@1.1.1: + resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + dependencies: + duplexer2: 0.1.4 + readable-stream: 2.3.8 + dev: true + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trim@1.2.7: + resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimend@1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimstart@1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.1 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + dependencies: + ansi-regex: 3.0.1 + dev: true + + /strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.0.1: + resolution: {integrity: sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==} + engines: {node: '>=8'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + dev: true + + /tempy@3.1.0: + resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} + engines: {node: '>=14.16'} + dependencies: + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-extensions@1.9.0: + resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} + engines: {node: '>=0.10'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + + /through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + dependencies: + readable-stream: 3.6.2 + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + dev: true + + /traverse@0.6.7: + resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} + dev: true + + /trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + dev: true + + /ts-node@10.9.1(@types/node@20.4.7)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.4.7 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + dev: true + + /type-fest@4.2.0: + resolution: {integrity: sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==} + engines: {node: '>=16'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + dev: true + + /unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + dependencies: + crypto-random-string: 4.0.0 + dev: true + + /universal-user-agent@6.0.0: + resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.10): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.10 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + dev: true + + /url-join@5.0.0: + resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-to-istanbul@9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array@1.1.11: + resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true From 3af1b7729dff190a6c740a16b79ef036b3e66381 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 28 Sep 2023 11:58:47 +0200 Subject: [PATCH 27/43] fix: prevent errors when the plugin is used with eslint < 8.40.0 by raising the min required version The plugin relies on context.sourceCode API which has been added in ESLint 8.40.0 BREAKING CHANGE: The minimum required eslint version has been raised to 8.40.0 --- package.json | 10 ++--- pnpm-lock.yaml | 120 ++++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index 41c3d6b..37cd7cc 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,7 @@ "name": "eslint-plugin-xstate", "version": "0.0.0-semantically-released", "description": "ESLint rules for XState", - "keywords": [ - "eslint", - "eslintplugin", - "eslint-plugin" - ], + "keywords": ["eslint", "eslintplugin", "eslint-plugin"], "author": "Richard Laffers", "main": "lib/index.js", "scripts": { @@ -28,7 +24,7 @@ "@commitlint/config-conventional": "^17.0.3", "commitizen": "^4.2.3", "cz-conventional-changelog": "^3.3.0", - "eslint": "^8.48.0", + "eslint": "^8.40.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", @@ -40,7 +36,7 @@ "semantic-release": "^21.0.7" }, "peerDependencies": { - "eslint": "^8.17.0" + "eslint": "^8.40.0" }, "engines": { "node": ">=16.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3875146..1a687bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,23 +32,23 @@ devDependencies: specifier: ^3.3.0 version: 3.3.0 eslint: - specifier: ^8.48.0 - version: 8.48.0 + specifier: ^8.40.0 + version: 8.40.0 eslint-config-prettier: specifier: ^8.5.0 - version: 8.5.0(eslint@8.48.0) + version: 8.5.0(eslint@8.40.0) eslint-config-standard: specifier: ^17.0.0 - version: 17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.48.0) + version: 17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.40.0) eslint-plugin-import: specifier: ^2.26.0 - version: 2.26.0(eslint@8.48.0) + version: 2.26.0(eslint@8.40.0) eslint-plugin-node: specifier: ^11.1.0 - version: 11.1.0(eslint@8.48.0) + version: 11.1.0(eslint@8.40.0) eslint-plugin-promise: specifier: ^6.0.0 - version: 6.0.0(eslint@8.48.0) + version: 6.0.0(eslint@8.40.0) husky: specifier: ^8.0.1 version: 8.0.1 @@ -588,18 +588,18 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.40.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.48.0 + eslint: 8.40.0 eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.8.0: - resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==} + /@eslint-community/regexpp@4.9.0: + resolution: {integrity: sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true @@ -620,13 +620,13 @@ packages: - supports-color dev: true - /@eslint/js@8.48.0: - resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} + /@eslint/js@8.40.0: + resolution: {integrity: sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + /@humanwhocodes/config-array@0.11.11: + resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 @@ -2336,16 +2336,16 @@ packages: engines: {node: '>=12'} dev: true - /eslint-config-prettier@8.5.0(eslint@8.48.0): + /eslint-config-prettier@8.5.0(eslint@8.40.0): resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.48.0 + eslint: 8.40.0 dev: true - /eslint-config-standard@17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.48.0): + /eslint-config-standard@17.0.0(eslint-plugin-import@2.26.0)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.0.0)(eslint@8.40.0): resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==} peerDependencies: eslint: ^8.0.1 @@ -2353,10 +2353,10 @@ packages: eslint-plugin-n: ^15.0.0 eslint-plugin-promise: ^6.0.0 dependencies: - eslint: 8.48.0 - eslint-plugin-import: 2.26.0(eslint@8.48.0) - eslint-plugin-n: 15.7.0(eslint@8.48.0) - eslint-plugin-promise: 6.0.0(eslint@8.48.0) + eslint: 8.40.0 + eslint-plugin-import: 2.26.0(eslint@8.40.0) + eslint-plugin-n: 15.7.0(eslint@8.40.0) + eslint-plugin-promise: 6.0.0(eslint@8.40.0) dev: true /eslint-import-resolver-node@0.3.9: @@ -2369,7 +2369,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.48.0): + /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.40.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -2391,35 +2391,35 @@ packages: optional: true dependencies: debug: 3.2.7 - eslint: 8.48.0 + eslint: 8.40.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-es@3.0.1(eslint@8.48.0): + /eslint-plugin-es@3.0.1(eslint@8.40.0): resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.48.0 + eslint: 8.40.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-es@4.1.0(eslint@8.48.0): + /eslint-plugin-es@4.1.0(eslint@8.40.0): resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.48.0 + eslint: 8.40.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-import@2.26.0(eslint@8.48.0): + /eslint-plugin-import@2.26.0(eslint@8.40.0): resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -2433,9 +2433,9 @@ packages: array.prototype.flat: 1.3.1 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.48.0 + eslint: 8.40.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.48.0) + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.40.0) has: 1.0.3 is-core-module: 2.13.0 is-glob: 4.0.3 @@ -2449,31 +2449,31 @@ packages: - supports-color dev: true - /eslint-plugin-n@15.7.0(eslint@8.48.0): + /eslint-plugin-n@15.7.0(eslint@8.40.0): resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==} engines: {node: '>=12.22.0'} peerDependencies: eslint: '>=7.0.0' dependencies: builtins: 5.0.1 - eslint: 8.48.0 - eslint-plugin-es: 4.1.0(eslint@8.48.0) - eslint-utils: 3.0.0(eslint@8.48.0) + eslint: 8.40.0 + eslint-plugin-es: 4.1.0(eslint@8.40.0) + eslint-utils: 3.0.0(eslint@8.40.0) ignore: 5.2.4 is-core-module: 2.13.0 minimatch: 3.1.2 - resolve: 1.22.4 + resolve: 1.22.6 semver: 7.5.4 dev: true - /eslint-plugin-node@11.1.0(eslint@8.48.0): + /eslint-plugin-node@11.1.0(eslint@8.40.0): resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: - eslint: 8.48.0 - eslint-plugin-es: 3.0.1(eslint@8.48.0) + eslint: 8.40.0 + eslint-plugin-es: 3.0.1(eslint@8.40.0) eslint-utils: 2.1.0 ignore: 5.2.4 minimatch: 3.1.2 @@ -2481,13 +2481,13 @@ packages: semver: 6.3.1 dev: true - /eslint-plugin-promise@6.0.0(eslint@8.48.0): + /eslint-plugin-promise@6.0.0(eslint@8.40.0): resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.48.0 + eslint: 8.40.0 dev: true /eslint-scope@7.2.2: @@ -2505,13 +2505,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils@3.0.0(eslint@8.48.0): + /eslint-utils@3.0.0(eslint@8.40.0): resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.48.0 + eslint: 8.40.0 eslint-visitor-keys: 2.1.0 dev: true @@ -2530,16 +2530,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.48.0: - resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} + /eslint@8.40.0: + resolution: {integrity: sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) - '@eslint-community/regexpp': 4.8.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0) + '@eslint-community/regexpp': 4.9.0 '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.48.0 - '@humanwhocodes/config-array': 0.11.10 + '@eslint/js': 8.40.0 + '@humanwhocodes/config-array': 0.11.11 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 @@ -2558,11 +2558,13 @@ packages: find-up: 5.0.0 glob-parent: 6.0.2 globals: 13.21.0 - graphemer: 1.4.0 + grapheme-splitter: 1.0.4 ignore: 5.2.4 + import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 + js-sdsl: 4.4.2 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 @@ -2571,6 +2573,7 @@ packages: natural-compare: 1.4.0 optionator: 0.9.3 strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color @@ -3143,8 +3146,8 @@ packages: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} dev: true - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true /handlebars@4.7.8: @@ -4230,6 +4233,10 @@ packages: - ts-node dev: true + /js-sdsl@4.4.2: + resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true @@ -5439,6 +5446,15 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /resolve@1.22.6: + resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /restore-cursor@2.0.0: resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} engines: {node: '>=4'} From 02ef191d3e5871b0c5750b0d0e8c30dddabcec9e Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 28 Sep 2023 12:00:31 +0200 Subject: [PATCH 28/43] docs: fix docs about the comment directive --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5856c2f..f1198ce 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,8 @@ By default, the plugin lints only code within the `createMachine` or `Machine` c ```js /* eslint-plugin-xstate-include */ -// 💡 This machine config will no w be linted too. -export machine = { +// 💡 This machine config will now be linted too. +export const machine = { initial: 'active', context: {}, // etc From dcd50f1b23f0f4c71b564a3bd833c5a180cfd48e Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 28 Sep 2023 12:03:17 +0200 Subject: [PATCH 29/43] feat(prefer-predictable-action-arguments): change auto-fix into a suggestion for switching this on Additionally, make this rule work within createMachine even if there is a eslint-plugin-xstate-include comment directive. --- .../prefer-predictable-action-arguments.js | 78 +++++++++--- .../prefer-predictable-action-arguments.js | 116 +++++++++++++++--- 2 files changed, 160 insertions(+), 34 deletions(-) diff --git a/lib/rules/prefer-predictable-action-arguments.js b/lib/rules/prefer-predictable-action-arguments.js index dd520b0..4675dbb 100644 --- a/lib/rules/prefer-predictable-action-arguments.js +++ b/lib/rules/prefer-predictable-action-arguments.js @@ -22,7 +22,12 @@ module.exports = { 'It is advised to configure predictableActionArguments: true at the top-level of your machine config', deprecatedPredictableActionArguments: 'The predictableActionArguments prop was removed in XState v5 so it has no effect. Please remove it.', + changeToTrue: 'Change to true', + + insertPredictableActionArguments: + 'Insert predictableActionArguments: true', }, + hasSuggestions: true, }, create: function (context) { @@ -43,34 +48,61 @@ module.exports = { node: predictableActionArgumentsProperty, messageId: 'deprecatedPredictableActionArguments', fix(fixer) { + const nextToken = context.sourceCode.getTokenAfter( + predictableActionArgumentsProperty + ) + if (nextToken.type === 'Punctuator' && nextToken.value === ',') { + return fixer.removeRange([ + predictableActionArgumentsProperty.range[0], + nextToken.range[1], + ]) + } return fixer.remove(predictableActionArgumentsProperty) }, }) return } + // version 4 if (!predictableActionArgumentsProperty) { if (node.properties.length === 0) { context.report({ node, messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.replaceText( - node, - '{ predictableActionArguments: true }' - ) - }, + suggest: [ + { + messageId: 'insertPredictableActionArguments', + fix(fixer) { + return fixer.replaceText( + node, + '{ predictableActionArguments: true }' + ) + }, + }, + ], }) } else { + // find the indentation of the first property + const { loc } = node.properties[0] + const offset = loc.start.column + context.report({ node, messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.insertTextBefore( - node.properties[0], - 'predictableActionArguments: true,\n' - ) - }, + suggest: [ + { + messageId: 'insertPredictableActionArguments', + fix(fixer) { + return fixer.insertTextBefore( + node.properties[0], + `predictableActionArguments: true,\n${''.padStart( + offset, + ' ' + )}` + ) + }, + }, + ], }) } return @@ -83,12 +115,17 @@ module.exports = { context.report({ node: predictableActionArgumentsProperty, messageId: 'preferPredictableActionArguments', - fix(fixer) { - return fixer.replaceText( - predictableActionArgumentsProperty.value, - 'true' - ) - }, + suggest: [ + { + messageId: 'changeToTrue', + fix(fixer) { + return fixer.replaceText( + predictableActionArgumentsProperty.value, + 'true' + ) + }, + }, + ], }) } } @@ -98,6 +135,11 @@ module.exports = { [`${prefix}> ObjectExpression:first-child`]: check, } : { + // it should still produce errors within the createMachine call even if there is no context + // to identify the root node + 'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:first-child': + check, + ObjectExpression(node) { // check if it is a root state node config if ( diff --git a/tests/lib/rules/prefer-predictable-action-arguments.js b/tests/lib/rules/prefer-predictable-action-arguments.js index 0119284..3bb7da9 100644 --- a/tests/lib/rules/prefer-predictable-action-arguments.js +++ b/tests/lib/rules/prefer-predictable-action-arguments.js @@ -45,12 +45,21 @@ const tests = { predictableActionArguments: false }) `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'changeToTrue', + output: ` createMachine({ predictableActionArguments: true }) `, + }, + ], + }, + ], }), withVersion(5, { code: ` @@ -65,14 +74,37 @@ const tests = { }) `, }), + // also removes a comma if there + withVersion(5, { + code: ` + createMachine({ + predictableActionArguments: false, + }) + `, + errors: [{ messageId: 'deprecatedPredictableActionArguments' }], + output: ` + createMachine({ + + }) + `, + }), withVersion(4, { code: ` createMachine({}) `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'insertPredictableActionArguments', + output: ` createMachine({ predictableActionArguments: true }) `, + }, + ], + }, + ], }), withVersion(4, { code: ` @@ -80,13 +112,22 @@ const tests = { initial: 'ready' }) `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'insertPredictableActionArguments', + output: ` createMachine({ predictableActionArguments: true, -initial: 'ready' + initial: 'ready' }) `, + }, + ], + }, + ], }), withVersion(4, { code: ` @@ -95,15 +136,24 @@ initial: 'ready' predictableActionArguments: 42 }) `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'changeToTrue', + output: ` createMachine({ states: {}, predictableActionArguments: true }) `, + }, + ], + }, + ], }), - // errors reported outside of createMachine if there is the comment directive + // // errors reported outside of createMachine if there is the comment directive withVersion(4, { code: ` /* eslint-plugin-xstate-include */ @@ -111,14 +161,23 @@ initial: 'ready' context: {}, } `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'insertPredictableActionArguments', + output: ` /* eslint-plugin-xstate-include */ const config = { predictableActionArguments: true, -context: {}, + context: {}, } `, + }, + ], + }, + ], }), withVersion(4, { code: ` @@ -128,21 +187,30 @@ context: {}, context: {}, } `, - errors: [{ messageId: 'preferPredictableActionArguments' }], - output: ` + errors: [ + { + messageId: 'preferPredictableActionArguments', + suggestions: [ + { + messageId: 'changeToTrue', + output: ` /* eslint-plugin-xstate-include */ const config = { predictableActionArguments: true, context: {}, } `, + }, + ], + }, + ], }), withVersion(5, { code: ` /* eslint-plugin-xstate-include */ const config = { context: {}, - predictableActionArguments: false + predictableActionArguments: false, } `, errors: [{ messageId: 'deprecatedPredictableActionArguments' }], @@ -154,6 +222,22 @@ context: {}, } `, }), + // // error reported even if there is no context property, because we are within the createMachine call + withVersion(5, { + code: ` + /* eslint-plugin-xstate-include */ + const machine = createMachine({ + predictableActionArguments: false + }) + `, + errors: [{ messageId: 'deprecatedPredictableActionArguments' }], + output: ` + /* eslint-plugin-xstate-include */ + const machine = createMachine({ + + }) + `, + }), ], } From 18e7d863e92184a82ed51d833e33a90aad298db8 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 28 Sep 2023 12:33:27 +0200 Subject: [PATCH 30/43] fix(event-names): fix event name linting in sendTo and forwardTo action creators fix #22 --- lib/rules/event-names.js | 2 +- tests/lib/rules/event-names.js | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/rules/event-names.js b/lib/rules/event-names.js index 2074be5..988c9fc 100644 --- a/lib/rules/event-names.js +++ b/lib/rules/event-names.js @@ -161,7 +161,7 @@ module.exports = { }, [selectorSendEvent(prefix)]: function (node) { - const eventArg = node.arguments[0] + const eventArg = (['sendTo', 'forwardTo'].includes(node.callee.name)) ? node.arguments[1] : node.arguments[0] if (!eventArg) { return } diff --git a/tests/lib/rules/event-names.js b/tests/lib/rules/event-names.js index 7b832a7..ba9ea65 100644 --- a/tests/lib/rules/event-names.js +++ b/tests/lib/rules/event-names.js @@ -19,6 +19,9 @@ const tests = { sendParent('MOUSE.CLICK'), raise('MY_MOUSE.SCROLL_DOWN'), send({ type: 'TOGGLE' }), + sendTo('myActor', 'TOGGLE'), + sendTo('myActor', { type: 'TOGGLE' }), + forwardTo('myActor'), ], }) `, @@ -71,6 +74,8 @@ const tests = { respond('My Event'), raise('myEvent.click'), send({ type: 'myEvent' }), + sendTo('myActor', 'myEvent2'), + sendTo('myActor', { type: 'myEvent3' }), ], }) `, @@ -114,6 +119,14 @@ const tests = { messageId: 'invalidEventName', data: { eventName: 'myEvent', fixedEventName: 'MY_EVENT' }, }, + { + messageId: 'invalidEventName', + data: { eventName: 'myEvent2', fixedEventName: 'MY_EVENT_2' }, + }, + { + messageId: 'invalidEventName', + data: { eventName: 'myEvent3', fixedEventName: 'MY_EVENT_3' }, + }, ], output: ` createMachine({ @@ -129,6 +142,8 @@ const tests = { respond('MY_EVENT'), raise('MY_EVENT.CLICK'), send({ type: 'MY_EVENT' }), + sendTo('myActor', 'MY_EVENT_2'), + sendTo('myActor', { type: 'MY_EVENT_3' }), ], }) `, @@ -150,6 +165,8 @@ const tests = { respond('My Event'), raise('myEvent.click'), send({ type: 'myEvent' }), + sendTo('myActor', 'myEvent2'), + sendTo('myActor', { type: 'myEvent3' }), ], }) `, @@ -193,6 +210,14 @@ const tests = { messageId: 'invalidEventName', data: { eventName: 'myEvent', fixedEventName: 'my_event' }, }, + { + messageId: 'invalidEventName', + data: { eventName: 'myEvent2', fixedEventName: 'my_event_2' }, + }, + { + messageId: 'invalidEventName', + data: { eventName: 'myEvent3', fixedEventName: 'my_event_3' }, + }, ], output: ` /* eslint event-names: [ "warn", "snakeCase" ] */ @@ -209,6 +234,8 @@ const tests = { respond('my_event'), raise('my_event.click'), send({ type: 'my_event' }), + sendTo('myActor', 'my_event_2'), + sendTo('myActor', { type: 'my_event_3' }), ], }) `, @@ -230,6 +257,8 @@ const tests = { respond('My Event'), raise('my_event.click'), send({ type: 'my_event' }), + sendTo('myActor', 'my_event_2'), + sendTo('myActor', { type: 'my_event_3' }), ], }) `, @@ -273,6 +302,14 @@ const tests = { messageId: 'invalidEventName', data: { eventName: 'my_event', fixedEventName: 'myEvent' }, }, + { + messageId: 'invalidEventName', + data: { eventName: 'my_event_2', fixedEventName: 'myEvent2' }, + }, + { + messageId: 'invalidEventName', + data: { eventName: 'my_event_3', fixedEventName: 'myEvent3' }, + }, ], output: ` /* eslint event-names: [ "warn", "camelCase" ] */ @@ -289,6 +326,8 @@ const tests = { respond('myEvent'), raise('myEvent.click'), send({ type: 'myEvent' }), + sendTo('myActor', 'myEvent2'), + sendTo('myActor', { type: 'myEvent3' }), ], }) `, @@ -303,6 +342,8 @@ const tests = { respond('*'), raise('EVENT.*'), send({ type: 'EVENT.*' }), + sendTo('myActor', 'EVENT.*'), + sendTo('myActor', { type: 'EVENT.*' }), ], }) `, @@ -322,6 +363,12 @@ const tests = { { messageId: 'invalidSendEventName', }, + { + messageId: 'invalidSendEventName', + }, + { + messageId: 'invalidSendEventName', + }, ], }, { From 7934e630c874e07e1b8484761a8f44291be676fb Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Tue, 3 Oct 2023 22:04:04 +0200 Subject: [PATCH 31/43] ci: update github workflows --- .github/workflows/pull-request.yml | 13 ++++++++++++ .github/workflows/release.yml | 15 ++++++-------- .github/workflows/test.yml | 33 ++++++++++++++++++++++++++++++ README.md | 1 + 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/pull-request.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..106ce98 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,13 @@ +name: Pull request code check +on: + pull_request: + branches: + - master + +permissions: + contents: read + +jobs: + check_code: + name: Check code & test + uses: ./.github/workflows/test.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 853c3c1..d333441 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,15 +2,18 @@ name: Release on: push: branches: - - next - master permissions: contents: read # for checkout jobs: - release: + check_code: + name: Check & test code + uses: ./.github/workflows/test.yml + release: name: Release + needs: check_code runs-on: ubuntu-latest permissions: contents: write # to be able to publish a GitHub release @@ -27,13 +30,7 @@ jobs: with: node-version: "lts/*" - name: Install dependencies - run: npm clean-install - - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies - run: npm audit signatures - - name: Lint code - run: npm run lint - - name: Run tests - run: npm test + run: npm clean-install - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e25e595 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,33 @@ +name: Code compliance +on: + workflow_call: + + +permissions: + contents: read # for checkout + +jobs: + check_code: + name: Check and test + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "lts/*" + - name: Install dependencies + run: npm clean-install + - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies + run: npm audit signatures + - name: Check code format + run: npm run format:check + - name: Lint code + run: npm run lint + - name: Run tests + run: npm test diff --git a/README.md b/README.md index f1198ce..a391215 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ESLint plugin to check for common mistakes and enforce good practices when using [XState library](https://xstate.js.org/). [![npm version](https://img.shields.io/npm/v/eslint-plugin-xstate)](https://npmjs.com/package/eslint-plugin-xstate) +[![build status](https://img.shields.io/github/actions/workflow/status/rlaffers/eslint-plugin-xstate/release.yml)](https://github.com/rlaffers/eslint-plugin-xstate/actions/workflows/release.yml) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) From 128d23902e75dbf3cc1ca1a689a77fcb616713db Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 16:08:51 +0200 Subject: [PATCH 32/43] feat(enforce-system-id): add rule enforce-system-id --- lib/index.js | 2 + lib/rules/enforce-system-id.js | 86 ++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 lib/rules/enforce-system-id.js diff --git a/lib/index.js b/lib/index.js index b680df0..30feca9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -28,6 +28,7 @@ module.exports = { 'no-invalid-state-props': require('./rules/no-invalid-state-props'), 'no-async-guard': require('./rules/no-async-guard'), 'no-invalid-conditional-action': require('./rules/no-invalid-conditional-action'), + 'enforce-system-id': require('./rules/enforce-system-id'), }, configs: { // Requires: xstate@5 @@ -79,6 +80,7 @@ module.exports = { 'xstate/no-invalid-state-props': 'error', 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', + 'xstate/enforce-system-id': 'error', }, }, // Requires: xstate@4 diff --git a/lib/rules/enforce-system-id.js b/lib/rules/enforce-system-id.js new file mode 100644 index 0000000..176787b --- /dev/null +++ b/lib/rules/enforce-system-id.js @@ -0,0 +1,86 @@ +'use strict' + +const getDocsUrl = require('../utils/getDocsUrl') +const getSettings = require('../utils/getSettings') +const getSelectorPrefix = require('../utils/getSelectorPrefix') + +module.exports = { + meta: { + type: 'suggestion', + docs: { + description: 'enforce using systemId on invoke', + category: 'Best Practices', + url: getDocsUrl('enforce-system-id'), + recommended: true, + }, + fixable: 'code', + schema: [], + messages: { + missingSystemId: 'Missing "systemId" property in "invoke" block.', + invalidSystemId: 'Property "systemId" should be a non-empty string.', + systemIdNotAllowedBeforeVersion5: + 'Property "systemId" is not supported in xstate < 5.', + }, + }, + + create(context) { + const { version } = getSettings(context) + const prefix = getSelectorPrefix(context.sourceCode) + + return { + [`${prefix}Property[key.name='invoke'] > ObjectExpression`]: (node) => { + const systemIdProp = node.properties.find( + (property) => property.key.name === 'systemId' + ) + if (systemIdProp) { + if (version < 5) { + context.report({ + node: systemIdProp, + messageId: 'systemIdNotAllowedBeforeVersion5', + fix(fixer) { + const nextToken = context.sourceCode.getTokenAfter(systemIdProp) + if ( + nextToken.type === 'Punctuator' && + nextToken.value === ',' + ) { + return fixer.removeRange([ + systemIdProp.range[0], + nextToken.range[1], + ]) + } + return fixer.remove(systemIdProp) + }, + }) + } else if ( + systemIdProp.value.type !== 'Literal' || + typeof systemIdProp.value.value !== 'string' || + systemIdProp.value.value.trim() === '' + ) { + context.report({ + node: systemIdProp, + messageId: 'invalidSystemId', + fix: (fixer) => + fixer.replaceText(systemIdProp.value, "'myActor'"), + }) + } + } else if (version >= 5) { + const { loc } = node.properties[0] + const offset = loc.start.column + context.report({ + node, + messageId: 'missingSystemId', + fix: (fixer) => { + return fixer.insertTextBefore( + node.properties[0], + `systemId: 'myActor',\n${''.padStart(offset, ' ')}` + ) + }, + }) + } + }, + + // TODO another check should make sure that the systemId is unique + // code here + } + }, +} From fbc914c17d480eb810c5efcdb3e0c979043a5a8a Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 16:25:54 +0200 Subject: [PATCH 33/43] feat(enforce-system-id): detect duplicate system IDs --- lib/rules/enforce-system-id.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/rules/enforce-system-id.js b/lib/rules/enforce-system-id.js index 176787b..95cc720 100644 --- a/lib/rules/enforce-system-id.js +++ b/lib/rules/enforce-system-id.js @@ -20,12 +20,14 @@ module.exports = { invalidSystemId: 'Property "systemId" should be a non-empty string.', systemIdNotAllowedBeforeVersion5: 'Property "systemId" is not supported in xstate < 5.', + duplicateSystemId: 'The systemId "{{systemId}}" is not unique.', }, }, create(context) { const { version } = getSettings(context) const prefix = getSelectorPrefix(context.sourceCode) + const systemIds = new Set() return { [`${prefix}Property[key.name='invoke'] > ObjectExpression`]: (node) => { @@ -79,8 +81,20 @@ module.exports = { } }, - // TODO another check should make sure that the systemId is unique - // code here + [`${prefix}Property[key.name='invoke'] > ObjectExpression > Property[key.name="systemId"]`]: + (node) => { + if (systemIds.has(node.value.value)) { + context.report({ + node, + messageId: 'duplicateSystemId', + data: { systemId: node.value.value }, + }) + } else { + systemIds.add(node.value.value) + } + }, + + // TODO check use of systemId in spawns } }, } From 92d077d119e9c2bd0d6778ec8ab059b993164786 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 17:43:05 +0200 Subject: [PATCH 34/43] feat(system-id): add detection of missing systemId within spawn calls --- lib/index.js | 4 +- .../{enforce-system-id.js => system-id.js} | 99 ++++++++++++++----- lib/utils/predicates.js | 22 +++++ 3 files changed, 100 insertions(+), 25 deletions(-) rename lib/rules/{enforce-system-id.js => system-id.js} (50%) diff --git a/lib/index.js b/lib/index.js index 30feca9..5de35af 100644 --- a/lib/index.js +++ b/lib/index.js @@ -28,7 +28,7 @@ module.exports = { 'no-invalid-state-props': require('./rules/no-invalid-state-props'), 'no-async-guard': require('./rules/no-async-guard'), 'no-invalid-conditional-action': require('./rules/no-invalid-conditional-action'), - 'enforce-system-id': require('./rules/enforce-system-id'), + 'system-id': require('./rules/system-id'), }, configs: { // Requires: xstate@5 @@ -80,7 +80,7 @@ module.exports = { 'xstate/no-invalid-state-props': 'error', 'xstate/no-invalid-conditional-action': 'error', 'xstate/no-async-guard': 'error', - 'xstate/enforce-system-id': 'error', + 'xstate/system-id': 'error', }, }, // Requires: xstate@4 diff --git a/lib/rules/enforce-system-id.js b/lib/rules/system-id.js similarity index 50% rename from lib/rules/enforce-system-id.js rename to lib/rules/system-id.js index 95cc720..911af73 100644 --- a/lib/rules/enforce-system-id.js +++ b/lib/rules/system-id.js @@ -3,6 +3,11 @@ const getDocsUrl = require('../utils/getDocsUrl') const getSettings = require('../utils/getSettings') const getSelectorPrefix = require('../utils/getSelectorPrefix') +const { + isAssignActionCreatorCall, + isWithinNode, + isFunctionExpression, +} = require('../utils/predicates') module.exports = { meta: { @@ -16,7 +21,8 @@ module.exports = { fixable: 'code', schema: [], messages: { - missingSystemId: 'Missing "systemId" property in "invoke" block.', + missingSystemId: 'Missing "systemId" property for an invoked actor.', + missingSystemIdSpawn: 'Missing "systemId" property for a spawned actor.', invalidSystemId: 'Property "systemId" should be a non-empty string.', systemIdNotAllowedBeforeVersion5: 'Property "systemId" is not supported in xstate < 5.', @@ -29,6 +35,69 @@ module.exports = { const prefix = getSelectorPrefix(context.sourceCode) const systemIds = new Set() + function checkSpawnExpression(node) { + // check if this spawn call is relevant - must be within a function expression inside the assign action creator + if ( + !isWithinNode( + node, + (ancestor) => + isFunctionExpression(ancestor) && + isWithinNode( + ancestor, + (x) => isAssignActionCreatorCall(x), + (ancestor) => isFunctionExpression(ancestor) + ) + ) + ) { + return + } + + if (node.arguments.length < 2) { + context.report({ + node, + messageId: 'missingSystemIdSpawn', + }) + return + } + const arg2 = node.arguments[1] + if ( + arg2.type !== 'ObjectExpression' || + !arg2.properties.some((prop) => prop.key.name === 'systemId') + ) { + context.report({ + node: arg2, + messageId: 'missingSystemIdSpawn', + }) + return + } + const systemIdProp = arg2.properties.find( + (prop) => prop.key.name === 'systemId' + ) + + if ( + systemIdProp.value.type !== 'Literal' || + typeof systemIdProp.value.value !== 'string' || + systemIdProp.value.value.trim() === '' + ) { + context.report({ + node: systemIdProp, + messageId: 'invalidSystemId', + }) + } + } + + function checkUniqueSystemId(node) { + if (systemIds.has(node.value.value)) { + context.report({ + node, + messageId: 'duplicateSystemId', + data: { systemId: node.value.value }, + }) + } else { + systemIds.add(node.value.value) + } + } + return { [`${prefix}Property[key.name='invoke'] > ObjectExpression`]: (node) => { const systemIdProp = node.properties.find( @@ -61,40 +130,24 @@ module.exports = { context.report({ node: systemIdProp, messageId: 'invalidSystemId', - fix: (fixer) => - fixer.replaceText(systemIdProp.value, "'myActor'"), }) } } else if (version >= 5) { - const { loc } = node.properties[0] - const offset = loc.start.column context.report({ node, messageId: 'missingSystemId', - fix: (fixer) => { - return fixer.insertTextBefore( - node.properties[0], - `systemId: 'myActor',\n${''.padStart(offset, ' ')}` - ) - }, }) } }, [`${prefix}Property[key.name='invoke'] > ObjectExpression > Property[key.name="systemId"]`]: - (node) => { - if (systemIds.has(node.value.value)) { - context.report({ - node, - messageId: 'duplicateSystemId', - data: { systemId: node.value.value }, - }) - } else { - systemIds.add(node.value.value) - } - }, + checkUniqueSystemId, + [`${prefix}CallExpression[callee.name="assign"] CallExpression[callee.name="spawn"] > ObjectExpression > Property[key.name="systemId"]`]: + checkUniqueSystemId, - // TODO check use of systemId in spawns + [`${prefix} CallExpression[callee.name="spawn"]`]: checkSpawnExpression, + [`${prefix} CallExpression[callee.property.name="spawn"]`]: + checkSpawnExpression, } }, } diff --git a/lib/utils/predicates.js b/lib/utils/predicates.js index 95d052d..2ded136 100644 --- a/lib/utils/predicates.js +++ b/lib/utils/predicates.js @@ -143,6 +143,22 @@ function isWithinInvoke(property) { ) } +function isWithinNode(node, predicate, stop = () => false) { + let current = node.parent + while (true) { + if (!current) { + return false + } + if (predicate(current)) { + return true + } + if (stop(current)) { + return false + } + current = current.parent + } +} + // list of property names which have special meaning to XState in some contexts (they are // part of the XState's API) const reservedWords = [ @@ -171,6 +187,10 @@ function isReservedXStateWord(string) { return reservedWords.includes(string) } +function isAssignActionCreatorCall(node) { + return node.type === 'CallExpression' && node.callee.name === 'assign' +} + module.exports = { isFirstArrayItem, propertyHasName, @@ -188,4 +208,6 @@ module.exports = { isKnownActionCreatorCall, isWithinInvoke, isReservedXStateWord, + isAssignActionCreatorCall, + isWithinNode, } From a27bbf87ff0326e6b0b4de2925641a8d18a55ddf Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:33:04 +0200 Subject: [PATCH 35/43] test(system-id): add a test for system-id rule --- tests/lib/rules/system-id.js | 137 +++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 tests/lib/rules/system-id.js diff --git a/tests/lib/rules/system-id.js b/tests/lib/rules/system-id.js new file mode 100644 index 0000000..a9aa767 --- /dev/null +++ b/tests/lib/rules/system-id.js @@ -0,0 +1,137 @@ +const { RuleTester } = require('eslint') +const { withVersion } = require('../utils/settings') +const rule = require('../../../lib/rules/system-id') + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 6, + }, +}) + +const missingSystemIdInvoke = { + messageId: 'missingSystemId', +} +const missingSystemIdSpawn = { + messageId: 'missingSystemIdSpawn', +} +const invalidSystemId = { + messageId: 'invalidSystemId', +} +const notAllowedIn4 = { + messageId: 'systemIdNotAllowedBeforeVersion5', +} + +ruleTester.run('system-id', rule, { + valid: [ + withVersion( + 5, + ` + const machine = createMachine({ + invoke: { + src: 'someActor', + systemId: 'someId', + }, + }) + ` + ), + withVersion( + 5, + ` + const machine = createMachine({ + initial: 'idle', + states: { + idle: { + entry: assign({ + ref: ({ spawn }) => spawn('someActor', { systemId: 'actor1' }), + }), + exit: assign(({ spawn }) => ({ + ref: spawn('someActor', { systemId: 'actor2' }), + })) + }, + }, + }) + ` + ), + ], + invalid: [ + withVersion(5, { + code: ` + const machine = createMachine({ + invoke: { + src: 'someActor', + }, + }) + `, + errors: [missingSystemIdInvoke], + }), + withVersion(5, { + code: ` + const machine = createMachine({ + invoke: { + src: 'someActor', + systemId: [], + }, + }) + `, + errors: [invalidSystemId], + }), + withVersion(4, { + code: ` + const machine = createMachine({ + invoke: { + src: 'someActor', + systemId: 'someId', + }, + }) + `, + errors: [notAllowedIn4], + output: ` + const machine = createMachine({ + invoke: { + src: 'someActor', + + }, + }) + `, + }), + withVersion(5, { + code: ` + const machine = createMachine({ + initial: 'idle', + states: { + idle: { + entry: assign({ + ref: ({ spawn }) => spawn('someActor'), + }), + exit: assign(({ spawn }) => ({ + ref: spawn('someActor'), + })), + }, + }, + }) + `, + errors: [missingSystemIdSpawn, missingSystemIdSpawn], + }), + withVersion(5, { + code: ` + const machine = createMachine({ + invoke: { + src: 'someActor', + systemId: 'myId', + }, + entry: assign({ + ref: ({ spawn }) => spawn('someActor', { systemId: 'myId' }), + }), + }) + `, + errors: [ + { + messageId: 'duplicateSystemId', + data: { + systemId: 'myId', + }, + }, + ], + }), + ], +}) From ced8e3ab5cbe83de0eda74f5823298ecc949c793 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:44:09 +0200 Subject: [PATCH 36/43] docs(system-id): add docs about system-id --- README.md | 4 +- docs/rules/system-id.md | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 docs/rules/system-id.md diff --git a/README.md b/README.md index a391215..37c67ac 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ Then configure the rules you want to use under the rules section. "xstate/event-names": ["warn", "macroCase"], "xstate/state-names": ["warn", "camelCase"], "xstate/no-inline-implementation": "warn", - "xstate/no-auto-forward": "warn" + "xstate/no-auto-forward": "warn", + "xstate/system-id": "warn", } } ``` @@ -127,6 +128,7 @@ If you do not use shareable configs, you need to manually specify the XState ver | [prefer-always](docs/rules/prefer-always.md) | Suggest using the `always` syntax for transient (eventless) transitions | :heavy_check_mark: | | [prefer-predictable-action-arguments](docs/rules/prefer-predictable-action-arguments.md) | Suggest turning on the `predictableActionArguments` option | :heavy_check_mark: | | [no-auto-forward](docs/rules/no-auto-forward.md) | Forbid auto-forwarding events to invoked services or spawned actors | | +| [system-id](docs/rules/system-id.md) | Suggest using systemId for invoked or spawned actors | | ### Stylistic Issues diff --git a/docs/rules/system-id.md b/docs/rules/system-id.md new file mode 100644 index 0000000..2b6837d --- /dev/null +++ b/docs/rules/system-id.md @@ -0,0 +1,89 @@ +# Suggest valid systemId for invoked or spawned actors + +Provide `systemId` for invoked and spawned actors to make them available in the `actor.system` registry. + +## Rule Details + +Specifying a `systemId` property within `invoke` blocks, and within options passed as a second argument to `spawn` calls, will make the actor available in the `actor.system` registry. + +**The `systemId` property is supported in XState version 5 and above.** + +Examples of **incorrect** code for this rule: + +```javascript +// ❌ missing systemId in an invoke block +createMachine({ + states: { + playing: { + invoke: { + src: 'game', + }, + }, + }, +}) + +// ❌ missing systemId in a spawn call +createMachine({ + states: { + initializing: { + entry: assign({ + gameRef: () => spawn(game), + }), + }, + }, +}) + +// ❌ invalid systemId value +createMachine({ + states: { + playing: { + invoke: { + src: 'game', + system: [], + }, + }, + }, +}) + +// ❌ duplicate systemIds +createMachine({ + states: { + playing: { + invoke: { + src: 'game', + system: 'actor1', + }, + entry: assign({ + gameRef: () => spawn(game, { systemId: 'actor1' }), + }), + }, + }, +}) +``` + +Examples of **correct** code for this rule: + +```javascript +// ✅ +createMachine{{ + states: { + playing: { + invoke: { + src: 'game', + systemId: 'actor1', + }, + }, + }, +}} + +// ✅ +createMachine({ + states: { + initializing: { + entry: assign({ + gameRef: () => spawn(game, { systemId: 'actor1' }), + }), + }, + }, +}) +``` From 23b0f3c75fc2020cdd70b76485d026e8cb3a63c1 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:49:28 +0200 Subject: [PATCH 37/43] ci: add format:check script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 37cd7cc..11c220f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test:watch": "jest --watch", "lint": "eslint lib/", "format": "prettier --write README.md {lib,docs,tests}/**/*.{js,md}", + "format:check": "prettier --check README.md {lib,docs,tests}/**/*.{js,md}", "prepare": "husky install", "semantic-release": "semantic-release" }, From d9f45ccfb80409fdb876c163c977354eaab57c5a Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:51:14 +0200 Subject: [PATCH 38/43] style: prettify code style --- README.md | 18 ++-- docs/rules/event-names.md | 2 +- docs/rules/no-inline-implementation.md | 109 +++++++++++++------------ lib/rules/event-names.js | 4 +- lib/utils/getSettings.js | 8 +- lib/utils/isXStateLintingEnforced.js | 6 +- 6 files changed, 79 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 37c67ac..be15dde 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Then configure the rules you want to use under the rules section. "xstate/state-names": ["warn", "camelCase"], "xstate/no-inline-implementation": "warn", "xstate/no-auto-forward": "warn", - "xstate/system-id": "warn", + "xstate/system-id": "warn" } } ``` @@ -77,6 +77,7 @@ There is also an `all` configuration which includes every available rule. It enf ``` ### XState Version + The default shareable configurations are for XState v5. If you use XState version 4, append `_v4` to the name of the configuration you want to use. ```json @@ -92,6 +93,7 @@ The default shareable configurations are for XState v5. If you use XState versio ``` If you do not use shareable configs, you need to manually specify the XState version in the ESLint config (defaults to 5): + ```json { "settings": { @@ -122,13 +124,13 @@ If you do not use shareable configs, you need to manually specify the XState ver ### Best Practices -| Rule | Description | Recommended | -| ------------------------------------------------------------------ | ----------------------------------------------------------------------- | ------------------ | -| [no-inline-implementation](docs/rules/no-inline-implementation.md) | Suggest refactoring guards, actions and services into machine options | | -| [prefer-always](docs/rules/prefer-always.md) | Suggest using the `always` syntax for transient (eventless) transitions | :heavy_check_mark: | -| [prefer-predictable-action-arguments](docs/rules/prefer-predictable-action-arguments.md) | Suggest turning on the `predictableActionArguments` option | :heavy_check_mark: | -| [no-auto-forward](docs/rules/no-auto-forward.md) | Forbid auto-forwarding events to invoked services or spawned actors | | -| [system-id](docs/rules/system-id.md) | Suggest using systemId for invoked or spawned actors | | +| Rule | Description | Recommended | +| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------ | +| [no-inline-implementation](docs/rules/no-inline-implementation.md) | Suggest refactoring guards, actions and services into machine options | | +| [prefer-always](docs/rules/prefer-always.md) | Suggest using the `always` syntax for transient (eventless) transitions | :heavy_check_mark: | +| [prefer-predictable-action-arguments](docs/rules/prefer-predictable-action-arguments.md) | Suggest turning on the `predictableActionArguments` option | :heavy_check_mark: | +| [no-auto-forward](docs/rules/no-auto-forward.md) | Forbid auto-forwarding events to invoked services or spawned actors | | +| [system-id](docs/rules/system-id.md) | Suggest using systemId for invoked or spawned actors | | ### Stylistic Issues diff --git a/docs/rules/event-names.md b/docs/rules/event-names.md index 2bd654d..3e49da0 100644 --- a/docs/rules/event-names.md +++ b/docs/rules/event-names.md @@ -11,7 +11,7 @@ While the XState library neither enforces nor recommends any particular format f - camelCase - regular expression -The default MACRO*CASE for event names is an *unofficial* convention, typically used within the XState community. +The default MACRO*CASE for event names is an *unofficial\* convention, typically used within the XState community. Examples of **incorrect** code for this rule: diff --git a/docs/rules/no-inline-implementation.md b/docs/rules/no-inline-implementation.md index 27279f2..5d1e712 100644 --- a/docs/rules/no-inline-implementation.md +++ b/docs/rules/no-inline-implementation.md @@ -10,6 +10,7 @@ Although this is convenient, this makes it difficult to debug, test, serialize a ### XState v5 In XState v5 some built-in action creators were removed, so this rule will report an error when they are inlined: + - `respond` - `send`: removed in favor of `raise` and `sendParent` - `sendUpdate` @@ -25,23 +26,24 @@ createMachine({ states: { inactive: { invoke: { - src: () => Promise.resolve(42) // inlined service + src: () => Promise.resolve(42), // inlined service }, on: { TRIGGER: { target: 'active', cond: () => {}, // inlined guard - actions: () => {} // inlined action - } + actions: () => {}, // inlined action + }, }, activities: () => {}, // inlined activity entry: assign({ - childActor: () => spawn( - () => {}, // inlined actor - ) + childActor: () => + spawn( + () => {} // inlined actor + ), }), - } - } + }, + }, }) // ❌ using variable references is not recommended for the same reasons @@ -49,23 +51,24 @@ createMachine({ states: { inactive: { invoke: { - src: someMachine // defined elsewhere + src: someMachine, // defined elsewhere }, on: { TRIGGER: { target: 'active', cond: isEnoughFuel, // defined elsewhere - actions: huffAndPuff // defined elsewhere - } + actions: huffAndPuff, // defined elsewhere + }, }, activities: beep, // defined elsewhere entry: assign({ - childActor: () => spawn( - childMachine, // inlined actor - ) + childActor: () => + spawn( + childMachine // inlined actor + ), }), - } - } + }, + }, }) ``` @@ -78,40 +81,38 @@ createMachine( states: { inactive: { invoke: { - src: 'someMachine' + src: 'someMachine', }, on: { TRIGGER: { target: 'active', cond: 'isEnoughFuel', - actions: ['huffAndPuff', 'log'] // arrays are ok too - } + actions: ['huffAndPuff', 'log'], // arrays are ok too + }, }, activities: 'beep', entry: assign({ - childActor: () => spawn( - 'childMachine', - ) + childActor: () => spawn('childMachine'), }), - } - } + }, + }, }, { // "services" in XState v4, renamed to "actors" in XState v5 services: { - someMachine: () => {} + someMachine: () => {}, }, guards: { - isEnoughFuel: () => true + isEnoughFuel: () => true, }, actions: { huffAndPuff: () => {}, - log: () => {} + log: () => {}, }, // only in XState v4 activities: { - beep: () => {} - } + beep: () => {}, + }, } ) @@ -123,11 +124,11 @@ createMachine({ entry: assign({ count: 1 }), on: { TRIGGER: { - actions: [assign({ count: 0 }), raise({ type: 'EVENT' })] // arrays are ok too - } - } - } - } + actions: [assign({ count: 0 }), raise({ type: 'EVENT' })], // arrays are ok too + }, + }, + }, + }, }) // ✅ inlined guard creator calls are ok if they match guardCreatorRegex @@ -138,11 +139,11 @@ createMachine({ on: { BUTTON_CLICKED: { cond: customGuard(['isStartButton', 'isReady']), - target: 'active' - } - } - } - } + target: 'active', + }, + }, + }, + }, }) // ✅ inlined built-in guards are ok with XState v5 @@ -153,16 +154,16 @@ createMachine({ BUTTON_CLICKED: [ { guard: and(['isStartButton', 'isDoubleClick']), - target: 'active' + target: 'active', }, { guard: stateIn('mode.active'), - target: 'inactive' + target: 'inactive', }, - ] - } - } - } + ], + }, + }, + }, }) // ✅ inlined action creator calls are ok if they match actionCreatorRegex @@ -174,10 +175,10 @@ createMachine({ BUTTON_CLICKED: { target: 'active', actions: customAction(), - } - } - } - } + }, + }, + }, + }, }) // ✅ inlined actor creator calls are ok if they match actorCreatorRegex @@ -186,10 +187,10 @@ createMachine({ states: { inactive: { invoke: { - src: customActor() - } - } - } + src: customActor(), + }, + }, + }, }) ``` @@ -200,7 +201,7 @@ createMachine({ | `allowKnownActionCreators` | No | `false` | Inlined action creators are visualized properly (but still difficult to test, debug and serialize). Setting this option to `true` will turn off the rule for [known action creators](https://xstate.js.org/docs/guides/actions.html) used inline. | | `guardCreatorRegex` | No | `''` | Use a regular expression to allow custom guard creators. | | `actionCreatorRegex` | No | `''` | Use a regular expression to allow custom action creators. | -| `actorCreatorRegex` | No | `''` | Use a regular expression to allow custom actor creators. | +| `actorCreatorRegex` | No | `''` | Use a regular expression to allow custom actor creators. | ## Example diff --git a/lib/rules/event-names.js b/lib/rules/event-names.js index 988c9fc..097ee50 100644 --- a/lib/rules/event-names.js +++ b/lib/rules/event-names.js @@ -161,7 +161,9 @@ module.exports = { }, [selectorSendEvent(prefix)]: function (node) { - const eventArg = (['sendTo', 'forwardTo'].includes(node.callee.name)) ? node.arguments[1] : node.arguments[0] + const eventArg = ['sendTo', 'forwardTo'].includes(node.callee.name) + ? node.arguments[1] + : node.arguments[0] if (!eventArg) { return } diff --git a/lib/utils/getSettings.js b/lib/utils/getSettings.js index cb39ccb..929b33f 100644 --- a/lib/utils/getSettings.js +++ b/lib/utils/getSettings.js @@ -1,7 +1,7 @@ 'use strict' const defaults = { - version: 5 + version: 5, } const supportedVersions = [4, 5] @@ -9,11 +9,13 @@ const supportedVersions = [4, 5] module.exports = function getSettings(context) { const settings = { ...defaults, - ...(context.settings ? context.settings.xstate : undefined) + ...(context.settings ? context.settings.xstate : undefined), } if (!supportedVersions.includes(settings.version)) { - throw new Error(`XState version "${settings.version}" is not supported. Check "settings.xstate.version" in your ESLint config.`) + throw new Error( + `XState version "${settings.version}" is not supported. Check "settings.xstate.version" in your ESLint config.` + ) } return settings } diff --git a/lib/utils/isXStateLintingEnforced.js b/lib/utils/isXStateLintingEnforced.js index 0944842..fa3f19c 100644 --- a/lib/utils/isXStateLintingEnforced.js +++ b/lib/utils/isXStateLintingEnforced.js @@ -1,3 +1,7 @@ module.exports = function isXStateLintingEnforced(sourceCode) { - return sourceCode.getAllComments().some(x => x.type === 'Block' && x.value === ' eslint-plugin-xstate-include ') + return sourceCode + .getAllComments() + .some( + (x) => x.type === 'Block' && x.value === ' eslint-plugin-xstate-include ' + ) } From 62afca24a67a1d094d0ec79d187c4bcf277ccffb Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:53:03 +0200 Subject: [PATCH 39/43] ci: update pull-request.yml --- .github/workflows/pull-request.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 106ce98..64a4b64 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -3,6 +3,7 @@ on: pull_request: branches: - master + - next permissions: contents: read From 2fd7856d41d391819cd6b7bd60d6b3594d68bb52 Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 18:53:31 +0200 Subject: [PATCH 40/43] ci: update release.yml --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d333441..6467441 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,7 @@ on: push: branches: - master + - next permissions: contents: read # for checkout From 5ccb82c9c31009d269833011cd3f541818071a0c Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Thu, 5 Oct 2023 19:00:05 +0200 Subject: [PATCH 41/43] docs(system-id): fix typos in docs --- docs/rules/system-id.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rules/system-id.md b/docs/rules/system-id.md index 2b6837d..8fdf06e 100644 --- a/docs/rules/system-id.md +++ b/docs/rules/system-id.md @@ -1,10 +1,10 @@ -# Suggest valid systemId for invoked or spawned actors +# Suggest using systemId for invoked or spawned actors Provide `systemId` for invoked and spawned actors to make them available in the `actor.system` registry. ## Rule Details -Specifying a `systemId` property within `invoke` blocks, and within options passed as a second argument to `spawn` calls, will make the actor available in the `actor.system` registry. +Specifying a `systemId` property within `invoke` blocks, and within options passed as the second argument to `spawn` calls, will make the actor available in the `actor.system` registry. **The `systemId` property is supported in XState version 5 and above.** @@ -51,7 +51,7 @@ createMachine({ playing: { invoke: { src: 'game', - system: 'actor1', + systemId: 'actor1', }, entry: assign({ gameRef: () => spawn(game, { systemId: 'actor1' }), From d946e252d77c3bd1ee0f40c5bb51519b03dd100b Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Wed, 18 Oct 2023 10:29:15 +0200 Subject: [PATCH 42/43] feat(no-invalid-state-props): add "output" as a valid prop on the root state --- lib/rules/no-invalid-state-props.js | 3 ++- tests/lib/rules/no-invalid-state-props.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-invalid-state-props.js b/lib/rules/no-invalid-state-props.js index 305fb56..006814e 100644 --- a/lib/rules/no-invalid-state-props.js +++ b/lib/rules/no-invalid-state-props.js @@ -55,7 +55,7 @@ const validProperties = { function isValidStateProperty(property, version) { return ( - validRootProperties[version] && + validProperties[version] && validProperties[version].includes(property.key.name) ) } @@ -100,6 +100,7 @@ const validRootProperties = { 'target', // only when type=history 'types', 'type', + 'output', ], } function isValidRootStateProperty(property, version) { diff --git a/tests/lib/rules/no-invalid-state-props.js b/tests/lib/rules/no-invalid-state-props.js index e1f8893..0bb0524 100644 --- a/tests/lib/rules/no-invalid-state-props.js +++ b/tests/lib/rules/no-invalid-state-props.js @@ -71,6 +71,7 @@ const tests = { types: {}, entry: 'log', exit: 'log', + output: { answer: 42 }, states: { idle: { type: 'parallel', From eef513cf940d87a41557a17a710a280d2e18983b Mon Sep 17 00:00:00 2001 From: Richard Laffers Date: Sat, 16 Dec 2023 12:22:57 +0100 Subject: [PATCH 43/43] chore: upgrade node version --- .nvmrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nvmrc b/.nvmrc index 603606b..f3f52b4 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.17.0 +20.9.0 diff --git a/package.json b/package.json index 11c220f..a58a622 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,6 @@ } }, "volta": { - "node": "18.17.0" + "node": "20.9.0" } }