diff --git a/__tests__/require-memo.ts b/__tests__/require-memo.ts
index c360228..eaa5e24 100644
--- a/__tests__/require-memo.ts
+++ b/__tests__/require-memo.ts
@@ -1,5 +1,6 @@
import { RuleTester } from "eslint";
import rule from "../require-memo";
+import { normalizeIndent } from '../utils';
const ruleTester = new RuleTester({
parser: require.resolve("@typescript-eslint/parser"),
@@ -11,72 +12,130 @@ const ruleTester = new RuleTester({
ruleTester.run("memo", rule, {
valid: [
{
- code: `const Component = React.memo(() =>
)`,
+ code: normalizeIndent`
+ const Component = memo(() => )
+ `,
},
{
- code: `const Component = memo(() => )`,
+ code: normalizeIndent`
+ const Component = memo(() => )
+ `,
},
{
- code: `const Component = memo(useRef(() => ))`,
+ code: normalizeIndent`
+ const Component = memo(useRef(() => ))
+ `,
},
{
- code: `const Component = React.useRef(React.memo(() => ))`,
+ code: normalizeIndent`
+ const Component = useRef(memo(() => ))
+ `,
},
{
- code: `const myFunction = () => `,
+ code: normalizeIndent`
+ const myFunction = () =>
+ `,
},
{
- code: `const myFunction = wrapper(() => )`,
+ code: normalizeIndent`
+ const myFunction = wrapper(() => )
+ `,
},
{
- code: `const Component = React.memo(function() { return ; });`,
+ code: normalizeIndent`
+ const Component = memo(function() { return ; });
+ `,
},
{
- code: `const Component = memo(function Component() { return ; });`,
+ code: normalizeIndent`
+ const Component = memo(function Component() { return ; });
+ `,
},
{
- code: `const myFunction = () => `,
+ code: normalizeIndent`
+ const myFunction = () =>
+ `,
},
{
- code: `const myFunction = wrapper(() => )`,
+ code: normalizeIndent`
+ const myFunction = wrapper(() => )
+ `,
},
{
- code: `function myFunction() { return ; }`,
+ code: normalizeIndent`
+ function myFunction() { return ; }
+ `,
},
{
- code: `const myFunction = wrapper(function() { return })`,
+ code: normalizeIndent`
+ const myFunction = wrapper(function() { return })
+ `,
},
{
filename: "dir/myFunction.js",
parserOptions: { ecmaVersion: 6, sourceType: "module" },
- code: `export default function() { return };`,
+ code: normalizeIndent`
+ export default function() { return };
+ `,
},
],
invalid: [
{
- code: `const Component = () => `,
+ code: `import { memo } from 'react'
+const Component = () => `,
errors: [{ messageId: "memo-required" }],
+ output: `import { memo } from 'react'
+const Component = memo(() => )`
},
{
- code: `const Component = useRef(() => )`,
+ code: `// @flow
+ import { map } from 'lodash'
+const Component = useRef(() => )`,
errors: [{ messageId: "memo-required" }],
- },
- {
- code: `const Component = function Component() { return ; }`,
- errors: [{ messageId: "memo-required" }],
- },
- {
- code: `const Component = useRef(function() { return ; })`,
+ output: `// @flow
+import { memo } from 'react'
+ import { map } from 'lodash'
+const Component = memo(useRef(() => ))`
+ },
+// {
+// code: `const Component = function Component() { return ; }`,
+// errors: [{ messageId: "memo-required" }],
+// output: `import { memo } from 'react'
+// const Component = memo(function Component() { return ; })`
+// },
+// {
+// code: `const Component = useRef(function() { return ; })`,
+// errors: [{ messageId: "memo-required" }],
+// output: `import { memo } from 'react'
+// const Component = useRef(memo(function() { return ; }))`
+// },
+ {
+ code: `// @flow
+import { map } from 'lodash'
+
+console.warn('Hello World')
+function Component() { return ; }`,
errors: [{ messageId: "memo-required" }],
+ output: `// @flow
+import { memo } from 'react'
+import { map } from 'lodash'
+
+console.warn('Hello World')
+memo(function Component() { return ; })`
},
{
- code: `function Component() { return ; }`,
+ code: `import { memo } from 'react'
+
+function Component() { return ; }`,
errors: [{ messageId: "memo-required" }],
+ output: `import { memo } from 'react'
+
+memo(function Component() { return ; })`
},
// {
// filename: "dir/Component.js",
// parserOptions: { ecmaVersion: 6, sourceType: "module" },
- // code: `export default function() { return };`,
+ // code: export default function() { return };,
// errors: [{ messageId: "memo-required" }],
// },
],
diff --git a/__tests__/require-usecallback.ts b/__tests__/require-usecallback.ts
index 6c3726e..368fe6e 100644
--- a/__tests__/require-usecallback.ts
+++ b/__tests__/require-usecallback.ts
@@ -1,5 +1,6 @@
import { RuleTester } from "eslint";
import rule from "../require-usememo";
+import { normalizeIndent } from '../utils';
const ruleTester = new RuleTester({
parser: require.resolve("@typescript-eslint/parser"),
@@ -11,114 +12,262 @@ const ruleTester = new RuleTester({
ruleTester.run("useCallback", rule, {
valid: [
{
- code: `const Component = () => {
- const myFn = React.useCallback(function() {}, []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = useCallback(function() {}, []);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn = useCallback(() => {}, []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = useCallback(() => {}, []);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn = function() {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = function() {};
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn = () => {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = () => {};
+ return ;
+ }
+ `,
},
{
- code: `
- const myFn = () => {};
- const Component = () => {
- return ;
- }`,
+ code: normalizeIndent`
+ const myFn = () => {};
+ const Component = () => {
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn1 = useCallback(() => [], []);
- const myFn2 = React.useCallback(() => myFn1, [myFn1]);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn1 = useCallback(() => [], []);
+ const myFn2 = useCallback(() => myFn1, [myFn1]);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn = memoize(() => {});
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = memoize(() => {});
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myFn = lodash.memoize(() => []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = lodash.memoize(() => []);
+ return ;
+ }
+ `,
},
],
invalid: [
{
- code: `const Component = () => {
- const myFn = function myFn() {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = function myFn() {};
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myFn = useCallback(function() {}, []);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "function-usecallback-props" }],
},
{
- code: `const Component = () => {
- const myFn = () => {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = () => {};
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myFn = useCallback(() => {}, []);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "function-usecallback-props" }],
},
+ // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- let myFn = useCallback(() => ({}));
- myFn = () => ({});
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ let myFn = useCallback(() => ({}));
+ myFn = () => ({});
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // let myFn = useCallback(() => ({}));
+ // myFn = () => ({});
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "usememo-const" }],
},
+ // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- return {}} />;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ return {}} />;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // return {}} />;
+ // }
+ // `,
errors: [{ messageId: "function-usecallback-props" }],
},
+ // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- return []} />;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ return []} />;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // return []} />;
+ // }
+ // `,
errors: [{ messageId: "function-usecallback-props" }],
},
+ // // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- const myFn = memoize(() => {});
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = memoize(() => {});
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myFn = memoize(() => {});
+ // return ;
+ // }
+ // `,
options: [{ strict: true }],
errors: [{ messageId: "unknown-usememo-props" }],
},
+ // // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- const myFn = lodash.memoize(() => []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn = lodash.memoize(() => []);
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myFn = lodash.memoize(() => []);
+ // return ;
+ // }
+ // `,
options: [{ strict: true }],
errors: [{ messageId: "unknown-usememo-props" }],
},
+ // // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- const myFn1 = () => [];
- const myFn2 = React.useCallback(() => myFn1, [myFn1]);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myFn1 = () => [];
+ const myFn2 = useCallback(() => myFn1, [myFn1]);
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myFn1 = () => [];
+ // const myFn2 = useCallback(() => myFn1, [myFn1]);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "function-usecallback-deps" }],
},
+ // {
+ // code: normalizeIndent`
+ // // @flow
+ // import { d2Uri } from 'd2/utils/Routes'
+ // import { prettyNumber } from '@vydia/js-core'
+ // import { useHistory } from 'react-router'
+ // import { useIsLabel } from 'd2/hooks/useIsLabel'
+ // import { useOrganizationTotalConflictsBoxQuery, useUserTotalConflictsBoxQuery } from './queries'
+ // import SummaryBox from 'd2/components/SummaryBox'
+ // import useTranslations from './translations'
+ // import type { StatelessFunctionalComponent } from 'react'
+
+ // const TotalConflictsBox: StatelessFunctionalComponent<{}> = () => {
+ // const [isLabel] = useIsLabel()
+ // const [organizationData] = useOrganizationTotalConflictsBoxQuery({ isLabel })
+ // const [userData] = useUserTotalConflictsBoxQuery({ isLabel })
+ // const t = useTranslations()
+ // const history = useHistory()
+
+ // const data = isLabel ? organizationData : userData
+ // return ( history.push(d2Uri('/insights/conflicts'))}
+ // testID='WidgetDashboard-TotalConflictsBox'
+ // title={isLabel ? t.labelTotalConflicts : t.userTotalConflicts}
+ // value={data && prettyNumber(data.totalConflicts)}
+ // />)
+ // }
+
+ // export default TotalConflictsBox
+ // `,
+ // output: normalizeIndent`
+ // // @flow
+ // import { d2Uri } from 'd2/utils/Routes'
+ // import { prettyNumber } from '@vydia/js-core'
+ // import { useHistory } from 'react-router'
+ // import { useIsLabel } from 'd2/hooks/useIsLabel'
+ // import { useOrganizationTotalConflictsBoxQuery, useUserTotalConflictsBoxQuery } from './queries'
+ // import SummaryBox from 'd2/components/SummaryBox'
+ // import useTranslations from './translations'
+ // import type { StatelessFunctionalComponent } from 'react'
+
+ // const TotalConflictsBox: StatelessFunctionalComponent<{}> = () => {
+ // const [isLabel] = useIsLabel()
+ // const [organizationData] = useOrganizationTotalConflictsBoxQuery({ isLabel })
+ // const [userData] = useUserTotalConflictsBoxQuery({ isLabel })
+ // const t = useTranslations()
+ // const history = useHistory()
+
+ // const data = isLabel ? organizationData : userData
+ // return ( history.push(d2Uri('/insights/conflicts'))}
+ // testID='WidgetDashboard-TotalConflictsBox'
+ // title={isLabel ? t.labelTotalConflicts : t.userTotalConflicts}
+ // value={data && prettyNumber(data.totalConflicts)}
+ // />)
+ // }
+
+ // export default TotalConflictsBox
+ // `,
+ // errors: [{ messageId: "function-usecallback-props"}]
+ // }
],
});
diff --git a/__tests__/require-usememo-children.ts b/__tests__/require-usememo-children.ts
index ec7c8f5..696e246 100644
--- a/__tests__/require-usememo-children.ts
+++ b/__tests__/require-usememo-children.ts
@@ -12,7 +12,7 @@ ruleTester.run("useMemo children", rule, {
valid: [
{
code: `const Component = () => {
- const children = React.useMemo(() =>
, []);
+ const children = useMemo(() =>
, []);
return {children};
}`,
},
@@ -23,7 +23,7 @@ ruleTester.run("useMemo children", rule, {
},
{
code: `const Component = () => {
- const renderFn = React.useCallback(() =>
, []);
+ const renderFn = useCallback(() =>
, []);
return {renderFn};
}`,
},
@@ -31,7 +31,7 @@ ruleTester.run("useMemo children", rule, {
invalid: [
{
code: `const Component = () => {
- const children = React.useMemo(() =>
, []);
+ const children = useMemo(() =>
, []);
return
<>
{children}
diff --git a/__tests__/require-usememo.ts b/__tests__/require-usememo.ts
index cbe60de..856dc8b 100644
--- a/__tests__/require-usememo.ts
+++ b/__tests__/require-usememo.ts
@@ -1,5 +1,6 @@
import { RuleTester } from "eslint";
import rule from "../require-usememo";
+import { normalizeIndent } from '../utils';
const ruleTester = new RuleTester({
parser: require.resolve("@typescript-eslint/parser"),
@@ -11,134 +12,239 @@ const ruleTester = new RuleTester({
ruleTester.run("useMemo", rule, {
valid: [
{
- code: `const Component = () => {
- const myObject = React.useMemo(() => ({}), []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myObject = useMemo(() => ({}), []);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myArray = useMemo(() => [], []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = useMemo(() => [], []);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myArray = React.useMemo(() => new Object(), []);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = useMemo(() => new Object(), []);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myObject = {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myObject = {};
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myArray = [];
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = [];
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myNumber1 = 123;
- const myNumber2 = 123 + 456;
- const myString1 = 'abc';
- const myString2 = \`abc\`;
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myNumber1 = 123;
+ const myNumber2 = 123 + 456;
+ const myString1 = 'abc';
+ const myString2 = \`abc\`;
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myObject = memoize({});
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myObject = memoize({});
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myArray = lodash.memoize([]);
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = lodash.memoize([]);
+ return ;
+ }
+ `,
},
{
- code: `const Component = () => {
- const myComplexString = css\`color: red;\`;
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myComplexString = css\`color: red;\`;
+ return ;
+ }
+ `,
},
],
invalid: [
{
- code: `const Component = () => {
- const myObject = {};
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myObject = {};
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myObject = useMemo(() => ({}), []);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "object-usememo-props" }],
},
{
- code: `const Component = () => {
- const myArray = [];
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = [];
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myArray = useMemo(() => [], []);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "array-usememo-props" }],
},
{
- code: `const Component = () => {
- const myInstance = new Object();
- return ;
- }`,
+ code: normalizeIndent`
+ const Component = () => {
+ const myInstance = new Object();
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myInstance = useMemo(() => new Object(), []);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "instance-usememo-props" }],
},
- {
- code: `const Component = () => {
- let myObject = useMemo({});
- myObject = {a: 'b'};
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ let myObject = useMemo({});
+ myObject = {a: 'b'};
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // let myObject = useMemo({});
+ // myObject = {a: 'b'};
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "usememo-const" }],
},
- {
- code: `const Component = () => {
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "object-usememo-props" }],
},
- {
- code: `const Component = () => {
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "array-usememo-props" }],
},
- {
- code: `const Component = () => {
- const myObject = memoize({});
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ const myObject = memoize({});
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myObject = memoize({});
+ // return ;
+ // }
+ // `,
options: [{ strict: true }],
errors: [{ messageId: "unknown-usememo-props" }],
},
+ // TODO: setup fixer for the following spec (output currently matches code)
{
- code: `const Component = () => {
- const myArray = lodash.memoize([]);
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray = lodash.memoize([]);
return ;
- }`,
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myArray = lodash.memoize([]);
+ // return ;
+ // }
+ // `,
options: [{ strict: true }],
errors: [{ messageId: "unknown-usememo-props" }],
},
- {
- code: `const Component = () => {
- const myArray1 = [];
- const myArray2 = React.useMemo(() => myArray1, [myArray1]);
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ const myArray1 = [];
+ const myArray2 = useMemo(() => myArray1, [myArray1]);
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myArray1 = [];
+ // const myArray2 = useMemo(() => myArray1, [myArray1]);
+ // return ;
+ // }
+ // `,
errors: [{ messageId: "array-usememo-deps" }],
},
- {
- code: `const Component = () => {
- const myComplexString = css\`color: red;\`;
- return ;
- }`,
+ // TODO: setup fixer for the following spec (output currently matches code)
+ {
+ code: normalizeIndent`
+ const Component = () => {
+ const myComplexString = css\`color: red;\`;
+ return ;
+ }
+ `,
+ // output: normalizeIndent`
+ // const Component = () => {
+ // const myComplexString = css\`color: red;\`;
+ // return ;
+ // }
+ // `,
options: [{ strict: true }],
errors: [{ messageId: "unknown-usememo-props" }],
},
diff --git a/common.ts b/common.ts
index 4512d15..4fb0bc2 100644
--- a/common.ts
+++ b/common.ts
@@ -61,7 +61,7 @@ export function getExpressionMemoStatus(
context: Rule.RuleContext,
expression: TSESTree.Expression
): MemoStatus {
- switch (expression.type) {
+ switch (expression?.type) {
case "ObjectExpression":
return MemoStatus.UnmemoizedObject;
case "ArrayExpression":
diff --git a/package.json b/package.json
index 471d2f5..e62ba0a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-react-memo",
- "version": "0.0.3",
+ "version": "0.0.11",
"description": "",
"main": "dist/index.js",
"author": "Stefano J. Attardi ",
@@ -14,9 +14,11 @@
"@rollup/plugin-typescript": "^8.2.1",
"@types/eslint": "^7.2.7",
"@types/jest": "^26.0.22",
+ "@types/lodash": "^4.14.175",
"@typescript-eslint/parser": "^4.19.0",
- "@typescript-eslint/types": "^4.19.0",
+ "@typescript-eslint/types": "^5.0.0",
"eslint": "^7.23.0",
+ "gitpkg": "^1.0.0-beta.2",
"jest": "^25.0.0",
"rollup": "^2.43.1",
"ts-jest": "^26.5.4",
@@ -24,11 +26,23 @@
},
"scripts": {
"test": "jest",
+ "test-debug": "node --inspect-brk node_modules/.bin/jest --watch",
+ "test-watch": "jest --watch",
"build": "rm -rf dist && rollup -c",
+ "build-and-watch": "rm -rf dist && rollup -c --watch",
"prepublish:public": "npm run build && npm run bump-version",
- "publish:public": "npm publish --access public"
+ "publish:public": "npm publish --access public",
+ "deploy": "yarn build && yarn publish-git",
+ "publish-git": "yarn version-bump && gitpkg publish",
+ "link-to-web": "cd ../web && yarn link-eslint-plugin-react-memo-auto && cd ../eslint-plugin-react-memo && yarn build-and-watch",
+ "link-prepare": "yarn install && yarn link && echo 'Now run \"yarn link-eslint-plugin-react-memo\" in mobile and web. And make sure you are running \"yarn build-and-watch\" to keep those dist folders available.'",
+ "unlink-prepare": "yarn install && yarn unlink && echo 'Now run \"yarn unlink-eslint-plugin-react-memo\" in mobile and web. And make sure you are running \"yarn build-and-watch\" to keep those dist folders available.'",
+ "version-bump": "npm version patch && git add . && git commit --allow-empty -m \"version-bump\""
},
"files": [
"dist"
- ]
+ ],
+ "dependencies": {
+ "typescript-eslint": "^0.0.1-alpha.0"
+ }
}
diff --git a/require-memo.ts b/require-memo.ts
index 8209011..f37e725 100644
--- a/require-memo.ts
+++ b/require-memo.ts
@@ -3,6 +3,7 @@ import * as ESTree from "estree";
import * as path from "path";
const componentNameRegex = /^[^a-z]/;
+const memoImportText = 'import { memo } from \'react\'\n'
function isMemoCallExpression(node: Rule.Node) {
if (node.type !== "CallExpression") return false;
@@ -32,7 +33,8 @@ function checkFunction(
| ESTree.FunctionExpression
| ESTree.FunctionDeclaration
) &
- Rule.NodeParentExtension
+ Rule.NodeParentExtension,
+ alreadyImportedMemo: boolean
) {
let currentNode = node.parent;
while (currentNode.type === "CallExpression") {
@@ -47,7 +49,52 @@ function checkFunction(
const { id } = currentNode;
if (id.type === "Identifier") {
if (componentNameRegex.test(id.name)) {
- context.report({ node, messageId: "memo-required" });
+ context.report({ node, messageId: "memo-required", fix: (fixer): Rule.Fix | null => {
+ // @ts-ignore
+ const parent = node.parent
+ let scope
+ if (parent.type === 'VariableDeclarator') {
+ scope = node
+ } else {
+ scope = parent
+ }
+
+ const sourceCode = context.getSourceCode();
+
+ const getIndexToInsertImport = () => {
+ const allComments = sourceCode.getAllComments()
+ let insertImportLoc = 1
+ for (let i = 0, l = allComments.length; i < l; i++) {
+ const comment = allComments[i]
+ // @ts-ignore
+ const commentIsBackToBackWithPrev = comment.loc.start.line <= insertImportLoc + 1
+
+ if (!commentIsBackToBackWithPrev) break
+ // @ts-ignore
+ insertImportLoc = comment.loc.end.line
+ }
+ try {
+ return sourceCode.getIndexFromLoc({ line: insertImportLoc + 1, column: 0 })
+ } catch {
+ null
+ }
+ }
+
+ const importIndex = getIndexToInsertImport()
+ const text = sourceCode.getText(scope);
+ // @ts-ignore
+ const fullSourceText = sourceCode.getText();
+
+ let fixedCode = `memo(${text})`
+ if (text.startsWith('useRef(function')) {
+ fixedCode = `useRef(${text.replace('useRef', 'memo')})`
+ }
+ // @ts-ignore
+ return [
+ importIndex && !alreadyImportedMemo ? fixer.insertTextAfterRange([importIndex, importIndex], memoImportText) : null,
+ fixer.replaceText(scope, fixedCode),
+ ].filter(i => i)
+ } });
}
}
} else if (
@@ -55,7 +102,40 @@ function checkFunction(
currentNode.type === "Program"
) {
if (node.id !== null && componentNameRegex.test(node.id.name)) {
- context.report({ node, messageId: "memo-required" });
+ context.report({ node, messageId: "memo-required", fix: (fixer): Rule.Fix => {
+ let scope = node
+ const sourceCode = context.getSourceCode();
+
+ const getIndexToInsertImport = () => {
+ const allComments = sourceCode.getAllComments()
+ let insertImportLoc = 1
+ for (let i = 0, l = allComments.length; i < l; i++) {
+ const comment = allComments[i]
+ // @ts-ignore
+ const commentIsBackToBackWithPrev = comment.loc.start.line <= insertImportLoc + 1
+
+ if (!commentIsBackToBackWithPrev) break
+ // @ts-ignore
+ insertImportLoc = comment.loc.end.line
+ }
+ try {
+ return sourceCode.getIndexFromLoc({ line: insertImportLoc + 1, column: 0 })
+ } catch {
+ null
+ }
+ }
+
+ const importIndex = getIndexToInsertImport()
+
+ const text = sourceCode.getText(scope);
+ const fullSourceText = sourceCode.getText();
+ let fixedCode = `memo(${text})`
+ // @ts-ignore
+ return [
+ importIndex && !alreadyImportedMemo ? fixer.insertTextAfterRange([importIndex, importIndex], memoImportText) : null,
+ fixer.replaceText(node, fixedCode),
+ ].filter(i => i)
+ } });
} else {
if (context.getFilename() === "") return;
const filename = path.basename(context.getFilename());
@@ -68,21 +148,38 @@ function checkFunction(
const rule: Rule.RuleModule = {
meta: {
+ fixable: 'code',
messages: {
"memo-required": "Component definition not wrapped in React.memo()",
},
},
- create: (context) => ({
- ArrowFunctionExpression(node) {
- checkFunction(context, node);
- },
- FunctionDeclaration(node) {
- checkFunction(context, node);
- },
- FunctionExpression(node) {
- checkFunction(context, node);
- },
- }),
+ create: (context) => {
+ let alreadyImportedMemo = false
+
+ return {
+ ImportDeclaration (node) {
+ if (alreadyImportedMemo) return
+
+ if (node.source.value === 'react') {
+ const specifiers = node.specifiers
+ for (let i = 0, l = specifiers.length; i < l && !alreadyImportedMemo; i++) {
+ // @ts-ignore
+ const name = specifiers[i]?.imported?.name
+ if (name === 'memo') alreadyImportedMemo = true
+ }
+ }
+ },
+ ArrowFunctionExpression(node) {
+ checkFunction(context, node, alreadyImportedMemo);
+ },
+ FunctionDeclaration(node) {
+ checkFunction(context, node, alreadyImportedMemo);
+ },
+ FunctionExpression(node) {
+ checkFunction(context, node, alreadyImportedMemo);
+ },
+ }
+ },
};
export default rule;
diff --git a/require-usememo-children.ts b/require-usememo-children.ts
index 209a3d5..e1ccb47 100644
--- a/require-usememo-children.ts
+++ b/require-usememo-children.ts
@@ -7,9 +7,6 @@ import {
MemoStatus,
} from "./common";
-const componentNameRegex = /^[^a-z]/;
-const hookNameRegex = /^use[A-Z0-9].*$/;
-
const messages = {
"object-usememo-children":
"Object literal should be wrapped in React.useMemo() when used as children",
@@ -30,6 +27,7 @@ const messages = {
const rule: Rule.RuleModule = {
meta: {
messages,
+ fixable: 'code',
schema: [
{
type: "object",
@@ -58,7 +56,7 @@ const rule: Rule.RuleModule = {
}
if (child.type === "JSXExpressionContainer") {
const { expression } = child;
- if (expression.type !== "JSXEmptyExpression") {
+ if (expression?.type !== "JSXEmptyExpression") {
switch (getExpressionMemoStatus(context, expression)) {
case MemoStatus.UnmemoizedObject:
report(node, "object-usememo-children");
diff --git a/require-usememo.ts b/require-usememo.ts
index 7702d72..28606d5 100644
--- a/require-usememo.ts
+++ b/require-usememo.ts
@@ -1,29 +1,15 @@
import { Rule } from "eslint";
import * as ESTree from "estree";
import { TSESTree } from "@typescript-eslint/types";
+import { Node } from "@typescript-eslint/types/dist/ast-spec"
+import { isArrowFn, isHook } from "./utils";
+
import {
getExpressionMemoStatus,
isComplexComponent,
MemoStatus,
} from "./common";
-const hookNameRegex = /^use[A-Z0-9].*$/;
-
-function isHook(node: TSESTree.Node) {
- if (node.type === "Identifier") {
- return hookNameRegex.test(node.name);
- } else if (
- node.type === "MemberExpression" &&
- !node.computed &&
- isHook(node.property)
- ) {
- const obj = node.object;
- return obj.type === "Identifier" && obj.name === "React";
- } else {
- return false;
- }
-}
-
const messages = {
"object-usememo-props":
"Object literal should be wrapped in React.useMemo() when used as a prop",
@@ -55,6 +41,7 @@ const messages = {
const rule: Rule.RuleModule = {
meta: {
+ fixable: 'code',
messages,
schema: [
{
@@ -69,27 +56,56 @@ const rule: Rule.RuleModule = {
context.report({ node, messageId: messageId as string });
}
+ const useMemoFix = (fixer: Rule.RuleFixer, implicitReturn: boolean = true): Rule.Fix | null => {
+ const sourceCode = context.getSourceCode();
+ const references = context.getScope()?.references
+ const filteredRefs = references?.filter((reference) => reference?.writeExpr)
+ // @ts-ignore
+ const definition = filteredRefs?.[0]?.writeExpr?.parent
+ if (!definition) return null
+ const [name, value] = sourceCode.getText(definition).split(/=(.+)/)
+ const fixedCode = `${name.trim()} = useMemo(() => ${implicitReturn ? value.trim() : `(${value.trim()})`}, [])`
+ return fixer.replaceText(definition, fixedCode)
+ }
+
+ const useCallbackFix = (fixer: Rule.RuleFixer): Rule.Fix | null => {
+ let fixedCode = ''
+ const sourceCode = context.getSourceCode();
+ const references = context.getScope()?.references
+ const filteredRefs = references?.filter((reference) => reference?.writeExpr)
+ // @ts-ignore
+ const definition = filteredRefs?.[0]?.writeExpr?.parent
+ if (!definition) return null
+ const [name, value] = sourceCode.getText(definition).split(/=(.+)/)
+ if(isArrowFn(value)){
+ fixedCode = `${name.trim()} = useCallback(${value.trim()}, [])`
+ } else {
+ fixedCode = `${name.trim()} = useCallback(${value.replace(`function ${name.trim()}`, 'function').trim()}, [])`
+ }
+ return fixer.replaceText(definition, fixedCode)
+ }
+
return {
- JSXAttribute: (node: ESTree.Node & Rule.NodeParentExtension) => {
+ JSXAttribute: (node: Rule.Node & Rule.NodeParentExtension) => {
const { parent, value } = (node as unknown) as TSESTree.JSXAttribute &
Rule.NodeParentExtension;
if (value === null) return;
if (!isComplexComponent(parent)) return;
if (value.type === "JSXExpressionContainer") {
const { expression } = value;
- if (expression.type !== "JSXEmptyExpression") {
+ if (expression?.type !== "JSXEmptyExpression") {
switch (getExpressionMemoStatus(context, expression)) {
case MemoStatus.UnmemoizedObject:
- report(node, "object-usememo-props");
+ context.report({ node, messageId: "object-usememo-props" });
break;
case MemoStatus.UnmemoizedArray:
- report(node, "array-usememo-props");
+ context.report({ node, messageId: "array-usememo-props" });
break;
case MemoStatus.UnmemoizedNew:
- report(node, "instance-usememo-props");
+ context.report({ node, messageId: "instance-usememo-props" });
break;
case MemoStatus.UnmemoizedFunction:
- report(node, "function-usecallback-props");
+ context.report({ node, messageId: "function-usecallback-props" });
break;
case MemoStatus.UnmemoizedFunctionCall:
case MemoStatus.UnmemoizedOther:
diff --git a/utils/index.ts b/utils/index.ts
new file mode 100644
index 0000000..b530bcf
--- /dev/null
+++ b/utils/index.ts
@@ -0,0 +1,38 @@
+import { TSESTree } from "@typescript-eslint/types";
+
+export function normalizeIndent(strings: TemplateStringsArray) {
+ const codeLines = strings[0].split('\n');
+ const match = codeLines[1].match(/\s+/);
+ const leftPadding = match ? match[0].length : 0;
+ return codeLines.map(line => line.substr(leftPadding)).join('\n');
+}
+
+export function isArrowFn(fn: string) { return /^[^{]+?=>/.test(fn.toString()); };
+
+export const hookNames: string[] = [
+ 'useState',
+ 'useEffect',
+ 'useContext',
+ 'useReducer',
+ 'useCallback',
+ 'useMemo',
+ 'useRef',
+ 'useImperativeHandle',
+ 'useLayoutEffect',
+ 'useDebugValue',
+]
+
+export function isHook(node: TSESTree.Node) {
+ if (node.type === "Identifier") {
+ return Boolean(hookNames.find(a => a.includes(node.name)));
+ } else if (
+ node.type === "MemberExpression" &&
+ !node.computed &&
+ isHook(node.property)
+ ) {
+ const obj = node.object;
+ return obj.type === "Identifier" && obj.name === "React";
+ } else {
+ return false;
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index d005058..52e642b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -615,6 +615,14 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
+"@types/glob@^7.1.1":
+ version "7.1.4"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672"
+ integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==
+ dependencies:
+ "@types/minimatch" "*"
+ "@types/node" "*"
+
"@types/graceful-fs@^4.1.2":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
@@ -662,6 +670,16 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
+"@types/lodash@^4.14.175":
+ version "4.14.175"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45"
+ integrity sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==
+
+"@types/minimatch@*":
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
+ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
+
"@types/node@*":
version "14.14.37"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e"
@@ -719,11 +737,16 @@
"@typescript-eslint/types" "4.19.0"
"@typescript-eslint/visitor-keys" "4.19.0"
-"@typescript-eslint/types@4.19.0", "@typescript-eslint/types@^4.19.0":
+"@typescript-eslint/types@4.19.0":
version "4.19.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.19.0.tgz#5181d5d2afd02e5b8f149ebb37ffc8bd7b07a568"
integrity sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==
+"@typescript-eslint/types@^5.0.0":
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.0.0.tgz#25d93f6d269b2d25fdc51a0407eb81ccba60eb0f"
+ integrity sha512-dU/pKBUpehdEqYuvkojmlv0FtHuZnLXFBn16zsDmlFF3LXkOpkAQ2vrKc3BidIIve9EMH2zfTlxqw9XM0fFN5w==
+
"@typescript-eslint/typescript-estree@4.19.0":
version "4.19.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz#8a709ffa400284ab72df33376df085e2e2f61147"
@@ -778,6 +801,14 @@ acorn@^7.1.0, acorn@^7.4.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+aggregate-error@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
+ integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
+ dependencies:
+ clean-stack "^2.0.0"
+ indent-string "^4.0.0"
+
ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -998,6 +1029,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
+base64-js@^1.3.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
+ integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -1018,6 +1054,20 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
+bl@^4.0.3:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+ integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
+ dependencies:
+ buffer "^5.5.0"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
+
+bluebird@^3.7.2:
+ version "3.7.2"
+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
+ integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1091,6 +1141,14 @@ buffer-from@1.x, buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+buffer@^5.5.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+ integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.1.13"
+
builtin-modules@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
@@ -1138,7 +1196,7 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-chalk@^2.0.0:
+chalk@^2.0.0, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1163,6 +1221,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chownr@^1.1.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
+ integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
+
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -1178,6 +1241,23 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
+clean-stack@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
+ integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
+
+cli-cursor@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
+ integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
+ dependencies:
+ restore-cursor "^3.1.0"
+
+cli-spinners@^2.2.0:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d"
+ integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
+
cliui@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
@@ -1187,6 +1267,11 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
+clone@^1.0.2:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
+ integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
+
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -1355,6 +1440,13 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
+defaults@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
+ integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
+ dependencies:
+ clone "^1.0.2"
+
define-property@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
@@ -1377,6 +1469,20 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
+del@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7"
+ integrity sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==
+ dependencies:
+ globby "^10.0.1"
+ graceful-fs "^4.2.2"
+ is-glob "^4.0.1"
+ is-path-cwd "^2.2.0"
+ is-path-inside "^3.0.1"
+ p-map "^3.0.0"
+ rimraf "^3.0.0"
+ slash "^3.0.0"
+
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -1436,7 +1542,7 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-end-of-stream@^1.1.0:
+end-of-stream@^1.1.0, end-of-stream@^1.4.1, end-of-stream@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -1634,6 +1740,21 @@ execa@^3.2.0:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
+execa@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
+ integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
+ dependencies:
+ cross-spawn "^7.0.0"
+ get-stream "^5.0.0"
+ human-signals "^1.1.1"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.0"
+ onetime "^5.1.0"
+ signal-exit "^3.0.2"
+ strip-final-newline "^2.0.0"
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -1713,6 +1834,17 @@ fast-deep-equal@^3.1.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+fast-glob@^3.0.3:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
+ integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
fast-glob@^3.1.1:
version "3.2.5"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
@@ -1820,6 +1952,11 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
+fs-constants@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
+ integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -1881,7 +2018,39 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
-glob-parent@^5.0.0, glob-parent@^5.1.0:
+git-remote-origin-url@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-3.1.0.tgz#c90c1cb0f66658566bbc900509ab093a1522d2b3"
+ integrity sha512-yVSfaTMO7Bqk6Xx3696ufNfjdrajX7Ig9GuAeO2V3Ji7stkDoBNFldnWIAsy0qviUd0Z+X2P6ziJENKztW7cBQ==
+ dependencies:
+ gitconfiglocal "^2.1.0"
+
+gitconfiglocal@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-2.1.0.tgz#07c28685c55cc5338b27b5acbcfe34aeb92e43d1"
+ integrity sha512-qoerOEliJn3z+Zyn1HW2F6eoYJqKwS6MgC9cztTLUB/xLWX8gD/6T60pKn4+t/d6tP7JlybI7Z3z+I572CR/Vg==
+ dependencies:
+ ini "^1.3.2"
+
+gitpkg@^1.0.0-beta.2:
+ version "1.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/gitpkg/-/gitpkg-1.0.0-beta.2.tgz#afb8cc99fc38ebe60497d35ea13d323fc88377e8"
+ integrity sha512-ASD0wK+xDx/mPWwasUIKD6o0gKCwhY1KyfNkeTjmjMXHNGMTz1I344D4V+ndFlZPdUccdrMyxHD7XB99+Kl7Ag==
+ dependencies:
+ bluebird "^3.7.2"
+ chalk "^3.0.0"
+ del "^5.1.0"
+ end-of-stream "^1.4.4"
+ execa "^4.0.0"
+ find-up "^4.1.0"
+ git-remote-origin-url "^3.1.0"
+ make-dir "^3.0.2"
+ ora "^4.0.3"
+ semver "^7.1.3"
+ tar-fs "^2.0.1"
+ yargs "^15.3.1"
+
+glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@@ -1919,6 +2088,20 @@ globals@^13.6.0:
dependencies:
type-fest "^0.20.2"
+globby@^10.0.1:
+ version "10.0.2"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543"
+ integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==
+ dependencies:
+ "@types/glob" "^7.1.1"
+ array-union "^2.1.0"
+ dir-glob "^3.0.1"
+ fast-glob "^3.0.3"
+ glob "^7.1.3"
+ ignore "^5.1.1"
+ merge2 "^1.2.3"
+ slash "^3.0.0"
+
globby@^11.0.1:
version "11.0.3"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
@@ -1931,6 +2114,11 @@ globby@^11.0.1:
merge2 "^1.3.0"
slash "^3.0.0"
+graceful-fs@^4.2.2:
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
+ integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
+
graceful-fs@^4.2.4:
version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
@@ -2040,12 +2228,17 @@ iconv-lite@0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
+ieee754@^1.1.13:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
+ integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
+
ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-ignore@^5.1.4:
+ignore@^5.1.1, ignore@^5.1.4:
version "5.1.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
@@ -2071,6 +2264,11 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+indent-string@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
+ integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
+
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -2079,11 +2277,16 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2:
+inherits@2, inherits@^2.0.3, inherits@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+ini@^1.3.2:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
+ integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+
ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
@@ -2198,6 +2401,11 @@ is-glob@^4.0.0, is-glob@^4.0.1:
dependencies:
is-extglob "^2.1.1"
+is-interactive@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
+ integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
+
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
@@ -2215,6 +2423,16 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+is-path-cwd@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
+ integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
+
+is-path-inside@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
@@ -2882,6 +3100,13 @@ lodash@4.x, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+log-symbols@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
+ integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
+ dependencies:
+ chalk "^2.4.2"
+
lolex@^5.0.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367"
@@ -2896,7 +3121,7 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
-make-dir@^3.0.0:
+make-dir@^3.0.0, make-dir@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@@ -2932,7 +3157,7 @@ merge-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-merge2@^1.3.0:
+merge2@^1.2.3, merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
@@ -2964,6 +3189,14 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.0.5"
+micromatch@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+ integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ dependencies:
+ braces "^3.0.1"
+ picomatch "^2.2.3"
+
mime-db@1.46.0:
version "1.46.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
@@ -3001,6 +3234,11 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
+mkdirp-classic@^0.5.2:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
+ integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+
mkdirp@1.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
@@ -3016,6 +3254,11 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+mute-stream@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
+ integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -3176,6 +3419,20 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
+ora@^4.0.3:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-4.1.1.tgz#566cc0348a15c36f5f0e979612842e02ba9dddbc"
+ integrity sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==
+ dependencies:
+ chalk "^3.0.0"
+ cli-cursor "^3.1.0"
+ cli-spinners "^2.2.0"
+ is-interactive "^1.0.0"
+ log-symbols "^3.0.0"
+ mute-stream "0.0.8"
+ strip-ansi "^6.0.0"
+ wcwidth "^1.0.1"
+
p-each-series@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a"
@@ -3205,6 +3462,13 @@ p-locate@^4.1.0:
dependencies:
p-limit "^2.2.0"
+p-map@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d"
+ integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==
+ dependencies:
+ aggregate-error "^3.0.0"
+
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
@@ -3277,6 +3541,11 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+picomatch@^2.2.3:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
+ integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
+
pirates@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
@@ -3401,6 +3670,15 @@ read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
+readable-stream@^3.1.1, readable-stream@^3.4.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
+ integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
realpath-native@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866"
@@ -3526,6 +3804,14 @@ resolve@^1.10.0, resolve@^1.17.0, resolve@^1.19.0:
is-core-module "^2.2.0"
path-parse "^1.0.6"
+restore-cursor@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
+ integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
+ dependencies:
+ onetime "^5.1.0"
+ signal-exit "^3.0.2"
+
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -3562,7 +3848,7 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
-safe-buffer@^5.0.1, safe-buffer@^5.1.2:
+safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -3611,7 +3897,7 @@ saxes@^3.1.9:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@7.x, semver@^7.2.1, semver@^7.3.2:
+semver@7.x, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
@@ -3850,6 +4136,13 @@ string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
strip-ansi@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
@@ -3921,6 +4214,27 @@ table@^6.0.4:
slice-ansi "^4.0.0"
string-width "^4.2.0"
+tar-fs@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
+ integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.1.4"
+
+tar-stream@^2.1.4:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
+ integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
+ dependencies:
+ bl "^4.0.3"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
terminal-link@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
@@ -4100,6 +4414,11 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
+typescript-eslint@^0.0.1-alpha.0:
+ version "0.0.1-alpha.0"
+ resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz#285d68a4e96588295cd436278801bcb6a6b916c1"
+ integrity sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==
+
typescript@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
@@ -4140,6 +4459,11 @@ use@^3.1.0:
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
+util-deprecate@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+ integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
@@ -4199,6 +4523,13 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
+wcwidth@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
+ integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
+ dependencies:
+ defaults "^1.0.3"
+
webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"