commit fd67e90cbc442731c090621b811960e8b7808acc Author: Alex <8125011+alex-kinokon@users.noreply.github.com> Date: Wed Jul 19 23:40:39 2023 -0400 Initial commit diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..12fe1ff --- /dev/null +++ b/.eslintrc @@ -0,0 +1,62 @@ +{ + "root": true, + "env": { + "node": true, + "browser": true, + "es6": true + }, + "extends": ["eslint:recommended", "prettier"], + "parserOptions": { + "sourceType": "module", + "ecmaVersion": "latest" + }, + "rules": { + "no-restricted-imports": [ + "warn", + { + "paths": [ + "array-includes", + "array.prototype.flat", + "array.prototype.flatmap", + "array.prototype.tosorted", + "object.entries", + "object.fromentries", + "object.hasown", + "object.values", + "string.prototype.matchall", + "has" + ] + } + ], + "arrow-body-style": ["error", "as-needed"], + "class-methods-use-this": [ + "warn", + { "exceptMethods": ["toString", "shouldComponentUpdate"] } + ], + "complexity": ["warn", { "max": 100 }], + "curly": ["error", "multi-line", "consistent"], + "eqeqeq": ["error", "smart"], + "no-async-promise-executor": "off", + "no-case-declarations": "off", + "no-constant-condition": ["error", { "checkLoops": false }], + "no-debugger": "off", + "no-empty": ["error", { "allowEmptyCatch": true }], + "no-inner-declarations": "off", + "no-lonely-if": "error", + "no-template-curly-in-string": "error", + "no-var": "error", + "object-shorthand": ["error", "always", { "ignoreConstructors": true }], + "one-var": ["error", { "var": "never", "let": "never" }], + "prefer-const": ["error", { "destructuring": "all" }], + "prefer-destructuring": [ + "warn", + { "AssignmentExpression": { "array": false, "object": false } } + ], + "prefer-rest-params": "warn", + "prefer-spread": "warn", + "quote-props": ["error", "as-needed"], + "spaced-comment": ["error", "always", { "markers": ["/"] }], + "sort-imports": ["warn", { "ignoreDeclarationSort": true }], + "yoda": ["error", "never", { "exceptRange": true }] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dfc0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,139 @@ +eslint-plugin-import +eslint-plugin-jsx-a11y +eslint-plugin-react +jsx-ast-utils +react + +dist/**/*.js +dist/**/*.js.map + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +repl.ts diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..9d6d6f4 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +registry http://raspberrypi.local:4873 +always-auth=true \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ef5152b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "editor.formatOnSave": true, + "eslint.runtime": "node", + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.code-search": true, + "**/__mocks__": true, + "**/__tests__": true, + "**/tests": true + } +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..bd7e84b --- /dev/null +++ b/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash +rm dist/*.js +mkdir -p dist +./esbuild.ts + +# Test +DEST=$HOME/Git/archive/node_modules +rm -rf "$DEST/@proteria/eslint-rules" +cp -r dist "$DEST/@proteria/eslint-rules" diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..f3de629 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,9 @@ +# eslint-rules + +Custom build of various ESLint rule libraries with little dependency as possible. + +## Includes + +- eslint-plugin-import +- eslint-plugin-jsx-a11y +- eslint-plugin-react diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000..e6370bf --- /dev/null +++ b/dist/package.json @@ -0,0 +1,30 @@ +{ + "name": "@aet/eslint-rules", + "version": "0.0.1-beta.11", + "license": "UNLICENSED", + "publishConfig": { + "registry": "http://raspberrypi.local:4873" + }, + "peerDependencies": { + "typescript": "^5.1.6" + }, + "dependencies": { + "aria-query": "^5.3.0", + "axe-core": "4.7.2", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "1.0.8", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "estraverse": "^5.3.0", + "is-core-module": "^2.12.1", + "is-glob": "^4.0.3", + "language-tags": "^1.0.8", + "minimatch": "^9.0.3", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^7.5.4", + "tsconfig-paths": "^4.2.0" + } +} diff --git a/esbuild.ts b/esbuild.ts new file mode 100755 index 0000000..03242c5 --- /dev/null +++ b/esbuild.ts @@ -0,0 +1,52 @@ +#!/usr/bin/env -S node -r esbin +import esbuild from 'esbuild'; +import { resolve } from 'path'; +import { babelPlugin } from './src/babel'; + +const args = process.argv.slice(2); +const ENV = process.env.NODE_ENV || 'development'; +const PROD = ENV === 'production'; + +async function main(entry: string, outfile: string) { + const context = await esbuild.context({ + entryPoints: [entry], + outfile, + bundle: true, + minify: PROD, + platform: 'node', + packages: 'external', + sourcemap: 'linked', + plugins: [ + babelPlugin, + { + name: 'alias', + setup(build) { + build.onResolve({ filter: /^jsx-ast-utils$/ }, () => ({ + path: resolve('./jsx-ast-utils/src/index.js'), + })); + build.onResolve({ filter: /^jsx-ast-utils\/.+$/ }, ({ path }) => ({ + path: + resolve('./jsx-ast-utils/', path.slice('jsx-ast-utils/'.length)) + '.js', + })); + }, + }, + ], + define: {}, + banner: { + js: '/* eslint-disable */', + }, + }); + + await context.rebuild(); + + if (args.includes('-w') || args.includes('--watch')) { + await context.watch(); + } else { + await context.dispose(); + } +} + +main('./eslint-plugin-react/index.js', './dist/react/index.js'); +main('./eslint-plugin-import/src/index.js', './dist/import/index.js'); +main('./eslint-plugin-jsx-a11y/src/index.js', './dist/jsx-a11y/index.js'); +main('./src/ensureRedirect.ts', './dist/ensureRedirect.js'); diff --git a/eslint-plugin-react-hooks/ExhaustiveDeps.ts b/eslint-plugin-react-hooks/ExhaustiveDeps.ts new file mode 100644 index 0000000..e9c251b --- /dev/null +++ b/eslint-plugin-react-hooks/ExhaustiveDeps.ts @@ -0,0 +1,1800 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* eslint-disable no-for-of-loops/no-for-of-loops */ + +'use strict'; + +export default { + meta: { + type: 'suggestion', + docs: { + description: + 'verifies the list of dependencies for Hooks like useEffect and similar', + recommended: true, + url: 'https://github.com/facebook/react/issues/14920', + }, + fixable: 'code', + hasSuggestions: true, + schema: [ + { + type: 'object', + additionalProperties: false, + enableDangerousAutofixThisMayCauseInfiniteLoops: false, + properties: { + additionalHooks: { + type: 'string', + }, + enableDangerousAutofixThisMayCauseInfiniteLoops: { + type: 'boolean', + }, + }, + }, + ], + }, + create(context) { + // Parse the `additionalHooks` regex. + const additionalHooks = + context.options && context.options[0] && context.options[0].additionalHooks + ? new RegExp(context.options[0].additionalHooks) + : undefined; + + const enableDangerousAutofixThisMayCauseInfiniteLoops = + (context.options && + context.options[0] && + context.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops) || + false; + + const options = { + additionalHooks, + enableDangerousAutofixThisMayCauseInfiniteLoops, + }; + + function reportProblem(problem) { + if (enableDangerousAutofixThisMayCauseInfiniteLoops) { + // Used to enable legacy behavior. Dangerous. + // Keep this as an option until major IDEs upgrade (including VSCode FB ESLint extension). + if (Array.isArray(problem.suggest) && problem.suggest.length > 0) { + problem.fix = problem.suggest[0].fix; + } + } + context.report(problem); + } + + const scopeManager = context.getSourceCode().scopeManager; + + // Should be shared between visitors. + const setStateCallSites = new WeakMap(); + const stateVariables = new WeakSet(); + const stableKnownValueCache = new WeakMap(); + const functionWithoutCapturedValueCache = new WeakMap(); + const useEffectEventVariables = new WeakSet(); + function memoizeWithWeakMap(fn, map) { + return function (arg) { + if (map.has(arg)) { + // to verify cache hits: + // console.log(arg.name) + return map.get(arg); + } + const result = fn(arg); + map.set(arg, result); + return result; + }; + } + /** + * Visitor for both function expressions and arrow function expressions. + */ + function visitFunctionWithDependencies( + node, + declaredDependenciesNode, + reactiveHook, + reactiveHookName, + isEffect, + ) { + if (isEffect && node.async) { + reportProblem({ + node: node, + message: + `Effect callbacks are synchronous to prevent race conditions. ` + + `Put the async function inside:\n\n` + + 'useEffect(() => {\n' + + ' async function fetchData() {\n' + + ' // You can await here\n' + + ' const response = await MyAPI.getData(someId);\n' + + ' // ...\n' + + ' }\n' + + ' fetchData();\n' + + `}, [someId]); // Or [] if effect doesn't need props or state\n\n` + + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching', + }); + } + + // Get the current scope. + const scope = scopeManager.acquire(node); + + // Find all our "pure scopes". On every re-render of a component these + // pure scopes may have changes to the variables declared within. So all + // variables used in our reactive hook callback but declared in a pure + // scope need to be listed as dependencies of our reactive hook callback. + // + // According to the rules of React you can't read a mutable value in pure + // scope. We can't enforce this in a lint so we trust that all variables + // declared outside of pure scope are indeed frozen. + const pureScopes = new Set(); + let componentScope = null; + { + let currentScope = scope.upper; + while (currentScope) { + pureScopes.add(currentScope); + if (currentScope.type === 'function') { + break; + } + currentScope = currentScope.upper; + } + // If there is no parent function scope then there are no pure scopes. + // The ones we've collected so far are incorrect. So don't continue with + // the lint. + if (!currentScope) { + return; + } + componentScope = currentScope; + } + + const isArray = Array.isArray; + + // Next we'll define a few helpers that helps us + // tell if some values don't have to be declared as deps. + + // Some are known to be stable based on Hook calls. + // const [state, setState] = useState() / React.useState() + // ^^^ true for this reference + // const [state, dispatch] = useReducer() / React.useReducer() + // ^^^ true for this reference + // const ref = useRef() + // ^^^ true for this reference + // const onStuff = useEffectEvent(() => {}) + // ^^^ true for this reference + // False for everything else. + function isStableKnownHookValue(resolved) { + if (!isArray(resolved.defs)) { + return false; + } + const def = resolved.defs[0]; + if (def == null) { + return false; + } + // Look for `let stuff = ...` + if (def.node.type !== 'VariableDeclarator') { + return false; + } + let init = def.node.init; + if (init == null) { + return false; + } + while (init.type === 'TSAsExpression') { + init = init.expression; + } + // Detect primitive constants + // const foo = 42 + let declaration = def.node.parent; + if (declaration == null) { + // This might happen if variable is declared after the callback. + // In that case ESLint won't set up .parent refs. + // So we'll set them up manually. + fastFindReferenceWithParent(componentScope.block, def.node.id); + declaration = def.node.parent; + if (declaration == null) { + return false; + } + } + if ( + declaration.kind === 'const' && + init.type === 'Literal' && + (typeof init.value === 'string' || + typeof init.value === 'number' || + init.value === null) + ) { + // Definitely stable + return true; + } + // Detect known Hook calls + // const [_, setState] = useState() + if (init.type !== 'CallExpression') { + return false; + } + let callee = init.callee; + // Step into `= React.something` initializer. + if ( + callee.type === 'MemberExpression' && + callee.object.name === 'React' && + callee.property != null && + !callee.computed + ) { + callee = callee.property; + } + if (callee.type !== 'Identifier') { + return false; + } + const id = def.node.id; + const { name } = callee; + if (name === 'useRef' && id.type === 'Identifier') { + // useRef() return value is stable. + return true; + } else if (isUseEffectEventIdentifier(callee) && id.type === 'Identifier') { + for (const ref of resolved.references) { + if (ref !== id) { + useEffectEventVariables.add(ref.identifier); + } + } + // useEffectEvent() return value is always unstable. + return true; + } else if (name === 'useState' || name === 'useReducer') { + // Only consider second value in initializing tuple stable. + if ( + id.type === 'ArrayPattern' && + id.elements.length === 2 && + isArray(resolved.identifiers) + ) { + // Is second tuple value the same reference we're checking? + if (id.elements[1] === resolved.identifiers[0]) { + if (name === 'useState') { + const references = resolved.references; + let writeCount = 0; + for (let i = 0; i < references.length; i++) { + if (references[i].isWrite()) { + writeCount++; + } + if (writeCount > 1) { + return false; + } + setStateCallSites.set(references[i].identifier, id.elements[0]); + } + } + // Setter is stable. + return true; + } else if (id.elements[0] === resolved.identifiers[0]) { + if (name === 'useState') { + const references = resolved.references; + for (let i = 0; i < references.length; i++) { + stateVariables.add(references[i].identifier); + } + } + // State variable itself is dynamic. + return false; + } + } + } else if (name === 'useTransition') { + // Only consider second value in initializing tuple stable. + if ( + id.type === 'ArrayPattern' && + id.elements.length === 2 && + Array.isArray(resolved.identifiers) + ) { + // Is second tuple value the same reference we're checking? + if (id.elements[1] === resolved.identifiers[0]) { + // Setter is stable. + return true; + } + } + } + // By default assume it's dynamic. + return false; + } + + // Some are just functions that don't reference anything dynamic. + function isFunctionWithoutCapturedValues(resolved) { + if (!isArray(resolved.defs)) { + return false; + } + const def = resolved.defs[0]; + if (def == null) { + return false; + } + if (def.node == null || def.node.id == null) { + return false; + } + // Search the direct component subscopes for + // top-level function definitions matching this reference. + const fnNode = def.node; + const childScopes = componentScope.childScopes; + let fnScope = null; + let i; + for (i = 0; i < childScopes.length; i++) { + const childScope = childScopes[i]; + const childScopeBlock = childScope.block; + if ( + // function handleChange() {} + (fnNode.type === 'FunctionDeclaration' && childScopeBlock === fnNode) || + // const handleChange = () => {} + // const handleChange = function() {} + (fnNode.type === 'VariableDeclarator' && childScopeBlock.parent === fnNode) + ) { + // Found it! + fnScope = childScope; + break; + } + } + if (fnScope == null) { + return false; + } + // Does this function capture any values + // that are in pure scopes (aka render)? + for (i = 0; i < fnScope.through.length; i++) { + const ref = fnScope.through[i]; + if (ref.resolved == null) { + continue; + } + if ( + pureScopes.has(ref.resolved.scope) && + // Stable values are fine though, + // although we won't check functions deeper. + !memoizedIsStableKnownHookValue(ref.resolved) + ) { + return false; + } + } + // If we got here, this function doesn't capture anything + // from render--or everything it captures is known stable. + return true; + } + + // Remember such values. Avoid re-running extra checks on them. + const memoizedIsStableKnownHookValue = memoizeWithWeakMap( + isStableKnownHookValue, + stableKnownValueCache, + ); + const memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap( + isFunctionWithoutCapturedValues, + functionWithoutCapturedValueCache, + ); + + // These are usually mistaken. Collect them. + const currentRefsInEffectCleanup = new Map(); + + // Is this reference inside a cleanup function for this effect node? + // We can check by traversing scopes upwards from the reference, and checking + // if the last "return () => " we encounter is located directly inside the effect. + function isInsideEffectCleanup(reference) { + let curScope = reference.from; + let isInReturnedFunction = false; + while (curScope.block !== node) { + if (curScope.type === 'function') { + isInReturnedFunction = + curScope.block.parent != null && + curScope.block.parent.type === 'ReturnStatement'; + } + curScope = curScope.upper; + } + return isInReturnedFunction; + } + + // Get dependencies from all our resolved references in pure scopes. + // Key is dependency string, value is whether it's stable. + const dependencies = new Map(); + const optionalChains = new Map(); + gatherDependenciesRecursively(scope); + + function gatherDependenciesRecursively(currentScope) { + for (const reference of currentScope.references) { + // If this reference is not resolved or it is not declared in a pure + // scope then we don't care about this reference. + if (!reference.resolved) { + continue; + } + if (!pureScopes.has(reference.resolved.scope)) { + continue; + } + + // Narrow the scope of a dependency if it is, say, a member expression. + // Then normalize the narrowed dependency. + const referenceNode = fastFindReferenceWithParent(node, reference.identifier); + const dependencyNode = getDependency(referenceNode); + const dependency = analyzePropertyChain(dependencyNode, optionalChains); + + // Accessing ref.current inside effect cleanup is bad. + if ( + // We're in an effect... + isEffect && + // ... and this look like accessing .current... + dependencyNode.type === 'Identifier' && + (dependencyNode.parent.type === 'MemberExpression' || + dependencyNode.parent.type === 'OptionalMemberExpression') && + !dependencyNode.parent.computed && + dependencyNode.parent.property.type === 'Identifier' && + dependencyNode.parent.property.name === 'current' && + // ...in a cleanup function or below... + isInsideEffectCleanup(reference) + ) { + currentRefsInEffectCleanup.set(dependency, { + reference, + dependencyNode, + }); + } + + if ( + dependencyNode.parent.type === 'TSTypeQuery' || + dependencyNode.parent.type === 'TSTypeReference' + ) { + continue; + } + + const def = reference.resolved.defs[0]; + if (def == null) { + continue; + } + // Ignore references to the function itself as it's not defined yet. + if (def.node != null && def.node.init === node.parent) { + continue; + } + // Ignore Flow type parameters + if (def.type === 'TypeParameter') { + continue; + } + + // Add the dependency to a map so we can make sure it is referenced + // again in our dependencies array. Remember whether it's stable. + if (!dependencies.has(dependency)) { + const resolved = reference.resolved; + const isStable = + memoizedIsStableKnownHookValue(resolved) || + memoizedIsFunctionWithoutCapturedValues(resolved); + dependencies.set(dependency, { + isStable, + references: [reference], + }); + } else { + dependencies.get(dependency).references.push(reference); + } + } + + for (const childScope of currentScope.childScopes) { + gatherDependenciesRecursively(childScope); + } + } + + // Warn about accessing .current in cleanup effects. + currentRefsInEffectCleanup.forEach(({ reference, dependencyNode }, dependency) => { + const references = reference.resolved.references; + // Is React managing this ref or us? + // Let's see if we can find a .current assignment. + let foundCurrentAssignment = false; + for (let i = 0; i < references.length; i++) { + const { identifier } = references[i]; + const { parent } = identifier; + if ( + parent != null && + // ref.current + // Note: no need to handle OptionalMemberExpression because it can't be LHS. + parent.type === 'MemberExpression' && + !parent.computed && + parent.property.type === 'Identifier' && + parent.property.name === 'current' && + // ref.current = + parent.parent.type === 'AssignmentExpression' && + parent.parent.left === parent + ) { + foundCurrentAssignment = true; + break; + } + } + // We only want to warn about React-managed refs. + if (foundCurrentAssignment) { + return; + } + reportProblem({ + node: dependencyNode.parent.property, + message: + `The ref value '${dependency}.current' will likely have ` + + `changed by the time this effect cleanup function runs. If ` + + `this ref points to a node rendered by React, copy ` + + `'${dependency}.current' to a variable inside the effect, and ` + + `use that variable in the cleanup function.`, + }); + }); + + // Warn about assigning to variables in the outer scope. + // Those are usually bugs. + const staleAssignments = new Set(); + function reportStaleAssignment(writeExpr, key) { + if (staleAssignments.has(key)) { + return; + } + staleAssignments.add(key); + reportProblem({ + node: writeExpr, + message: + `Assignments to the '${key}' variable from inside React Hook ` + + `${context.getSource(reactiveHook)} will be lost after each ` + + `render. To preserve the value over time, store it in a useRef ` + + `Hook and keep the mutable value in the '.current' property. ` + + `Otherwise, you can move this variable directly inside ` + + `${context.getSource(reactiveHook)}.`, + }); + } + + // Remember which deps are stable and report bad usage first. + const stableDependencies = new Set(); + dependencies.forEach(({ isStable, references }, key) => { + if (isStable) { + stableDependencies.add(key); + } + references.forEach(reference => { + if (reference.writeExpr) { + reportStaleAssignment(reference.writeExpr, key); + } + }); + }); + + if (staleAssignments.size > 0) { + // The intent isn't clear so we'll wait until you fix those first. + return; + } + + if (!declaredDependenciesNode) { + // Check if there are any top-level setState() calls. + // Those tend to lead to infinite loops. + let setStateInsideEffectWithoutDeps = null; + dependencies.forEach(({ isStable, references }, key) => { + if (setStateInsideEffectWithoutDeps) { + return; + } + references.forEach(reference => { + if (setStateInsideEffectWithoutDeps) { + return; + } + + const id = reference.identifier; + const isSetState = setStateCallSites.has(id); + if (!isSetState) { + return; + } + + let fnScope = reference.from; + while (fnScope.type !== 'function') { + fnScope = fnScope.upper; + } + const isDirectlyInsideEffect = fnScope.block === node; + if (isDirectlyInsideEffect) { + // TODO: we could potentially ignore early returns. + setStateInsideEffectWithoutDeps = key; + } + }); + }); + if (setStateInsideEffectWithoutDeps) { + const { suggestedDependencies } = collectRecommendations({ + dependencies, + declaredDependencies: [], + stableDependencies, + externalDependencies: new Set(), + isEffect: true, + }); + reportProblem({ + node: reactiveHook, + message: + `React Hook ${reactiveHookName} contains a call to '${setStateInsideEffectWithoutDeps}'. ` + + `Without a list of dependencies, this can lead to an infinite chain of updates. ` + + `To fix this, pass [` + + suggestedDependencies.join(', ') + + `] as a second argument to the ${reactiveHookName} Hook.`, + suggest: [ + { + desc: `Add dependencies array: [${suggestedDependencies.join(', ')}]`, + fix(fixer) { + return fixer.insertTextAfter( + node, + `, [${suggestedDependencies.join(', ')}]`, + ); + }, + }, + ], + }); + } + return; + } + + const declaredDependencies = []; + const externalDependencies = new Set(); + if (declaredDependenciesNode.type !== 'ArrayExpression') { + // If the declared dependencies are not an array expression then we + // can't verify that the user provided the correct dependencies. Tell + // the user this in an error. + reportProblem({ + node: declaredDependenciesNode, + message: + `React Hook ${context.getSource(reactiveHook)} was passed a ` + + 'dependency list that is not an array literal. This means we ' + + "can't statically verify whether you've passed the correct " + + 'dependencies.', + }); + } else { + declaredDependenciesNode.elements.forEach(declaredDependencyNode => { + // Skip elided elements. + if (declaredDependencyNode === null) { + return; + } + // If we see a spread element then add a special warning. + if (declaredDependencyNode.type === 'SpreadElement') { + reportProblem({ + node: declaredDependencyNode, + message: + `React Hook ${context.getSource(reactiveHook)} has a spread ` + + "element in its dependency array. This means we can't " + + "statically verify whether you've passed the " + + 'correct dependencies.', + }); + return; + } + if (useEffectEventVariables.has(declaredDependencyNode)) { + reportProblem({ + node: declaredDependencyNode, + message: + 'Functions returned from `useEffectEvent` must not be included in the dependency array. ' + + `Remove \`${context.getSource(declaredDependencyNode)}\` from the list.`, + suggest: [ + { + desc: `Remove the dependency \`${context.getSource( + declaredDependencyNode, + )}\``, + fix(fixer) { + return fixer.removeRange(declaredDependencyNode.range); + }, + }, + ], + }); + } + // Try to normalize the declared dependency. If we can't then an error + // will be thrown. We will catch that error and report an error. + let declaredDependency; + try { + declaredDependency = analyzePropertyChain(declaredDependencyNode, null); + } catch (error) { + if (/Unsupported node type/.test(error.message)) { + if (declaredDependencyNode.type === 'Literal') { + if (dependencies.has(declaredDependencyNode.value)) { + reportProblem({ + node: declaredDependencyNode, + message: + `The ${declaredDependencyNode.raw} literal is not a valid dependency ` + + `because it never changes. ` + + `Did you mean to include ${declaredDependencyNode.value} in the array instead?`, + }); + } else { + reportProblem({ + node: declaredDependencyNode, + message: + `The ${declaredDependencyNode.raw} literal is not a valid dependency ` + + 'because it never changes. You can safely remove it.', + }); + } + } else { + reportProblem({ + node: declaredDependencyNode, + message: + `React Hook ${context.getSource(reactiveHook)} has a ` + + `complex expression in the dependency array. ` + + 'Extract it to a separate variable so it can be statically checked.', + }); + } + + return; + } else { + throw error; + } + } + + let maybeID = declaredDependencyNode; + while ( + maybeID.type === 'MemberExpression' || + maybeID.type === 'OptionalMemberExpression' || + maybeID.type === 'ChainExpression' + ) { + maybeID = maybeID.object || maybeID.expression.object; + } + const isDeclaredInComponent = !componentScope.through.some( + ref => ref.identifier === maybeID, + ); + + // Add the dependency to our declared dependency map. + declaredDependencies.push({ + key: declaredDependency, + node: declaredDependencyNode, + }); + + if (!isDeclaredInComponent) { + externalDependencies.add(declaredDependency); + } + }); + } + + const { + suggestedDependencies, + unnecessaryDependencies, + missingDependencies, + duplicateDependencies, + } = collectRecommendations({ + dependencies, + declaredDependencies, + stableDependencies, + externalDependencies, + isEffect, + }); + + let suggestedDeps = suggestedDependencies; + + const problemCount = + duplicateDependencies.size + + missingDependencies.size + + unnecessaryDependencies.size; + + if (problemCount === 0) { + // If nothing else to report, check if some dependencies would + // invalidate on every render. + const constructions = scanForConstructions({ + declaredDependencies, + declaredDependenciesNode, + componentScope, + scope, + }); + constructions.forEach(({ construction, isUsedOutsideOfHook, depType }) => { + const wrapperHook = depType === 'function' ? 'useCallback' : 'useMemo'; + + const constructionType = + depType === 'function' ? 'definition' : 'initialization'; + + const defaultAdvice = `wrap the ${constructionType} of '${construction.name.name}' in its own ${wrapperHook}() Hook.`; + + const advice = isUsedOutsideOfHook + ? `To fix this, ${defaultAdvice}` + : `Move it inside the ${reactiveHookName} callback. Alternatively, ${defaultAdvice}`; + + const causation = + depType === 'conditional' || depType === 'logical expression' + ? 'could make' + : 'makes'; + + const message = + `The '${construction.name.name}' ${depType} ${causation} the dependencies of ` + + `${reactiveHookName} Hook (at line ${declaredDependenciesNode.loc.start.line}) ` + + `change on every render. ${advice}`; + + let suggest; + // Only handle the simple case of variable assignments. + // Wrapping function declarations can mess up hoisting. + if ( + isUsedOutsideOfHook && + construction.type === 'Variable' && + // Objects may be mutated after construction, which would make this + // fix unsafe. Functions _probably_ won't be mutated, so we'll + // allow this fix for them. + depType === 'function' + ) { + suggest = [ + { + desc: `Wrap the ${constructionType} of '${construction.name.name}' in its own ${wrapperHook}() Hook.`, + fix(fixer) { + const [before, after] = + wrapperHook === 'useMemo' + ? [`useMemo(() => { return `, '; })'] + : ['useCallback(', ')']; + return [ + // TODO: also add an import? + fixer.insertTextBefore(construction.node.init, before), + // TODO: ideally we'd gather deps here but it would require + // restructuring the rule code. This will cause a new lint + // error to appear immediately for useCallback. Note we're + // not adding [] because would that changes semantics. + fixer.insertTextAfter(construction.node.init, after), + ]; + }, + }, + ]; + } + // TODO: What if the function needs to change on every render anyway? + // Should we suggest removing effect deps as an appropriate fix too? + reportProblem({ + // TODO: Why not report this at the dependency site? + node: construction.node, + message, + suggest, + }); + }); + return; + } + + // If we're going to report a missing dependency, + // we might as well recalculate the list ignoring + // the currently specified deps. This can result + // in some extra deduplication. We can't do this + // for effects though because those have legit + // use cases for over-specifying deps. + if (!isEffect && missingDependencies.size > 0) { + suggestedDeps = collectRecommendations({ + dependencies, + declaredDependencies: [], // Pretend we don't know + stableDependencies, + externalDependencies, + isEffect, + }).suggestedDependencies; + } + + // Alphabetize the suggestions, but only if deps were already alphabetized. + function areDeclaredDepsAlphabetized() { + if (declaredDependencies.length === 0) { + return true; + } + const declaredDepKeys = declaredDependencies.map(dep => dep.key); + const sortedDeclaredDepKeys = declaredDepKeys.slice().sort(); + return declaredDepKeys.join(',') === sortedDeclaredDepKeys.join(','); + } + if (areDeclaredDepsAlphabetized()) { + suggestedDeps.sort(); + } + + // Most of our algorithm deals with dependency paths with optional chaining stripped. + // This function is the last step before printing a dependency, so now is a good time to + // check whether any members in our path are always used as optional-only. In that case, + // we will use ?. instead of . to concatenate those parts of the path. + function formatDependency(path) { + const members = path.split('.'); + let finalPath = ''; + for (let i = 0; i < members.length; i++) { + if (i !== 0) { + const pathSoFar = members.slice(0, i + 1).join('.'); + const isOptional = optionalChains.get(pathSoFar) === true; + finalPath += isOptional ? '?.' : '.'; + } + finalPath += members[i]; + } + return finalPath; + } + + function getWarningMessage(deps, singlePrefix, label, fixVerb) { + if (deps.size === 0) { + return null; + } + return ( + (deps.size > 1 ? '' : singlePrefix + ' ') + + label + + ' ' + + (deps.size > 1 ? 'dependencies' : 'dependency') + + ': ' + + joinEnglish( + Array.from(deps) + .sort() + .map(name => "'" + formatDependency(name) + "'"), + ) + + `. Either ${fixVerb} ${ + deps.size > 1 ? 'them' : 'it' + } or remove the dependency array.` + ); + } + + let extraWarning = ''; + if (unnecessaryDependencies.size > 0) { + let badRef = null; + Array.from(unnecessaryDependencies.keys()).forEach(key => { + if (badRef !== null) { + return; + } + if (key.endsWith('.current')) { + badRef = key; + } + }); + if (badRef !== null) { + extraWarning = + ` Mutable values like '${badRef}' aren't valid dependencies ` + + "because mutating them doesn't re-render the component."; + } else if (externalDependencies.size > 0) { + const dep = Array.from(externalDependencies)[0]; + // Don't show this warning for things that likely just got moved *inside* the callback + // because in that case they're clearly not referring to globals. + if (!scope.set.has(dep)) { + extraWarning = + ` Outer scope values like '${dep}' aren't valid dependencies ` + + `because mutating them doesn't re-render the component.`; + } + } + } + + // `props.foo()` marks `props` as a dependency because it has + // a `this` value. This warning can be confusing. + // So if we're going to show it, append a clarification. + if (!extraWarning && missingDependencies.has('props')) { + const propDep = dependencies.get('props'); + if (propDep == null) { + return; + } + const refs = propDep.references; + if (!Array.isArray(refs)) { + return; + } + let isPropsOnlyUsedInMembers = true; + for (let i = 0; i < refs.length; i++) { + const ref = refs[i]; + const id = fastFindReferenceWithParent(componentScope.block, ref.identifier); + if (!id) { + isPropsOnlyUsedInMembers = false; + break; + } + const parent = id.parent; + if (parent == null) { + isPropsOnlyUsedInMembers = false; + break; + } + if ( + parent.type !== 'MemberExpression' && + parent.type !== 'OptionalMemberExpression' + ) { + isPropsOnlyUsedInMembers = false; + break; + } + } + if (isPropsOnlyUsedInMembers) { + extraWarning = + ` However, 'props' will change when *any* prop changes, so the ` + + `preferred fix is to destructure the 'props' object outside of ` + + `the ${reactiveHookName} call and refer to those specific props ` + + `inside ${context.getSource(reactiveHook)}.`; + } + } + + if (!extraWarning && missingDependencies.size > 0) { + // See if the user is trying to avoid specifying a callable prop. + // This usually means they're unaware of useCallback. + let missingCallbackDep = null; + missingDependencies.forEach(missingDep => { + if (missingCallbackDep) { + return; + } + // Is this a variable from top scope? + const topScopeRef = componentScope.set.get(missingDep); + const usedDep = dependencies.get(missingDep); + if (usedDep.references[0].resolved !== topScopeRef) { + return; + } + // Is this a destructured prop? + const def = topScopeRef.defs[0]; + if (def == null || def.name == null || def.type !== 'Parameter') { + return; + } + // Was it called in at least one case? Then it's a function. + let isFunctionCall = false; + let id; + for (let i = 0; i < usedDep.references.length; i++) { + id = usedDep.references[i].identifier; + if ( + id != null && + id.parent != null && + (id.parent.type === 'CallExpression' || + id.parent.type === 'OptionalCallExpression') && + id.parent.callee === id + ) { + isFunctionCall = true; + break; + } + } + if (!isFunctionCall) { + return; + } + // If it's missing (i.e. in component scope) *and* it's a parameter + // then it is definitely coming from props destructuring. + // (It could also be props itself but we wouldn't be calling it then.) + missingCallbackDep = missingDep; + }); + if (missingCallbackDep !== null) { + extraWarning = + ` If '${missingCallbackDep}' changes too often, ` + + `find the parent component that defines it ` + + `and wrap that definition in useCallback.`; + } + } + + if (!extraWarning && missingDependencies.size > 0) { + let setStateRecommendation = null; + missingDependencies.forEach(missingDep => { + if (setStateRecommendation !== null) { + return; + } + const usedDep = dependencies.get(missingDep); + const references = usedDep.references; + let id; + let maybeCall; + for (let i = 0; i < references.length; i++) { + id = references[i].identifier; + maybeCall = id.parent; + // Try to see if we have setState(someExpr(missingDep)). + while (maybeCall != null && maybeCall !== componentScope.block) { + if (maybeCall.type === 'CallExpression') { + const correspondingStateVariable = setStateCallSites.get( + maybeCall.callee, + ); + if (correspondingStateVariable != null) { + if (correspondingStateVariable.name === missingDep) { + // setCount(count + 1) + setStateRecommendation = { + missingDep, + setter: maybeCall.callee.name, + form: 'updater', + }; + } else if (stateVariables.has(id)) { + // setCount(count + increment) + setStateRecommendation = { + missingDep, + setter: maybeCall.callee.name, + form: 'reducer', + }; + } else { + const resolved = references[i].resolved; + if (resolved != null) { + // If it's a parameter *and* a missing dep, + // it must be a prop or something inside a prop. + // Therefore, recommend an inline reducer. + const def = resolved.defs[0]; + if (def != null && def.type === 'Parameter') { + setStateRecommendation = { + missingDep, + setter: maybeCall.callee.name, + form: 'inlineReducer', + }; + } + } + } + break; + } + } + maybeCall = maybeCall.parent; + } + if (setStateRecommendation !== null) { + break; + } + } + }); + if (setStateRecommendation !== null) { + switch (setStateRecommendation.form) { + case 'reducer': + extraWarning = + ` You can also replace multiple useState variables with useReducer ` + + `if '${setStateRecommendation.setter}' needs the ` + + `current value of '${setStateRecommendation.missingDep}'.`; + break; + case 'inlineReducer': + extraWarning = + ` If '${setStateRecommendation.setter}' needs the ` + + `current value of '${setStateRecommendation.missingDep}', ` + + `you can also switch to useReducer instead of useState and ` + + `read '${setStateRecommendation.missingDep}' in the reducer.`; + break; + case 'updater': + extraWarning = + ` You can also do a functional update '${ + setStateRecommendation.setter + }(${setStateRecommendation.missingDep.slice( + 0, + 1, + )} => ...)' if you only need '${setStateRecommendation.missingDep}'` + + ` in the '${setStateRecommendation.setter}' call.`; + break; + default: + throw new Error('Unknown case.'); + } + } + } + + reportProblem({ + node: declaredDependenciesNode, + message: + `React Hook ${context.getSource(reactiveHook)} has ` + + // To avoid a long message, show the next actionable item. + (getWarningMessage(missingDependencies, 'a', 'missing', 'include') || + getWarningMessage(unnecessaryDependencies, 'an', 'unnecessary', 'exclude') || + getWarningMessage(duplicateDependencies, 'a', 'duplicate', 'omit')) + + extraWarning, + suggest: [ + { + desc: `Update the dependencies array to be: [${suggestedDeps + .map(formatDependency) + .join(', ')}]`, + fix(fixer) { + // TODO: consider preserving the comments or formatting? + return fixer.replaceText( + declaredDependenciesNode, + `[${suggestedDeps.map(formatDependency).join(', ')}]`, + ); + }, + }, + ], + }); + } + + function visitCallExpression(node) { + const callbackIndex = getReactiveHookCallbackIndex(node.callee, options); + if (callbackIndex === -1) { + // Not a React Hook call that needs deps. + return; + } + const callback = node.arguments[callbackIndex]; + const reactiveHook = node.callee; + const reactiveHookName = getNodeWithoutReactNamespace(reactiveHook).name; + const declaredDependenciesNode = node.arguments[callbackIndex + 1]; + const isEffect = /Effect($|[^a-z])/g.test(reactiveHookName); + + // Check whether a callback is supplied. If there is no callback supplied + // then the hook will not work and React will throw a TypeError. + // So no need to check for dependency inclusion. + if (!callback) { + reportProblem({ + node: reactiveHook, + message: + `React Hook ${reactiveHookName} requires an effect callback. ` + + `Did you forget to pass a callback to the hook?`, + }); + return; + } + + // Check the declared dependencies for this reactive hook. If there is no + // second argument then the reactive callback will re-run on every render. + // So no need to check for dependency inclusion. + if (!declaredDependenciesNode && !isEffect) { + // These are only used for optimization. + if (reactiveHookName === 'useMemo' || reactiveHookName === 'useCallback') { + // TODO: Can this have a suggestion? + reportProblem({ + node: reactiveHook, + message: + `React Hook ${reactiveHookName} does nothing when called with ` + + `only one argument. Did you forget to pass an array of ` + + `dependencies?`, + }); + } + return; + } + + switch (callback.type) { + case 'FunctionExpression': + case 'ArrowFunctionExpression': + visitFunctionWithDependencies( + callback, + declaredDependenciesNode, + reactiveHook, + reactiveHookName, + isEffect, + ); + return; // Handled + case 'Identifier': + if (!declaredDependenciesNode) { + // No deps, no problems. + return; // Handled + } + // The function passed as a callback is not written inline. + // But perhaps it's in the dependencies array? + if ( + declaredDependenciesNode.elements && + declaredDependenciesNode.elements.some( + el => el && el.type === 'Identifier' && el.name === callback.name, + ) + ) { + // If it's already in the list of deps, we don't care because + // this is valid regardless. + return; // Handled + } + // We'll do our best effort to find it, complain otherwise. + const variable = context.getScope().set.get(callback.name); + if (variable == null || variable.defs == null) { + // If it's not in scope, we don't care. + return; // Handled + } + // The function passed as a callback is not written inline. + // But it's defined somewhere in the render scope. + // We'll do our best effort to find and check it, complain otherwise. + const def = variable.defs[0]; + if (!def || !def.node) { + break; // Unhandled + } + if (def.type !== 'Variable' && def.type !== 'FunctionName') { + // Parameter or an unusual pattern. Bail out. + break; // Unhandled + } + switch (def.node.type) { + case 'FunctionDeclaration': + // useEffect(() => { ... }, []); + visitFunctionWithDependencies( + def.node, + declaredDependenciesNode, + reactiveHook, + reactiveHookName, + isEffect, + ); + return; // Handled + case 'VariableDeclarator': + const init = def.node.init; + if (!init) { + break; // Unhandled + } + switch (init.type) { + // const effectBody = () => {...}; + // useEffect(effectBody, []); + case 'ArrowFunctionExpression': + case 'FunctionExpression': + // We can inspect this function as if it were inline. + visitFunctionWithDependencies( + init, + declaredDependenciesNode, + reactiveHook, + reactiveHookName, + isEffect, + ); + return; // Handled + } + break; // Unhandled + } + break; // Unhandled + default: + // useEffect(generateEffectBody(), []); + reportProblem({ + node: reactiveHook, + message: + `React Hook ${reactiveHookName} received a function whose dependencies ` + + `are unknown. Pass an inline function instead.`, + }); + return; // Handled + } + + // Something unusual. Fall back to suggesting to add the body itself as a dep. + reportProblem({ + node: reactiveHook, + message: + `React Hook ${reactiveHookName} has a missing dependency: '${callback.name}'. ` + + `Either include it or remove the dependency array.`, + suggest: [ + { + desc: `Update the dependencies array to be: [${callback.name}]`, + fix(fixer) { + return fixer.replaceText(declaredDependenciesNode, `[${callback.name}]`); + }, + }, + ], + }); + } + + return { + CallExpression: visitCallExpression, + }; + }, +}; + +// The meat of the logic. +function collectRecommendations({ + dependencies, + declaredDependencies, + stableDependencies, + externalDependencies, + isEffect, +}) { + // Our primary data structure. + // It is a logical representation of property chains: + // `props` -> `props.foo` -> `props.foo.bar` -> `props.foo.bar.baz` + // -> `props.lol` + // -> `props.huh` -> `props.huh.okay` + // -> `props.wow` + // We'll use it to mark nodes that are *used* by the programmer, + // and the nodes that were *declared* as deps. Then we will + // traverse it to learn which deps are missing or unnecessary. + const depTree = createDepTree(); + function createDepTree() { + return { + isUsed: false, // True if used in code + isSatisfiedRecursively: false, // True if specified in deps + isSubtreeUsed: false, // True if something deeper is used by code + children: new Map(), // Nodes for properties + }; + } + + // Mark all required nodes first. + // Imagine exclamation marks next to each used deep property. + dependencies.forEach((_, key) => { + const node = getOrCreateNodeByPath(depTree, key); + node.isUsed = true; + markAllParentsByPath(depTree, key, parent => { + parent.isSubtreeUsed = true; + }); + }); + + // Mark all satisfied nodes. + // Imagine checkmarks next to each declared dependency. + declaredDependencies.forEach(({ key }) => { + const node = getOrCreateNodeByPath(depTree, key); + node.isSatisfiedRecursively = true; + }); + stableDependencies.forEach(key => { + const node = getOrCreateNodeByPath(depTree, key); + node.isSatisfiedRecursively = true; + }); + + // Tree manipulation helpers. + function getOrCreateNodeByPath(rootNode, path) { + const keys = path.split('.'); + let node = rootNode; + for (const key of keys) { + let child = node.children.get(key); + if (!child) { + child = createDepTree(); + node.children.set(key, child); + } + node = child; + } + return node; + } + function markAllParentsByPath(rootNode, path, fn) { + const keys = path.split('.'); + let node = rootNode; + for (const key of keys) { + const child = node.children.get(key); + if (!child) { + return; + } + fn(child); + node = child; + } + } + + // Now we can learn which dependencies are missing or necessary. + const missingDependencies = new Set(); + const satisfyingDependencies = new Set(); + scanTreeRecursively(depTree, missingDependencies, satisfyingDependencies, key => key); + function scanTreeRecursively(node, missingPaths, satisfyingPaths, keyToPath) { + node.children.forEach((child, key) => { + const path = keyToPath(key); + if (child.isSatisfiedRecursively) { + if (child.isSubtreeUsed) { + // Remember this dep actually satisfied something. + satisfyingPaths.add(path); + } + // It doesn't matter if there's something deeper. + // It would be transitively satisfied since we assume immutability. + // `props.foo` is enough if you read `props.foo.id`. + return; + } + if (child.isUsed) { + // Remember that no declared deps satisfied this node. + missingPaths.add(path); + // If we got here, nothing in its subtree was satisfied. + // No need to search further. + return; + } + scanTreeRecursively( + child, + missingPaths, + satisfyingPaths, + childKey => path + '.' + childKey, + ); + }); + } + + // Collect suggestions in the order they were originally specified. + const suggestedDependencies = []; + const unnecessaryDependencies = new Set(); + const duplicateDependencies = new Set(); + declaredDependencies.forEach(({ key }) => { + // Does this declared dep satisfy a real need? + if (satisfyingDependencies.has(key)) { + if (suggestedDependencies.indexOf(key) === -1) { + // Good one. + suggestedDependencies.push(key); + } else { + // Duplicate. + duplicateDependencies.add(key); + } + } else { + if (isEffect && !key.endsWith('.current') && !externalDependencies.has(key)) { + // Effects are allowed extra "unnecessary" deps. + // Such as resetting scroll when ID changes. + // Consider them legit. + // The exception is ref.current which is always wrong. + if (suggestedDependencies.indexOf(key) === -1) { + suggestedDependencies.push(key); + } + } else { + // It's definitely not needed. + unnecessaryDependencies.add(key); + } + } + }); + + // Then add the missing ones at the end. + missingDependencies.forEach(key => { + suggestedDependencies.push(key); + }); + + return { + suggestedDependencies, + unnecessaryDependencies, + duplicateDependencies, + missingDependencies, + }; +} + +// If the node will result in constructing a referentially unique value, return +// its human readable type name, else return null. +function getConstructionExpressionType(node) { + switch (node.type) { + case 'ObjectExpression': + return 'object'; + case 'ArrayExpression': + return 'array'; + case 'ArrowFunctionExpression': + case 'FunctionExpression': + return 'function'; + case 'ClassExpression': + return 'class'; + case 'ConditionalExpression': + if ( + getConstructionExpressionType(node.consequent) != null || + getConstructionExpressionType(node.alternate) != null + ) { + return 'conditional'; + } + return null; + case 'LogicalExpression': + if ( + getConstructionExpressionType(node.left) != null || + getConstructionExpressionType(node.right) != null + ) { + return 'logical expression'; + } + return null; + case 'JSXFragment': + return 'JSX fragment'; + case 'JSXElement': + return 'JSX element'; + case 'AssignmentExpression': + if (getConstructionExpressionType(node.right) != null) { + return 'assignment expression'; + } + return null; + case 'NewExpression': + return 'object construction'; + case 'Literal': + if (node.value instanceof RegExp) { + return 'regular expression'; + } + return null; + case 'TypeCastExpression': + return getConstructionExpressionType(node.expression); + case 'TSAsExpression': + return getConstructionExpressionType(node.expression); + } + return null; +} + +// Finds variables declared as dependencies +// that would invalidate on every render. +function scanForConstructions({ + declaredDependencies, + declaredDependenciesNode, + componentScope, + scope, +}) { + const constructions = declaredDependencies + .map(({ key }) => { + const ref = componentScope.variables.find(v => v.name === key); + if (ref == null) { + return null; + } + + const node = ref.defs[0]; + if (node == null) { + return null; + } + // const handleChange = function () {} + // const handleChange = () => {} + // const foo = {} + // const foo = [] + // etc. + if ( + node.type === 'Variable' && + node.node.type === 'VariableDeclarator' && + node.node.id.type === 'Identifier' && // Ensure this is not destructed assignment + node.node.init != null + ) { + const constantExpressionType = getConstructionExpressionType(node.node.init); + if (constantExpressionType != null) { + return [ref, constantExpressionType]; + } + } + // function handleChange() {} + if (node.type === 'FunctionName' && node.node.type === 'FunctionDeclaration') { + return [ref, 'function']; + } + + // class Foo {} + if (node.type === 'ClassName' && node.node.type === 'ClassDeclaration') { + return [ref, 'class']; + } + return null; + }) + .filter(Boolean); + + function isUsedOutsideOfHook(ref) { + let foundWriteExpr = false; + for (let i = 0; i < ref.references.length; i++) { + const reference = ref.references[i]; + if (reference.writeExpr) { + if (foundWriteExpr) { + // Two writes to the same function. + return true; + } else { + // Ignore first write as it's not usage. + foundWriteExpr = true; + continue; + } + } + let currentScope = reference.from; + while (currentScope !== scope && currentScope != null) { + currentScope = currentScope.upper; + } + if (currentScope !== scope) { + // This reference is outside the Hook callback. + // It can only be legit if it's the deps array. + if (!isAncestorNodeOf(declaredDependenciesNode, reference.identifier)) { + return true; + } + } + } + return false; + } + + return constructions.map(([ref, depType]) => ({ + construction: ref.defs[0], + depType, + isUsedOutsideOfHook: isUsedOutsideOfHook(ref), + })); +} + +/** + * Assuming () means the passed/returned node: + * (props) => (props) + * props.(foo) => (props.foo) + * props.foo.(bar) => (props).foo.bar + * props.foo.bar.(baz) => (props).foo.bar.baz + */ +function getDependency(node) { + if ( + (node.parent.type === 'MemberExpression' || + node.parent.type === 'OptionalMemberExpression') && + node.parent.object === node && + node.parent.property.name !== 'current' && + !node.parent.computed && + !( + node.parent.parent != null && + (node.parent.parent.type === 'CallExpression' || + node.parent.parent.type === 'OptionalCallExpression') && + node.parent.parent.callee === node.parent + ) + ) { + return getDependency(node.parent); + } else if ( + // Note: we don't check OptionalMemberExpression because it can't be LHS. + node.type === 'MemberExpression' && + node.parent && + node.parent.type === 'AssignmentExpression' && + node.parent.left === node + ) { + return node.object; + } else { + return node; + } +} + +/** + * Mark a node as either optional or required. + * Note: If the node argument is an OptionalMemberExpression, it doesn't necessarily mean it is optional. + * It just means there is an optional member somewhere inside. + * This particular node might still represent a required member, so check .optional field. + */ +function markNode(node, optionalChains, result) { + if (optionalChains) { + if (node.optional) { + // We only want to consider it optional if *all* usages were optional. + if (!optionalChains.has(result)) { + // Mark as (maybe) optional. If there's a required usage, this will be overridden. + optionalChains.set(result, true); + } + } else { + // Mark as required. + optionalChains.set(result, false); + } + } +} + +/** + * Assuming () means the passed node. + * (foo) -> 'foo' + * foo(.)bar -> 'foo.bar' + * foo.bar(.)baz -> 'foo.bar.baz' + * Otherwise throw. + */ +function analyzePropertyChain(node, optionalChains) { + if (node.type === 'Identifier' || node.type === 'JSXIdentifier') { + const result = node.name; + if (optionalChains) { + // Mark as required. + optionalChains.set(result, false); + } + return result; + } else if (node.type === 'MemberExpression' && !node.computed) { + const object = analyzePropertyChain(node.object, optionalChains); + const property = analyzePropertyChain(node.property, null); + const result = `${object}.${property}`; + markNode(node, optionalChains, result); + return result; + } else if (node.type === 'OptionalMemberExpression' && !node.computed) { + const object = analyzePropertyChain(node.object, optionalChains); + const property = analyzePropertyChain(node.property, null); + const result = `${object}.${property}`; + markNode(node, optionalChains, result); + return result; + } else if (node.type === 'ChainExpression' && !node.computed) { + const expression = node.expression; + + if (expression.type === 'CallExpression') { + throw new Error(`Unsupported node type: ${expression.type}`); + } + + const object = analyzePropertyChain(expression.object, optionalChains); + const property = analyzePropertyChain(expression.property, null); + const result = `${object}.${property}`; + markNode(expression, optionalChains, result); + return result; + } else { + throw new Error(`Unsupported node type: ${node.type}`); + } +} + +function getNodeWithoutReactNamespace(node, options) { + if ( + node.type === 'MemberExpression' && + node.object.type === 'Identifier' && + node.object.name === 'React' && + node.property.type === 'Identifier' && + !node.computed + ) { + return node.property; + } + return node; +} + +// What's the index of callback that needs to be analyzed for a given Hook? +// -1 if it's not a Hook we care about (e.g. useState). +// 0 for useEffect/useMemo/useCallback(fn). +// 1 for useImperativeHandle(ref, fn). +// For additionally configured Hooks, assume that they're like useEffect (0). +function getReactiveHookCallbackIndex(calleeNode, options) { + const node = getNodeWithoutReactNamespace(calleeNode); + if (node.type !== 'Identifier') { + return -1; + } + switch (node.name) { + case 'useEffect': + case 'useLayoutEffect': + case 'useCallback': + case 'useMemo': + // useEffect(fn) + return 0; + case 'useImperativeHandle': + // useImperativeHandle(ref, fn) + return 1; + default: + if (node === calleeNode && options && options.additionalHooks) { + // Allow the user to provide a regular expression which enables the lint to + // target custom reactive hooks. + let name; + try { + name = analyzePropertyChain(node, null); + } catch (error) { + if (/Unsupported node type/.test(error.message)) { + return 0; + } else { + throw error; + } + } + return options.additionalHooks.test(name) ? 0 : -1; + } else { + return -1; + } + } +} + +/** + * ESLint won't assign node.parent to references from context.getScope() + * + * So instead we search for the node from an ancestor assigning node.parent + * as we go. This mutates the AST. + * + * This traversal is: + * - optimized by only searching nodes with a range surrounding our target node + * - agnostic to AST node types, it looks for `{ type: string, ... }` + */ +function fastFindReferenceWithParent(start, target) { + const queue = [start]; + let item = null; + + while (queue.length) { + item = queue.shift(); + + if (isSameIdentifier(item, target)) { + return item; + } + + if (!isAncestorNodeOf(item, target)) { + continue; + } + + for (const [key, value] of Object.entries(item)) { + if (key === 'parent') { + continue; + } + if (isNodeLike(value)) { + value.parent = item; + queue.push(value); + } else if (Array.isArray(value)) { + value.forEach(val => { + if (isNodeLike(val)) { + val.parent = item; + queue.push(val); + } + }); + } + } + } + + return null; +} + +function joinEnglish(arr) { + let s = ''; + for (let i = 0; i < arr.length; i++) { + s += arr[i]; + if (i === 0 && arr.length === 2) { + s += ' and '; + } else if (i === arr.length - 2 && arr.length > 2) { + s += ', and '; + } else if (i < arr.length - 1) { + s += ', '; + } + } + return s; +} + +function isNodeLike(val) { + return ( + typeof val === 'object' && + val !== null && + !Array.isArray(val) && + typeof val.type === 'string' + ); +} + +function isSameIdentifier(a, b) { + return ( + (a.type === 'Identifier' || a.type === 'JSXIdentifier') && + a.type === b.type && + a.name === b.name && + a.range[0] === b.range[0] && + a.range[1] === b.range[1] + ); +} + +function isAncestorNodeOf(a, b) { + return a.range[0] <= b.range[0] && a.range[1] >= b.range[1]; +} + +function isUseEffectEventIdentifier(node) { + if (__EXPERIMENTAL__) { + return node.type === 'Identifier' && node.name === 'useEffectEvent'; + } + return false; +} diff --git a/eslint-plugin-react-hooks/RulesOfHooks.ts b/eslint-plugin-react-hooks/RulesOfHooks.ts new file mode 100644 index 0000000..03b88b6 --- /dev/null +++ b/eslint-plugin-react-hooks/RulesOfHooks.ts @@ -0,0 +1,706 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* global BigInt */ +/* eslint-disable no-for-of-loops/no-for-of-loops */ + +'use strict'; + +/** + * Catch all identifiers that begin with "use" followed by an uppercase Latin + * character to exclude identifiers like "user". + */ + +function isHookName(s) { + if (__EXPERIMENTAL__) { + return s === 'use' || /^use[A-Z0-9]/.test(s); + } + return /^use[A-Z0-9]/.test(s); +} + +/** + * We consider hooks to be a hook name identifier or a member expression + * containing a hook name. + */ + +function isHook(node) { + if (node.type === 'Identifier') { + return isHookName(node.name); + } else if ( + node.type === 'MemberExpression' && + !node.computed && + isHook(node.property) + ) { + const obj = node.object; + const isPascalCaseNameSpace = /^[A-Z].*/; + return obj.type === 'Identifier' && isPascalCaseNameSpace.test(obj.name); + } else { + return false; + } +} + +/** + * Checks if the node is a React component name. React component names must + * always start with an uppercase letter. + */ + +function isComponentName(node) { + return node.type === 'Identifier' && /^[A-Z]/.test(node.name); +} + +function isReactFunction(node, functionName) { + return ( + node.name === functionName || + (node.type === 'MemberExpression' && + node.object.name === 'React' && + node.property.name === functionName) + ); +} + +/** + * Checks if the node is a callback argument of forwardRef. This render function + * should follow the rules of hooks. + */ + +function isForwardRefCallback(node) { + return !!( + node.parent && + node.parent.callee && + isReactFunction(node.parent.callee, 'forwardRef') + ); +} + +/** + * Checks if the node is a callback argument of React.memo. This anonymous + * functional component should follow the rules of hooks. + */ + +function isMemoCallback(node) { + return !!( + node.parent && + node.parent.callee && + isReactFunction(node.parent.callee, 'memo') + ); +} + +function isInsideComponentOrHook(node) { + while (node) { + const functionName = getFunctionName(node); + if (functionName) { + if (isComponentName(functionName) || isHook(functionName)) { + return true; + } + } + if (isForwardRefCallback(node) || isMemoCallback(node)) { + return true; + } + node = node.parent; + } + return false; +} + +function isUseEffectEventIdentifier(node) { + if (__EXPERIMENTAL__) { + return node.type === 'Identifier' && node.name === 'useEffectEvent'; + } + return false; +} + +function isUseIdentifier(node) { + if (__EXPERIMENTAL__) { + return node.type === 'Identifier' && node.name === 'use'; + } + return false; +} + +export default { + meta: { + type: 'problem', + docs: { + description: 'enforces the Rules of Hooks', + recommended: true, + url: 'https://reactjs.org/docs/hooks-rules.html', + }, + }, + create(context) { + let lastEffect = null; + const codePathReactHooksMapStack = []; + const codePathSegmentStack = []; + const useEffectEventFunctions = new WeakSet(); + + // For a given scope, iterate through the references and add all useEffectEvent definitions. We can + // do this in non-Program nodes because we can rely on the assumption that useEffectEvent functions + // can only be declared within a component or hook at its top level. + function recordAllUseEffectEventFunctions(scope) { + for (const reference of scope.references) { + const parent = reference.identifier.parent; + if ( + parent.type === 'VariableDeclarator' && + parent.init && + parent.init.type === 'CallExpression' && + parent.init.callee && + isUseEffectEventIdentifier(parent.init.callee) + ) { + for (const ref of reference.resolved.references) { + if (ref !== reference) { + useEffectEventFunctions.add(ref.identifier); + } + } + } + } + } + + return { + // Maintain code segment path stack as we traverse. + onCodePathSegmentStart: segment => codePathSegmentStack.push(segment), + onCodePathSegmentEnd: () => codePathSegmentStack.pop(), + + // Maintain code path stack as we traverse. + onCodePathStart: () => codePathReactHooksMapStack.push(new Map()), + + // Process our code path. + // + // Everything is ok if all React Hooks are both reachable from the initial + // segment and reachable from every final segment. + onCodePathEnd(codePath, codePathNode) { + const reactHooksMap = codePathReactHooksMapStack.pop(); + if (reactHooksMap.size === 0) { + return; + } + + // All of the segments which are cyclic are recorded in this set. + const cyclic = new Set(); + + /** + * Count the number of code paths from the start of the function to this + * segment. For example: + * + * ```js + * function MyComponent() { + * if (condition) { + * // Segment 1 + * } else { + * // Segment 2 + * } + * // Segment 3 + * } + * ``` + * + * Segments 1 and 2 have one path to the beginning of `MyComponent` and + * segment 3 has two paths to the beginning of `MyComponent` since we + * could have either taken the path of segment 1 or segment 2. + * + * Populates `cyclic` with cyclic segments. + */ + + function countPathsFromStart(segment, pathHistory) { + const { cache } = countPathsFromStart; + let paths = cache.get(segment.id); + const pathList = new Set(pathHistory); + + // If `pathList` includes the current segment then we've found a cycle! + // We need to fill `cyclic` with all segments inside cycle + if (pathList.has(segment.id)) { + const pathArray = [...pathList]; + const cyclicSegments = pathArray.slice(pathArray.indexOf(segment.id) + 1); + for (const cyclicSegment of cyclicSegments) { + cyclic.add(cyclicSegment); + } + + return BigInt('0'); + } + + // add the current segment to pathList + pathList.add(segment.id); + + // We have a cached `paths`. Return it. + if (paths !== undefined) { + return paths; + } + + if (codePath.thrownSegments.includes(segment)) { + paths = BigInt('0'); + } else if (segment.prevSegments.length === 0) { + paths = BigInt('1'); + } else { + paths = BigInt('0'); + for (const prevSegment of segment.prevSegments) { + paths += countPathsFromStart(prevSegment, pathList); + } + } + + // If our segment is reachable then there should be at least one path + // to it from the start of our code path. + if (segment.reachable && paths === BigInt('0')) { + cache.delete(segment.id); + } else { + cache.set(segment.id, paths); + } + + return paths; + } + + /** + * Count the number of code paths from this segment to the end of the + * function. For example: + * + * ```js + * function MyComponent() { + * // Segment 1 + * if (condition) { + * // Segment 2 + * } else { + * // Segment 3 + * } + * } + * ``` + * + * Segments 2 and 3 have one path to the end of `MyComponent` and + * segment 1 has two paths to the end of `MyComponent` since we could + * either take the path of segment 1 or segment 2. + * + * Populates `cyclic` with cyclic segments. + */ + + function countPathsToEnd(segment, pathHistory) { + const { cache } = countPathsToEnd; + let paths = cache.get(segment.id); + const pathList = new Set(pathHistory); + + // If `pathList` includes the current segment then we've found a cycle! + // We need to fill `cyclic` with all segments inside cycle + if (pathList.has(segment.id)) { + const pathArray = Array.from(pathList); + const cyclicSegments = pathArray.slice(pathArray.indexOf(segment.id) + 1); + for (const cyclicSegment of cyclicSegments) { + cyclic.add(cyclicSegment); + } + + return BigInt('0'); + } + + // add the current segment to pathList + pathList.add(segment.id); + + // We have a cached `paths`. Return it. + if (paths !== undefined) { + return paths; + } + + if (codePath.thrownSegments.includes(segment)) { + paths = BigInt('0'); + } else if (segment.nextSegments.length === 0) { + paths = BigInt('1'); + } else { + paths = BigInt('0'); + for (const nextSegment of segment.nextSegments) { + paths += countPathsToEnd(nextSegment, pathList); + } + } + + cache.set(segment.id, paths); + return paths; + } + + /** + * Gets the shortest path length to the start of a code path. + * For example: + * + * ```js + * function MyComponent() { + * if (condition) { + * // Segment 1 + * } + * // Segment 2 + * } + * ``` + * + * There is only one path from segment 1 to the code path start. Its + * length is one so that is the shortest path. + * + * There are two paths from segment 2 to the code path start. One + * through segment 1 with a length of two and another directly to the + * start with a length of one. The shortest path has a length of one + * so we would return that. + */ + + function shortestPathLengthToStart(segment) { + const { cache } = shortestPathLengthToStart; + let length = cache.get(segment.id); + + // If `length` is null then we found a cycle! Return infinity since + // the shortest path is definitely not the one where we looped. + if (length === null) { + return Infinity; + } + + // We have a cached `length`. Return it. + if (length !== undefined) { + return length; + } + + // Compute `length` and cache it. Guarding against cycles. + cache.set(segment.id, null); + if (segment.prevSegments.length === 0) { + length = 1; + } else { + length = Infinity; + for (const prevSegment of segment.prevSegments) { + const prevLength = shortestPathLengthToStart(prevSegment); + if (prevLength < length) { + length = prevLength; + } + } + length += 1; + } + cache.set(segment.id, length); + return length; + } + + countPathsFromStart.cache = new Map(); + countPathsToEnd.cache = new Map(); + shortestPathLengthToStart.cache = new Map(); + + // Count all code paths to the end of our component/hook. Also primes + // the `countPathsToEnd` cache. + const allPathsFromStartToEnd = countPathsToEnd(codePath.initialSegment); + + // Gets the function name for our code path. If the function name is + // `undefined` then we know either that we have an anonymous function + // expression or our code path is not in a function. In both cases we + // will want to error since neither are React function components or + // hook functions - unless it is an anonymous function argument to + // forwardRef or memo. + const codePathFunctionName = getFunctionName(codePathNode); + + // This is a valid code path for React hooks if we are directly in a React + // function component or we are in a hook function. + const isSomewhereInsideComponentOrHook = isInsideComponentOrHook(codePathNode); + const isDirectlyInsideComponentOrHook = codePathFunctionName + ? isComponentName(codePathFunctionName) || isHook(codePathFunctionName) + : isForwardRefCallback(codePathNode) || isMemoCallback(codePathNode); + + // Compute the earliest finalizer level using information from the + // cache. We expect all reachable final segments to have a cache entry + // after calling `visitSegment()`. + let shortestFinalPathLength = Infinity; + for (const finalSegment of codePath.finalSegments) { + if (!finalSegment.reachable) { + continue; + } + const length = shortestPathLengthToStart(finalSegment); + if (length < shortestFinalPathLength) { + shortestFinalPathLength = length; + } + } + + // Make sure all React Hooks pass our lint invariants. Log warnings + // if not. + for (const [segment, reactHooks] of reactHooksMap) { + // NOTE: We could report here that the hook is not reachable, but + // that would be redundant with more general "no unreachable" + // lint rules. + if (!segment.reachable) { + continue; + } + + // If there are any final segments with a shorter path to start then + // we possibly have an early return. + // + // If our segment is a final segment itself then siblings could + // possibly be early returns. + const possiblyHasEarlyReturn = + segment.nextSegments.length === 0 + ? shortestFinalPathLength <= shortestPathLengthToStart(segment) + : shortestFinalPathLength < shortestPathLengthToStart(segment); + + // Count all the paths from the start of our code path to the end of + // our code path that go _through_ this segment. The critical piece + // of this is _through_. If we just call `countPathsToEnd(segment)` + // then we neglect that we may have gone through multiple paths to get + // to this point! Consider: + // + // ```js + // function MyComponent() { + // if (a) { + // // Segment 1 + // } else { + // // Segment 2 + // } + // // Segment 3 + // if (b) { + // // Segment 4 + // } else { + // // Segment 5 + // } + // } + // ``` + // + // In this component we have four code paths: + // + // 1. `a = true; b = true` + // 2. `a = true; b = false` + // 3. `a = false; b = true` + // 4. `a = false; b = false` + // + // From segment 3 there are two code paths to the end through segment + // 4 and segment 5. However, we took two paths to get here through + // segment 1 and segment 2. + // + // If we multiply the paths from start (two) by the paths to end (two) + // for segment 3 we get four. Which is our desired count. + const pathsFromStartToEnd = + countPathsFromStart(segment) * countPathsToEnd(segment); + + // Is this hook a part of a cyclic segment? + const cycled = cyclic.has(segment.id); + + for (const hook of reactHooks) { + // Report an error if a hook may be called more then once. + // `use(...)` can be called in loops. + if (cycled && !isUseIdentifier(hook)) { + context.report({ + node: hook, + message: + `React Hook "${context.getSource(hook)}" may be executed ` + + 'more than once. Possibly because it is called in a loop. ' + + 'React Hooks must be called in the exact same order in ' + + 'every component render.', + }); + } + + // If this is not a valid code path for React hooks then we need to + // log a warning for every hook in this code path. + // + // Pick a special message depending on the scope this hook was + // called in. + if (isDirectlyInsideComponentOrHook) { + // Report an error if the hook is called inside an async function. + const isAsyncFunction = codePathNode.async; + if (isAsyncFunction) { + context.report({ + node: hook, + message: + `React Hook "${context.getSource(hook)}" cannot be ` + + 'called in an async function.', + }); + } + + // Report an error if a hook does not reach all finalizing code + // path segments. + // + // Special case when we think there might be an early return. + if ( + !cycled && + pathsFromStartToEnd !== allPathsFromStartToEnd && + !isUseIdentifier(hook) // `use(...)` can be called conditionally. + ) { + const message = + `React Hook "${context.getSource(hook)}" is called ` + + 'conditionally. React Hooks must be called in the exact ' + + 'same order in every component render.' + + (possiblyHasEarlyReturn + ? ' Did you accidentally call a React Hook after an' + + ' early return?' + : ''); + context.report({ node: hook, message }); + } + } else if ( + codePathNode.parent && + (codePathNode.parent.type === 'MethodDefinition' || + codePathNode.parent.type === 'ClassProperty') && + codePathNode.parent.value === codePathNode + ) { + // Custom message for hooks inside a class + const message = + `React Hook "${context.getSource(hook)}" cannot be called ` + + 'in a class component. React Hooks must be called in a ' + + 'React function component or a custom React Hook function.'; + context.report({ node: hook, message }); + } else if (codePathFunctionName) { + // Custom message if we found an invalid function name. + const message = + `React Hook "${context.getSource(hook)}" is called in ` + + `function "${context.getSource(codePathFunctionName)}" ` + + 'that is neither a React function component nor a custom ' + + 'React Hook function.' + + ' React component names must start with an uppercase letter.' + + ' React Hook names must start with the word "use".'; + context.report({ node: hook, message }); + } else if (codePathNode.type === 'Program') { + // These are dangerous if you have inline requires enabled. + const message = + `React Hook "${context.getSource(hook)}" cannot be called ` + + 'at the top level. React Hooks must be called in a ' + + 'React function component or a custom React Hook function.'; + context.report({ node: hook, message }); + } else { + // Assume in all other cases the user called a hook in some + // random function callback. This should usually be true for + // anonymous function expressions. Hopefully this is clarifying + // enough in the common case that the incorrect message in + // uncommon cases doesn't matter. + // `use(...)` can be called in callbacks. + if (isSomewhereInsideComponentOrHook && !isUseIdentifier(hook)) { + const message = + `React Hook "${context.getSource(hook)}" cannot be called ` + + 'inside a callback. React Hooks must be called in a ' + + 'React function component or a custom React Hook function.'; + context.report({ node: hook, message }); + } + } + } + } + }, + + // Missed opportunity...We could visit all `Identifier`s instead of all + // `CallExpression`s and check that _every use_ of a hook name is valid. + // But that gets complicated and enters type-system territory, so we're + // only being strict about hook calls for now. + CallExpression(node) { + if (isHook(node.callee)) { + // Add the hook node to a map keyed by the code path segment. We will + // do full code path analysis at the end of our code path. + const reactHooksMap = last(codePathReactHooksMapStack); + const codePathSegment = last(codePathSegmentStack); + let reactHooks = reactHooksMap.get(codePathSegment); + if (!reactHooks) { + reactHooks = []; + reactHooksMap.set(codePathSegment, reactHooks); + } + reactHooks.push(node.callee); + } + + // useEffectEvent: useEffectEvent functions can be passed by reference within useEffect as well as in + // another useEffectEvent + if ( + node.callee.type === 'Identifier' && + (node.callee.name === 'useEffect' || isUseEffectEventIdentifier(node.callee)) && + node.arguments.length > 0 + ) { + // Denote that we have traversed into a useEffect call, and stash the CallExpr for + // comparison later when we exit + lastEffect = node; + } + }, + + Identifier(node) { + // This identifier resolves to a useEffectEvent function, but isn't being referenced in an + // effect or another event function. It isn't being called either. + if ( + lastEffect == null && + useEffectEventFunctions.has(node) && + node.parent.type !== 'CallExpression' + ) { + context.report({ + node, + message: + `\`${context.getSource( + node, + )}\` is a function created with React Hook "useEffectEvent", and can only be called from ` + + 'the same component. They cannot be assigned to variables or passed down.', + }); + } + }, + + 'CallExpression:exit'(node) { + if (node === lastEffect) { + lastEffect = null; + } + }, + + FunctionDeclaration(node) { + // function MyComponent() { const onClick = useEffectEvent(...) } + if (isInsideComponentOrHook(node)) { + recordAllUseEffectEventFunctions(context.getScope()); + } + }, + + ArrowFunctionExpression(node) { + // const MyComponent = () => { const onClick = useEffectEvent(...) } + if (isInsideComponentOrHook(node)) { + recordAllUseEffectEventFunctions(context.getScope()); + } + }, + }; + }, +}; + +/** + * Gets the static name of a function AST node. For function declarations it is + * easy. For anonymous function expressions it is much harder. If you search for + * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places + * where JS gives anonymous function expressions names. We roughly detect the + * same AST nodes with some exceptions to better fit our use case. + */ + +function getFunctionName(node) { + if ( + node.type === 'FunctionDeclaration' || + (node.type === 'FunctionExpression' && node.id) + ) { + // function useHook() {} + // const whatever = function useHook() {}; + // + // Function declaration or function expression names win over any + // assignment statements or other renames. + return node.id; + } else if ( + node.type === 'FunctionExpression' || + node.type === 'ArrowFunctionExpression' + ) { + if (node.parent.type === 'VariableDeclarator' && node.parent.init === node) { + // const useHook = () => {}; + return node.parent.id; + } else if ( + node.parent.type === 'AssignmentExpression' && + node.parent.right === node && + node.parent.operator === '=' + ) { + // useHook = () => {}; + return node.parent.left; + } else if ( + node.parent.type === 'Property' && + node.parent.value === node && + !node.parent.computed + ) { + // {useHook: () => {}} + // {useHook() {}} + return node.parent.key; + + // NOTE: We could also support `ClassProperty` and `MethodDefinition` + // here to be pedantic. However, hooks in a class are an anti-pattern. So + // we don't allow it to error early. + // + // class {useHook = () => {}} + // class {useHook() {}} + } else if ( + node.parent.type === 'AssignmentPattern' && + node.parent.right === node && + !node.parent.computed + ) { + // const {useHook = () => {}} = {}; + // ({useHook = () => {}} = {}); + // + // Kinda clowny, but we'd said we'd follow spec convention for + // `IsAnonymousFunctionDefinition()` usage. + return node.parent.left; + } else { + return undefined; + } + } else { + return undefined; + } +} + +/** + * Convenience function for peeking the last item in a stack. + */ + +function last(array) { + return array[array.length - 1]; +} diff --git a/eslint-plugin-react-hooks/index.ts b/eslint-plugin-react-hooks/index.ts new file mode 100644 index 0000000..57eea02 --- /dev/null +++ b/eslint-plugin-react-hooks/index.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import RulesOfHooks from './RulesOfHooks'; +import ExhaustiveDeps from './ExhaustiveDeps'; + +export const configs = { + recommended: { + plugins: ['react-hooks'], + rules: { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + }, + }, +}; + +export const rules = { + 'rules-of-hooks': RulesOfHooks, + 'exhaustive-deps': ExhaustiveDeps, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..9398c06 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "scripts": { + "build": "./esbuild.ts", + "check-import": "for js in dist/*.js; do cat $js | grep 'require('; done" + }, + "private": true, + "devDependencies": { + "@babel/core": "^7.22.9", + "@babel/plugin-transform-flow-strip-types": "^7.22.5", + "@babel/preset-env": "^7.22.9", + "@types/babel-plugin-macros": "^3.1.0", + "@types/babel__core": "^7.20.1", + "@types/node": "^20.4.2", + "babel-plugin-macros": "^3.1.0", + "esbin": "0.0.1-beta.1", + "esbuild": "0.18.14", + "esbuild-plugin-alias": "^0.2.1", + "esbuild-register": "3.4.2", + "eslint": "8.45.0", + "eslint-config-prettier": "8.8.0", + "eslint-plugin-import": "^2.27.5", + "glob": "^10.3.3", + "prettier": "^3.0.0" + }, + "prettier": { + "arrowParens": "avoid", + "tabWidth": 2, + "printWidth": 90, + "semi": true, + "singleQuote": true, + "trailingComma": "all" + } +} diff --git a/patch/eslint-plugin-import.patch b/patch/eslint-plugin-import.patch new file mode 100644 index 0000000..551b392 --- /dev/null +++ b/patch/eslint-plugin-import.patch @@ -0,0 +1,498 @@ +diff --git a/.babelrc b/.babelrc +index 883c03b7..0111d616 100644 +--- a/.babelrc ++++ b/.babelrc +@@ -1,18 +1,11 @@ + { +- "presets": ["airbnb"], +- "sourceMaps": "inline", +- "retainLines": true, ++ "presets": [["@babel/preset-env", { "targets": { "node": 16 } }]], + "env": { + "test": { +- "plugins": [ +- "istanbul", +- ["module-resolver", { "root": ["./src/"] }], +- ] ++ "plugins": ["istanbul", ["module-resolver", { "root": ["./src/"] }]] + }, + "testCompiled": { +- "plugins": [ +- ["module-resolver", { "root": ["./lib/"] }], +- ] ++ "plugins": [["module-resolver", { "root": ["./lib/"] }]] + } + } + } +diff --git a/.eslintrc b/.eslintrc +deleted file mode 100644 +index 709a4744..00000000 +--- a/.eslintrc ++++ /dev/null +@@ -1,247 +0,0 @@ +-{ +- "root": true, +- "plugins": [ +- "eslint-plugin", +- "import", +- ], +- "extends": [ +- "eslint:recommended", +- "plugin:eslint-plugin/recommended", +- "plugin:import/recommended", +- ], +- "env": { +- "node": true, +- "es6": true, +- "es2017": true, +- }, +- "parserOptions": { +- "sourceType": "module", +- "ecmaVersion": 2020, +- }, +- "rules": { +- "arrow-body-style": [2, "as-needed"], +- "arrow-parens": [2, "always"], +- "arrow-spacing": [2, { "before": true, "after": true }], +- "block-spacing": [2, "always"], +- "brace-style": [2, "1tbs", { "allowSingleLine": true }], +- "comma-dangle": ["error", { +- "arrays": "always-multiline", +- "objects": "always-multiline", +- "imports": "always-multiline", +- "exports": "always-multiline", +- "functions": "always-multiline", +- }], +- "comma-spacing": [2, { "before": false, "after": true }], +- "comma-style": [2, "last"], +- "computed-property-spacing": [2, "never"], +- "curly": [2, "all"], +- "default-case": [2, { "commentPattern": "(?:)" }], +- "default-case-last": [2], +- "default-param-last": [2], +- "dot-location": [2, "property"], +- "dot-notation": [2, { "allowKeywords": true, "allowPattern": "throws" }], +- "eol-last": [2, "always"], +- "eqeqeq": [2, "allow-null"], +- "for-direction": [2], +- "function-call-argument-newline": [2, "consistent"], +- "func-call-spacing": [2, "never"], +- "implicit-arrow-linebreak": [2, "beside"], +- "indent": [2, 2, { +- "SwitchCase": 1, +- "VariableDeclarator": 1, +- "outerIIFEBody": 1, +- "FunctionDeclaration": { +- "parameters": 1, +- "body": 1 +- }, +- "FunctionExpression": { +- "parameters": 1, +- "body": 1 +- }, +- "CallExpression": { +- "arguments": 1 +- }, +- "ArrayExpression": 1, +- "ObjectExpression": 1, +- "ImportDeclaration": 1, +- "flatTernaryExpressions": false, +- }], +- "jsx-quotes": [2, "prefer-double"], +- "key-spacing": [2, { +- "beforeColon": false, +- "afterColon": true, +- "mode": "strict", +- }], +- "keyword-spacing": ["error", { +- "before": true, +- "after": true, +- "overrides": { +- "return": { "after": true }, +- "throw": { "after": true }, +- "case": { "after": true } +- } +- }], +- "linebreak-style": [2, "unix"], +- "lines-around-directive": [2, { +- "before": "always", +- "after": "always", +- }], +- "max-len": 0, +- "new-parens": 2, +- "no-array-constructor": 2, +- "no-compare-neg-zero": 2, +- "no-cond-assign": [2, "always"], +- "no-extra-parens": 2, +- "no-multiple-empty-lines": [2, { "max": 1, "maxEOF": 1, "maxBOF": 0 }], +- "no-return-assign": [2, "always"], +- "no-trailing-spaces": 2, +- "no-var": 2, +- "object-curly-spacing": [2, "always"], +- "object-shorthand": ["error", "always", { +- "ignoreConstructors": false, +- "avoidQuotes": false, +- "avoidExplicitReturnArrows": true, +- }], +- "one-var": [2, "never"], +- "operator-linebreak": [2, "none", { +- "overrides": { +- "?": "before", +- ":": "before", +- "&&": "before", +- "||": "before", +- }, +- }], +- "prefer-const": 2, +- "prefer-object-spread": 2, +- "prefer-rest-params": 2, +- "prefer-template": 2, +- "quote-props": [2, "as-needed", { "keywords": false }], +- "quotes": [2, "single", { +- "allowTemplateLiterals": true, +- "avoidEscape": true, +- }], +- "rest-spread-spacing": [2, "never"], +- "semi": [2, "always"], +- "semi-spacing": [2, { "before": false, "after": true }], +- "semi-style": [2, "last"], +- "space-before-blocks": [2, { "functions": "always", "keywords": "always", "classes": "always" }], +- "space-before-function-paren": ["error", { +- "anonymous": "always", +- "named": "never", +- "asyncArrow": "always", +- }], +- "space-in-parens": [2, "never"], +- "space-infix-ops": [2], +- "space-unary-ops": [2, { "words": true, "nonwords": false }], +- "switch-colon-spacing": [2, { "after": true, "before": false }], +- "template-curly-spacing": [2, "never"], +- "template-tag-spacing": [2, "never"], +- "unicode-bom": [2, "never"], +- "use-isnan": [2, { "enforceForSwitchCase": true }], +- "valid-typeof": [2], +- "wrap-iife": [2, "outside", { "functionPrototypeMethods": true }], +- "wrap-regex": [2], +- "yield-star-spacing": [2, { "before": false, "after": true }], +- "yoda": [2, "never", { "exceptRange": true, "onlyEquality": false }], +- +- "eslint-plugin/consistent-output": [ +- "error", +- "always", +- ], +- "eslint-plugin/meta-property-ordering": "error", +- "eslint-plugin/no-deprecated-context-methods": "error", +- "eslint-plugin/no-deprecated-report-api": "off", +- "eslint-plugin/prefer-replace-text": "error", +- "eslint-plugin/report-message-format": "error", +- "eslint-plugin/require-meta-docs-description": ["error", { "pattern": "^(Enforce|Ensure|Prefer|Forbid).+\\.$" }], +- "eslint-plugin/require-meta-schema": "error", +- "eslint-plugin/require-meta-type": "error", +- +- // dog fooding +- "import/no-extraneous-dependencies": ["error", { +- "devDependencies": [ +- "tests/**", +- "resolvers/*/test/**", +- "scripts/**" +- ], +- "optionalDependencies": false, +- "peerDependencies": true, +- "bundledDependencies": false, +- }], +- "import/unambiguous": "off", +- }, +- +- "settings": { +- "import/resolver": { +- "node": { +- "paths": [ +- "src", +- ], +- }, +- }, +- }, +- +- "overrides": [ +- { +- "files": "scripts/**", +- "rules": { +- "no-console": "off", +- }, +- }, +- { +- "files": "resolvers/**", +- "env": { +- "es6": false, +- }, +- }, +- { +- "files": "resolvers/webpack/**", +- "rules": { +- "no-console": 1, +- "prefer-template": 0, +- "prefer-object-spread": 0, +- "prefer-rest-params": 0, +- }, +- "env": { +- "es6": true, +- }, +- }, +- { +- "files": [ +- "resolvers/*/test/**/*", +- ], +- "env": { +- "mocha": true, +- "es6": false +- }, +- }, +- { +- "files": "utils/**", +- "parserOptions": { +- "ecmaVersion": 6, +- }, +- "rules": { +- "comma-dangle": ["error", { +- "arrays": "always-multiline", +- "objects": "always-multiline", +- "imports": "always-multiline", +- "exports": "always-multiline", +- "functions": "never" +- }], +- "prefer-object-spread": "off", +- "prefer-template": "off", +- "no-console": 1, +- }, +- }, +- { +- "files": "tests/**", +- "env": { +- "mocha": true, +- }, +- "rules": { +- "max-len": 0, +- "import/default": 0, +- }, +- }, +- ], +-} +diff --git a/scripts/resolverDirectories.js b/scripts/resolverDirectories.js +index f0c03a3c..a7cadb55 100644 +--- a/scripts/resolverDirectories.js ++++ b/scripts/resolverDirectories.js +@@ -1,3 +1,3 @@ +-import glob from 'glob'; ++import { globSync } from 'glob'; + +-export default glob.sync('./resolvers/*/'); ++export default globSync('./resolvers/*/'); +diff --git a/src/docsUrl.js b/src/docsUrl.js +index 92b838c0..ccb13ba0 100644 +--- a/src/docsUrl.js ++++ b/src/docsUrl.js +@@ -1,7 +1,7 @@ +-import pkg from '../package.json'; ++import { version } from '../package.json'; + + const repoUrl = 'https://github.com/import-js/eslint-plugin-import'; + +-export default function docsUrl(ruleName, commitish = `v${pkg.version}`) { ++export default function docsUrl(ruleName, commitish = `v${version}`) { + return `${repoUrl}/blob/${commitish}/docs/rules/${ruleName}.md`; + } +diff --git a/src/index.js b/src/index.js +index feafba90..84992bef 100644 +--- a/src/index.js ++++ b/src/index.js +@@ -1,71 +1,132 @@ +-export const rules = { +- 'no-unresolved': require('./rules/no-unresolved'), +- named: require('./rules/named'), +- default: require('./rules/default'), +- namespace: require('./rules/namespace'), +- 'no-namespace': require('./rules/no-namespace'), +- export: require('./rules/export'), +- 'no-mutable-exports': require('./rules/no-mutable-exports'), +- extensions: require('./rules/extensions'), +- 'no-restricted-paths': require('./rules/no-restricted-paths'), +- 'no-internal-modules': require('./rules/no-internal-modules'), +- 'group-exports': require('./rules/group-exports'), +- 'no-relative-packages': require('./rules/no-relative-packages'), +- 'no-relative-parent-imports': require('./rules/no-relative-parent-imports'), +- 'consistent-type-specifier-style': require('./rules/consistent-type-specifier-style'), ++/* eslint-disable spaced-comment */ ++import noUnresolved from './rules/no-unresolved'; ++import named from './rules/named'; ++import defaultRule from './rules/default'; ++import namespace from './rules/namespace'; ++import noNamespace from './rules/no-namespace'; ++import exportRule from './rules/export'; ++import noMutableExports from './rules/no-mutable-exports'; ++import extensions from './rules/extensions'; ++import noRestrictedPaths from './rules/no-restricted-paths'; ++import noInternalModules from './rules/no-internal-modules'; ++import groupExports from './rules/group-exports'; ++import noRelativePackages from './rules/no-relative-packages'; ++import noRelativeParentImports from './rules/no-relative-parent-imports'; ++import consistentTypeSpecifierStyle from './rules/consistent-type-specifier-style'; ++import noSelfImport from './rules/no-self-import'; ++import noCycle from './rules/no-cycle'; ++import noNamedDefault from './rules/no-named-default'; ++import noNamedAsDefault from './rules/no-named-as-default'; ++import noNamedAsDefaultMember from './rules/no-named-as-default-member'; ++import noAnonymousDefaultExport from './rules/no-anonymous-default-export'; ++import noUnusedModules from './rules/no-unused-modules'; ++import noCommonjs from './rules/no-commonjs'; ++import noAmd from './rules/no-amd'; ++import noDuplicates from './rules/no-duplicates'; ++import first from './rules/first'; ++import maxDependencies from './rules/max-dependencies'; ++import noExtraneousDependencies from './rules/no-extraneous-dependencies'; ++import noAbsolutePath from './rules/no-absolute-path'; ++import noNodejsModules from './rules/no-nodejs-modules'; ++import noWebpackLoaderSyntax from './rules/no-webpack-loader-syntax'; ++import order from './rules/order'; ++import newlineAfterImport from './rules/newline-after-import'; ++import preferDefaultExport from './rules/prefer-default-export'; ++import noDefaultExport from './rules/no-default-export'; ++import noNamedExport from './rules/no-named-export'; ++import noDynamicRequire from './rules/no-dynamic-require'; ++import unambiguous from './rules/unambiguous'; ++import noUnassignedImport from './rules/no-unassigned-import'; ++import noUselessPathSegments from './rules/no-useless-path-segments'; ++import dynamicImportChunkname from './rules/dynamic-import-chunkname'; ++import noImportModuleExports from './rules/no-import-module-exports'; ++import noEmptyNamedBlocks from './rules/no-empty-named-blocks'; ++import exportsLast from './rules/exports-last'; ++import noDeprecated from './rules/no-deprecated'; ++import importsFirst from './rules/imports-first'; ++import recommended from '../config/recommended'; ++import errors from '../config/errors'; ++import warnings from '../config/warnings'; ++import stage0 from '../config/stage-0'; ++import react from '../config/react'; ++import reactNative from '../config/react-native'; ++import electron from '../config/electron'; ++import typescript from '../config/typescript'; + +- 'no-self-import': require('./rules/no-self-import'), +- 'no-cycle': require('./rules/no-cycle'), +- 'no-named-default': require('./rules/no-named-default'), +- 'no-named-as-default': require('./rules/no-named-as-default'), +- 'no-named-as-default-member': require('./rules/no-named-as-default-member'), +- 'no-anonymous-default-export': require('./rules/no-anonymous-default-export'), +- 'no-unused-modules': require('./rules/no-unused-modules'), ++export const rules = /*#__PURE__*/ kebabCase({ ++ noUnresolved, ++ named, ++ default: defaultRule, ++ namespace, ++ noNamespace, ++ export: exportRule, ++ noMutableExports, ++ extensions, ++ noRestrictedPaths, ++ noInternalModules, ++ groupExports, ++ noRelativePackages, ++ noRelativeParentImports, ++ consistentTypeSpecifierStyle, + +- 'no-commonjs': require('./rules/no-commonjs'), +- 'no-amd': require('./rules/no-amd'), +- 'no-duplicates': require('./rules/no-duplicates'), +- first: require('./rules/first'), +- 'max-dependencies': require('./rules/max-dependencies'), +- 'no-extraneous-dependencies': require('./rules/no-extraneous-dependencies'), +- 'no-absolute-path': require('./rules/no-absolute-path'), +- 'no-nodejs-modules': require('./rules/no-nodejs-modules'), +- 'no-webpack-loader-syntax': require('./rules/no-webpack-loader-syntax'), +- order: require('./rules/order'), +- 'newline-after-import': require('./rules/newline-after-import'), +- 'prefer-default-export': require('./rules/prefer-default-export'), +- 'no-default-export': require('./rules/no-default-export'), +- 'no-named-export': require('./rules/no-named-export'), +- 'no-dynamic-require': require('./rules/no-dynamic-require'), +- unambiguous: require('./rules/unambiguous'), +- 'no-unassigned-import': require('./rules/no-unassigned-import'), +- 'no-useless-path-segments': require('./rules/no-useless-path-segments'), +- 'dynamic-import-chunkname': require('./rules/dynamic-import-chunkname'), +- 'no-import-module-exports': require('./rules/no-import-module-exports'), +- 'no-empty-named-blocks': require('./rules/no-empty-named-blocks'), ++ noSelfImport, ++ noCycle, ++ noNamedDefault, ++ noNamedAsDefault, ++ noNamedAsDefaultMember, ++ noAnonymousDefaultExport, ++ noUnusedModules, ++ ++ noCommonjs, ++ noAmd, ++ noDuplicates, ++ first, ++ maxDependencies, ++ noExtraneousDependencies, ++ noAbsolutePath, ++ noNodejsModules, ++ noWebpackLoaderSyntax, ++ order, ++ newlineAfterImport, ++ preferDefaultExport, ++ noDefaultExport, ++ noNamedExport, ++ noDynamicRequire, ++ unambiguous, ++ noUnassignedImport, ++ noUselessPathSegments, ++ dynamicImportChunkname, ++ noImportModuleExports, ++ noEmptyNamedBlocks, + + // export +- 'exports-last': require('./rules/exports-last'), ++ exportsLast, + + // metadata-based +- 'no-deprecated': require('./rules/no-deprecated'), ++ noDeprecated, + + // deprecated aliases to rules +- 'imports-first': require('./rules/imports-first'), +-}; ++ importsFirst, ++}); + +-export const configs = { +- recommended: require('../config/recommended'), ++export const configs = /*#__PURE__*/ kebabCase({ ++ recommended, + +- errors: require('../config/errors'), +- warnings: require('../config/warnings'), ++ errors, ++ warnings, + + // shhhh... work in progress "secret" rules +- 'stage-0': require('../config/stage-0'), ++ 'stage-0': stage0, + + // useful stuff for folks using various environments +- react: require('../config/react'), +- 'react-native': require('../config/react-native'), +- electron: require('../config/electron'), +- typescript: require('../config/typescript'), +-}; ++ react, ++ reactNative, ++ electron, ++ typescript, ++}); ++ ++function kebabCase(obj) { ++ return Object.fromEntries( ++ Object.entries(obj).map(([key, value]) => [key.replace(/([A-Z])/g, '-$1').toLowerCase(), value]) ++ ) ++} +\ No newline at end of file diff --git a/patch/eslint-plugin-jsx-a11y.patch b/patch/eslint-plugin-jsx-a11y.patch new file mode 100644 index 0000000..6dd95ef --- /dev/null +++ b/patch/eslint-plugin-jsx-a11y.patch @@ -0,0 +1,144 @@ +diff --git a/src/index.js b/src/index.js +index 7b931fe..f7c1f91 100644 +--- a/src/index.js ++++ b/src/index.js +@@ -1,47 +1,87 @@ + /* eslint-disable global-require */ ++// @ts-check ++import accessibleEmoji from './rules/accessible-emoji'; ++import altText from './rules/alt-text'; ++import anchorAmbiguousText from './rules/anchor-ambiguous-text'; ++import anchorHasContent from './rules/anchor-has-content'; ++import anchorIsValid from './rules/anchor-is-valid'; ++import ariaActivedescendantHasTabindex from './rules/aria-activedescendant-has-tabindex'; ++import ariaProps from './rules/aria-props'; ++import ariaProptypes from './rules/aria-proptypes'; ++import ariaRole from './rules/aria-role'; ++import ariaUnsupportedElements from './rules/aria-unsupported-elements'; ++import autocompleteValid from './rules/autocomplete-valid'; ++import clickEventsHaveKeyEvents from './rules/click-events-have-key-events'; ++import controlHasAssociatedLabel from './rules/control-has-associated-label'; ++import headingHasContent from './rules/heading-has-content'; ++import htmlHasLang from './rules/html-has-lang'; ++import iframeHasTitle from './rules/iframe-has-title'; ++import imgRedundantAlt from './rules/img-redundant-alt'; ++import interactiveSupportsFocus from './rules/interactive-supports-focus'; ++import labelHasAssociatedControl from './rules/label-has-associated-control'; ++import labelHasFor from './rules/label-has-for'; ++import lang from './rules/lang'; ++import mediaHasCaption from './rules/media-has-caption'; ++import mouseEventsHaveKeyEvents from './rules/mouse-events-have-key-events'; ++import noAriaHiddenOnFocusable from './rules/no-aria-hidden-on-focusable'; ++import noAccessKey from './rules/no-access-key'; ++import noAutofocus from './rules/no-autofocus'; ++import noDistractingElements from './rules/no-distracting-elements'; ++import noInteractiveElementToNoninteractiveRole from './rules/no-interactive-element-to-noninteractive-role'; ++import noNoninteractiveElementInteractions from './rules/no-noninteractive-element-interactions'; ++import noNoninteractiveElementToInteractiveRole from './rules/no-noninteractive-element-to-interactive-role'; ++import noNoninteractiveTabindex from './rules/no-noninteractive-tabindex'; ++import noOnChange from './rules/no-onchange'; ++import noRedundantRoles from './rules/no-redundant-roles'; ++import noStaticElementInteractions from './rules/no-static-element-interactions'; ++import preferTagOverRole from './rules/prefer-tag-over-role'; ++import roleHasRequiredAriaProps from './rules/role-has-required-aria-props'; ++import roleSupportsAriaProps from './rules/role-supports-aria-props'; ++import scope from './rules/scope'; ++import tabindexNoPositive from './rules/tabindex-no-positive'; + + module.exports = { +- rules: { +- 'accessible-emoji': require('./rules/accessible-emoji'), +- 'alt-text': require('./rules/alt-text'), +- 'anchor-ambiguous-text': require('./rules/anchor-ambiguous-text'), +- 'anchor-has-content': require('./rules/anchor-has-content'), +- 'anchor-is-valid': require('./rules/anchor-is-valid'), +- 'aria-activedescendant-has-tabindex': require('./rules/aria-activedescendant-has-tabindex'), +- 'aria-props': require('./rules/aria-props'), +- 'aria-proptypes': require('./rules/aria-proptypes'), +- 'aria-role': require('./rules/aria-role'), +- 'aria-unsupported-elements': require('./rules/aria-unsupported-elements'), +- 'autocomplete-valid': require('./rules/autocomplete-valid'), +- 'click-events-have-key-events': require('./rules/click-events-have-key-events'), +- 'control-has-associated-label': require('./rules/control-has-associated-label'), +- 'heading-has-content': require('./rules/heading-has-content'), +- 'html-has-lang': require('./rules/html-has-lang'), +- 'iframe-has-title': require('./rules/iframe-has-title'), +- 'img-redundant-alt': require('./rules/img-redundant-alt'), +- 'interactive-supports-focus': require('./rules/interactive-supports-focus'), +- 'label-has-associated-control': require('./rules/label-has-associated-control'), +- 'label-has-for': require('./rules/label-has-for'), +- lang: require('./rules/lang'), +- 'media-has-caption': require('./rules/media-has-caption'), +- 'mouse-events-have-key-events': require('./rules/mouse-events-have-key-events'), +- 'no-access-key': require('./rules/no-access-key'), +- 'no-aria-hidden-on-focusable': require('./rules/no-aria-hidden-on-focusable'), +- 'no-autofocus': require('./rules/no-autofocus'), +- 'no-distracting-elements': require('./rules/no-distracting-elements'), +- 'no-interactive-element-to-noninteractive-role': require('./rules/no-interactive-element-to-noninteractive-role'), +- 'no-noninteractive-element-interactions': require('./rules/no-noninteractive-element-interactions'), +- 'no-noninteractive-element-to-interactive-role': require('./rules/no-noninteractive-element-to-interactive-role'), +- 'no-noninteractive-tabindex': require('./rules/no-noninteractive-tabindex'), +- 'no-onchange': require('./rules/no-onchange'), +- 'no-redundant-roles': require('./rules/no-redundant-roles'), +- 'no-static-element-interactions': require('./rules/no-static-element-interactions'), +- 'prefer-tag-over-role': require('./rules/prefer-tag-over-role'), +- 'role-has-required-aria-props': require('./rules/role-has-required-aria-props'), +- 'role-supports-aria-props': require('./rules/role-supports-aria-props'), +- scope: require('./rules/scope'), +- 'tabindex-no-positive': require('./rules/tabindex-no-positive'), +- }, ++ rules: kebabCase({ ++ accessibleEmoji, ++ altText, ++ anchorAmbiguousText, ++ anchorHasContent, ++ anchorIsValid, ++ ariaActivedescendantHasTabindex, ++ ariaProps, ++ ariaProptypes, ++ ariaRole, ++ ariaUnsupportedElements, ++ autocompleteValid, ++ clickEventsHaveKeyEvents, ++ controlHasAssociatedLabel, ++ headingHasContent, ++ htmlHasLang, ++ iframeHasTitle, ++ imgRedundantAlt, ++ interactiveSupportsFocus, ++ labelHasAssociatedControl, ++ labelHasFor, ++ lang, ++ mediaHasCaption, ++ mouseEventsHaveKeyEvents, ++ noAccessKey, ++ noAriaHiddenOnFocusable, ++ noAutofocus, ++ noDistractingElements, ++ noInteractiveElementToNoninteractiveRole, ++ noNoninteractiveElementInteractions, ++ noNoninteractiveElementToInteractiveRole, ++ noNoninteractiveTabindex, ++ noOnChange, ++ noRedundantRoles, ++ noStaticElementInteractions, ++ preferTagOverRole, ++ roleHasRequiredAriaProps, ++ roleSupportsAriaProps, ++ scope, ++ tabindexNoPositive, ++ }), + configs: { + recommended: { + plugins: [ +@@ -294,3 +334,9 @@ module.exports = { + }, + }, + }; ++ ++function kebabCase(obj) { ++ return Object.fromEntries( ++ Object.entries(obj).map(([key, value]) => [key.replace(/([A-Z])/g, '-$1').toLowerCase(), value]) ++ ) ++} +\ No newline at end of file diff --git a/patch/eslint-plugin-react.patch b/patch/eslint-plugin-react.patch new file mode 100644 index 0000000..cb34d17 --- /dev/null +++ b/patch/eslint-plugin-react.patch @@ -0,0 +1,310 @@ +diff --git a/.eslintrc b/.eslintrc +deleted file mode 100644 +index 4991f200..00000000 +--- a/.eslintrc ++++ /dev/null +@@ -1,82 +0,0 @@ +-{ +- "root": true, +- "extends": ["airbnb-base", "plugin:eslint-plugin/recommended"], +- "plugins": ["eslint-plugin"], +- "env": { +- "es6": true, +- "node": true +- }, +- "parserOptions": { +- "ecmaVersion": 6, +- "ecmaFeatures": { +- "jsx": true +- }, +- "sourceType": "script", +- }, +- "ignorePatterns": [ +- "coverage/", +- ".nyc_output/", +- ], +- "rules": { +- "comma-dangle": [2, "always-multiline"], +- "object-shorthand": [2, "always", { +- "ignoreConstructors": false, +- "avoidQuotes": false, // this is the override vs airbnb +- }], +- "max-len": [2, 120, { +- "ignoreStrings": true, +- "ignoreTemplateLiterals": true, +- "ignoreComments": true, +- }], +- "consistent-return": 0, +- +- "prefer-destructuring": [2, { "array": false, "object": false }, { "enforceForRenamedProperties": false }], +- "prefer-object-spread": 0, // until node 8 is required +- "prefer-rest-params": 0, // until node 6 is required +- "prefer-spread": 0, // until node 6 is required +- "function-call-argument-newline": 1, // TODO: enable +- "function-paren-newline": 0, +- "no-plusplus": [2, {"allowForLoopAfterthoughts": true}], +- "no-param-reassign": 1, +- "no-restricted-syntax": [2, { +- "selector": "ObjectPattern", +- "message": "Object destructuring is not compatible with Node v4" +- }], +- "strict": [2, "safe"], +- "valid-jsdoc": [2, { +- "requireReturn": false, +- "requireParamDescription": false, +- "requireReturnDescription": false, +- }], +- +- "eslint-plugin/consistent-output": 0, +- "eslint-plugin/require-meta-docs-description": [2, { "pattern": "^(Enforce|Require|Disallow)" }], +- "eslint-plugin/require-meta-schema": 0, +- "eslint-plugin/require-meta-type": 0 +- }, +- "overrides": [ +- { +- "files": "tests/**", +- "rules": { +- "no-template-curly-in-string": 1, +- }, +- }, +- { +- "files": "markdown.config.js", +- "rules": { +- "no-console": 0, +- }, +- }, +- { +- "files": ".github/workflows/*.js", +- "parserOptions": { +- "ecmaVersion": 2019, +- }, +- "rules": { +- "camelcase": 0, +- "no-console": 0, +- "no-restricted-syntax": 0, +- }, +- }, +- ], +-} +diff --git a/index.js b/index.js +index 4140c6c8..792ceb4f 100644 +--- a/index.js ++++ b/index.js +@@ -1,15 +1,13 @@ + 'use strict'; + +-const configAll = require('./configs/all'); +-const configRecommended = require('./configs/recommended'); +-const configRuntime = require('./configs/jsx-runtime'); +- +-const allRules = require('./lib/rules'); ++import configAll from './configs/all'; ++import configRecommended from './configs/recommended'; ++import configRuntime from './configs/jsx-runtime'; ++import { name } from './package.json'; ++import allRules from './lib/rules'; + + // for legacy config system +-const plugins = [ +- 'react', +-]; ++const plugins = [name]; + + module.exports = { + deprecatedRules: configAll.plugins.react.deprecatedRules, +diff --git a/lib/rules/button-has-type.js b/lib/rules/button-has-type.js +index 204a33c4..01d992c2 100644 +--- a/lib/rules/button-has-type.js ++++ b/lib/rules/button-has-type.js +@@ -5,8 +5,7 @@ + + 'use strict'; + +-const getProp = require('jsx-ast-utils/getProp'); +-const getLiteralPropValue = require('jsx-ast-utils/getLiteralPropValue'); ++const { getProp, getLiteralPropValue } = require('jsx-ast-utils'); + const docsUrl = require('../util/docsUrl'); + const isCreateElement = require('../util/isCreateElement'); + const report = require('../util/report'); +diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js +index 38b4dd8b..d0575572 100644 +--- a/lib/rules/jsx-fragments.js ++++ b/lib/rules/jsx-fragments.js +@@ -5,7 +5,7 @@ + + 'use strict'; + +-const elementType = require('jsx-ast-utils/elementType'); ++import { elementType } from 'jsx-ast-utils'; + const pragmaUtil = require('../util/pragma'); + const variableUtil = require('../util/variable'); + const testReactVersion = require('../util/version').testReactVersion; +diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js +index 263ed824..e413ef5d 100644 +--- a/lib/rules/jsx-key.js ++++ b/lib/rules/jsx-key.js +@@ -5,8 +5,7 @@ + + 'use strict'; + +-const hasProp = require('jsx-ast-utils/hasProp'); +-const propName = require('jsx-ast-utils/propName'); ++import { hasProp, propName } from 'jsx-ast-utils'; + const values = require('object.values'); + const docsUrl = require('../util/docsUrl'); + const pragmaUtil = require('../util/pragma'); +diff --git a/lib/rules/jsx-no-bind.js b/lib/rules/jsx-no-bind.js +index 0a4c38e6..75a57bd9 100644 +--- a/lib/rules/jsx-no-bind.js ++++ b/lib/rules/jsx-no-bind.js +@@ -7,7 +7,7 @@ + + 'use strict'; + +-const propName = require('jsx-ast-utils/propName'); ++import { propName } from 'jsx-ast-utils'; + const docsUrl = require('../util/docsUrl'); + const jsxUtil = require('../util/jsx'); + const report = require('../util/report'); +diff --git a/lib/rules/jsx-pascal-case.js b/lib/rules/jsx-pascal-case.js +index a1bb4811..db051356 100644 +--- a/lib/rules/jsx-pascal-case.js ++++ b/lib/rules/jsx-pascal-case.js +@@ -5,7 +5,7 @@ + + 'use strict'; + +-const elementType = require('jsx-ast-utils/elementType'); ++import { elementType } from 'jsx-ast-utils'; + const minimatch = require('minimatch'); + const docsUrl = require('../util/docsUrl'); + const jsxUtil = require('../util/jsx'); +diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js +index 5de5bee1..8013a8de 100644 +--- a/lib/rules/jsx-sort-props.js ++++ b/lib/rules/jsx-sort-props.js +@@ -5,7 +5,7 @@ + + 'use strict'; + +-const propName = require('jsx-ast-utils/propName'); ++import { propName } from 'jsx-ast-utils'; + const includes = require('array-includes'); + const toSorted = require('array.prototype.tosorted'); + +diff --git a/lib/rules/no-namespace.js b/lib/rules/no-namespace.js +index 64bbc8d5..b5e9c803 100644 +--- a/lib/rules/no-namespace.js ++++ b/lib/rules/no-namespace.js +@@ -5,7 +5,7 @@ + + 'use strict'; + +-const elementType = require('jsx-ast-utils/elementType'); ++import { elementType } from 'jsx-ast-utils'; + const docsUrl = require('../util/docsUrl'); + const isCreateElement = require('../util/isCreateElement'); + const report = require('../util/report'); +diff --git a/lib/util/annotations.js b/lib/util/annotations.js +index 60aaef8c..ad8dc0bf 100644 +--- a/lib/util/annotations.js ++++ b/lib/util/annotations.js +@@ -27,6 +27,6 @@ function isAnnotatedFunctionPropsDeclaration(node, context) { + return (isAnnotated && (isDestructuredProps || isProps)); + } + +-module.exports = { ++export { + isAnnotatedFunctionPropsDeclaration, + }; +diff --git a/lib/util/ast.js b/lib/util/ast.js +index fd6019a3..3cbc293e 100644 +--- a/lib/util/ast.js ++++ b/lib/util/ast.js +@@ -4,7 +4,7 @@ + + 'use strict'; + +-const estraverse = require('estraverse'); ++import estraverse from 'estraverse'; + // const pragmaUtil = require('./pragma'); + + /** +@@ -428,7 +428,7 @@ function isTSTypeParameterInstantiation(node) { + return nodeType === 'TSTypeParameterInstantiation'; + } + +-module.exports = { ++export { + traverse, + findReturnStatement, + getFirstNodeInLine, +diff --git a/lib/util/jsx.js b/lib/util/jsx.js +index 55073bfe..efc07af1 100644 +--- a/lib/util/jsx.js ++++ b/lib/util/jsx.js +@@ -4,7 +4,7 @@ + + 'use strict'; + +-const elementType = require('jsx-ast-utils/elementType'); ++import { elementType } from 'jsx-ast-utils'; + + const astUtil = require('./ast'); + const isCreateElement = require('./isCreateElement'); +diff --git a/package.json b/package.json +index cb736434..a97113c0 100644 +--- a/package.json ++++ b/package.json +@@ -25,21 +25,13 @@ + "homepage": "https://github.com/jsx-eslint/eslint-plugin-react", + "bugs": "https://github.com/jsx-eslint/eslint-plugin-react/issues", + "dependencies": { +- "array-includes": "^3.1.6", +- "array.prototype.flatmap": "^1.3.1", +- "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", +- "object.entries": "^1.1.6", +- "object.fromentries": "^2.0.6", +- "object.hasown": "^1.1.2", +- "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", +- "semver": "^6.3.0", +- "string.prototype.matchall": "^4.0.8" ++ "semver": "^6.3.0" + }, + "devDependencies": { + "@babel/core": "^7.21.0", +diff --git a/tsconfig.json b/tsconfig.json +deleted file mode 100644 +index 39187b7f..00000000 +--- a/tsconfig.json ++++ /dev/null +@@ -1,23 +0,0 @@ +-{ +- "compilerOptions": { +- "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ +- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ +- // "lib": ["es2015"], /* Specify library files to be included in the compilation. */ +- "allowJs": true, /* Allow javascript files to be compiled. */ +- "checkJs": true, /* Report errors in .js files. */ +- "noEmit": true, /* Do not emit outputs. */ +- "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ +- +- /* Strict Type-Checking Options */ +- // "strict": true, /* Enable all strict type-checking options. */ +- "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */ +- // "strictNullChecks": true, /* Enable strict null checks. */ +- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ +- "strictFunctionTypes": true, /* Enable strict checking of function types. */ +- "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ +- "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ +- "alwaysStrict": false, /* Parse in strict mode and emit "use strict" for each source file. */ +- "resolveJsonModule": true +- }, +- "include": ["lib"], +-} diff --git a/patch/jsx-ast-utils.patch b/patch/jsx-ast-utils.patch new file mode 100644 index 0000000..ec4cef8 --- /dev/null +++ b/patch/jsx-ast-utils.patch @@ -0,0 +1,459 @@ +diff --git a/elementType.js b/elementType.js +index 96873ac..c7b909a 100644 +--- a/elementType.js ++++ b/elementType.js +@@ -1 +1 @@ +-module.exports = require('./lib').elementType; // eslint-disable-line import/no-unresolved ++export { elementType as default } from './src'; +\ No newline at end of file +diff --git a/eventHandlers.js b/eventHandlers.js +index b5d7f62..208eaca 100644 +--- a/eventHandlers.js ++++ b/eventHandlers.js +@@ -1 +1 @@ +-module.exports = require('./lib').eventHandlers; // eslint-disable-line import/no-unresolved ++export { eventHandlers as default } from './src'; +\ No newline at end of file +diff --git a/eventHandlersByType.js b/eventHandlersByType.js +index b7a0c42..e2757e9 100644 +--- a/eventHandlersByType.js ++++ b/eventHandlersByType.js +@@ -1 +1 @@ +-module.exports = require('./lib').eventHandlersByType; // eslint-disable-line import/no-unresolved ++export { eventHandlersByType as default } from './src'; +\ No newline at end of file +diff --git a/getLiteralPropValue.js b/getLiteralPropValue.js +index efc5c8d..970fc39 100644 +--- a/getLiteralPropValue.js ++++ b/getLiteralPropValue.js +@@ -1 +1 @@ +-module.exports = require('./lib').getLiteralPropValue; // eslint-disable-line import/no-unresolved ++export { getLiteralPropValue as default } from './src'; +\ No newline at end of file +diff --git a/getProp.js b/getProp.js +index e523c2c..4e270e9 100644 +--- a/getProp.js ++++ b/getProp.js +@@ -1 +1 @@ +-module.exports = require('./lib').getProp; // eslint-disable-line import/no-unresolved ++export { getProp as default } from './src'; +\ No newline at end of file +diff --git a/getPropValue.js b/getPropValue.js +index 883a37c..86bf585 100644 +--- a/getPropValue.js ++++ b/getPropValue.js +@@ -1 +1 @@ +-module.exports = require('./lib').getPropValue; // eslint-disable-line import/no-unresolved ++export { getPropValue as default } from './src'; +\ No newline at end of file +diff --git a/hasAnyProp.js b/hasAnyProp.js +index 2a88420..95b3adc 100644 +--- a/hasAnyProp.js ++++ b/hasAnyProp.js +@@ -1 +1 @@ +-module.exports = require('./lib').hasAnyProp; // eslint-disable-line import/no-unresolved ++export { hasAnyProp as default } from './src'; +\ No newline at end of file +diff --git a/hasEveryProp.js b/hasEveryProp.js +index 338f569..e865100 100644 +--- a/hasEveryProp.js ++++ b/hasEveryProp.js +@@ -1 +1 @@ +-module.exports = require('./lib').hasEveryProp; // eslint-disable-line import/no-unresolved ++export { hasEveryProp } from './src'; +\ No newline at end of file +diff --git a/hasProp.js b/hasProp.js +index 0f1cd04..bfed363 100644 +--- a/hasProp.js ++++ b/hasProp.js +@@ -1 +1 @@ +-module.exports = require('./lib').hasProp; // eslint-disable-line import/no-unresolved ++export { hasProp } from './src'; +\ No newline at end of file +diff --git a/package.json b/package.json +index 738d1b3..befb66e 100644 +--- a/package.json ++++ b/package.json +@@ -2,7 +2,7 @@ + "name": "jsx-ast-utils", + "version": "3.3.4", + "description": "AST utility module for statically analyzing JSX", +- "main": "lib/index.js", ++ "main": "src/index.js", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated && npm run build", + "prebuild": "rimraf lib", +@@ -62,8 +62,6 @@ + }, + "license": "MIT", + "dependencies": { +- "array-includes": "^3.1.6", +- "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, +diff --git a/propName.js b/propName.js +index 361a52b..4424cfe 100644 +--- a/propName.js ++++ b/propName.js +@@ -1 +1 @@ +-module.exports = require('./lib').propName; // eslint-disable-line import/no-unresolved ++export { propName } from './src'; +\ No newline at end of file +diff --git a/src/index.js b/src/index.js +index 6814764..565a66e 100644 +--- a/src/index.js ++++ b/src/index.js +@@ -5,7 +5,7 @@ import getProp from './getProp'; + import getPropValue, { getLiteralPropValue } from './getPropValue'; + import propName from './propName'; + +-module.exports = { ++export { + hasProp, + hasAnyProp, + hasEveryProp, +diff --git a/src/values/JSXElement.js b/src/values/JSXElement.js +index e5a049f..029c23d 100644 +--- a/src/values/JSXElement.js ++++ b/src/values/JSXElement.js +@@ -1,12 +1,11 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a JSXElement type value node. + * + * Returns self-closing element with correct name. + */ + export default function extractValueFromJSXElement(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; +- + const Tag = value.openingElement.name.name; + if (value.openingElement.selfClosing) { + return `<${Tag} />`; +diff --git a/src/values/JSXFragment.js b/src/values/JSXFragment.js +index 379137e..90cbc54 100644 +--- a/src/values/JSXFragment.js ++++ b/src/values/JSXFragment.js +@@ -1,12 +1,11 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a JSXFragment type value node. + * + * Returns self-closing element with correct name. + */ + export default function extractValueFromJSXFragment(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; +- + if (value.children.length === 0) { + return '<>'; + } +diff --git a/src/values/expressions/ArrayExpression.js b/src/values/expressions/ArrayExpression.js +index f333d58..4462c9d 100644 +--- a/src/values/expressions/ArrayExpression.js ++++ b/src/values/expressions/ArrayExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for an ArrayExpression type value node. + * An array expression is an expression with [] syntax. +@@ -5,8 +7,6 @@ + * @returns - An array of the extracted elements. + */ + export default function extractValueFromArrayExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return value.elements.map((element) => { + if (element === null) return undefined; + return getValue(element); +diff --git a/src/values/expressions/AssignmentExpression.js b/src/values/expressions/AssignmentExpression.js +index 7a14de5..6fce401 100644 +--- a/src/values/expressions/AssignmentExpression.js ++++ b/src/values/expressions/AssignmentExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a AssignmentExpression type value node. + * An assignment expression looks like `x = y` or `x += y` in expression position. +@@ -7,7 +9,5 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromAssignmentExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return `${getValue(value.left)} ${value.operator} ${getValue(value.right)}`; + } +diff --git a/src/values/expressions/BinaryExpression.js b/src/values/expressions/BinaryExpression.js +index 5764f3f..7cf9c07 100644 +--- a/src/values/expressions/BinaryExpression.js ++++ b/src/values/expressions/BinaryExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a BinaryExpression type value node. + * A binary expression has a left and right side separated by an operator +@@ -7,8 +9,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromBinaryExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const { operator, left, right } = value; + const leftVal = getValue(left); + const rightVal = getValue(right); +diff --git a/src/values/expressions/BindExpression.js b/src/values/expressions/BindExpression.js +index bc0bf0f..6c10fa4 100644 +--- a/src/values/expressions/BindExpression.js ++++ b/src/values/expressions/BindExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a BindExpression type value node. + * A bind expression looks like `::this.foo` +@@ -8,8 +10,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromBindExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const callee = getValue(value.callee); + + // If value.object === null, the callee must be a MemberExpression. +diff --git a/src/values/expressions/CallExpression.js b/src/values/expressions/CallExpression.js +index f225d16..ce7e43d 100644 +--- a/src/values/expressions/CallExpression.js ++++ b/src/values/expressions/CallExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a CallExpression type value node. + * A call expression looks like `bar()` +@@ -8,8 +10,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromCallExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const args = Array.isArray(value.arguments) ? value.arguments.map((x) => getValue(x)).join(', ') : ''; + return `${getValue(value.callee)}${value.optional ? '?.' : ''}(${args})`; + } +diff --git a/src/values/expressions/ChainExpression.js b/src/values/expressions/ChainExpression.js +index 1fb00a7..e8b3b75 100644 +--- a/src/values/expressions/ChainExpression.js ++++ b/src/values/expressions/ChainExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a ChainExpression type value node. + * A member expression is accessing a property on an object `obj.property`. +@@ -7,7 +9,5 @@ + * and maintaing `obj?.property` convention. + */ + export default function extractValueFromChainExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return getValue(value.expression || value); + } +diff --git a/src/values/expressions/ConditionalExpression.js b/src/values/expressions/ConditionalExpression.js +index 4fd185d..a3308f6 100644 +--- a/src/values/expressions/ConditionalExpression.js ++++ b/src/values/expressions/ConditionalExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a ConditionalExpression type value node. + * +@@ -5,8 +7,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromConditionalExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const { + test, + alternate, +diff --git a/src/values/expressions/LogicalExpression.js b/src/values/expressions/LogicalExpression.js +index 5b65a4e..b5cc573 100644 +--- a/src/values/expressions/LogicalExpression.js ++++ b/src/values/expressions/LogicalExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a LogicalExpression type value node. + * A logical expression is `a && b` or `a || b`, so we evaluate both sides +@@ -7,8 +9,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromLogicalExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const { operator, left, right } = value; + const leftVal = getValue(left); + const rightVal = getValue(right); +diff --git a/src/values/expressions/MemberExpression.js b/src/values/expressions/MemberExpression.js +index 5d48fd5..d0cb7af 100644 +--- a/src/values/expressions/MemberExpression.js ++++ b/src/values/expressions/MemberExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a MemberExpression type value node. + * A member expression is accessing a property on an object `obj.property`. +@@ -7,7 +9,5 @@ + * and maintaing `obj.property` convention. + */ + export default function extractValueFromMemberExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return `${getValue(value.object)}${value.optional ? '?.' : '.'}${getValue(value.property)}`; + } +diff --git a/src/values/expressions/ObjectExpression.js b/src/values/expressions/ObjectExpression.js +index 383b569..c1c08a8 100644 +--- a/src/values/expressions/ObjectExpression.js ++++ b/src/values/expressions/ObjectExpression.js +@@ -1,4 +1,5 @@ + import assign from 'object.assign'; ++import getValue from './index'; + + /** + * Extractor function for an ObjectExpression type value node. +@@ -7,8 +8,6 @@ import assign from 'object.assign'; + * @returns - a representation of the object + */ + export default function extractValueFromObjectExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return value.properties.reduce((obj, property) => { + // Support types: SpreadProperty and ExperimentalSpreadProperty + if (/^(?:Experimental)?Spread(?:Property|Element)$/.test(property.type)) { +diff --git a/src/values/expressions/OptionalCallExpression.js b/src/values/expressions/OptionalCallExpression.js +index bcee760..3a36971 100644 +--- a/src/values/expressions/OptionalCallExpression.js ++++ b/src/values/expressions/OptionalCallExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a OptionalCallExpression type value node. + * A member expression is accessing a property on an object `obj.property` and invoking it. +@@ -7,7 +9,5 @@ + * and maintaing `obj.property?.()` convention. + */ + export default function extractValueFromOptionalCallExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return `${getValue(value.callee)}?.(${value.arguments.map((x) => getValue(x)).join(', ')})`; + } +diff --git a/src/values/expressions/OptionalMemberExpression.js b/src/values/expressions/OptionalMemberExpression.js +index 8062eae..d236b04 100644 +--- a/src/values/expressions/OptionalMemberExpression.js ++++ b/src/values/expressions/OptionalMemberExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a OptionalMemberExpression type value node. + * A member expression is accessing a property on an object `obj.property`. +@@ -7,7 +9,5 @@ + * and maintaing `obj?.property` convention. + */ + export default function extractValueFromOptionalMemberExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return `${getValue(value.object)}?.${getValue(value.property)}`; + } +diff --git a/src/values/expressions/SequenceExpression.js b/src/values/expressions/SequenceExpression.js +index 129d992..d644730 100644 +--- a/src/values/expressions/SequenceExpression.js ++++ b/src/values/expressions/SequenceExpression.js +@@ -1,3 +1,5 @@ ++import getValue from './index'; ++ + /** + * Extractor function for a SequenceExpression type value node. + * A Sequence expression is an object with an attribute named +@@ -7,7 +9,5 @@ + * @returns - An array of the extracted elements. + */ + export default function extractValueFromSequenceExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return value.expressions.map((element) => getValue(element)); + } +diff --git a/src/values/expressions/TSNonNullExpression.js b/src/values/expressions/TSNonNullExpression.js +index 79dd1b0..7d74c8f 100644 +--- a/src/values/expressions/TSNonNullExpression.js ++++ b/src/values/expressions/TSNonNullExpression.js +@@ -1,5 +1,5 @@ +-const extractValueFromThisExpression = require('./ThisExpression').default; +-const extractValueFromCallExpression = require('./CallExpression').default; ++import extractValueFromThisExpression from './ThisExpression'; ++import extractValueFromCallExpression from './CallExpression'; + + function navigate(obj, prop, value) { + if (value.computed) { +diff --git a/src/values/expressions/TypeCastExpression.js b/src/values/expressions/TypeCastExpression.js +index 1afd232..aeda1e5 100644 +--- a/src/values/expressions/TypeCastExpression.js ++++ b/src/values/expressions/TypeCastExpression.js +@@ -1,3 +1,4 @@ ++import getValue from './index'; + /** + * Extractor function for a TypeCastExpression type value node. + * A type cast expression looks like `(this.handleClick: (event: MouseEvent) => void))` +@@ -7,7 +8,5 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromTypeCastExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + return getValue(value.expression); + } +diff --git a/src/values/expressions/UnaryExpression.js b/src/values/expressions/UnaryExpression.js +index b699722..cc1fa35 100644 +--- a/src/values/expressions/UnaryExpression.js ++++ b/src/values/expressions/UnaryExpression.js +@@ -1,3 +1,4 @@ ++import getValue from './index'; + /** + * Extractor function for a UnaryExpression type value node. + * A unary expression is an expression with a unary operator. +@@ -7,8 +8,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromUnaryExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const { operator, argument } = value; + + switch (operator) { +diff --git a/src/values/expressions/UpdateExpression.js b/src/values/expressions/UpdateExpression.js +index 0e3898c..ca005a2 100644 +--- a/src/values/expressions/UpdateExpression.js ++++ b/src/values/expressions/UpdateExpression.js +@@ -1,3 +1,4 @@ ++import getValue from './index'; + /** + * Extractor function for an UpdateExpression type value node. + * An update expression is an expression with an update operator. +@@ -7,8 +8,6 @@ + * @returns - The extracted value converted to correct type. + */ + export default function extractValueFromUpdateExpression(value) { +- // eslint-disable-next-line global-require +- const getValue = require('.').default; + const { operator, argument, prefix } = value; + + let val = getValue(argument); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..c4ffc39 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3380 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@babel/core': + specifier: ^7.22.9 + version: 7.22.9 + '@babel/plugin-transform-flow-strip-types': + specifier: ^7.22.5 + version: 7.22.5(@babel/core@7.22.9) + '@babel/preset-env': + specifier: ^7.22.9 + version: 7.22.9(@babel/core@7.22.9) + '@types/babel-plugin-macros': + specifier: ^3.1.0 + version: 3.1.0 + '@types/babel__core': + specifier: ^7.20.1 + version: 7.20.1 + '@types/node': + specifier: ^20.4.2 + version: 20.4.2 + babel-plugin-macros: + specifier: ^3.1.0 + version: 3.1.0 + esbin: + specifier: 0.0.1-beta.1 + version: 0.0.1-beta.1(esbuild@0.18.14) + esbuild: + specifier: 0.18.14 + version: 0.18.14 + esbuild-plugin-alias: + specifier: ^0.2.1 + version: 0.2.1 + esbuild-register: + specifier: 3.4.2 + version: 3.4.2(esbuild@0.18.14) + eslint: + specifier: 8.45.0 + version: 8.45.0 + eslint-config-prettier: + specifier: 8.8.0 + version: 8.8.0(eslint@8.45.0) + eslint-plugin-import: + specifier: ^2.27.5 + version: 2.27.5(eslint@8.45.0) + glob: + specifier: ^10.3.3 + version: 10.3.3 + prettier: + specifier: ^3.0.0 + version: 3.0.0 + +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.18 + dev: true + + /@babel/code-frame@7.21.4: + resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/code-frame@7.22.5: + resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.5 + 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.9: + resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helpers': 7.22.6 + '@babel/parser': 7.22.7 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 + '@babel/types': 7.22.5 + 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.9: + resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.5: + resolution: {integrity: sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-validator-option': 7.22.5 + browserslist: 4.21.9 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.21.8(@babel/core@7.22.9): + resolution: {integrity: sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.4.1(@babel/core@7.22.9): + resolution: {integrity: sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.2 + transitivePeerDependencies: + - supports-color + 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.5 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-member-expression-to-functions@7.22.5: + resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + 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.5 + dev: true + + /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@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-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 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-remap-async-to-generator@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-wrap-function': 7.22.9 + dev: true + + /@babel/helper-replace-supers@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + 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.5 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + 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.5 + dev: true + + /@babel/helper-string-parser@7.21.5: + resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} + engines: {node: '>=6.9.0'} + 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.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + 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/helper-wrap-function@7.22.9: + resolution: {integrity: sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.22.5 + '@babel/template': 7.22.5 + '@babel/types': 7.22.5 + dev: true + + /@babel/helpers@7.22.6: + resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/highlight@7.22.5: + resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} + 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.21.8: + resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/parser@7.22.7: + resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9) + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + dev: true + + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.9): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.9): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.22.7(@babel/core@7.22.9): + resolution: {integrity: sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-block-scoping@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-static-block@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-classes@7.22.6(@babel/core@7.22.9): + resolution: {integrity: sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + dev: true + + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.5 + dev: true + + /@babel/plugin-transform-destructuring@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dynamic-import@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-flow-strip-types@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-for-of@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-function-name': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-json-strings@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-systemjs@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-numeric-separator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-optional-chaining@7.22.6(@babel/core@7.22.9): + resolution: {integrity: sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-property-in-object@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-regenerator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-escapes@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/preset-env@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.9) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-async-generator-functions': 7.22.7(@babel/core@7.22.9) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.9) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-regenerator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-escapes': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.9) + '@babel/preset-modules': 0.1.5(@babel/core@7.22.9) + '@babel/types': 7.22.5 + babel-plugin-polyfill-corejs2: 0.4.4(@babel/core@7.22.9) + babel-plugin-polyfill-corejs3: 0.8.2(@babel/core@7.22.9) + babel-plugin-polyfill-regenerator: 0.5.1(@babel/core@7.22.9) + core-js-compat: 3.31.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules@0.1.5(@babel/core@7.22.9): + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9) + '@babel/types': 7.22.5 + esutils: 2.0.3 + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.21.5: + resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + dev: true + + /@babel/template@7.22.5: + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.5 + '@babel/parser': 7.22.7 + '@babel/types': 7.22.5 + dev: true + + /@babel/traverse@7.22.8: + resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 + '@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.7 + '@babel/types': 7.22.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.21.5: + resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.21.5 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + + /@babel/types@7.22.5: + resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} + 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 + + /@esbuild/android-arm64@0.18.14: + resolution: {integrity: sha512-rZ2v+Luba5/3D6l8kofWgTnqE+qsC/L5MleKIKFyllHTKHrNBMqeRCnZI1BtRx8B24xMYxeU32iIddRQqMsOsg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.14: + resolution: {integrity: sha512-blODaaL+lngG5bdK/t4qZcQvq2BBqrABmYwqPPcS5VRxrCSGHb9R/rA3fqxh7R18I7WU4KKv+NYkt22FDfalcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.14: + resolution: {integrity: sha512-qSwh8y38QKl+1Iqg+YhvCVYlSk3dVLk9N88VO71U4FUjtiSFylMWK3Ugr8GC6eTkkP4Tc83dVppt2n8vIdlSGg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.14: + resolution: {integrity: sha512-9Hl2D2PBeDYZiNbnRKRWuxwHa9v5ssWBBjisXFkVcSP5cZqzZRFBUWEQuqBHO4+PKx4q4wgHoWtfQ1S7rUqJ2Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.14: + resolution: {integrity: sha512-ZnI3Dg4ElQ6tlv82qLc/UNHtFsgZSKZ7KjsUNAo1BF1SoYDjkGKHJyCrYyWjFecmXpvvG/KJ9A/oe0H12odPLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.14: + resolution: {integrity: sha512-h3OqR80Da4oQCIa37zl8tU5MwHQ7qgPV0oVScPfKJK21fSRZEhLE4IIVpmcOxfAVmqjU6NDxcxhYaM8aDIGRLw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.14: + resolution: {integrity: sha512-ha4BX+S6CZG4BoH9tOZTrFIYC1DH13UTCRHzFc3GWX74nz3h/N6MPF3tuR3XlsNjMFUazGgm35MPW5tHkn2lzQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.14: + resolution: {integrity: sha512-IXORRe22In7U65NZCzjwAUc03nn8SDIzWCnfzJ6t/8AvGx5zBkcLfknI+0P+hhuftufJBmIXxdSTbzWc8X/V4w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.14: + resolution: {integrity: sha512-5+7vehI1iqru5WRtJyU2XvTOvTGURw3OZxe3YTdE9muNNIdmKAVmSHpB3Vw2LazJk2ifEdIMt/wTWnVe5V98Kg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.14: + resolution: {integrity: sha512-BfHlMa0nibwpjG+VXbOoqJDmFde4UK2gnW351SQ2Zd4t1N3zNdmUEqRkw/srC1Sa1DRBE88Dbwg4JgWCbNz/FQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.14: + resolution: {integrity: sha512-j2/Ex++DRUWIAaUDprXd3JevzGtZ4/d7VKz+AYDoHZ3HjJzCyYBub9CU1wwIXN+viOP0b4VR3RhGClsvyt/xSw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.14: + resolution: {integrity: sha512-qn2+nc+ZCrJmiicoAnJXJJkZWt8Nwswgu1crY7N+PBR8ChBHh89XRxj38UU6Dkthl2yCVO9jWuafZ24muzDC/A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.14: + resolution: {integrity: sha512-aGzXzd+djqeEC5IRkDKt3kWzvXoXC6K6GyYKxd+wsFJ2VQYnOWE954qV2tvy5/aaNrmgPTb52cSCHFE+Z7Z0yg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.14: + resolution: {integrity: sha512-8C6vWbfr0ygbAiMFLS6OPz0BHvApkT2gCboOGV76YrYw+sD/MQJzyITNsjZWDXJwPu9tjrFQOVG7zijRzBCnLw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.14: + resolution: {integrity: sha512-G/Lf9iu8sRMM60OVGOh94ZW2nIStksEcITkXdkD09/T6QFD/o+g0+9WVyR/jajIb3A0LvBJ670tBnGe1GgXMgw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.14: + resolution: {integrity: sha512-TBgStYBQaa3EGhgqIDM+ECnkreb0wkcKqL7H6m+XPcGUoU4dO7dqewfbm0mWEQYH3kzFHrzjOFNpSAVzDZRSJw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.14: + resolution: {integrity: sha512-stvCcjyCQR2lMTroqNhAbvROqRjxPEq0oQ380YdXxA81TaRJEucH/PzJ/qsEtsHgXlWFW6Ryr/X15vxQiyRXVg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.14: + resolution: {integrity: sha512-apAOJF14CIsN5ht1PA57PboEMsNV70j3FUdxLmA2liZ20gEQnfTG5QU0FhENo5nwbTqCB2O3WDsXAihfODjHYw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.14: + resolution: {integrity: sha512-fYRaaS8mDgZcGybPn2MQbn1ZNZx+UXFSUoS5Hd2oEnlsyUcr/l3c6RnXf1bLDRKKdLRSabTmyCy7VLQ7VhGdOQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.14: + resolution: {integrity: sha512-1c44RcxKEJPrVj62XdmYhxXaU/V7auELCmnD+Ri+UCt+AGxTvzxl9uauQhrFso8gj6ZV1DaORV0sT9XSHOAk8Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.14: + resolution: {integrity: sha512-EXAFttrdAxZkFQmpvcAQ2bywlWUsONp/9c2lcfvPUhu8vXBBenCXpoq9YkUvVP639ld3YGiYx0YUQ6/VQz3Maw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.14: + resolution: {integrity: sha512-K0QjGbcskx+gY+qp3v4/940qg8JitpXbdxFhRDA1aYoNaPff88+aEwoq45aqJ+ogpxQxmU0ZTjgnrQD/w8iiUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.45.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.45.0 + eslint-visitor-keys: 3.4.1 + dev: true + + /@eslint-community/regexpp@4.5.1: + resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.0: + resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} + 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.20.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.44.0: + resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} + 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 + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.0.1 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + 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.18 + dev: true + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + 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.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@nicolo-ribaudo/semver-v6@6.3.3: + resolution: {integrity: sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==} + hasBin: true + 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 + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@types/babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-kxYWx+NISzy46KMgnXUthHJNbcGw9w1jn6e1LZAciTv8KKO5z9z1LakHnXCj5aYrwydZ5dGE3MAgEu4X/MdWkA==} + dependencies: + '@types/babel__core': 7.20.1 + dev: true + + /@types/babel__core@7.20.1: + resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} + dependencies: + '@babel/parser': 7.21.8 + '@babel/types': 7.21.5 + '@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.21.5 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.21.8 + '@babel/types': 7.21.5 + dev: true + + /@types/babel__traverse@7.20.1: + resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/node@20.4.2: + resolution: {integrity: sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==} + dev: true + + /@types/parse-json@4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + 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@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + 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 + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + 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@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + 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-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.21.2 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + 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.21.2 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap@1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + es-shim-unscopables: 1.0.0 + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.21.5 + cosmiconfig: 7.1.0 + resolve: 1.22.2 + dev: true + + /babel-plugin-polyfill-corejs2@0.4.4(@babel/core@7.22.9): + resolution: {integrity: sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9) + '@nicolo-ribaudo/semver-v6': 6.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.8.2(@babel/core@7.22.9): + resolution: {integrity: sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9) + core-js-compat: 3.31.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.5.1(@babel/core@7.22.9): + resolution: {integrity: sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.1(@babel/core@7.22.9) + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + 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 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /browserslist@4.21.9: + resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001516 + electron-to-chromium: 1.4.463 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.9) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + 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 + + /caniuse-lite@1.0.30001516: + resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==} + 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 + + /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 + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /core-js-compat@3.31.1: + resolution: {integrity: sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==} + dependencies: + browserslist: 4.21.9 + dev: true + + /cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + 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 + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + 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 + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + 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 + + /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 + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /electron-to-chromium@1.4.463: + resolution: {integrity: sha512-fT3hvdUWLjDbaTGzyOjng/CQhQJSQP8ThO3XZAoaxHvHo2kUXiRQVMj9M235l8uDFiNPsPa6KHT1p3RaR6ugRw==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + 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.21.2: + resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + 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.10 + 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-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-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + 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 + + /esbin@0.0.1-beta.1(esbuild@0.18.14): + resolution: {integrity: sha512-rRsTEauPQz1f0UyqeRu5IxF6XHZ5lo4qcftYe6WzheyEr3Q9Lap8KgqH+fVOANQQqfD4D6I8duo4mrXh3yNfLA==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.18.14 + joycon: 3.1.1 + pirates: 4.0.6 + source-map: 0.7.4 + source-map-support: 0.5.21 + tsconfig-paths: 4.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + dev: true + + /esbuild-register@3.4.2(esbuild@0.18.14): + resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.18.14 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild@0.18.14: + resolution: {integrity: sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.14 + '@esbuild/android-arm64': 0.18.14 + '@esbuild/android-x64': 0.18.14 + '@esbuild/darwin-arm64': 0.18.14 + '@esbuild/darwin-x64': 0.18.14 + '@esbuild/freebsd-arm64': 0.18.14 + '@esbuild/freebsd-x64': 0.18.14 + '@esbuild/linux-arm': 0.18.14 + '@esbuild/linux-arm64': 0.18.14 + '@esbuild/linux-ia32': 0.18.14 + '@esbuild/linux-loong64': 0.18.14 + '@esbuild/linux-mips64el': 0.18.14 + '@esbuild/linux-ppc64': 0.18.14 + '@esbuild/linux-riscv64': 0.18.14 + '@esbuild/linux-s390x': 0.18.14 + '@esbuild/linux-x64': 0.18.14 + '@esbuild/netbsd-x64': 0.18.14 + '@esbuild/openbsd-x64': 0.18.14 + '@esbuild/sunos-x64': 0.18.14 + '@esbuild/win32-arm64': 0.18.14 + '@esbuild/win32-ia32': 0.18.14 + '@esbuild/win32-x64': 0.18.14 + 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@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-prettier@8.8.0(eslint@8.45.0): + resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.45.0 + dev: true + + /eslint-import-resolver-node@0.3.7: + resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} + dependencies: + debug: 3.2.7 + is-core-module: 2.12.1 + resolve: 1.22.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.45.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.45.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-import@2.27.5(eslint@8.45.0): + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + 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 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.45.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.45.0) + has: 1.0.3 + is-core-module: 2.12.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.2 + semver: 6.3.0 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-scope@7.2.0: + resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.1: + resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.45.0: + resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) + '@eslint-community/regexpp': 4.5.1 + '@eslint/eslintrc': 2.1.0 + '@eslint/js': 8.44.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.0 + eslint-visitor-keys: 3.4.1 + 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.20.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.1 + 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 + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + 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 + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + 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 + + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + 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 + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.0.2 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: 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.21.2 + 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-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-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 + + /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@10.3.3: + resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.2.1 + minimatch: 9.0.1 + minipass: 6.0.2 + path-scurry: 1.10.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 + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + 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 + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + 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@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + 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 + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + 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 + + /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 + + /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.10 + 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-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.12.1: + resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + dependencies: + has: 1.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-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + 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-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + 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-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-typed-array@1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + 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 + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /jackspeak@2.2.1: + resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + 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 + + /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 + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@9.1.1: + resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==} + engines: {node: 14 || >=16.14} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@6.0.2: + resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + 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.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.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.21.2 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + 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 + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.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 + + /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@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.21.4 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + 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-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 9.1.1 + minipass: 6.0.2 + 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 + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@3.0.0: + resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /regenerate-unicode-properties@10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-transform@0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.21.5 + 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 + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + dependencies: + is-core-module: 2.12.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + 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-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + 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 + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + 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@4.0.2: + resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + engines: {node: '>=14'} + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + 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-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.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.21.2 + 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.21.2 + 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.21.2 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi@7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + 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-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + 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 + + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + 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-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + 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.10 + dev: 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 + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.9): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.9 + 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 + + /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.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + 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 + is-typed-array: 1.1.10 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + 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 + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/save_patch.sh b/save_patch.sh new file mode 100755 index 0000000..e1a8d8b --- /dev/null +++ b/save_patch.sh @@ -0,0 +1,9 @@ +#!/bin/bash +sync() ( + cd "$1" && git diff > "../patch/$1.patch" +) + +sync eslint-plugin-import +sync eslint-plugin-jsx-a11y +sync eslint-plugin-react +sync jsx-ast-utils diff --git a/src/babel.ts b/src/babel.ts new file mode 100644 index 0000000..ea902ad --- /dev/null +++ b/src/babel.ts @@ -0,0 +1,156 @@ +import assert from 'node:assert'; +import { readFileSync } from 'node:fs'; +import { extname } from 'node:path'; +import * as babel from '@babel/core'; +import type { types as t } from '@babel/core'; +import type { Loader, Plugin } from 'esbuild'; +import { createMacro, type MacroHandler } from 'babel-plugin-macros'; + +class HandlerMap { + map = new Map(); + + set(names: string | string[], handler: MacroHandler) { + names = Array.isArray(names) ? names : [names]; + const macro = createMacro(handler); + for (const name of names) { + this.map.set(name, macro); + } + return this; + } + + get keys() { + return Array.from(this.map.keys()); + } + + resolvePath = (module: string) => module; + require = (module: string) => this.map.get(module); + isMacrosName = (module: string) => this.map.has(module); +} + +const map = new HandlerMap() + .set( + 'object.assign', + replace(t => t.memberExpression(t.identifier('Object'), t.identifier('assign'))), + ) + .set( + ['object-values', 'object.values'], + replace(t => t.memberExpression(t.identifier('Object'), t.identifier('values'))), + ) + .set( + 'object.fromentries', + replace(t => t.memberExpression(t.identifier('Object'), t.identifier('fromEntries'))), + ) + .set( + 'object.entries', + replace(t => t.memberExpression(t.identifier('Object'), t.identifier('entries'))), + ) + .set( + 'has', + replace(t => t.memberExpression(t.identifier('Object'), t.identifier('hasOwn'))), + ) + .set( + 'array-includes', + proto(t => t.identifier('includes')), + ) + .set( + 'array.prototype.flatmap', + proto(t => t.identifier('flatMap')), + ) + .set( + 'array.prototype.flat', + proto(t => t.identifier('flat')), + ) + .set( + 'array.prototype.findlastindex', + proto(t => t.identifier('findLastIndex')), + ) + .set( + 'array.prototype.tosorted', + proto(t => t.identifier('toSorted')), + ) + .set( + 'string.prototype.matchall', + proto(t => t.identifier('matchAll')), + ); + +function replace(getReplacement: (types: typeof t) => t.Expression): MacroHandler { + return ({ references, babel: { types: t } }) => { + references.default.forEach(referencePath => { + referencePath.replaceWith(getReplacement(t)); + }); + }; +} + +function proto(getProperty: (types: typeof t) => t.Expression): MacroHandler { + return ({ references, babel: { types: t } }) => { + references.default.forEach(referencePath => { + const { parent, parentPath } = referencePath; + assert(t.isCallExpression(parent)); + const [callee, ...rest] = parent.arguments; + parentPath!.replaceWith( + t.callExpression( + t.memberExpression(callee as t.Expression, getProperty(t)), + rest, + ), + ); + }); + }; +} + +export const babelPlugin: Plugin = { + name: 'babel', + setup(build) { + const { keys, ...macroOptions } = map; + + build.onLoad({ filter: /\.[jt]sx?$/ }, args => { + const { path } = args; + if (path.includes('node_modules/')) { + return null; + } + + let source = readFileSync(path, 'utf-8') + .replaceAll("require('object.hasown/polyfill')()", 'Object.hasOwn') + .replaceAll("require('object.fromentries/polyfill')()", 'Object.fromEntries'); + + if ( + path.includes('eslint-plugin-import/src/rules/') || + path.includes('eslint-plugin-import/config/') + ) { + source = source.replace('\nmodule.exports = {', '\nexport default {'); + } + + const isFlow = source.includes('@flow'); + const loader = extname(path).slice(1) as Loader; + + if (!isFlow && !keys.some(key => source.includes(key))) { + return { contents: source, loader }; + } + + const res = babel.transformSync(source, { + filename: path, + babelrc: false, + configFile: false, + parserOpts: { + plugins: [isFlow ? 'flow' : 'typescript'], + }, + plugins: [ + isFlow && '@babel/plugin-transform-flow-strip-types', + ['babel-plugin-macros', macroOptions], + ].filter(Boolean), + })!; + + return { + contents: res.code!, + loader, + }; + }); + }, +}; + +declare global { + interface Array { + filter( + predicate: BooleanConstructor, + ): Exclude[]; + } +} diff --git a/src/rules/no-import-dot.ts b/src/rules/no-import-dot.ts new file mode 100644 index 0000000..52762bd --- /dev/null +++ b/src/rules/no-import-dot.ts @@ -0,0 +1,39 @@ +import type { Rule } from "eslint"; + +const rule: Rule.RuleModule = { + meta: { + type: "problem", + docs: { + description: + "Bans import from the specifier '.' and '..' and replaces it with '.+/index'", + category: "Best Practices", + recommended: true, + }, + fixable: "code", + }, + create: context => ({ + ImportDeclaration(node) { + if (node.source.value === ".") { + context.report({ + node: node.source, + message: + "Importing from the specifier '.' is not allowed. Use './index' instead.", + fix(fixer) { + return fixer.replaceText(node.source, '"./index"'); + }, + }); + } else if (node.source.value === "..") { + context.report({ + node: node.source, + message: + "Importing from the specifier '..' is not allowed. Use '../index' instead.", + fix(fixer) { + return fixer.replaceText(node.source, '"../index"'); + }, + }); + } + }, + }), +}; + +export default rule; diff --git a/src/rules/no-new-prisma.ts b/src/rules/no-new-prisma.ts new file mode 100644 index 0000000..a53f4b6 --- /dev/null +++ b/src/rules/no-new-prisma.ts @@ -0,0 +1,32 @@ +import type { Rule } from "eslint"; + +const rule: Rule.RuleModule = { + meta: { + type: "problem", + docs: { + description: "Disallow direct usage of `new PrismaClient()`", + category: "Best Practices", + recommended: true, + }, + }, + create(context) { + // Check if the file is the target file where the import is allowed + if (context.filename.endsWith("src/utils/db.ts")) { + return {}; + } + + return { + NewExpression(node) { + if (node.callee.type === "Identifier" && node.callee.name === "PrismaClient") { + context.report({ + node, + message: + "Avoid direct usage of `new PrismaClient()`. Import from `src/utils/db.ts` instead.", + }); + } + }, + }; + }, +}; + +export default rule; diff --git a/src/rules/no-webcrypto-import.ts b/src/rules/no-webcrypto-import.ts new file mode 100644 index 0000000..d2926eb --- /dev/null +++ b/src/rules/no-webcrypto-import.ts @@ -0,0 +1,33 @@ +import type { Rule } from "eslint"; + +const rule: Rule.RuleModule = { + meta: { + type: "problem", + docs: { + description: "Disallow importing webcrypto from node:crypto and crypto modules", + category: "Best Practices", + recommended: true, + }, + schema: [], + }, + create: context => ({ + ImportDeclaration(node) { + const importedSource = node.source.value as string; + const importedSpecifier = node.specifiers[0]; + + if ( + (importedSource === "crypto" || importedSource === "node:crypto") && + importedSpecifier.type === "ImportSpecifier" && + importedSpecifier.local.name === "webcrypto" + ) { + context.report({ + node: importedSpecifier, + message: + "Do not import 'webcrypto' from 'crypto' or 'node:crypto'. Use the global variable 'crypto' instead.", + }); + } + }, + }), +}; + +export default rule; diff --git a/src/rules/require-node-prefix.ts b/src/rules/require-node-prefix.ts new file mode 100644 index 0000000..9df5d61 --- /dev/null +++ b/src/rules/require-node-prefix.ts @@ -0,0 +1,36 @@ +// @ts-check +import { builtinModules } from "node:module"; +import type { Rule } from "eslint"; + +const rule: Rule.RuleModule = { + meta: { + type: "problem", + docs: { + description: + "Disallow imports of built-in Node.js modules without the `node:` prefix", + category: "Best Practices", + recommended: true, + }, + fixable: "code", + schema: [], + }, + create: context => ({ + ImportDeclaration(node) { + const { source } = node; + + if (source?.type === "Literal" && typeof source.value === "string") { + const moduleName = source.value; + + if (builtinModules.includes(moduleName) && !moduleName.startsWith("node:")) { + context.report({ + node: source, + message: `Import of built-in Node.js module "${moduleName}" must use the "node:" prefix.`, + fix: fixer => fixer.replaceText(source, `"node:${moduleName}"`), + }); + } + } + }, + }), +}; + +export default rule; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7a68fba --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowArbitraryExtensions": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "jsx": "react-jsx", + "module": "commonjs", + "moduleResolution": "bundler", + "noImplicitOverride": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "strict": true, + "stripInternal": true, + "target": "esnext", + "useUnknownInCatchVariables": false + }, + "ts-node": { + "transpileOnly": true, + "compilerOptions": { + "module": "commonjs" + } + } +}