diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..834904d --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + extends: ['eslint-config-fusion'], + env: { + 'node': true + } +}; diff --git a/Dockerfile b/Dockerfile index a0a6de4..9b3348a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,4 +5,5 @@ WORKDIR /dubstep-core COPY . . RUN yarn +RUN yarn lint RUN yarn test \ No newline at end of file diff --git a/README.md b/README.md index 0488385..97171e7 100644 --- a/README.md +++ b/README.md @@ -301,15 +301,10 @@ visitJsImport( ```js import {generateJs} from '@dubstep/core'; -generateJs = (path: NodePath, options: GenerateJsObject) => string; -type GenerateJsOptions = ?{ - formatter: ?('babel' | 'prettier'), - formatterOptions: ?Object, -}; +generateJs = (path: NodePath) => string; ``` -Converts a Program `NodePath` into a Javascript code string. The default formatter is `prettier`. The `formatterOptions` object should be [prettier options map](https://prettier.io/docs/en/options.html) or a [babel generator options map](https://babeljs.io/docs/en/next/babel-generator.html#options) depending on which `formatter` is specified. - +Converts a Program `NodePath` into a Javascript code string. A `NodePath` can be obtained from `withJsFile`, `withJsFiles` or `parseJs`. ##### insertJsAfter diff --git a/package.json b/package.json index 2ce9b3d..ca9cda9 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dev": "npm-watch | grep --invert-match nodemon", "build": "babel src -d dist -q", "test": "jest", + "lint": "eslint src/", "cover": "jest --coverage", "flow": "flow check || true", "prepare": "babel src -d dist -s" @@ -39,21 +40,18 @@ } }, "dependencies": { - "@babel/generator": "^7.1.5", "@babel/parser": "^7.1.5", "@babel/template": "^7.1.2", "@babel/traverse": "^7.1.5", "@babel/types": "^7.1.5", - "eslint": "^5.9.0", - "eslint-config-prettier": "^3.1.0", - "eslint-plugin-prettier": "^3.0.0", "execa": "^1.0.0", "flow-coverage-report": "^0.6.0", "fs-extra": "^7.0.1", "globby": "^8.0.1", "ini": "^1.3.5", "isomorphic-git": "^0.39.3", - "prettier": "^1.15.1" + "prettier": "^1.15.1", + "recast": "^0.16.0" }, "devDependencies": { "@babel/cli": "7.1.5", @@ -65,6 +63,15 @@ "babel-eslint": "10.0.1", "babel-jest": "23.6.0", "babel-preset-flow": "6.23.0", + "eslint": "^5.9.0", + "eslint-config-fusion": "^4.0.0", + "eslint-config-prettier": "^3.1.0", + "eslint-plugin-cup": "^2.0.0", + "eslint-plugin-flowtype": "^3.2.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-jest": "^22.0.0", + "eslint-plugin-prettier": "^3.0.0", + "eslint-plugin-react": "^7.11.1", "flow-bin": "0.86.0", "jest": "23.6.0", "markdown-it": "^8.4.2", diff --git a/src/core/index.test.js b/src/core/index.test.js index c9ac3f8..dbf87cf 100644 --- a/src/core/index.test.js +++ b/src/core/index.test.js @@ -25,6 +25,7 @@ THE SOFTWARE. import * as API from './index.js'; import markdown from 'markdown-it'; import fs from 'fs'; + const {Stepper, step, StepperError} = API; test('test', () => { diff --git a/src/utils/ensure-js-imports.test.js b/src/utils/ensure-js-imports.test.js index 1aaf0d0..2f25cc4 100644 --- a/src/utils/ensure-js-imports.test.js +++ b/src/utils/ensure-js-imports.test.js @@ -30,7 +30,7 @@ test('ensureJsImports', () => { const path = parseJs(''); const vars = ensureJsImports(path, `import foo, {bar} from 'bar';`); const code = generateJs(path); - expect(code.trim()).toEqual(`import foo, { bar } from 'bar';`); + expect(code.trim()).toMatchInlineSnapshot(`"import foo, {bar} from 'bar';"`); expect(vars).toEqual([{default: 'foo', bar: 'bar'}]); }); @@ -38,7 +38,9 @@ test('ensureJsImports after', () => { const path = parseJs(`import 'x';`); const vars = ensureJsImports(path, `import foo, {bar} from 'bar';`); const code = generateJs(path); - expect(code.trim()).toEqual(`import 'x';\nimport foo, { bar } from 'bar';`); + expect(code.trim()).toMatchInlineSnapshot( + `"import 'x';import foo, {bar} from 'bar';"` + ); expect(vars).toEqual([{default: 'foo', bar: 'bar'}]); }); @@ -46,7 +48,9 @@ test('ensureJsImports before', () => { const path = parseJs(`const a = 1;`); const vars = ensureJsImports(path, `import foo, {bar} from 'bar';`); const code = generateJs(path); - expect(code.trim()).toEqual(`import foo, { bar } from 'bar';\nconst a = 1;`); + expect(code.trim()).toMatchInlineSnapshot( + `"import foo, {bar} from 'bar';const a = 1;"` + ); expect(vars).toEqual([{default: 'foo', bar: 'bar'}]); }); @@ -54,7 +58,9 @@ test('merge', () => { const path = parseJs(`import {x} from 'foo'`); const vars = ensureJsImports(path, `import foo, {bar} from 'foo';`); const code = generateJs(path); - expect(code.trim()).toEqual(`import foo, { x, bar } from 'foo';`); + expect(code.trim()).toMatchInlineSnapshot( + `"import foo, { x, bar } from 'foo';"` + ); expect(vars).toEqual([{default: 'foo', x: 'x', bar: 'bar'}]); }); @@ -62,7 +68,7 @@ test('retain default', () => { const path = parseJs(`import foo from 'foo'`); const vars = ensureJsImports(path, `import wildcard from 'foo';`); const code = generateJs(path); - expect(code.trim()).toEqual(`import foo from 'foo';`); + expect(code.trim()).toMatchInlineSnapshot(`"import foo from 'foo'"`); expect(vars).toEqual([{default: 'foo'}]); }); @@ -70,11 +76,11 @@ test('multiple', () => { const path = parseJs(`import foo from 'foo';import bar from 'bar'`); const vars = ensureJsImports( path, - `import wildcard from 'foo';import another, {x} from 'bar';`, + `import wildcard from 'foo';import another, {x} from 'bar';` ); const code = generateJs(path); - expect(code.trim()).toEqual( - `import foo from 'foo';\nimport bar, { x } from 'bar';`, + expect(code.trim()).toMatchInlineSnapshot( + `"import foo from 'foo';import bar, { x } from 'bar';"` ); expect(vars).toEqual([{default: 'foo'}, {default: 'bar', x: 'x'}]); }); diff --git a/src/utils/generate-js.js b/src/utils/generate-js.js index 8476633..dad5d1c 100644 --- a/src/utils/generate-js.js +++ b/src/utils/generate-js.js @@ -22,30 +22,8 @@ THE SOFTWARE. @flow */ -import generate from '@babel/generator'; -import prettier from 'prettier'; -import {writeFile} from './write-file.js'; +import recast from 'recast'; -export type GenerateJsOptions = ?{ - formatter: ?('babel' | 'prettier'), - formatterOptions: ?Object, -}; - -export const generateJs = (path: NodePath, options: GenerateJsOptions) => { - const formatter = options ? options.formatter : 'babel'; - const formatterOptions = options ? options.formatterOptions : {}; - switch (formatter) { - case 'babel': - const generated = generate(path.parent, formatterOptions); - return generated.code; - case 'prettier': - default: - // placeholder is needed to prevent prettier from short-circuiting before the parser runs - return prettier.format('__placeholder__', { - parser() { - return path.node; - }, - ...formatterOptions, - }); - } +export const generateJs = (path: NodePath) => { + return recast.print(path.parent).code; }; diff --git a/src/utils/insert-js-after.js b/src/utils/insert-js-after.js index 140713f..b131f54 100644 --- a/src/utils/insert-js-after.js +++ b/src/utils/insert-js-after.js @@ -28,7 +28,7 @@ export const insertJsAfter = ( path: NodePath, target: string, code: string, - wildcards: Array = [], + wildcards: Array = [] ) => { return replaceJs(path, target, `${target}\n${code}`, wildcards); }; diff --git a/src/utils/insert-js-before.js b/src/utils/insert-js-before.js index 4f1e5ad..7f1456c 100644 --- a/src/utils/insert-js-before.js +++ b/src/utils/insert-js-before.js @@ -28,7 +28,7 @@ export const insertJsBefore = ( path: NodePath, target: string, code: string, - wildcards: Array = [], + wildcards: Array = [] ) => { return replaceJs(path, target, `${code}\n${target}`, wildcards); }; diff --git a/src/utils/parse-js.js b/src/utils/parse-js.js index c6c4c57..86165d6 100644 --- a/src/utils/parse-js.js +++ b/src/utils/parse-js.js @@ -25,8 +25,7 @@ THE SOFTWARE. import traverse from '@babel/traverse'; import NodePath from '@babel/traverse/lib/path'; import {parse} from '@babel/parser'; -import {readFile} from './read-file.js'; -import generate from '@babel/generator'; +import recast from 'recast'; export type ParserOptions = ?{mode: ?('typescript' | 'flow')}; @@ -36,32 +35,38 @@ export const parseJs = (code: string, options: ParserOptions) => { ? ['typescript'] : ['flow', 'flowComments']; - const ast = parse(code, { - sourceType: 'unambiguous', - plugins: [ - ...typeSystem, - 'jsx', - 'doExpressions', - 'objectRestSpread', - ['decorators', {decoratorsBeforeExport: false}], - 'classProperties', - 'classPrivateProperties', - 'classPrivateMethods', - 'exportDefaultFrom', - 'exportNamespaceFrom', - 'asyncGenerators', - 'functionBind', - 'functionSent', - 'dynamicImport', - 'numericSeparator', - 'optionalChaining', - 'importMeta', - 'bigInt', - 'optionalCatchBinding', - 'throwExpressions', - ['pipelineOperator', {proposal: 'minimal'}], - 'nullishCoalescingOperator', - ], + const ast = recast.parse(code, { + parser: { + parse(source) { + return parse(source, { + sourceType: 'unambiguous', + plugins: [ + ...typeSystem, + 'jsx', + 'doExpressions', + 'objectRestSpread', + ['decorators', {decoratorsBeforeExport: false}], + 'classProperties', + 'classPrivateProperties', + 'classPrivateMethods', + 'exportDefaultFrom', + 'exportNamespaceFrom', + 'asyncGenerators', + 'functionBind', + 'functionSent', + 'dynamicImport', + 'numericSeparator', + 'optionalChaining', + 'importMeta', + 'bigInt', + 'optionalCatchBinding', + 'throwExpressions', + ['pipelineOperator', {proposal: 'minimal'}], + 'nullishCoalescingOperator', + ], + }); + }, + }, }); // ensure `path` has correct type to keep flow.js happy diff --git a/src/utils/read-file.test.js b/src/utils/read-file.test.js index 06aa40c..8288d92 100644 --- a/src/utils/read-file.test.js +++ b/src/utils/read-file.test.js @@ -22,7 +22,6 @@ THE SOFTWARE. @flow */ -import util from 'util'; import fse from 'fs-extra'; import {writeFile} from './write-file.js'; import {readFile} from './read-file.js'; diff --git a/src/utils/remove-js-imports.test.js b/src/utils/remove-js-imports.test.js index e99fbb6..2987332 100644 --- a/src/utils/remove-js-imports.test.js +++ b/src/utils/remove-js-imports.test.js @@ -63,7 +63,7 @@ test('removeJsImports dependent statements', () => { c.toString(); function x(a) { a(); - }`, + }` ); removeJsImports(path, `import a, {b} from 'c';`); expect(generateJs(path).trim()).toEqual('function x(a) {\n a();\n}'); @@ -75,7 +75,7 @@ test('removeJsImports namespace dependent statements', () => { foo(a.test()); function x(a) { a(); - }`, + }` ); removeJsImports(path, `import * as a from 'c';`); expect(generateJs(path).trim()).toEqual('function x(a) {\n a();\n}'); diff --git a/src/utils/replace-js.js b/src/utils/replace-js.js index 7f69f19..5746926 100644 --- a/src/utils/replace-js.js +++ b/src/utils/replace-js.js @@ -29,7 +29,7 @@ export const replaceJs = ( path: NodePath, source: string, target: string, - wildcards: Array = [], + wildcards: Array = [] ): boolean => { const sourcePath = parseJs(source); const sourceNode = sourcePath.node.body[0]; diff --git a/src/utils/visit-js-import.js b/src/utils/visit-js-import.js index a6931f7..feab24a 100644 --- a/src/utils/visit-js-import.js +++ b/src/utils/visit-js-import.js @@ -31,7 +31,7 @@ import { export const visitJsImport = ( path: NodePath, source: string, - handler: (path: NodePath, refPaths: Array) => Boolean | void, + handler: (path: NodePath, refPaths: Array) => Boolean | void ) => { const sourcePath = parseJs(source); const sourceNode = sourcePath.node.body[0]; @@ -39,13 +39,13 @@ export const visitJsImport = ( throw new Error( `Expected source with type ImportDeclaration. Received: ${ sourceNode.type - }`, + }` ); } const specifiers = sourceNode.specifiers; if (specifiers.length !== 1) { throw new Error( - `Expected exactly one import specifier. Received: ${specifiers.length}`, + `Expected exactly one import specifier. Received: ${specifiers.length}` ); } const sourceSpecifier = specifiers[0]; diff --git a/src/utils/visit-js-import.test.js b/src/utils/visit-js-import.test.js index 08e1706..36f8e82 100644 --- a/src/utils/visit-js-import.test.js +++ b/src/utils/visit-js-import.test.js @@ -38,7 +38,7 @@ test('visitJsImport named', () => { expect(refPaths).toHaveLength(2); }); visitJsImport(path, `import {a} from 'c'`, handler); - expect(handler).toBeCalledTimes(1); + expect(handler).toHaveBeenCalledTimes(1); }); test('visitJsImport no references', () => { @@ -49,7 +49,7 @@ test('visitJsImport no references', () => { expect(refPaths).toHaveLength(0); }); visitJsImport(path, `import {a} from 'c'`, handler); - expect(handler).toBeCalledTimes(1); + expect(handler).toHaveBeenCalledTimes(1); }); test('visitJsImport no binding', () => { @@ -60,7 +60,7 @@ test('visitJsImport no binding', () => { expect(refPaths).toHaveLength(0); }); visitJsImport(path, `import {a} from 'c'`, handler); - expect(handler).toBeCalledTimes(0); + expect(handler).toHaveBeenCalledTimes(0); }); test('visitJsImport namespace', () => { @@ -77,7 +77,7 @@ test('visitJsImport namespace', () => { expect(refPaths).toHaveLength(2); }); visitJsImport(path, `import * as b from 'c'`, handler); - expect(handler).toBeCalledTimes(1); + expect(handler).toHaveBeenCalledTimes(1); }); test('visitJsImport default', () => { @@ -94,7 +94,7 @@ test('visitJsImport default', () => { expect(refPaths).toHaveLength(2); }); visitJsImport(path, `import b from 'c'`, handler); - expect(handler).toBeCalledTimes(1); + expect(handler).toHaveBeenCalledTimes(1); }); test('visitJsImport validation', () => { diff --git a/src/utils/with-ignore-file.js b/src/utils/with-ignore-file.js index 4a1924b..992888b 100644 --- a/src/utils/with-ignore-file.js +++ b/src/utils/with-ignore-file.js @@ -26,7 +26,7 @@ import {readFile} from '../utils/read-file.js'; import {writeFile} from '../utils/write-file.js'; export type IgnoreFileMutation = ( - data: Array, + data: Array ) => Promise>; export const withIgnoreFile = async (file: string, fn: IgnoreFileMutation) => { diff --git a/src/utils/with-js-file.js b/src/utils/with-js-file.js index deaea34..ae15063 100644 --- a/src/utils/with-js-file.js +++ b/src/utils/with-js-file.js @@ -40,6 +40,7 @@ export const withJsFile = async (file: string, transform: JsFileMutation) => { const generated = generateJs(program); await writeFile(file, generated); } catch (e) { + // eslint-disable-next-line no-console console.log(`Failed to handle file: ${file}`); throw e; } diff --git a/src/utils/with-js-files.js b/src/utils/with-js-files.js index 93eafac..945d7d0 100644 --- a/src/utils/with-js-files.js +++ b/src/utils/with-js-files.js @@ -29,7 +29,7 @@ import type {JsFileMutation} from './with-js-file.js'; export const withJsFiles = async ( root: string, regexp: RegExp, - fn: JsFileMutation, + fn: JsFileMutation ) => { const files = await findFiles(root, f => regexp.test(f)); for (const file of files) { diff --git a/src/utils/with-js-files.test.js b/src/utils/with-js-files.test.js index 384c010..3b25785 100644 --- a/src/utils/with-js-files.test.js +++ b/src/utils/with-js-files.test.js @@ -22,7 +22,6 @@ THE SOFTWARE. @flow */ -import {parse} from '@babel/parser'; import fse from 'fs-extra'; import {writeFile} from './write-file.js'; import {withJsFiles} from './with-js-files.js'; diff --git a/src/utils/with-json-file.test.js b/src/utils/with-json-file.test.js index a04da36..83d0354 100644 --- a/src/utils/with-json-file.test.js +++ b/src/utils/with-json-file.test.js @@ -41,7 +41,7 @@ test('withJsonFile throws error w/ filename when invalid JSON', async () => { await expect( withJsonFile(file, () => { return Promise.resolve(); - }), + }) ).rejects.toThrow(/__json_2__.json/); await fse.remove(file); }); diff --git a/yarn.lock b/yarn.lock index 5be463d..aafcb16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -387,6 +387,14 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -444,6 +452,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types@0.11.6: + version "0.11.6" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.6.tgz#4e2266c2658829aef3b40cc33ad599c4e9eb89ef" + integrity sha512-nHiuV14upVGl7MWwFUYbzJ6YlfwWS084CU9EA8HajfYQjMSli5TQi3UTRygGF58LFWVkXxS1rbgRhROEqlQkXg== + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -1097,6 +1110,11 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" @@ -1345,6 +1363,14 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -1457,6 +1483,25 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-cup@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-cup/-/eslint-config-cup-2.0.1.tgz#20f5af07c66594a3bbcce718ccc30639e894ff81" + integrity sha1-IPWvB8ZllKO7zOcYzMMGOeiU/4E= + +eslint-config-fusion@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-fusion/-/eslint-config-fusion-4.0.0.tgz#31b40bc4a880983af5ad3a9821b613e2cae79e21" + integrity sha512-vc5mnlu8xbcGMSqgmLaJByLbLJ61x3OZ21iwxfqVRblPZygPdw7Ts3LtmPQsB3gC2VyHupuc4jvBvQnCpTplRA== + dependencies: + eslint-config-uber-universal-stage-3 "^2.0.0" + +eslint-config-prettier@^2.0.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.10.0.tgz#ec07bc1d01f87d09f61d3840d112dc8a9791e30b" + integrity sha512-Mhl90VLucfBuhmcWBgbUNtgBiK955iCDK1+aHAz7QfDQF6wuzWZ6JjihZ3ejJoGlJWIuko7xLqNm8BA5uenKhA== + dependencies: + get-stdin "^5.0.1" + eslint-config-prettier@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d" @@ -1464,6 +1509,79 @@ eslint-config-prettier@^3.1.0: dependencies: get-stdin "^6.0.0" +eslint-config-uber-base-stage-3@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-uber-base-stage-3/-/eslint-config-uber-base-stage-3-2.1.0.tgz#97aa40c3b254f6bdc40411eb3c7fa366b1777efe" + integrity sha512-P6Z4Hk6lbxTKxJ/IYU5rpugJIWxwU7SiTeCnM6QMIKS3IdLH/cXXE8XIU3x6DVdn3Og5QO4fHB5daApbnP4Jkg== + dependencies: + eslint-config-uber-base "^2.1.0" + +eslint-config-uber-base@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-uber-base/-/eslint-config-uber-base-2.1.0.tgz#588d200eec45243728f2eeb66fab6fd296cf02cd" + integrity sha512-F3cTfu2V6TtAfvHVcyh4l1EKm2bXmh0VM5mX1sLLMtMEG4v0wM7pdsvr/FWcX9EMP0V1HGD/So9ui0/qGWqy3w== + dependencies: + eslint-config-prettier "^2.0.0" + +eslint-config-uber-universal-stage-3@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-uber-universal-stage-3/-/eslint-config-uber-universal-stage-3-2.1.0.tgz#a4e799377473065899e2232069d46fdea1c45b87" + integrity sha512-GEpGIbfQZpzvPhUmBwPzFr0MbuBbbmkhLG31vZ5izQHZarrGmWfR7T5bPQCZIRMuL7+45ZcOLBLP9C/smeHEwA== + dependencies: + eslint-config-cup "^2.0.0" + eslint-config-uber-base-stage-3 "^2.1.0" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-cup@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-cup/-/eslint-plugin-cup-2.0.0.tgz#ff38dd34a1aa103eee90dcb14560bb0cf2ab6232" + integrity sha1-/zjdNKGqED7ukNyxRWC7DPKrYjI= + dependencies: + globals "^11.5.0" + +eslint-plugin-flowtype@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.2.0.tgz#824364ed5940a404b91326fdb5a313a2a74760df" + integrity sha512-baJmzngM6UKbEkJ5OY3aGw2zjXBt5L2QKZvTsOlXX7yHKIjNRrlJx2ods8Rng6EdqPR9rVNIQNYHpTs0qfn2qA== + dependencies: + lodash "^4.17.10" + +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-plugin-jest@^22.0.0: + version "22.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.0.0.tgz#87dc52bbdd47f37f23bf2b10bb8469458bb3ed68" + integrity sha512-YOj8cYI5ZXEZUrX2kUBLachR1ffjQiicIMBoivN7bXXHnxi8RcwNvmVzwlu3nTmjlvk5AP3kIpC5i8HcinmhPA== + eslint-plugin-prettier@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.0.tgz#f6b823e065f8c36529918cdb766d7a0e975ec30c" @@ -1471,6 +1589,17 @@ eslint-plugin-prettier@^3.0.0: dependencies: prettier-linter-helpers "^1.0.0" +eslint-plugin-react@^7.11.1: + version "7.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" + integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw== + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.2" + eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -1555,7 +1684,7 @@ esprima@^3.1.3: resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= -esprima@^4.0.0: +esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -2039,6 +2168,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -2153,7 +2287,7 @@ global-prefix@^0.1.4: is-windows "^0.2.0" which "^1.2.12" -globals@^11.1.0, globals@^11.7.0: +globals@^11.1.0, globals@^11.5.0, globals@^11.7.0: version "11.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== @@ -2306,7 +2440,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1: +has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -2753,7 +2887,7 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -isarray@1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -3316,6 +3450,13 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsx-ast-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + integrity sha1-6AGxs5mF4g//yHtA43SAgOLcrH8= + dependencies: + array-includes "^3.0.3" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4152,6 +4293,13 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -4214,7 +4362,7 @@ printj@~1.1.0: resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== -private@^0.1.8: +private@^0.1.8, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -4244,7 +4392,7 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.5.7: +prop-types@^15.5.7, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== @@ -4423,6 +4571,16 @@ realpath-native@^1.0.0: dependencies: util.promisify "^1.0.0" +recast@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.16.0.tgz#1eb1881cae1f8834b9290caa987349430d5e8526" + integrity sha512-cm2jw4gCBatvs404ZJrxmGirSgWswW+S1U3SQTPHKNqdlUMg+V3J2XAOUvdAAgD7Hg2th2nxZ4wmYUekHI2Qmg== + dependencies: + ast-types "0.11.6" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -4590,7 +4748,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.3.2: +resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==