diff --git a/.gitignore b/.gitignore index af8a6a6..6897440 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules dist .DS_Store -coverage/ \ No newline at end of file +coverage/ +*.log diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..6835724 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +test/ +dist/ +!test/transformers.test.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..f3fc57b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "printWidth": 120, + "tabWidth": 4, + "trailingComma": "all" +} diff --git a/.travis.yml b/.travis.yml index 0d26c0d..57e0f7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ language: node_js -node_js: 7 -cache: - directories: - - node_modules \ No newline at end of file +node_js: stable +cache: yarn diff --git a/.vscode/launch.json b/.vscode/launch.json index 81d50c3..fff8a01 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,15 +7,13 @@ "env": { "NODE_ENV": "test" }, - "externalConsole": false, + "console": "internalConsole", "name": "Run Tests", - "outDir": "${workspaceRoot}/dist", - "preLaunchTask": "compile", + "outFiles": ["${workspaceRoot}/dist"], + "preLaunchTask": "tsc", "program": "${workspaceRoot}/node_modules/.bin/jest", "request": "launch", - "runtimeArgs": [ - - ], + "runtimeArgs": [], "runtimeExecutable": null, "sourceMaps": true, "stopOnEntry": false, @@ -28,4 +26,4 @@ "port": 5858 } ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a1e2ab6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/node_modules": true, + "**/dist": true + }, + "search.exclude": { + "**/node_modules": true, + "**/dist": true + }, + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 926b1dd..319e8a4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,4 +7,4 @@ "args": ["-p", "."], "showOutput": "silent", "problemMatcher": "$tsc" -} \ No newline at end of file +} diff --git a/LICENSE.md b/LICENSE.md index 906b9c0..806595a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,182 +1,181 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" @@ -187,16 +186,16 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2014 Lyft, Inc. +Copyright 2014 Lyft, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index 5ca3147..535d695 100644 --- a/README.md +++ b/README.md @@ -4,60 +4,71 @@ Transforms React code written in JavaScript to TypeScript. -## Features: +[**🖥 Download the VSCode Extension**](https://marketplace.visualstudio.com/items?itemName=mohsen1.react-javascript-to-typescript-transform-vscode) -* Proxies `PropTypes` to `React.Component` generic type and removes PropTypes -* Provides state typing for `React.Component` based on initial state and `setState()` calls in the component -* Hoist large interfaces for props and state out of `React.Component<P, S>` into declared types -* Convert functional components with `PropTypes` property to TypeScript and uses propTypes to generate function type declaration +## Features: +* Proxies `PropTypes` to `React.Component` generic type and removes PropTypes +* Provides state typing for `React.Component` based on initial state and `setState()` calls in the component +* Hoist large interfaces for props and state out of `React.Component<P, S>` into declared types +* Convert functional components with `PropTypes` property to TypeScript and uses propTypes to generate function type declaration ## Example **input** + ```jsx class MyComponent extends React.Component { - static propTypes = { - prop1: React.PropTypes.string.isRequired, - prop2: React.PropTypes.number - } - constructor() { - super(); - this.state = { foo: 1, bar: 'str' }; - } - render() { - return <div>{this.state.foo}, {this.state.bar}, {this.state.baz}</div> - } - onClick() { - this.setState({ baz: 3 }) - } + static propTypes = { + prop1: React.PropTypes.string.isRequired, + prop2: React.PropTypes.number, + }; + constructor() { + super(); + this.state = { foo: 1, bar: 'str' }; + } + render() { + return ( + <div> + {this.state.foo}, {this.state.bar}, {this.state.baz} + </div> + ); + } + onClick() { + this.setState({ baz: 3 }); + } } ``` **output** + ```tsx type MyComponentProps = { - prop1: string; - prop2?: number; -} + prop1: string; + prop2?: number; +}; type MyComponentState = { - foo: number; - bar: string; - baz: number; -} + foo: number; + bar: string; + baz: number; +}; class MyComponent extends React.Component<MyComponentProps, MyComponentState> { - constructor() { - super(); - this.state = { foo: 1, bar: 'str' }; - } - render() { - return <div>{this.state.foo}, {this.state.bar}, {this.state.baz}</div> - } - onClick() { - this.setState({ baz: 3 }) - } + constructor() { + super(); + this.state = { foo: 1, bar: 'str' }; + } + render() { + return ( + <div> + {this.state.foo}, {this.state.bar}, {this.state.baz} + </div> + ); + } + onClick() { + this.setState({ baz: 3 }); + } } ``` @@ -73,10 +84,10 @@ npm install -g react-js-to-ts react-js-to-ts my-react-js-file.js ``` - ### VSCode plugin -[Download from VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=mohsen1.react-javascript-to-typescript-transform-vscode#review-details) +details +[Download from VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=mohsen1.react-javascript-to-typescript-transform-vscode#overview) ## Development @@ -91,13 +102,14 @@ npm test #### Watch mode Pass `-w` to `npm test` + ``` npm test -- -w ``` #### Only a single test case -Pass `-t` with transform name and case name space separated to `npm test` +Pass `-t` with transform name and case name space separated to `npm test` ``` npm test -- -t "react-js-make-props-and-state-transform propless-stateless" diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b87d3a2..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2019 +0,0 @@ -{ - "name": "react-js-to-ts", - "version": "1.0.0-alpha-5", - "lockfileVersion": 1, - "dependencies": { - "@types/chalk": { - "version": "https://registry.npmjs.org/@types/chalk/-/chalk-0.4.31.tgz", - "integrity": "sha1-ox10JBprHtu5c8822XooloNKUfk=", - "dev": true - }, - "@types/commander": { - "version": "https://registry.npmjs.org/@types/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-3QevH8NddoM+DaJupnor4Ii1+vw=", - "dev": true - }, - "@types/glob": { - "version": "https://registry.npmjs.org/@types/glob/-/glob-5.0.30.tgz", - "integrity": "sha1-ECZAnFYlqGiQdGAoCNCCsoZ7ilE=", - "dev": true - }, - "@types/jest": { - "version": "https://registry.npmjs.org/@types/jest/-/jest-19.2.3.tgz", - "integrity": "sha1-YXSAQOhYmokd/C7B0Wot10SCmA4=", - "dev": true - }, - "@types/minimatch": { - "version": "https://registry.npmjs.org/@types/minimatch/-/minimatch-2.0.29.tgz", - "integrity": "sha1-UALhT3Xi1x5WQoHfBDHIwbSio2o=", - "dev": true - }, - "@types/node": { - "version": "https://registry.npmjs.org/@types/node/-/node-7.0.22.tgz", - "integrity": "sha1-RZP02Ci91hKSlHjqQMZ7T0A8olU=", - "dev": true - }, - "@types/react": { - "version": "https://registry.npmjs.org/@types/react/-/react-15.0.24.tgz", - "integrity": "sha1-inUpncN5Bt8yfBjKkYv5elXnEjs=", - "dev": true - }, - "abab": { - "version": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", - "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", - "dev": true - }, - "acorn": { - "version": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", - "integrity": "sha1-7c2jvZN+dVZBDULtWGD2c5nHlMA=", - "dev": true - }, - "acorn-globals": { - "version": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "dev": true - }, - "ajv": { - "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true - }, - "align-text": { - "version": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true - }, - "amdefine": { - "version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-escapes": { - "version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", - "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", - "dev": true - }, - "append-transform": { - "version": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", - "dev": true - }, - "argparse": { - "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true - }, - "arr-diff": { - "version": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true - }, - "arr-flatten": { - "version": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", - "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", - "dev": true - }, - "array-equal": { - "version": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-unique": { - "version": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "async": { - "version": "https://registry.npmjs.org/async/-/async-2.4.1.tgz", - "integrity": "sha1-YqVrJ5yYoR0JhwlqAcw+6463u9c=", - "dev": true - }, - "asynckit": { - "version": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "babel-code-frame": { - "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", - "dev": true - }, - "babel-core": { - "version": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.1.tgz", - "integrity": "sha1-jEKFZNzh4fQfszfsNPTDsCK1rYM=", - "dev": true - }, - "babel-generator": { - "version": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.1.tgz", - "integrity": "sha1-5xX0hsWN7SVknYiJRNUqoHxdlJc=", - "dev": true - }, - "babel-helpers": { - "version": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true - }, - "babel-jest": { - "version": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", - "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", - "dev": true - }, - "babel-messages": { - "version": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true - }, - "babel-plugin-istanbul": { - "version": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.3.tgz", - "integrity": "sha1-buYoBBDc9Zx3R1GMPf2YaAlY8QI=", - "dev": true - }, - "babel-plugin-jest-hoist": { - "version": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", - "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=", - "dev": true - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", - "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", - "dev": true - }, - "babel-plugin-transform-strict-mode": { - "version": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true - }, - "babel-preset-jest": { - "version": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", - "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", - "dev": true - }, - "babel-register": { - "version": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true - }, - "babel-runtime": { - "version": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "dev": true - }, - "babel-template": { - "version": "https://registry.npmjs.org/babel-template/-/babel-template-6.24.1.tgz", - "integrity": "sha1-BK5RTx+Ts6JTfyoPYKWkX7gwgzM=", - "dev": true - }, - "babel-traverse": { - "version": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.24.1.tgz", - "integrity": "sha1-qzZnP9NW+aCUhlnnszjV/q2zFpU=", - "dev": true - }, - "babel-types": { - "version": "https://registry.npmjs.org/babel-types/-/babel-types-6.24.1.tgz", - "integrity": "sha1-oTaHncFbNga9oNkMH8dDBML/CXU=", - "dev": true - }, - "babylon": { - "version": "https://registry.npmjs.org/babylon/-/babylon-6.17.1.tgz", - "integrity": "sha1-F/FP3fNhtpWYH+Z5OF5PHAHr2G8=", - "dev": true - }, - "balanced-match": { - "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" - }, - "bcrypt-pbkdf": { - "version": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true - }, - "boom": { - "version": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true - }, - "brace-expansion": { - "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=" - }, - "braces": { - "version": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true - }, - "browser-resolve": { - "version": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", - "dev": true, - "dependencies": { - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "bser": { - "version": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", - "dev": true - }, - "builtin-modules": { - "version": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "callsites": { - "version": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, - "camelcase": { - "version": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - }, - "caseless": { - "version": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "center-align": { - "version": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "optional": true - }, - "chalk": { - "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true - }, - "ci-info": { - "version": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", - "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", - "dev": true - }, - "cliui": { - "version": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "optional": true, - "dependencies": { - "wordwrap": { - "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true, - "optional": true - } - } - }, - "co": { - "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "dev": true - }, - "color-name": { - "version": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz", - "integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0=", - "dev": true - }, - "colors": { - "version": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "combined-stream": { - "version": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true - }, - "commander": { - "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=" - }, - "concat-map": { - "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "content-type-parser": { - "version": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", - "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", - "dev": true - }, - "convert-source-map": { - "version": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", - "dev": true - }, - "core-js": { - "version": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", - "dev": true - }, - "cross-spawn": { - "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true - }, - "cryptiles": { - "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true - }, - "cssom": { - "version": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", - "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", - "dev": true - }, - "cssstyle": { - "version": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", - "dev": true - }, - "dashdash": { - "version": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true - }, - "decamelize": { - "version": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-is": { - "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "default-require-extensions": { - "version": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", - "dev": true - }, - "delayed-stream": { - "version": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "detect-indent": { - "version": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true - }, - "diff": { - "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "ecc-jsbn": { - "version": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true - }, - "errno": { - "version": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", - "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", - "dev": true - }, - "error-ex": { - "version": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true - }, - "escape-string-regexp": { - "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "dependencies": { - "esprima": { - "version": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "source-map": { - "version": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true - } - } - }, - "esprima": { - "version": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "esutils": { - "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "exec-sh": { - "version": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.0.tgz", - "integrity": "sha1-FPdd4/INKG75MwmbLOUKkDWc7xA=", - "dev": true - }, - "execa": { - "version": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", - "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", - "dev": true - }, - "expand-brackets": { - "version": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true - }, - "expand-range": { - "version": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true - }, - "extend": { - "version": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extglob": { - "version": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true - }, - "extsprintf": { - "version": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", - "dev": true - }, - "fast-levenshtein": { - "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fb-watchman": { - "version": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", - "dev": true - }, - "filename-regex": { - "version": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fileset": { - "version": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true - }, - "fill-range": { - "version": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true - }, - "find-up": { - "version": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true - }, - "for-in": { - "version": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true - }, - "forever-agent": { - "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true - }, - "fs-extra": { - "version": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true - }, - "fs.realpath": { - "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "get-caller-file": { - "version": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-stream": { - "version": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true - }, - "getpass": { - "version": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "glob": { - "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=" - }, - "glob-all": { - "version": "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz", - "integrity": "sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=", - "dev": true, - "dependencies": { - "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", - "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", - "dev": true - }, - "yargs": { - "version": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", - "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", - "dev": true - } - } - }, - "glob-base": { - "version": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true - }, - "glob-parent": { - "version": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true - }, - "globals": { - "version": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", - "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=", - "dev": true - }, - "graceful-fs": { - "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "graceful-readlink": { - "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - }, - "growly": { - "version": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "handlebars": { - "version": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", - "dev": true, - "dependencies": { - "async": { - "version": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "source-map": { - "version": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true - } - } - }, - "har-schema": { - "version": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true - }, - "har-validator": { - "version": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true - }, - "has-ansi": { - "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true - }, - "has-flag": { - "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "hawk": { - "version": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true - }, - "hoek": { - "version": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "home-or-tmp": { - "version": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true - }, - "hosted-git-info": { - "version": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", - "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", - "dev": true - }, - "html-encoding-sniffer": { - "version": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", - "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", - "dev": true - }, - "http-signature": { - "version": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true - }, - "iconv-lite": { - "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - }, - "inflight": { - "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" - }, - "inherits": { - "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "invariant": { - "version": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true - }, - "invert-kv": { - "version": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-arrayish": { - "version": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "dev": true - }, - "is-builtin-module": { - "version": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true - }, - "is-ci": { - "version": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true - }, - "is-dotfile": { - "version": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", - "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=", - "dev": true - }, - "is-equal-shallow": { - "version": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true - }, - "is-extendable": { - "version": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true - }, - "is-glob": { - "version": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true - }, - "is-number": { - "version": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true - }, - "is-posix-bracket": { - "version": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-stream": { - "version": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-utf8": { - "version": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "isarray": { - "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true - }, - "isstream": { - "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-api": { - "version": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.8.tgz", - "integrity": "sha1-qETlXG+a7uKS5/QpQhlvYLI9yT4=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", - "integrity": "sha1-ysoZ3srvNSW11jMdcB8/O3rUhSg=", - "dev": true - }, - "istanbul-lib-hook": { - "version": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.6.tgz", - "integrity": "sha1-wIZtHoHPLVMZJJUQEx/Bbe5JIx8=", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.1.tgz", - "integrity": "sha1-Fp4xvGLHeIUamUOd2Zw8wSGE02A=", - "dev": true - }, - "istanbul-lib-report": { - "version": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.0.tgz", - "integrity": "sha1-RExOzKmvqTz1hPVrEPGVv3aMB3A=", - "dev": true, - "dependencies": { - "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true - } - } - }, - "istanbul-lib-source-maps": { - "version": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.0.tgz", - "integrity": "sha1-jHcG1Jfib+62rz4MKP1bBmlZjQ4=", - "dev": true - }, - "istanbul-reports": { - "version": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.0.tgz", - "integrity": "sha1-HvO3lYiSGc+1+tFjZfbOEI1fjGY=", - "dev": true - }, - "jest": { - "version": "https://registry.npmjs.org/jest/-/jest-20.0.3.tgz", - "integrity": "sha1-5P0FTE8RcKEWoAdh2kz9tz8c3DM=", - "dev": true, - "dependencies": { - "jest-cli": { - "version": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.3.tgz", - "integrity": "sha1-/ojdu3qfOhbQ7VUzmgokJPfw02E=", - "dev": true - } - } - }, - "jest-changed-files": { - "version": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", - "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=", - "dev": true - }, - "jest-config": { - "version": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.3.tgz", - "integrity": "sha1-qTTyfup2SRWAHN2ib2+O7CrHkmY=", - "dev": true - }, - "jest-diff": { - "version": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", - "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", - "dev": true - }, - "jest-docblock": { - "version": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", - "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=", - "dev": true - }, - "jest-environment-jsdom": { - "version": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", - "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", - "dev": true - }, - "jest-environment-node": { - "version": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", - "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", - "dev": true - }, - "jest-haste-map": { - "version": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.3.tgz", - "integrity": "sha1-Y3fVN+rzTrX3USGmkcrj/egrqXE=", - "dev": true - }, - "jest-jasmine2": { - "version": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.3.tgz", - "integrity": "sha1-GMTp0CnaftGucnxVMABk0aBUKXQ=", - "dev": true - }, - "jest-matcher-utils": { - "version": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", - "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", - "dev": true - }, - "jest-matchers": { - "version": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", - "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", - "dev": true - }, - "jest-message-util": { - "version": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", - "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", - "dev": true - }, - "jest-mock": { - "version": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", - "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=", - "dev": true - }, - "jest-regex-util": { - "version": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", - "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=", - "dev": true - }, - "jest-resolve": { - "version": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.3.tgz", - "integrity": "sha1-N1MHqkD3hTLUD/ixfVMAsVGfjdQ=", - "dev": true - }, - "jest-resolve-dependencies": { - "version": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", - "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", - "dev": true - }, - "jest-runtime": { - "version": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.3.tgz", - "integrity": "sha1-3d0iu8Qp4m5qltGs1GylVxSwklI=", - "dev": true, - "dependencies": { - "strip-bom": { - "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "jest-snapshot": { - "version": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", - "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", - "dev": true - }, - "jest-util": { - "version": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", - "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", - "dev": true - }, - "jest-validate": { - "version": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", - "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", - "dev": true - }, - "jodid25519": { - "version": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", - "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", - "dev": true, - "optional": true - }, - "js-tokens": { - "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", - "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", - "dev": true - }, - "js-yaml": { - "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", - "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", - "dev": true - }, - "jsbn": { - "version": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "jsdom": { - "version": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", - "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", - "dev": true - }, - "jsesc": { - "version": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-schema": { - "version": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-stable-stringify": { - "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true - }, - "json-stringify-safe": { - "version": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonfile": { - "version": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.0.tgz", - "integrity": "sha1-kufHRE5f/V+jLmqa6LhQNN+DR9A=", - "dev": true - }, - "jsonify": { - "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsprim": { - "version": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", - "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", - "dev": true, - "dependencies": { - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "kind-of": { - "version": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true - }, - "lazy-cache": { - "version": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true - }, - "lcid": { - "version": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true - }, - "leven": { - "version": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, - "levn": { - "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true - }, - "load-json-file": { - "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true - }, - "locate-path": { - "version": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true - }, - "lodash": { - "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "longest": { - "version": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loose-envify": { - "version": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true - }, - "lru-cache": { - "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "dev": true - }, - "make-error": { - "version": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", - "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", - "dev": true - }, - "makeerror": { - "version": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true - }, - "mem": { - "version": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true - }, - "merge": { - "version": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", - "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", - "dev": true - }, - "micromatch": { - "version": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true - }, - "mime-db": { - "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", - "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", - "dev": true - }, - "mime-types": { - "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", - "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", - "dev": true - }, - "mimic-fn": { - "version": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "minimatch": { - "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=" - }, - "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true - }, - "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "natural-compare": { - "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-int64": { - "version": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-notifier": { - "version": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", - "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", - "dev": true - }, - "normalize-package-data": { - "version": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", - "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", - "dev": true - }, - "normalize-path": { - "version": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true - }, - "npm-run-path": { - "version": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true - }, - "number-is-nan": { - "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nwmatcher": { - "version": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.0.tgz", - "integrity": "sha1-tDiTYhcOfvl5jDx3FtgOvAEG/M8=", - "dev": true - }, - "oauth-sign": { - "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object.omit": { - "version": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true - }, - "once": { - "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" - }, - "optimist": { - "version": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true - }, - "optionator": { - "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "dependencies": { - "wordwrap": { - "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "os-homedir": { - "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true - }, - "os-tmpdir": { - "version": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-finally": { - "version": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true - }, - "p-locate": { - "version": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true - }, - "p-map": { - "version": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", - "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", - "dev": true - }, - "parse-glob": { - "version": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true - }, - "parse-json": { - "version": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true - }, - "parse5": { - "version": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", - "dev": true - }, - "path-exists": { - "version": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-type": { - "version": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true - }, - "performance-now": { - "version": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true - }, - "pify": { - "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true - }, - "pkg-dir": { - "version": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true - }, - "prelude-ls": { - "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-format": { - "version": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", - "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", - "dev": true, - "dependencies": { - "ansi-styles": { - "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.0.0.tgz", - "integrity": "sha1-VATpOlRMT+x/BIJil3vr/jFV4ME=", - "dev": true - } - } - }, - "private": { - "version": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", - "dev": true - }, - "prr": { - "version": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, - "pseudomap": { - "version": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "punycode": { - "version": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "randomatic": { - "version": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", - "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", - "dev": true - }, - "read-pkg": { - "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true - }, - "read-pkg-up": { - "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "dependencies": { - "find-up": { - "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true - }, - "path-exists": { - "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true - } - } - }, - "regenerator-runtime": { - "version": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - }, - "regex-cache": { - "version": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", - "dev": true - }, - "remove-trailing-separator": { - "version": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", - "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=", - "dev": true - }, - "repeat-element": { - "version": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true - }, - "request": { - "version": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true - }, - "require-directory": { - "version": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", - "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", - "dev": true - }, - "right-align": { - "version": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "optional": true - }, - "rimraf": { - "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true - }, - "safe-buffer": { - "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", - "dev": true - }, - "sane": { - "version": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", - "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", - "dev": true, - "dependencies": { - "bser": { - "version": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", - "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", - "dev": true - }, - "fb-watchman": { - "version": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", - "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", - "dev": true - }, - "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "sax": { - "version": "https://registry.npmjs.org/sax/-/sax-1.2.2.tgz", - "integrity": "sha1-/YYxojvHgmvvXYcb24c3jJVkeCg=", - "dev": true - }, - "semver": { - "version": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "set-blocking": { - "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shellwords": { - "version": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", - "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=", - "dev": true - }, - "signal-exit": { - "version": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "sntp": { - "version": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true - }, - "source-map": { - "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - }, - "source-map-support": { - "version": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", - "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", - "dev": true - }, - "spdx-correct": { - "version": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true - }, - "spdx-expression-parse": { - "version": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "sprintf-js": { - "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", - "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", - "dev": true, - "dependencies": { - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "string-length": { - "version": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", - "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", - "dev": true - }, - "string-width": { - "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true - }, - "stringstream": { - "version": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "strip-ansi": { - "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true - }, - "strip-bom": { - "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true - }, - "strip-eof": { - "version": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "symbol-tree": { - "version": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true - }, - "test-exclude": { - "version": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.0.tgz", - "integrity": "sha1-BMpwtzkN04yY1KADoXOAbKeZHJE=", - "dev": true - }, - "throat": { - "version": "https://registry.npmjs.org/throat/-/throat-3.0.0.tgz", - "integrity": "sha1-58ZMhny7OEXxCHdkL3tgBVuOwNY=", - "dev": true - }, - "tmpl": { - "version": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "to-fast-properties": { - "version": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "tough-cookie": { - "version": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "dev": true - }, - "tr46": { - "version": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "trim-right": { - "version": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "ts-jest": { - "version": "https://registry.npmjs.org/ts-jest/-/ts-jest-20.0.4.tgz", - "integrity": "sha1-/+OYfUjIdizXtq6DUY0gPsoWdhg=", - "dev": true, - "dependencies": { - "camelcase": { - "version": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "dependencies": { - "string-width": { - "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true - } - } - }, - "load-json-file": { - "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true - }, - "os-locale": { - "version": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", - "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=", - "dev": true - }, - "path-type": { - "version": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true - }, - "read-pkg": { - "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true - }, - "read-pkg-up": { - "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true - }, - "string-width": { - "version": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": { - "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "strip-bom": { - "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "which-module": { - "version": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "yargs": { - "version": "https://registry.npmjs.org/yargs/-/yargs-8.0.1.tgz", - "integrity": "sha1-Qg73XoQMFFeoCtzKm8b6OEneUao=", - "dev": true - }, - "yargs-parser": { - "version": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true - } - } - }, - "ts-node": { - "version": "https://registry.npmjs.org/ts-node/-/ts-node-3.0.4.tgz", - "integrity": "sha1-oUdevyT9Ti7i+6ixqhYFuXe95QY=", - "dev": true, - "dependencies": { - "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tsconfig": { - "version": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", - "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", - "dev": true, - "dependencies": { - "strip-bom": { - "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "tslib": { - "version": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", - "integrity": "sha1-vIAEFkaRkjp5/oN4u+s9ogF1OOw=", - "dev": true - }, - "tslint": { - "version": "https://registry.npmjs.org/tslint/-/tslint-5.3.2.tgz", - "integrity": "sha1-5WRZ+wlacwfxA7hAUhdPXju+9u0=", - "dev": true - }, - "tsutils": { - "version": "https://registry.npmjs.org/tsutils/-/tsutils-2.0.0.tgz", - "integrity": "sha1-rgykiktDG1wE5PcRqSJ6ouN+LgQ=", - "dev": true - }, - "tunnel-agent": { - "version": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true - }, - "tweetnacl": { - "version": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-check": { - "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true - }, - "typescript": { - "version": "https://registry.npmjs.org/typescript/-/typescript-2.3.3.tgz", - "integrity": "sha1-ljnzw7QBSOjKl/4IpR3RiRu2viI=" - }, - "uglify-js": { - "version": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.27.tgz", - "integrity": "sha1-R3h/kSsPJC5bmENDvo416V9pTJw=", - "dev": true, - "optional": true, - "dependencies": { - "yargs": { - "version": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "optional": true - } - } - }, - "uglify-to-browserify": { - "version": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, - "universalify": { - "version": "https://registry.npmjs.org/universalify/-/universalify-0.1.0.tgz", - "integrity": "sha1-nrHEZR3rzGcMyU8adXYjMruWd3g=", - "dev": true - }, - "user-home": { - "version": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "uuid": { - "version": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", - "dev": true - }, - "v8flags": { - "version": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true - }, - "validate-npm-package-license": { - "version": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true - }, - "verror": { - "version": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", - "dev": true - }, - "walker": { - "version": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true - }, - "watch": { - "version": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", - "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=", - "dev": true - }, - "webidl-conversions": { - "version": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", - "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", - "dev": true - }, - "whatwg-encoding": { - "version": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", - "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", - "dev": true - }, - "whatwg-url": { - "version": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", - "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", - "dev": true, - "dependencies": { - "webidl-conversions": { - "version": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - } - } - }, - "which": { - "version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true - }, - "which-module": { - "version": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "window-size": { - "version": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true, - "optional": true - }, - "wordwrap": { - "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "worker-farm": { - "version": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.3.1.tgz", - "integrity": "sha1-QzMRK7SbF6oFC4eJXKayys9A5f8=", - "dev": true - }, - "wrap-ansi": { - "version": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true - }, - "wrappy": { - "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xml-name-validator": { - "version": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", - "dev": true - }, - "xtend": { - "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "dependencies": { - "camelcase": { - "version": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "dependencies": { - "camelcase": { - "version": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - } - } - }, - "yn": { - "version": "https://registry.npmjs.org/yn/-/yn-1.3.0.tgz", - "integrity": "sha1-GwgSq7jYBdSJZvjfOF3J2syaGdg=", - "dev": true - } - } -} diff --git a/package.json b/package.json index fa67c9d..55994ac 100644 --- a/package.json +++ b/package.json @@ -1,50 +1,60 @@ { - "name": "react-js-to-ts", - "version": "1.2.0", - "description": "Convert React code from JavaScript to TypeScript", - "main": "dist/index.js", - "scripts": { - "pretest": "npm run build", - "test": "jest", - "coverage": "jest --coverage", - "posttest": "npm run lint", - "prelint": "npm run clean", - "lint": "tslint --type-check --project tsconfig.json --format codeFrame --exclude test/**/*.tsx", - "prepublish": "npm run build", - "clean": "rm -rf dist", - "prebuild": "npm run clean", - "build": "tsc --pretty" - }, - "jest": { - "mapCoverage": true, - "transform": { - ".ts": "<rootDir>/node_modules/ts-jest/preprocessor.js" + "name": "react-js-to-ts", + "version": "1.4.0", + "description": "Convert React code from JavaScript to TypeScript", + "main": "dist/index.js", + "scripts": { + "pretest": "npm run build", + "test": "jest", + "coverage": "jest --coverage", + "posttest": "npm run lint", + "prelint": "npm run clean", + "lint": "tslint --project tsconfig.json --format codeFrame --exclude test/**/*.tsx", + "prepublish": "npm run build", + "clean": "rm -rf dist", + "prebuild": "npm run clean", + "build": "tsc --pretty", + "precommit": "lint-staged", + "prettier": "prettier --write *.{js,json,css,md,ts,tsx}" }, - "testRegex": "test/runner.ts", - "moduleFileExtensions": [ - "ts", - "js" - ] - }, - "bin": "dist/cli.js", - "author": "Mohsen Azimi <me@azimi.me>", - "license": "Apache-2.0", - "dependencies": { - "chalk": "^1.1.3", - "commander": "^2.10.0", - "glob": "^7.1.2", - "typescript": "^2.4.0" - }, - "devDependencies": { - "@types/chalk": "^0.4.31", - "@types/commander": "^2.9.1", - "@types/glob": "^5.0.30", - "@types/jest": "^20.0.2", - "@types/node": "^8.0.2", - "@types/react": "^15.0.31", - "jest": "^20.0.4", - "ts-jest": "^20.0.6", - "ts-node": "^3.1.0", - "tslint": "^5.2.0" - } + "jest": { + "transform": { + ".ts": "<rootDir>/node_modules/ts-jest/preprocessor.js" + }, + "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "moduleFileExtensions": ["ts", "js"] + }, + "lint-staged": { + "*.{js,json,css,md,ts,tsx}": ["node_modules/.bin/prettier --write", "git add"] + }, + "bin": "dist/cli.js", + "author": "Mohsen Azimi <me@azimi.me>", + "license": "Apache-2.0", + "dependencies": { + "chalk": "^2.4.1", + "commander": "^2.15.1", + "detect-indent": "^5.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.10", + "prettier": "^1.12.1", + "typescript": "2.8.3" + }, + "devDependencies": { + "@types/chalk": "^2.2.0", + "@types/commander": "^2.9.1", + "@types/detect-indent": "^5.0.0", + "@types/glob": "^5.0.35", + "@types/jest": "^22.2.3", + "@types/lodash": "^4.14.109", + "@types/node": "^10.1.2", + "@types/prettier": "^1.12.2", + "@types/react": "^16.3.14", + "dedent": "^0.7.0", + "husky": "^0.14.3", + "jest": "^22.4.4", + "lint-staged": "^7.1.1", + "ts-jest": "^22.4.6", + "ts-node": "^6.0.3", + "tslint": "^5.10.0" + } } diff --git a/src/cli.ts b/src/cli.ts index 42ba40e..779f0a9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -4,31 +4,95 @@ import * as program from 'commander'; import * as glob from 'glob'; import * as fs from 'fs'; import * as path from 'path'; +import * as prettier from 'prettier'; import { run } from '.'; +import { CompilationOptions } from './compiler'; + +function resolveGlobs(globPatterns: string[]): string[] { + const files: string[] = []; + function addFile(file: string) { + file = path.resolve(file); + if (files.indexOf(file) === -1) { + files.push(file); + } + } + globPatterns.forEach(pattern => { + if (/[{}*?+\[\]]/.test(pattern)) { + // Smells like globs + glob.sync(pattern, {}).forEach(file => { + addFile(file); + }); + } else { + addFile(pattern); + } + }); + return files; +} program .version('1.0.0') + .option('--arrow-parens <avoid|always>', 'Include parentheses around a sole arrow function parameter.', 'avoid') + .option('--no-bracket-spacing', 'Do not print spaces between brackets.', false) + .option('--jsx-bracket-same-line', 'Put > on the last line instead of at a new line.', false) + .option('--print-width <int>', 'The line length where Prettier will try wrap.', 80) + .option('--prose-wrap <always|never|preserve> How to wrap prose. (markdown)', 'preserve') + .option('--no-semi', 'Do not print semicolons, except at the beginning of lines which may need them', false) + .option('--single-quote', 'Use single quotes instead of double quotes.', false) + .option('--tab-width <int>', 'Number of spaces per indentation level.', 2) + .option('--trailing-comma <none|es5|all>', 'Print trailing commas wherever possible when multi-line.', 'none') + .option('--use-tabs', 'Indent with tabs instead of spaces.', false) + .option('--ignore-prettier-errors', 'Ignore (but warn about) errors in Prettier', false) + .option('--keep-original-files', 'Keep original files', false) + .option('--keep-temporary-files', 'Keep temporary files', false) .usage('[options] <filename or glob>') - .command('* <glob>') - .action((globPattern) => { - if (!globPattern) { - throw new Error('You must provide a file name or glob pattern to transform'); + .command('* [glob/filename...]') + .action((globPatterns: string[]) => { + const prettierOptions: prettier.Options = { + arrowParens: program.arrowParens, + bracketSpacing: !program.noBracketSpacing, + jsxBracketSameLine: !!program.jsxBracketSameLine, + printWidth: parseInt(program.printWidth, 10), + proseWrap: program.proseWrap, + semi: !program.noSemi, + singleQuote: !!program.singleQuote, + tabWidth: parseInt(program.tabWidth, 10), + trailingComma: program.trailingComma, + useTabs: !!program.useTabs, + }; + const compilationOptions: CompilationOptions = { + ignorePrettierErrors: !!program.ignorePrettierErrors, + }; + const files = resolveGlobs(globPatterns); + if (!files.length) { + throw new Error('Nothing to do. You must provide file names or glob patterns to transform.'); } - const files = glob.sync(globPattern, {}); - for (const file of files) { - const filePath = path.resolve(file); + let errors = false; + for (const filePath of files) { + console.log(`Transforming ${filePath}...`); const newPath = filePath.replace(/\.jsx?$/, '.tsx'); - + const temporaryPath = filePath.replace(/\.jsx?$/, `_js2ts_${+new Date()}.tsx`); try { - fs.renameSync(filePath, newPath); - const result = run(newPath); + fs.copyFileSync(filePath, temporaryPath); + const result = run(temporaryPath, prettierOptions, compilationOptions); fs.writeFileSync(newPath, result); - } catch(error) { - console.warn(`Failed to convert ${file}`); + if (!program.keepOriginalFiles) { + fs.unlinkSync(filePath); + } + } catch (error) { + console.warn(`Failed to convert ${filePath}`); console.warn(error); + errors = true; + } + if (!program.keepTemporaryFiles) { + if (fs.existsSync(temporaryPath)) { + fs.unlinkSync(temporaryPath); + } } } + if (errors) { + process.exit(1); + } }); program.parse(process.argv); diff --git a/src/compiler.ts b/src/compiler.ts index 6b5b0d9..4953a7c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1,20 +1,43 @@ +import * as os from 'os'; +import * as fs from 'fs'; import * as ts from 'typescript'; -import * as chalk from 'chalk'; +import chalk from 'chalk'; +import * as _ from 'lodash'; +import * as prettier from 'prettier'; +import * as detectIndent from 'detect-indent'; import { TransformFactoryFactory } from '.'; +export interface CompilationOptions { + ignorePrettierErrors: boolean; +} + +const DEFAULT_COMPILATION_OPTIONS: CompilationOptions = { + ignorePrettierErrors: false, +}; + +export { DEFAULT_COMPILATION_OPTIONS }; + /** * Compile and return result TypeScript * @param filePath Path to file to compile */ -export function compile(filePath: string, factoryFactories: TransformFactoryFactory[]) { +export function compile( + filePath: string, + factoryFactories: TransformFactoryFactory[], + incomingPrettierOptions: prettier.Options = {}, + compilationOptions: CompilationOptions = DEFAULT_COMPILATION_OPTIONS, +) { const compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.ES2015, }; const program = ts.createProgram([filePath], compilerOptions); - const sourceFiles = program.getSourceFiles().filter(sf => !sf.isDeclarationFile); + // `program.getSourceFiles()` will include those imported files, + // like: `import * as a from './file-a'`. + // We should only transform current file. + const sourceFiles = program.getSourceFiles().filter(sf => sf.fileName === filePath); const typeChecker = program.getTypeChecker(); const result = ts.transform( @@ -22,21 +45,96 @@ export function compile(filePath: string, factoryFactories: TransformFactoryFact factoryFactories.map(factoryFactory => factoryFactory(typeChecker), compilerOptions), ); - if (result.diagnostics && result.diagnostics.length) { - console.log(chalk.yellow(` + console.log( + chalk.yellow(` ======================= Diagnostics for ${filePath} ======================= - `)); + `), + ); for (const diag of result.diagnostics) { if (diag.file && diag.start) { const pos = diag.file.getLineAndCharacterOfPosition(diag.start); - console.log(`(${pos.line}, ${pos.character}) ${diag.messageText}`) + console.log(`(${pos.line}, ${pos.character}) ${diag.messageText}`); } } } - const printer = ts.createPrinter() + const printer = ts.createPrinter(); // TODO: fix the index 0 access... What if program have multiple source files? - return printer.printNode(ts.EmitHint.SourceFile, result.transformed[0], sourceFiles[0]); + const printed = printer.printNode(ts.EmitHint.SourceFile, result.transformed[0], sourceFiles[0]); + + const inputSource = fs.readFileSync(filePath, 'utf-8'); + const prettierOptions = getPrettierOptions(filePath, inputSource, incomingPrettierOptions); + + try { + return prettier.format(printed, prettierOptions); + } catch (prettierError) { + if (compilationOptions.ignorePrettierErrors) { + console.warn(`Prettier failed for ${filePath} (ignorePrettierErrors is on):`); + console.warn(prettierError); + return printed; + } + throw prettierError; + } +} + +/** + * Get Prettier options based on style of a JavaScript + * @param filePath Path to source file + * @param source Body of a JavaScript + * @param options Existing prettier option + */ +export function getPrettierOptions(filePath: string, source: string, options: prettier.Options): prettier.Options { + const resolvedOptions = prettier.resolveConfig.sync(filePath); + if (resolvedOptions) { + _.defaults(resolvedOptions, options); + return resolvedOptions; + } + const { amount: indentAmount, type: indentType } = detectIndent(source); + const sourceWidth = getCodeWidth(source, 80); + const semi = getUseOfSemi(source); + const quotations = getQuotation(source); + + _.defaults(Object.assign({}, options), { + tabWidth: indentAmount, + useTabs: indentType && indentType === 'tab', + printWidth: sourceWidth, + semi, + singleQuote: quotations === 'single', + }); + + return options; +} + +/** + * Given body of a source file, return its code width + * @param source + */ +function getCodeWidth(source: string, defaultWidth: number): number { + return source.split(os.EOL).reduce((result, line) => Math.max(result, line.length), defaultWidth); +} + +/** + * Detect if a source file is using semicolon + * @todo: use an actual parser. This is not a proper implementation + * @param source + * @return true if code is using semicolons + */ +function getUseOfSemi(source: string): boolean { + return source.indexOf(';') !== -1; +} + +/** + * Detect if a source file is using single quotes or double quotes + * @todo use an actual parser. This is not a proper implementation + * @param source + */ +function getQuotation(source: string): 'single' | 'double' { + const numberOfSingleQuotes = (source.match(/\'/g) || []).length; + const numberOfDoubleQuotes = (source.match(/\"/g) || []).length; + if (numberOfSingleQuotes > numberOfDoubleQuotes) { + return 'single'; + } + return 'double'; } diff --git a/src/helpers/build-prop-type-interface.ts b/src/helpers/build-prop-type-interface.ts new file mode 100644 index 0000000..df0730a --- /dev/null +++ b/src/helpers/build-prop-type-interface.ts @@ -0,0 +1,188 @@ +import * as ts from 'typescript'; + +/** + * Build props interface from propTypes object + * @example + * { + * foo: React.PropTypes.string.isRequired + * } + * + * becomes + * { + * foo: string; + * } + * @param objectLiteral + */ +export function buildInterfaceFromPropTypeObjectLiteral(objectLiteral: ts.ObjectLiteralExpression) { + const members = objectLiteral.properties + // We only need to process PropertyAssignment: + // { + // a: 123 // PropertyAssignment + // } + // + // filter out: + // { + // a() {}, // MethodDeclaration + // b, // ShorthandPropertyAssignment + // ...c, // SpreadAssignment + // get d() {}, // AccessorDeclaration + // } + .filter(ts.isPropertyAssignment) + // Ignore children, React types have it + .filter(property => property.name.getText() !== 'children') + .map(propertyAssignment => { + const name = propertyAssignment.name.getText(); + const initializer = propertyAssignment.initializer; + const isRequired = isPropTypeRequired(initializer); + const typeExpression = isRequired + ? // We have guaranteed the type in `isPropTypeRequired()` + (initializer as ts.PropertyAccessExpression).expression + : initializer; + const typeValue = getTypeFromReactPropTypeExpression(typeExpression); + + return ts.createPropertySignature( + [], + name, + isRequired ? undefined : ts.createToken(ts.SyntaxKind.QuestionToken), + typeValue, + undefined, + ); + }); + + return ts.createTypeLiteralNode(members); +} + +/** + * Turns React.PropTypes.* into TypeScript type value + * + * @param node React propTypes value + */ +function getTypeFromReactPropTypeExpression(node: ts.Expression): ts.TypeNode { + let result = null; + if (ts.isPropertyAccessExpression(node)) { + /** + * PropTypes.array, + * PropTypes.bool, + * PropTypes.func, + * PropTypes.number, + * PropTypes.object, + * PropTypes.string, + * PropTypes.symbol, (ignore) + * PropTypes.node, + * PropTypes.element, + * PropTypes.any, + */ + const text = node.getText().replace(/React\.PropTypes\./, ''); + + if (/string/.test(text)) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); + } else if (/any/.test(text)) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + } else if (/array/.test(text)) { + result = ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); + } else if (/bool/.test(text)) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); + } else if (/number/.test(text)) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + } else if (/object/.test(text)) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword); + } else if (/node/.test(text)) { + result = ts.createTypeReferenceNode('React.ReactNode', []); + } else if (/element/.test(text)) { + result = ts.createTypeReferenceNode('JSX.Element', []); + } else if (/func/.test(text)) { + const arrayOfAny = ts.createParameter( + [], + [], + ts.createToken(ts.SyntaxKind.DotDotDotToken), + 'args', + undefined, + ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + undefined, + ); + result = ts.createFunctionTypeNode([], [arrayOfAny], ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); + } + } else if (ts.isCallExpression(node)) { + /** + * PropTypes.instanceOf(), (ignore) + * PropTypes.oneOf(), // only support oneOf([1, 2]), oneOf(['a', 'b']) + * PropTypes.oneOfType(), + * PropTypes.arrayOf(), + * PropTypes.objectOf(), + * PropTypes.shape(), + */ + const text = node.expression.getText(); + if (/oneOf$/.test(text)) { + const argument = node.arguments[0]; + if (ts.isArrayLiteralExpression(argument)) { + if (argument.elements.every(elm => ts.isStringLiteral(elm) || ts.isNumericLiteral(elm))) { + result = ts.createUnionTypeNode( + (argument.elements as ts.NodeArray<ts.StringLiteral | ts.NumericLiteral>).map(elm => + ts.createLiteralTypeNode(elm), + ), + ); + } + } + } else if (/oneOfType$/.test(text)) { + const argument = node.arguments[0]; + if (ts.isArrayLiteralExpression(argument)) { + result = ts.createUnionOrIntersectionTypeNode( + ts.SyntaxKind.UnionType, + argument.elements.map(elm => getTypeFromReactPropTypeExpression(elm)), + ); + } + } else if (/arrayOf$/.test(text)) { + const argument = node.arguments[0]; + if (argument) { + result = ts.createArrayTypeNode(getTypeFromReactPropTypeExpression(argument)); + } + } else if (/objectOf$/.test(text)) { + const argument = node.arguments[0]; + if (argument) { + result = ts.createTypeLiteralNode([ + ts.createIndexSignature( + undefined, + undefined, + [ + ts.createParameter( + undefined, + undefined, + undefined, + 'key', + undefined, + ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + ), + ], + getTypeFromReactPropTypeExpression(argument), + ), + ]); + } + } else if (/shape$/.test(text)) { + const argument = node.arguments[0]; + if (ts.isObjectLiteralExpression(argument)) { + return buildInterfaceFromPropTypeObjectLiteral(argument); + } + } + } + + /** + * customProp, + * anything others + */ + if (result === null) { + result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + } + + return result; +} + +/** + * Decide if node is required + * @param node React propTypes member node + */ +function isPropTypeRequired(node: ts.Expression) { + if (!ts.isPropertyAccessExpression(node)) return false; + + const text = node.getText().replace(/React\.PropTypes\./, ''); + return /\.isRequired/.test(text); +} diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 42e54e4..04a2c29 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,7 +1,7 @@ import * as ts from 'typescript'; -import * as kinds from './isKind'; +import * as _ from 'lodash'; -export * from './isKind'; +export * from './build-prop-type-interface'; /** * If a class declaration a react class? @@ -52,10 +52,12 @@ export function isReactComponent(classDeclaration: ts.ClassDeclaration, typeChec * @param clause */ export function isReactHeritageClause(clause: ts.HeritageClause) { - return clause.token === ts.SyntaxKind.ExtendsKeyword && + return ( + clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length === 1 && - kinds.isExpressionWithTypeArguments(clause.types[0]) && - /Component/.test(clause.types[0].expression.getText()); + ts.isExpressionWithTypeArguments(clause.types[0]) && + /Component/.test(clause.types[0].expression.getText()) + ); } /** @@ -65,11 +67,13 @@ export function isReactHeritageClause(clause: ts.HeritageClause) { * @param statement */ export function isReactPropTypeAssignmentStatement(statement: ts.Statement): statement is ts.ExpressionStatement { - return kinds.isExpressionStatement(statement) - && kinds.isBinaryExpression(statement.expression) - && statement.expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment - && kinds.isPropertyAccessExpression(statement.expression.left) - && /\.propTypes$|\.propTypes\..+$/.test(statement.expression.left.getText()) + return ( + ts.isExpressionStatement(statement) && + ts.isBinaryExpression(statement.expression) && + statement.expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment && + ts.isPropertyAccessExpression(statement.expression.left) && + /\.propTypes$|\.propTypes\..+$/.test(statement.expression.left.getText()) + ); } /** @@ -80,7 +84,7 @@ export function hasStaticModifier(classMember: ts.ClassElement) { if (!classMember.modifiers) { return false; } - const staticModifier = find(classMember.modifiers, (modifier) => { + const staticModifier = _.find(classMember.modifiers, modifier => { return modifier.kind == ts.SyntaxKind.StaticKeyword; }); return staticModifier !== undefined; @@ -93,43 +97,61 @@ export function hasStaticModifier(classMember: ts.ClassElement) { */ export function isPropTypesMember(classMember: ts.ClassElement, sourceFile: ts.SourceFile) { try { - return classMember.name !== undefined && classMember.name.getFullText(sourceFile) !== 'propTypes' + const name = + classMember.name !== undefined && ts.isIdentifier(classMember.name) ? classMember.name.escapedText : null; + return name === 'propTypes'; } catch (e) { return false; } } -// TODO: replace following functions with Lodash? -// --------------------------------------------------------------------------------------------------------- - /** - * Find an item in a collection with a matcher - * @param collection - * @param matcher + * Get component name off of a propType assignment statement + * @param propTypeAssignment + * @param sourceFile */ -export function find<T>(collection: T[], matcher: (item: T) => boolean): T | undefined { - for (const item of collection) { - if (matcher(item)) { return item; } - } - - return undefined; +export function getComponentName(propTypeAssignment: ts.Statement, sourceFile: ts.SourceFile) { + const text = propTypeAssignment.getText(sourceFile); + return text.substr(0, text.indexOf('.')); } /** - * Look in a collection and see if collection has a specific item - * @param collection - * @param matcher + * Convert react stateless function to arrow function + * @example + * Before: + * function Hello(message) { + * return <div>{message}</div> + * } + * + * After: + * const Hello = message => { + * return <div>{message}</div> + * } */ -export function has<T>(collection: T[], matcher: (item: T) => boolean): boolean { - if (!collection || !collection.length) { - return false; - } - - for (const item of collection) { - if (matcher(item)) { return true; } - } - - return false; +export function convertReactStatelessFunctionToArrowFunction( + statelessFunc: ts.FunctionDeclaration | ts.VariableStatement, +) { + if (ts.isVariableStatement(statelessFunc)) return statelessFunc; + + const funcName = statelessFunc.name || 'Component'; + const funcBody = statelessFunc.body || ts.createBlock([]); + + const initializer = ts.createArrowFunction( + undefined, + undefined, + statelessFunc.parameters, + undefined, + undefined, + funcBody, + ); + + return ts.createVariableStatement( + statelessFunc.modifiers, + ts.createVariableDeclarationList( + [ts.createVariableDeclaration(funcName, undefined, initializer)], + ts.NodeFlags.Const, + ), + ); } /** @@ -138,10 +160,12 @@ export function has<T>(collection: T[], matcher: (item: T) => boolean): boolean * @param afterItem * @param newItem */ -export function insertAfter<T>(collection: T[], afterItem: T, newItem: T) { - const index = collection.indexOf(afterItem) + 1; +export function insertAfter<T>(collection: ArrayLike<T>, afterItem: T, newItem: T) { + const index = _.indexOf(collection, afterItem) + 1; - return collection.slice(0, index).concat(newItem).concat(collection.slice(index)); + return _.slice(collection, 0, index) + .concat(newItem) + .concat(_.slice(collection, index)); } /** @@ -150,10 +174,12 @@ export function insertAfter<T>(collection: T[], afterItem: T, newItem: T) { * @param beforeItem * @param newItem */ -export function insertBefore<T>(collection: T[], beforeItem: T, newItem: T) { - const index = collection.indexOf(beforeItem); +export function insertBefore<T>(collection: ArrayLike<T>, beforeItem: T, newItems: T | T[]) { + const index = _.indexOf(collection, beforeItem); - return collection.slice(0, index).concat(newItem).concat(collection.slice(index)); + return _.slice(collection, 0, index) + .concat(newItems) + .concat(_.slice(collection, index)); } /** @@ -162,10 +188,11 @@ export function insertBefore<T>(collection: T[], beforeItem: T, newItem: T) { * @param item * @param newItem */ -export function replaceItem<T>(collection: T[], item: T, newItem: T) { - const index = collection.indexOf(item); - - return collection.slice(0, index).concat(newItem).concat(collection.slice(index + 1)); +export function replaceItem<T>(collection: ArrayLike<T>, item: T, newItem: T) { + const index = _.indexOf(collection, item); + return _.slice(collection, 0, index) + .concat(newItem) + .concat(_.slice(collection, index + 1)); } /** @@ -174,8 +201,7 @@ export function replaceItem<T>(collection: T[], item: T, newItem: T) { * @param item * @param newItem */ -export function removeItem<T>(collection: T[], item: T) { - const index = collection.indexOf(item); - - return collection.slice(0, index).concat(collection.slice(index + 1)); +export function removeItem<T>(collection: ArrayLike<T>, item: T) { + const index = _.indexOf(collection, item); + return _.slice(collection, 0, index).concat(_.slice(collection, index + 1)); } diff --git a/src/helpers/isKind.ts b/src/helpers/isKind.ts deleted file mode 100644 index 8756ad9..0000000 --- a/src/helpers/isKind.ts +++ /dev/null @@ -1,1185 +0,0 @@ -import * as ts from 'typescript'; - -/** - * Return true if node is `EndOfFileToken` - * @param node A TypeScript node - */ -export function isEndOfFileToken(node: ts.Node): node is ts.EndOfFileToken { - return node.kind === ts.SyntaxKind.EndOfFileToken; -} - -/** - * Return true if node is `NumericLiteral` - * @param node A TypeScript node - */ -export function isNumericLiteral(node: ts.Node): node is ts.NumericLiteral { - return node.kind === ts.SyntaxKind.NumericLiteral; -} - -/** - * Return true if node is `StringLiteral` - * @param node A TypeScript node - */ -export function isStringLiteral(node: ts.Node): node is ts.StringLiteral { - return node.kind === ts.SyntaxKind.StringLiteral; -} - -/** - * Return true if node is `JsxText` - * @param node A TypeScript node - */ -export function isJsxText(node: ts.Node): node is ts.JsxText { - return node.kind === ts.SyntaxKind.JsxText; -} - -/** - * Return true if node is `RegularExpressionLiteral` - * @param node A TypeScript node - */ -export function isRegularExpressionLiteral(node: ts.Node): node is ts.RegularExpressionLiteral { - return node.kind === ts.SyntaxKind.RegularExpressionLiteral; -} - -/** - * Return true if node is `NoSubstitutionTemplateLiteral` - * @param node A TypeScript node - */ -export function isNoSubstitutionTemplateLiteral(node: ts.Node): node is ts.NoSubstitutionTemplateLiteral { - return node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral; -} - -/** - * Return true if node is `TemplateHead` - * @param node A TypeScript node - */ -export function isTemplateHead(node: ts.Node): node is ts.TemplateHead { - return node.kind === ts.SyntaxKind.TemplateHead; -} - -/** - * Return true if node is `TemplateMiddle` - * @param node A TypeScript node - */ -export function isTemplateMiddle(node: ts.Node): node is ts.TemplateMiddle { - return node.kind === ts.SyntaxKind.TemplateMiddle; -} - -/** - * Return true if node is `TemplateTail` - * @param node A TypeScript node - */ -export function isTemplateTail(node: ts.Node): node is ts.TemplateTail { - return node.kind === ts.SyntaxKind.TemplateTail; -} - -/** - * Return true if node is `DotDotDotToken` - * @param node A TypeScript node - */ -export function isDotDotDotToken(node: ts.Node): node is ts.DotDotDotToken { - return node.kind === ts.SyntaxKind.DotDotDotToken; -} - -/** - * Return true if node is `EqualsGreaterThanToken` - * @param node A TypeScript node - */ -export function isEqualsGreaterThanToken(node: ts.Node): node is ts.EqualsGreaterThanToken { - return node.kind === ts.SyntaxKind.EqualsGreaterThanToken; -} - -/** - * Return true if node is `AsteriskToken` - * @param node A TypeScript node - */ -export function isAsteriskToken(node: ts.Node): node is ts.AsteriskToken { - return node.kind === ts.SyntaxKind.AsteriskToken; -} - -/** - * Return true if node is `QuestionToken` - * @param node A TypeScript node - */ -export function isQuestionToken(node: ts.Node): node is ts.QuestionToken { - return node.kind === ts.SyntaxKind.QuestionToken; -} - -/** - * Return true if node is `ColonToken` - * @param node A TypeScript node - */ -export function isColonToken(node: ts.Node): node is ts.ColonToken { - return node.kind === ts.SyntaxKind.ColonToken; -} - -/** - * Return true if node is `AtToken` - * @param node A TypeScript node - */ -export function isAtToken(node: ts.Node): node is ts.AtToken { - return node.kind === ts.SyntaxKind.AtToken; -} - -/** - * Return true if node is `EqualsToken` - * @param node A TypeScript node - */ -export function isEqualsToken(node: ts.Node): node is ts.EqualsToken { - return node.kind === ts.SyntaxKind.EqualsToken; -} - -/** - * Return true if node is `Identifier` - * @param node A TypeScript node - */ -export function isIdentifier(node: ts.Node): node is ts.Identifier { - return node.kind === ts.SyntaxKind.Identifier; -} - -/** - * Return true if node is `QualifiedName` - * @param node A TypeScript node - */ -export function isQualifiedName(node: ts.Node): node is ts.QualifiedName { - return node.kind === ts.SyntaxKind.QualifiedName; -} - -/** - * Return true if node is `ComputedPropertyName` - * @param node A TypeScript node - */ -export function isComputedPropertyName(node: ts.Node): node is ts.ComputedPropertyName { - return node.kind === ts.SyntaxKind.ComputedPropertyName; -} - -/** - * Return true if node is `Decorator` - * @param node A TypeScript node - */ -export function isDecorator(node: ts.Node): node is ts.Decorator { - return node.kind === ts.SyntaxKind.Decorator; -} - -/** - * Return true if node is `PropertySignature` - * @param node A TypeScript node - */ -export function isPropertySignature(node: ts.Node): node is ts.PropertySignature { - return node.kind === ts.SyntaxKind.PropertySignature; -} - -/** - * Return true if node is `PropertyDeclaration` - * @param node A TypeScript node - */ -export function isPropertyDeclaration(node: ts.Node): node is ts.PropertyDeclaration { - return node.kind === ts.SyntaxKind.PropertyDeclaration; -} - -/** - * Return true if node is `MethodSignature` - * @param node A TypeScript node - */ -export function isMethodSignature(node: ts.Node): node is ts.MethodSignature { - return node.kind === ts.SyntaxKind.MethodSignature; -} - -/** - * Return true if node is `MethodDeclaration` - * @param node A TypeScript node - */ -export function isMethodDeclaration(node: ts.Node): node is ts.MethodDeclaration { - return node.kind === ts.SyntaxKind.MethodDeclaration; -} - -/** - * Return true if node is `ObjectBindingPattern` - * @param node A TypeScript node - */ -export function isObjectBindingPattern(node: ts.Node): node is ts.ObjectBindingPattern { - return node.kind === ts.SyntaxKind.ObjectBindingPattern; -} - -/** - * Return true if node is `ArrayBindingPattern` - * @param node A TypeScript node - */ -export function isArrayBindingPattern(node: ts.Node): node is ts.ArrayBindingPattern { - return node.kind === ts.SyntaxKind.ArrayBindingPattern; -} - -/** - * Return true if node is `BindingElement` - * @param node A TypeScript node - */ -export function isBindingElement(node: ts.Node): node is ts.BindingElement { - return node.kind === ts.SyntaxKind.BindingElement; -} - -/** - * Return true if node is `ArrayLiteralExpression` - * @param node A TypeScript node - */ -export function isArrayLiteralExpression(node: ts.Node): node is ts.ArrayLiteralExpression { - return node.kind === ts.SyntaxKind.ArrayLiteralExpression; -} - -/** - * Return true if node is `ObjectLiteralExpression` - * @param node A TypeScript node - */ -export function isObjectLiteralExpression(node: ts.Node): node is ts.ObjectLiteralExpression { - return node.kind === ts.SyntaxKind.ObjectLiteralExpression; -} - -/** - * Return true if node is `PropertyAccessExpression` - * @param node A TypeScript node - */ -export function isPropertyAccessExpression(node: ts.Node): node is ts.PropertyAccessExpression { - return node.kind === ts.SyntaxKind.PropertyAccessExpression; -} - -/** - * Return true if node is `ElementAccessExpression` - * @param node A TypeScript node - */ -export function isElementAccessExpression(node: ts.Node): node is ts.ElementAccessExpression { - return node.kind === ts.SyntaxKind.ElementAccessExpression; -} - -/** - * Return true if node is `CallExpression` - * @param node A TypeScript node - */ -export function isCallExpression(node: ts.Node): node is ts.CallExpression { - return node.kind === ts.SyntaxKind.CallExpression; -} - -/** - * Return true if node is `NewExpression` - * @param node A TypeScript node - */ -export function isNewExpression(node: ts.Node): node is ts.NewExpression { - return node.kind === ts.SyntaxKind.NewExpression; -} - -/** - * Return true if node is `TaggedTemplateExpression` - * @param node A TypeScript node - */ -export function isTaggedTemplateExpression(node: ts.Node): node is ts.TaggedTemplateExpression { - return node.kind === ts.SyntaxKind.TaggedTemplateExpression; -} - -/** - * Return true if node is `ParenthesizedExpression` - * @param node A TypeScript node - */ -export function isParenthesizedExpression(node: ts.Node): node is ts.ParenthesizedExpression { - return node.kind === ts.SyntaxKind.ParenthesizedExpression; -} - -/** - * Return true if node is `FunctionExpression` - * @param node A TypeScript node - */ -export function isFunctionExpression(node: ts.Node): node is ts.FunctionExpression { - return node.kind === ts.SyntaxKind.FunctionExpression; -} - -/** - * Return true if node is `ArrowFunction` - * @param node A TypeScript node - */ -export function isArrowFunction(node: ts.Node): node is ts.ArrowFunction { - return node.kind === ts.SyntaxKind.ArrowFunction; -} - -/** - * Return true if node is `DeleteExpression` - * @param node A TypeScript node - */ -export function isDeleteExpression(node: ts.Node): node is ts.DeleteExpression { - return node.kind === ts.SyntaxKind.DeleteExpression; -} - -/** - * Return true if node is `TypeOfExpression` - * @param node A TypeScript node - */ -export function isTypeOfExpression(node: ts.Node): node is ts.TypeOfExpression { - return node.kind === ts.SyntaxKind.TypeOfExpression; -} - -/** - * Return true if node is `VoidExpression` - * @param node A TypeScript node - */ -export function isVoidExpression(node: ts.Node): node is ts.VoidExpression { - return node.kind === ts.SyntaxKind.VoidExpression; -} - -/** - * Return true if node is `AwaitExpression` - * @param node A TypeScript node - */ -export function isAwaitExpression(node: ts.Node): node is ts.AwaitExpression { - return node.kind === ts.SyntaxKind.AwaitExpression; -} - -/** - * Return true if node is `PrefixUnaryExpression` - * @param node A TypeScript node - */ -export function isPrefixUnaryExpression(node: ts.Node): node is ts.PrefixUnaryExpression { - return node.kind === ts.SyntaxKind.PrefixUnaryExpression; -} - -/** - * Return true if node is `PostfixUnaryExpression` - * @param node A TypeScript node - */ -export function isPostfixUnaryExpression(node: ts.Node): node is ts.PostfixUnaryExpression { - return node.kind === ts.SyntaxKind.PostfixUnaryExpression; -} - -/** - * Return true if node is `BinaryExpression` - * @param node A TypeScript node - */ -export function isBinaryExpression(node: ts.Node): node is ts.BinaryExpression { - return node.kind === ts.SyntaxKind.BinaryExpression; -} - -/** - * Return true if node is `ConditionalExpression` - * @param node A TypeScript node - */ -export function isConditionalExpression(node: ts.Node): node is ts.ConditionalExpression { - return node.kind === ts.SyntaxKind.ConditionalExpression; -} - -/** - * Return true if node is `TemplateExpression` - * @param node A TypeScript node - */ -export function isTemplateExpression(node: ts.Node): node is ts.TemplateExpression { - return node.kind === ts.SyntaxKind.TemplateExpression; -} - -/** - * Return true if node is `YieldExpression` - * @param node A TypeScript node - */ -export function isYieldExpression(node: ts.Node): node is ts.YieldExpression { - return node.kind === ts.SyntaxKind.YieldExpression; -} - -/** - * Return true if node is `SpreadElement` - * @param node A TypeScript node - */ -export function isSpreadElement(node: ts.Node): node is ts.SpreadElement { - return node.kind === ts.SyntaxKind.SpreadElement; -} - -/** - * Return true if node is `ClassExpression` - * @param node A TypeScript node - */ -export function isClassExpression(node: ts.Node): node is ts.ClassExpression { - return node.kind === ts.SyntaxKind.ClassExpression; -} - -/** - * Return true if node is `OmittedExpression` - * @param node A TypeScript node - */ -export function isOmittedExpression(node: ts.Node): node is ts.OmittedExpression { - return node.kind === ts.SyntaxKind.OmittedExpression; -} - -/** - * Return true if node is `ExpressionWithTypeArguments` - * @param node A TypeScript node - */ -export function isExpressionWithTypeArguments(node: ts.Node): node is ts.ExpressionWithTypeArguments { - return node.kind === ts.SyntaxKind.ExpressionWithTypeArguments; -} - -/** - * Return true if node is `AsExpression` - * @param node A TypeScript node - */ -export function isAsExpression(node: ts.Node): node is ts.AsExpression { - return node.kind === ts.SyntaxKind.AsExpression; -} - -/** - * Return true if node is `NonNullExpression` - * @param node A TypeScript node - */ -export function isNonNullExpression(node: ts.Node): node is ts.NonNullExpression { - return node.kind === ts.SyntaxKind.NonNullExpression; -} - -/** - * Return true if node is `MetaProperty` - * @param node A TypeScript node - */ -export function isMetaProperty(node: ts.Node): node is ts.MetaProperty { - return node.kind === ts.SyntaxKind.MetaProperty; -} - -/** - * Return true if node is `TemplateSpan` - * @param node A TypeScript node - */ -export function isTemplateSpan(node: ts.Node): node is ts.TemplateSpan { - return node.kind === ts.SyntaxKind.TemplateSpan; -} - -/** - * Return true if node is `SemicolonClassElement` - * @param node A TypeScript node - */ -export function isSemicolonClassElement(node: ts.Node): node is ts.SemicolonClassElement { - return node.kind === ts.SyntaxKind.SemicolonClassElement; -} - -/** - * Return true if node is `Block` - * @param node A TypeScript node - */ -export function isBlock(node: ts.Node): node is ts.Block { - return node.kind === ts.SyntaxKind.Block; -} - -/** - * Return true if node is `VariableStatement` - * @param node A TypeScript node - */ -export function isVariableStatement(node: ts.Node): node is ts.VariableStatement { - return node.kind === ts.SyntaxKind.VariableStatement; -} - -/** - * Return true if node is `EmptyStatement` - * @param node A TypeScript node - */ -export function isEmptyStatement(node: ts.Node): node is ts.EmptyStatement { - return node.kind === ts.SyntaxKind.EmptyStatement; -} - -/** - * Return true if node is `ExpressionStatement` - * @param node A TypeScript node - */ -export function isExpressionStatement(node: ts.Node): node is ts.ExpressionStatement { - return node.kind === ts.SyntaxKind.ExpressionStatement; -} - -/** - * Return true if node is `IfStatement` - * @param node A TypeScript node - */ -export function isIfStatement(node: ts.Node): node is ts.IfStatement { - return node.kind === ts.SyntaxKind.IfStatement; -} - -/** - * Return true if node is `DoStatement` - * @param node A TypeScript node - */ -export function isDoStatement(node: ts.Node): node is ts.DoStatement { - return node.kind === ts.SyntaxKind.DoStatement; -} - -/** - * Return true if node is `WhileStatement` - * @param node A TypeScript node - */ -export function isWhileStatement(node: ts.Node): node is ts.WhileStatement { - return node.kind === ts.SyntaxKind.WhileStatement; -} - -/** - * Return true if node is `ForStatement` - * @param node A TypeScript node - */ -export function isForStatement(node: ts.Node): node is ts.ForStatement { - return node.kind === ts.SyntaxKind.ForStatement; -} - -/** - * Return true if node is `ForInStatement` - * @param node A TypeScript node - */ -export function isForInStatement(node: ts.Node): node is ts.ForInStatement { - return node.kind === ts.SyntaxKind.ForInStatement; -} - -/** - * Return true if node is `ForOfStatement` - * @param node A TypeScript node - */ -export function isForOfStatement(node: ts.Node): node is ts.ForOfStatement { - return node.kind === ts.SyntaxKind.ForOfStatement; -} - -/** - * Return true if node is `ContinueStatement` - * @param node A TypeScript node - */ -export function isContinueStatement(node: ts.Node): node is ts.ContinueStatement { - return node.kind === ts.SyntaxKind.ContinueStatement; -} - -/** - * Return true if node is `BreakStatement` - * @param node A TypeScript node - */ -export function isBreakStatement(node: ts.Node): node is ts.BreakStatement { - return node.kind === ts.SyntaxKind.BreakStatement; -} - -/** - * Return true if node is `ReturnStatement` - * @param node A TypeScript node - */ -export function isReturnStatement(node: ts.Node): node is ts.ReturnStatement { - return node.kind === ts.SyntaxKind.ReturnStatement; -} - -/** - * Return true if node is `WithStatement` - * @param node A TypeScript node - */ -export function isWithStatement(node: ts.Node): node is ts.WithStatement { - return node.kind === ts.SyntaxKind.WithStatement; -} - -/** - * Return true if node is `SwitchStatement` - * @param node A TypeScript node - */ -export function isSwitchStatement(node: ts.Node): node is ts.SwitchStatement { - return node.kind === ts.SyntaxKind.SwitchStatement; -} - -/** - * Return true if node is `LabeledStatement` - * @param node A TypeScript node - */ -export function isLabeledStatement(node: ts.Node): node is ts.LabeledStatement { - return node.kind === ts.SyntaxKind.LabeledStatement; -} - -/** - * Return true if node is `ThrowStatement` - * @param node A TypeScript node - */ -export function isThrowStatement(node: ts.Node): node is ts.ThrowStatement { - return node.kind === ts.SyntaxKind.ThrowStatement; -} - -/** - * Return true if node is `TryStatement` - * @param node A TypeScript node - */ -export function isTryStatement(node: ts.Node): node is ts.TryStatement { - return node.kind === ts.SyntaxKind.TryStatement; -} - -/** - * Return true if node is `DebuggerStatement` - * @param node A TypeScript node - */ -export function isDebuggerStatement(node: ts.Node): node is ts.DebuggerStatement { - return node.kind === ts.SyntaxKind.DebuggerStatement; -} - -/** - * Return true if node is `VariableDeclaration` - * @param node A TypeScript node - */ -export function isVariableDeclaration(node: ts.Node): node is ts.VariableDeclaration { - return node.kind === ts.SyntaxKind.VariableDeclaration; -} - -/** - * Return true if node is `VariableDeclarationList` - * @param node A TypeScript node - */ -export function isVariableDeclarationList(node: ts.Node): node is ts.VariableDeclarationList { - return node.kind === ts.SyntaxKind.VariableDeclarationList; -} - -/** - * Return true if node is `FunctionDeclaration` - * @param node A TypeScript node - */ -export function isFunctionDeclaration(node: ts.Node): node is ts.FunctionDeclaration { - return node.kind === ts.SyntaxKind.FunctionDeclaration; -} - -/** - * Return true if node is `ClassDeclaration` - * @param node A TypeScript node - */ -export function isClassDeclaration(node: ts.Node): node is ts.ClassDeclaration { - return node.kind === ts.SyntaxKind.ClassDeclaration; -} - -/** - * Return true if node is `InterfaceDeclaration` - * @param node A TypeScript node - */ -export function isInterfaceDeclaration(node: ts.Node): node is ts.InterfaceDeclaration { - return node.kind === ts.SyntaxKind.InterfaceDeclaration; -} - -/** - * Return true if node is `TypeAliasDeclaration` - * @param node A TypeScript node - */ -export function isTypeAliasDeclaration(node: ts.Node): node is ts.TypeAliasDeclaration { - return node.kind === ts.SyntaxKind.TypeAliasDeclaration; -} - -/** - * Return true if node is `EnumDeclaration` - * @param node A TypeScript node - */ -export function isEnumDeclaration(node: ts.Node): node is ts.EnumDeclaration { - return node.kind === ts.SyntaxKind.EnumDeclaration; -} - -/** - * Return true if node is `ModuleDeclaration` - * @param node A TypeScript node - */ -export function isModuleDeclaration(node: ts.Node): node is ts.ModuleDeclaration { - return node.kind === ts.SyntaxKind.ModuleDeclaration; -} - -/** - * Return true if node is `ModuleBlock` - * @param node A TypeScript node - */ -export function isModuleBlock(node: ts.Node): node is ts.ModuleBlock { - return node.kind === ts.SyntaxKind.ModuleBlock; -} - -/** - * Return true if node is `CaseBlock` - * @param node A TypeScript node - */ -export function isCaseBlock(node: ts.Node): node is ts.CaseBlock { - return node.kind === ts.SyntaxKind.CaseBlock; -} - -/** - * Return true if node is `NamespaceExportDeclaration` - * @param node A TypeScript node - */ -export function isNamespaceExportDeclaration(node: ts.Node): node is ts.NamespaceExportDeclaration { - return node.kind === ts.SyntaxKind.NamespaceExportDeclaration; -} - -/** - * Return true if node is `ImportEqualsDeclaration` - * @param node A TypeScript node - */ -export function isImportEqualsDeclaration(node: ts.Node): node is ts.ImportEqualsDeclaration { - return node.kind === ts.SyntaxKind.ImportEqualsDeclaration; -} - -/** - * Return true if node is `ImportDeclaration` - * @param node A TypeScript node - */ -export function isImportDeclaration(node: ts.Node): node is ts.ImportDeclaration { - return node.kind === ts.SyntaxKind.ImportDeclaration; -} - -/** - * Return true if node is `ImportClause` - * @param node A TypeScript node - */ -export function isImportClause(node: ts.Node): node is ts.ImportClause { - return node.kind === ts.SyntaxKind.ImportClause; -} - -/** - * Return true if node is `NamespaceImport` - * @param node A TypeScript node - */ -export function isNamespaceImport(node: ts.Node): node is ts.NamespaceImport { - return node.kind === ts.SyntaxKind.NamespaceImport; -} - -/** - * Return true if node is `NamedImports` - * @param node A TypeScript node - */ -export function isNamedImports(node: ts.Node): node is ts.NamedImports { - return node.kind === ts.SyntaxKind.NamedImports; -} - -/** - * Return true if node is `ImportSpecifier` - * @param node A TypeScript node - */ -export function isImportSpecifier(node: ts.Node): node is ts.ImportSpecifier { - return node.kind === ts.SyntaxKind.ImportSpecifier; -} - -/** - * Return true if node is `ExportAssignment` - * @param node A TypeScript node - */ -export function isExportAssignment(node: ts.Node): node is ts.ExportAssignment { - return node.kind === ts.SyntaxKind.ExportAssignment; -} - -/** - * Return true if node is `ExportDeclaration` - * @param node A TypeScript node - */ -export function isExportDeclaration(node: ts.Node): node is ts.ExportDeclaration { - return node.kind === ts.SyntaxKind.ExportDeclaration; -} - -/** - * Return true if node is `NamedExports` - * @param node A TypeScript node - */ -export function isNamedExports(node: ts.Node): node is ts.NamedExports { - return node.kind === ts.SyntaxKind.NamedExports; -} - -/** - * Return true if node is `ExportSpecifier` - * @param node A TypeScript node - */ -export function isExportSpecifier(node: ts.Node): node is ts.ExportSpecifier { - return node.kind === ts.SyntaxKind.ExportSpecifier; -} - -/** - * Return true if node is `MissingDeclaration` - * @param node A TypeScript node - */ -export function isMissingDeclaration(node: ts.Node): node is ts.MissingDeclaration { - return node.kind === ts.SyntaxKind.MissingDeclaration; -} - -/** - * Return true if node is `ExternalModuleReference` - * @param node A TypeScript node - */ -export function isExternalModuleReference(node: ts.Node): node is ts.ExternalModuleReference { - return node.kind === ts.SyntaxKind.ExternalModuleReference; -} - -/** - * Return true if node is `JsxElement` - * @param node A TypeScript node - */ -export function isJsxElement(node: ts.Node): node is ts.JsxElement { - return node.kind === ts.SyntaxKind.JsxElement; -} - -/** - * Return true if node is `JsxSelfClosingElement` - * @param node A TypeScript node - */ -export function isJsxSelfClosingElement(node: ts.Node): node is ts.JsxSelfClosingElement { - return node.kind === ts.SyntaxKind.JsxSelfClosingElement; -} - -/** - * Return true if node is `JsxOpeningElement` - * @param node A TypeScript node - */ -export function isJsxOpeningElement(node: ts.Node): node is ts.JsxOpeningElement { - return node.kind === ts.SyntaxKind.JsxOpeningElement; -} - -/** - * Return true if node is `JsxClosingElement` - * @param node A TypeScript node - */ -export function isJsxClosingElement(node: ts.Node): node is ts.JsxClosingElement { - return node.kind === ts.SyntaxKind.JsxClosingElement; -} - -/** - * Return true if node is `JsxAttribute` - * @param node A TypeScript node - */ -export function isJsxAttribute(node: ts.Node): node is ts.JsxAttribute { - return node.kind === ts.SyntaxKind.JsxAttribute; -} - -/** - * Return true if node is `JsxAttributes` - * @param node A TypeScript node - */ -export function isJsxAttributes(node: ts.Node): node is ts.JsxAttributes { - return node.kind === ts.SyntaxKind.JsxAttributes; -} - -/** - * Return true if node is `JsxSpreadAttribute` - * @param node A TypeScript node - */ -export function isJsxSpreadAttribute(node: ts.Node): node is ts.JsxSpreadAttribute { - return node.kind === ts.SyntaxKind.JsxSpreadAttribute; -} - -/** - * Return true if node is `JsxExpression` - * @param node A TypeScript node - */ -export function isJsxExpression(node: ts.Node): node is ts.JsxExpression { - return node.kind === ts.SyntaxKind.JsxExpression; -} - -/** - * Return true if node is `CaseClause` - * @param node A TypeScript node - */ -export function isCaseClause(node: ts.Node): node is ts.CaseClause { - return node.kind === ts.SyntaxKind.CaseClause; -} - -/** - * Return true if node is `DefaultClause` - * @param node A TypeScript node - */ -export function isDefaultClause(node: ts.Node): node is ts.DefaultClause { - return node.kind === ts.SyntaxKind.DefaultClause; -} - -/** - * Return true if node is `HeritageClause` - * @param node A TypeScript node - */ -export function isHeritageClause(node: ts.Node): node is ts.HeritageClause { - return node.kind === ts.SyntaxKind.HeritageClause; -} - -/** - * Return true if node is `CatchClause` - * @param node A TypeScript node - */ -export function isCatchClause(node: ts.Node): node is ts.CatchClause { - return node.kind === ts.SyntaxKind.CatchClause; -} - -/** - * Return true if node is `PropertyAssignment` - * @param node A TypeScript node - */ -export function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment { - return node.kind === ts.SyntaxKind.PropertyAssignment; -} - -/** - * Return true if node is `ShorthandPropertyAssignment` - * @param node A TypeScript node - */ -export function isShorthandPropertyAssignment(node: ts.Node): node is ts.ShorthandPropertyAssignment { - return node.kind === ts.SyntaxKind.ShorthandPropertyAssignment; -} - -/** - * Return true if node is `SpreadAssignment` - * @param node A TypeScript node - */ -export function isSpreadAssignment(node: ts.Node): node is ts.SpreadAssignment { - return node.kind === ts.SyntaxKind.SpreadAssignment; -} - -/** - * Return true if node is `EnumMember` - * @param node A TypeScript node - */ -export function isEnumMember(node: ts.Node): node is ts.EnumMember { - return node.kind === ts.SyntaxKind.EnumMember; -} - -/** - * Return true if node is `SourceFile` - * @param node A TypeScript node - */ -export function isSourceFile(node: ts.Node): node is ts.SourceFile { - return node.kind === ts.SyntaxKind.SourceFile; -} - -/** - * Return true if node is `Bundle` - * @param node A TypeScript node - */ -export function isBundle(node: ts.Node): node is ts.Bundle { - return node.kind === ts.SyntaxKind.Bundle; -} - -/** - * Return true if node is `JSDocTypeExpression` - * @param node A TypeScript node - */ -export function isJSDocTypeExpression(node: ts.Node): node is ts.JSDocTypeExpression { - return node.kind === ts.SyntaxKind.JSDocTypeExpression; -} - -/** - * Return true if node is `JSDocAllType` - * @param node A TypeScript node - */ -export function isJSDocAllType(node: ts.Node): node is ts.JSDocAllType { - return node.kind === ts.SyntaxKind.JSDocAllType; -} - -/** - * Return true if node is `JSDocUnknownType` - * @param node A TypeScript node - */ -export function isJSDocUnknownType(node: ts.Node): node is ts.JSDocUnknownType { - return node.kind === ts.SyntaxKind.JSDocUnknownType; -} - -/** - * Return true if node is `JSDocArrayType` - * @param node A TypeScript node - */ -export function isJSDocArrayType(node: ts.Node): node is ts.JSDocArrayType { - return node.kind === ts.SyntaxKind.JSDocArrayType; -} - -/** - * Return true if node is `JSDocUnionType` - * @param node A TypeScript node - */ -export function isJSDocUnionType(node: ts.Node): node is ts.JSDocUnionType { - return node.kind === ts.SyntaxKind.JSDocUnionType; -} - -/** - * Return true if node is `JSDocTupleType` - * @param node A TypeScript node - */ -export function isJSDocTupleType(node: ts.Node): node is ts.JSDocTupleType { - return node.kind === ts.SyntaxKind.JSDocTupleType; -} - -/** - * Return true if node is `JSDocNullableType` - * @param node A TypeScript node - */ -export function isJSDocNullableType(node: ts.Node): node is ts.JSDocNullableType { - return node.kind === ts.SyntaxKind.JSDocNullableType; -} - -/** - * Return true if node is `JSDocNonNullableType` - * @param node A TypeScript node - */ -export function isJSDocNonNullableType(node: ts.Node): node is ts.JSDocNonNullableType { - return node.kind === ts.SyntaxKind.JSDocNonNullableType; -} - -/** - * Return true if node is `JSDocRecordType` - * @param node A TypeScript node - */ -export function isJSDocRecordType(node: ts.Node): node is ts.JSDocRecordType { - return node.kind === ts.SyntaxKind.JSDocRecordType; -} - -/** - * Return true if node is `JSDocRecordMember` - * @param node A TypeScript node - */ -export function isJSDocRecordMember(node: ts.Node): node is ts.JSDocRecordMember { - return node.kind === ts.SyntaxKind.JSDocRecordMember; -} - -/** - * Return true if node is `JSDocTypeReference` - * @param node A TypeScript node - */ -export function isJSDocTypeReference(node: ts.Node): node is ts.JSDocTypeReference { - return node.kind === ts.SyntaxKind.JSDocTypeReference; -} - -/** - * Return true if node is `JSDocOptionalType` - * @param node A TypeScript node - */ -export function isJSDocOptionalType(node: ts.Node): node is ts.JSDocOptionalType { - return node.kind === ts.SyntaxKind.JSDocOptionalType; -} - -/** - * Return true if node is `JSDocFunctionType` - * @param node A TypeScript node - */ -export function isJSDocFunctionType(node: ts.Node): node is ts.JSDocFunctionType { - return node.kind === ts.SyntaxKind.JSDocFunctionType; -} - -/** - * Return true if node is `JSDocVariadicType` - * @param node A TypeScript node - */ -export function isJSDocVariadicType(node: ts.Node): node is ts.JSDocVariadicType { - return node.kind === ts.SyntaxKind.JSDocVariadicType; -} - -/** - * Return true if node is `JSDocConstructorType` - * @param node A TypeScript node - */ -export function isJSDocConstructorType(node: ts.Node): node is ts.JSDocConstructorType { - return node.kind === ts.SyntaxKind.JSDocConstructorType; -} - -/** - * Return true if node is `JSDocThisType` - * @param node A TypeScript node - */ -export function isJSDocThisType(node: ts.Node): node is ts.JSDocThisType { - return node.kind === ts.SyntaxKind.JSDocThisType; -} - -/** - * Return true if node is `JSDocTag` - * @param node A TypeScript node - */ -export function isJSDocTag(node: ts.Node): node is ts.JSDocTag { - return node.kind === ts.SyntaxKind.JSDocTag; -} - -/** - * Return true if node is `JSDocAugmentsTag` - * @param node A TypeScript node - */ -export function isJSDocAugmentsTag(node: ts.Node): node is ts.JSDocAugmentsTag { - return node.kind === ts.SyntaxKind.JSDocAugmentsTag; -} - -/** - * Return true if node is `JSDocParameterTag` - * @param node A TypeScript node - */ -export function isJSDocParameterTag(node: ts.Node): node is ts.JSDocParameterTag { - return node.kind === ts.SyntaxKind.JSDocParameterTag; -} - -/** - * Return true if node is `JSDocReturnTag` - * @param node A TypeScript node - */ -export function isJSDocReturnTag(node: ts.Node): node is ts.JSDocReturnTag { - return node.kind === ts.SyntaxKind.JSDocReturnTag; -} - -/** - * Return true if node is `JSDocTypeTag` - * @param node A TypeScript node - */ -export function isJSDocTypeTag(node: ts.Node): node is ts.JSDocTypeTag { - return node.kind === ts.SyntaxKind.JSDocTypeTag; -} - -/** - * Return true if node is `JSDocTemplateTag` - * @param node A TypeScript node - */ -export function isJSDocTemplateTag(node: ts.Node): node is ts.JSDocTemplateTag { - return node.kind === ts.SyntaxKind.JSDocTemplateTag; -} - -/** - * Return true if node is `JSDocTypedefTag` - * @param node A TypeScript node - */ -export function isJSDocTypedefTag(node: ts.Node): node is ts.JSDocTypedefTag { - return node.kind === ts.SyntaxKind.JSDocTypedefTag; -} - -/** - * Return true if node is `JSDocPropertyTag` - * @param node A TypeScript node - */ -export function isJSDocPropertyTag(node: ts.Node): node is ts.JSDocPropertyTag { - return node.kind === ts.SyntaxKind.JSDocPropertyTag; -} - -/** - * Return true if node is `JSDocTypeLiteral` - * @param node A TypeScript node - */ -export function isJSDocTypeLiteral(node: ts.Node): node is ts.JSDocTypeLiteral { - return node.kind === ts.SyntaxKind.JSDocTypeLiteral; -} - -/** - * Return true if node is `JSDocLiteralType` - * @param node A TypeScript node - */ -export function isJSDocLiteralType(node: ts.Node): node is ts.JSDocLiteralType { - return node.kind === ts.SyntaxKind.JSDocLiteralType; -} - -/** - * Return true if node is `SyntaxList` - * @param node A TypeScript node - */ -export function isSyntaxList(node: ts.Node): node is ts.SyntaxList { - return node.kind === ts.SyntaxKind.SyntaxList; -} - -/** - * Return true if node is `NotEmittedStatement` - * @param node A TypeScript node - */ -export function isNotEmittedStatement(node: ts.Node): node is ts.NotEmittedStatement { - return node.kind === ts.SyntaxKind.NotEmittedStatement; -} - -/** - * Return true if node is `PartiallyEmittedExpression` - * @param node A TypeScript node - */ -export function isPartiallyEmittedExpression(node: ts.Node): node is ts.PartiallyEmittedExpression { - return node.kind === ts.SyntaxKind.PartiallyEmittedExpression; -} - -/** - * Return true if node is `IntersectionTypeNode` - * @param node A TypeScript node - */ -export function isIntersectionTypeNode(node: ts.TypeNode): node is ts.IntersectionTypeNode { - return node.kind === ts.SyntaxKind.IntersectionType; -} - -/** - * Return true if node is `LiteralTypeNode` - * @param node A TypeScript node - */ -export function isTypeLiteralNode(node: ts.TypeNode): node is ts.LiteralTypeNode { - return node.kind === ts.SyntaxKind.TypeLiteral; -} - -/** - * Return true if node is `GetAccessorDeclaration` - * @param node A TypeScript node - */ -export function isGetAccessorDeclaration(node: ts.Node): node is ts.GetAccessorDeclaration { - return node.kind === ts.SyntaxKind.GetAccessor; -} diff --git a/src/index.ts b/src/index.ts index 5d6d524..5c26c27 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,50 +1,46 @@ import * as ts from 'typescript'; +import * as prettier from 'prettier'; -import { compile } from './compiler'; -import { - reactJSMakePropsAndStateInterfaceTransformFactoryFactory, -} from './transforms/react-js-make-props-and-state-transform'; -import { - reactHoistGenericsTransformFactoryFactory, -} from './transforms/react-hoist-generics-transform'; -import { - reactRemovePropTypesAssignmentTransformFactoryFactory, -} from './transforms/react-remove-prop-types-assignment-transform'; -import { - reactMovePropTypesToClassTransformFactoryFactory, -} from './transforms/react-move-prop-types-to-class-transform'; -import { - collapseIntersectionInterfacesTransformFactoryFactory, -} from './transforms/collapse-intersection-interfaces-transform'; -import { - reactRemoveStaticPropTypesMemberTransformFactoryFactory, -} from './transforms/react-remove-static-prop-types-member-transform'; +import { compile, CompilationOptions, DEFAULT_COMPILATION_OPTIONS } from './compiler'; +import { reactJSMakePropsAndStateInterfaceTransformFactoryFactory } from './transforms/react-js-make-props-and-state-transform'; +import { reactRemovePropTypesAssignmentTransformFactoryFactory } from './transforms/react-remove-prop-types-assignment-transform'; +import { reactMovePropTypesToClassTransformFactoryFactory } from './transforms/react-move-prop-types-to-class-transform'; +import { collapseIntersectionInterfacesTransformFactoryFactory } from './transforms/collapse-intersection-interfaces-transform'; +import { reactRemoveStaticPropTypesMemberTransformFactoryFactory } from './transforms/react-remove-static-prop-types-member-transform'; +import { reactStatelessFunctionMakePropsTransformFactoryFactory } from './transforms/react-stateless-function-make-props-transform'; +import { reactRemovePropTypesImportTransformFactoryFactory } from './transforms/react-remove-prop-types-import'; export { reactMovePropTypesToClassTransformFactoryFactory, reactJSMakePropsAndStateInterfaceTransformFactoryFactory, - reactHoistGenericsTransformFactoryFactory, + reactStatelessFunctionMakePropsTransformFactoryFactory, collapseIntersectionInterfacesTransformFactoryFactory, reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, + reactRemovePropTypesImportTransformFactoryFactory, compile, }; export const allTransforms = [ reactMovePropTypesToClassTransformFactoryFactory, reactJSMakePropsAndStateInterfaceTransformFactoryFactory, - reactHoistGenericsTransformFactoryFactory, + reactStatelessFunctionMakePropsTransformFactoryFactory, collapseIntersectionInterfacesTransformFactoryFactory, reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, + reactRemovePropTypesImportTransformFactoryFactory, ]; -export type TransformFactoryFactory = (typeChecker: ts.TypeChecker) => ts.TransformerFactory<ts.Node>; +export type TransformFactoryFactory = (typeChecker: ts.TypeChecker) => ts.TransformerFactory<ts.SourceFile>; /** * Run React JavaScript to TypeScript transform for file at `filePath` * @param filePath */ -export function run(filePath: string): string { - return compile(filePath, allTransforms); -} \ No newline at end of file +export function run( + filePath: string, + prettierOptions: prettier.Options = {}, + compilationOptions: CompilationOptions = DEFAULT_COMPILATION_OPTIONS, +): string { + return compile(filePath, allTransforms, prettierOptions, compilationOptions); +} diff --git a/src/transforms/collapse-intersection-interfaces-transform.ts b/src/transforms/collapse-intersection-interfaces-transform.ts index f04a9d1..cca02a4 100644 --- a/src/transforms/collapse-intersection-interfaces-transform.ts +++ b/src/transforms/collapse-intersection-interfaces-transform.ts @@ -1,4 +1,5 @@ import * as ts from 'typescript'; +import * as _ from 'lodash'; import * as helpers from '../helpers'; @@ -13,8 +14,8 @@ import * as helpers from '../helpers'; * type Foo = {foo: string; bar: number;} */ export function collapseIntersectionInterfacesTransformFactoryFactory( - typeChecker: ts.TypeChecker, - ): ts.TransformerFactory<ts.Node> { + typeChecker: ts.TypeChecker, +): ts.TransformerFactory<ts.SourceFile> { return function collapseIntersectionInterfacesTransformFactory(context: ts.TransformationContext) { return function collapseIntersectionInterfacesTransform(sourceFile: ts.SourceFile) { const visited = ts.visitEachChild(sourceFile, visitor, context); @@ -23,7 +24,7 @@ export function collapseIntersectionInterfacesTransformFactoryFactory( return visited; function visitor(node: ts.Node) { - if (helpers.isTypeAliasDeclaration(node)) { + if (ts.isTypeAliasDeclaration(node)) { return visitTypeAliasDeclaration(node); } @@ -31,26 +32,121 @@ export function collapseIntersectionInterfacesTransformFactoryFactory( } function visitTypeAliasDeclaration(node: ts.TypeAliasDeclaration) { - if ( - helpers.isIntersectionTypeNode(node.type) - && node.type.types.every((type) => helpers.isTypeLiteralNode(type)) - ) { - const allMembers = node.type.types - .map((type: ts.TypeLiteralNode) => type.members) - .reduce((all, members) => ts.createNodeArray(all.concat(members)), ts.createNodeArray([])); - + if (ts.isIntersectionTypeNode(node.type)) { return ts.createTypeAliasDeclaration( [], [], node.name.text, [], - ts.createTypeLiteralNode(allMembers), + visitIntersectionTypeNode(node.type), ); } return node; } - } - } -} + function visitIntersectionTypeNode(node: ts.IntersectionTypeNode) { + // Only intersection of type literals can be colapsed. + // We are currently ignoring intersections such as `{foo: string} & {bar: string} & TypeRef` + // TODO: handle mix of type references and multiple literal types + if (!node.types.every(typeNode => ts.isTypeLiteralNode(typeNode))) { + return node; + } + + // We need cast `node.type.types` to `ts.NodeArray<ts.TypeLiteralNode>` + // because TypeScript can't figure out `node.type.types.every(ts.isTypeLiteralNode)` + const types = node.types as ts.NodeArray<ts.TypeLiteralNode>; + + // Build a map of member names to all of types found in intersectioning type literals + // For instance {foo: string, bar: number} & { foo: number } will result in a map like this: + // Map { + // 'foo' => Set { 'string', 'number' }, + // 'bar' => Set { 'number' } + // } + const membersMap = new Map<string | symbol, Set<ts.TypeNode>>(); + + // A sepecial member of type literal nodes is index signitures which don't have a name + // We use this symbol to track it in our members map + const INDEX_SIGNITUTRE_MEMBER = Symbol('Index signiture member'); + + // Keep a reference of first index signiture member parameters. (ignore rest) + let indexMemberParameter: ts.NodeArray<ts.ParameterDeclaration> | null = null; + + // Iterate through all of type literal nodes members and add them to the members map + types.forEach(typeNode => { + typeNode.members.forEach(member => { + if (ts.isIndexSignatureDeclaration(member)) { + if (member.type !== undefined) { + if (membersMap.has(INDEX_SIGNITUTRE_MEMBER)) { + membersMap.get(INDEX_SIGNITUTRE_MEMBER)!.add(member.type); + } else { + indexMemberParameter = member.parameters; + membersMap.set(INDEX_SIGNITUTRE_MEMBER, new Set([member.type])); + } + } + } else if (ts.isPropertySignature(member)) { + if (member.type !== undefined) { + let memberName = member.name.getText(sourceFile); + + // For unknown reasons, member.name.getText() is returning nothing in some cases + // This is probably because previous transformers did something with the AST that + // index of text string of member identifier is lost + // TODO: investigate + if (!memberName) { + memberName = (member.name as any).escapedText; + } + + if (membersMap.has(memberName)) { + membersMap.get(memberName)!.add(member.type); + } else { + membersMap.set(memberName, new Set([member.type])); + } + } + } + }); + }); + + // Result type literal members list + const finalMembers: Array<ts.PropertySignature | ts.IndexSignatureDeclaration> = []; + + // Put together the map into a type literal that has member per each map entery and type of that + // member is a union of all types in vlues for that member name in members map + // if a member has only one type, create a simple type literal for it + for (const [name, types] of membersMap.entries()) { + if (typeof name === 'symbol') { + continue; + } + // if for this name there is only one type found use the first type, otherwise make a union of all types + let resultType = types.size === 1 ? Array.from(types)[0] : createUnionType(Array.from(types)); + + finalMembers.push(ts.createPropertySignature([], name, undefined, resultType, undefined)); + } + + // Handle index signiture member + if (membersMap.has(INDEX_SIGNITUTRE_MEMBER)) { + const indexTypes = Array.from(membersMap.get(INDEX_SIGNITUTRE_MEMBER)!); + let indexType = indexTypes[0]; + if (indexTypes.length > 1) { + indexType = createUnionType(indexTypes); + } + const indexSigniture = ts.createIndexSignature([], [], indexMemberParameter!, indexType); + finalMembers.push(indexSigniture); + } + + // Generate one single type literal node + return ts.createTypeLiteralNode(finalMembers); + } + + /** + * Create a union type from multiple type nodes + * @param types + */ + function createUnionType(types: ts.TypeNode[]) { + // first dedupe literal types + // TODO: this only works if all types are primitive types like string or number + const uniqueTypes = _.uniqBy(types, type => type.kind); + return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, uniqueTypes); + } + }; + }; +} diff --git a/src/transforms/react-hoist-generics-transform.ts b/src/transforms/react-hoist-generics-transform.ts deleted file mode 100644 index b2aa4c3..0000000 --- a/src/transforms/react-hoist-generics-transform.ts +++ /dev/null @@ -1,121 +0,0 @@ -import * as ts from 'typescript'; - -import * as helpers from '../helpers'; - -/** - * Hoist generics to top of a class declarations in a React component - * - * @example - * Before: - * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {} - * - * After - * type SomeComponentProps = {foo: number;}; - * type SomeComponentState = {bar: string;}; - * class SomeComponent extends React.Component<SomeComponentProps, SomeComponentState> {} - */ -export function reactHoistGenericsTransformFactoryFactory(typeChecker: ts.TypeChecker): ts.TransformerFactory<ts.Node> { - return function reactHoistGenericsTransformFactory(context: ts.TransformationContext) { - return function reactHoistGenericsTransform(node: ts.SourceFile) { - return visitSourceFile(node); - }; - }; - - function visitSourceFile(sourceFile: ts.SourceFile) { - - for (const statement of sourceFile.statements) { - if (helpers.isClassDeclaration(statement) && helpers.isReactComponent(statement, typeChecker)) { - return hoist(statement, sourceFile); - } - } - - return sourceFile; - } -} - -/** - * Hoist props and state generic types - * @param reactClass - * @param sourceFile - */ -function hoist(reactClass: ts.ClassDeclaration, sourceFile: ts.SourceFile) { - if (!reactClass.heritageClauses) { - return reactClass; - } - const className = reactClass && reactClass.name && reactClass.name.getText(sourceFile); - const reactHeritageClauses = helpers.find(reactClass.heritageClauses, helpers.isReactHeritageClause); - - if (reactHeritageClauses === undefined || !reactHeritageClauses.types == undefined) { - return reactClass; - } - const [reactType] = reactHeritageClauses.types; - if (reactType.typeArguments === undefined || reactType.typeArguments.length < 2) { - return reactClass; - } - - const [propType, stateType] = reactType.typeArguments; - const propTypeName = `${className}Props`; - const stateTypeName = `${className}State`; - const propTypeDeclaration = ts.createTypeAliasDeclaration([], [], propTypeName, [], propType); - const stateTypeDeclaration = ts.createTypeAliasDeclaration([], [], stateTypeName, [], stateType); - const propTypeRef = ts.createTypeReferenceNode(propTypeName, []); - const stateTypeRef = ts.createTypeReferenceNode(stateTypeName, []); - const newClassStatement = insertTypeRefs(reactClass, propTypeRef, stateTypeRef); - - let statements = helpers.insertBefore(sourceFile.statements, reactClass, propTypeDeclaration) - statements = helpers.insertAfter(statements, propTypeDeclaration, stateTypeDeclaration); - statements = helpers.replaceItem(statements, reactClass, newClassStatement); - - return ts.updateSourceFileNode(sourceFile, statements); -} - -/** - * Replace props and state types in a React component with type references - * - * @example - * input - * ``` - * class MyComp extends React.Component<{}, {}> {} - * ``` - * - * output - * ``` - * class MyComp extends React.Component<IFoo, IBar> {} - * ``` - * - * @param reactClassDeclaration A React class declaration - * @param propTypeRef React Props type reference - * @param stateTypeRef React State type reference - */ -function insertTypeRefs( - reactClassDeclaration: ts.ClassDeclaration, - propTypeRef: ts.TypeReferenceNode, - stateTypeRef: ts.TypeReferenceNode, -) { - if (reactClassDeclaration.heritageClauses === undefined) { - return reactClassDeclaration; - } - const reactHeritageClause = helpers.find(reactClassDeclaration.heritageClauses, helpers.isReactHeritageClause); - - if (reactHeritageClause === undefined) { - return reactClassDeclaration; - } - - const [reactExpression] = reactHeritageClause.types; - const newReactExpression = ts.updateExpressionWithTypeArguments( - reactExpression, - [propTypeRef, stateTypeRef], - reactExpression.expression, - ); - const newHeritageClauses = ts.updateHeritageClause(reactHeritageClause, [newReactExpression]); - - return ts.updateClassDeclaration( - reactClassDeclaration, - reactClassDeclaration.decorators, - reactClassDeclaration.modifiers, - reactClassDeclaration.name, - reactClassDeclaration.typeParameters, - helpers.replaceItem(reactClassDeclaration.heritageClauses, reactHeritageClause, newHeritageClauses), - reactClassDeclaration.members, - ); -} diff --git a/src/transforms/react-js-make-props-and-state-transform.ts b/src/transforms/react-js-make-props-and-state-transform.ts index 8f6b9f6..c61d193 100644 --- a/src/transforms/react-js-make-props-and-state-transform.ts +++ b/src/transforms/react-js-make-props-and-state-transform.ts @@ -1,8 +1,8 @@ import * as ts from 'typescript'; - +import * as _ from 'lodash'; import * as helpers from '../helpers'; -export type Factory = ts.TransformerFactory<ts.Node>; +export type Factory = ts.TransformerFactory<ts.SourceFile>; /** * Get transform for transforming React code originally written in JS which does not have @@ -12,297 +12,250 @@ export type Factory = ts.TransformerFactory<ts.Node>; export function reactJSMakePropsAndStateInterfaceTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { return function reactJSMakePropsAndStateInterfaceTransformFactory(context: ts.TransformationContext) { return function reactJSMakePropsAndStateInterfaceTransform(sourceFile: ts.SourceFile) { - const visited = ts.visitEachChild(sourceFile, visitor, context); + const visited = visitSourceFile(sourceFile, typeChecker); ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; + }; + }; +} + +function visitSourceFile(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker) { + let newSourceFile = sourceFile; + for (const statement of sourceFile.statements) { + if (ts.isClassDeclaration(statement) && helpers.isReactComponent(statement, typeChecker)) { + newSourceFile = visitReactClassDeclaration(statement, newSourceFile, typeChecker); + } + } + + return newSourceFile; +} + +function visitReactClassDeclaration( + classDeclaration: ts.ClassDeclaration, + sourceFile: ts.SourceFile, + typeChecker: ts.TypeChecker, +) { + if (!classDeclaration.heritageClauses || !classDeclaration.heritageClauses.length) { + return sourceFile; + } + const className = classDeclaration && classDeclaration.name && classDeclaration.name.getText(sourceFile); + const propType = getPropsTypeOfReactComponentClass(classDeclaration, sourceFile); + const stateType = getStateTypeOfReactComponentClass(classDeclaration, typeChecker); + const shouldMakePropTypeDeclaration = propType.members.length > 0; + const shouldMakeStateTypeDeclaration = !isStateTypeMemberEmpty(stateType); + const propTypeName = `${className}Props`; + const stateTypeName = `${className}State`; + const propTypeDeclaration = ts.createTypeAliasDeclaration([], [], propTypeName, [], propType); + const stateTypeDeclaration = ts.createTypeAliasDeclaration([], [], stateTypeName, [], stateType); + const propTypeRef = ts.createTypeReferenceNode(propTypeName, []); + const stateTypeRef = ts.createTypeReferenceNode(stateTypeName, []); + + const newClassDeclaration = getNewReactClassDeclaration( + classDeclaration, + shouldMakePropTypeDeclaration ? propTypeRef : propType, + shouldMakeStateTypeDeclaration ? stateTypeRef : stateType, + ); + + const allTypeDeclarations = []; + if (shouldMakePropTypeDeclaration) allTypeDeclarations.push(propTypeDeclaration); + if (shouldMakeStateTypeDeclaration) allTypeDeclarations.push(stateTypeDeclaration); + + let statements = helpers.insertBefore(sourceFile.statements, classDeclaration, allTypeDeclarations); + statements = helpers.replaceItem(statements, classDeclaration, newClassDeclaration); + return ts.updateSourceFileNode(sourceFile, statements); +} + +function getNewReactClassDeclaration( + classDeclaration: ts.ClassDeclaration, + propTypeRef: ts.TypeNode, + stateTypeRef: ts.TypeNode, +) { + if (!classDeclaration.heritageClauses || !classDeclaration.heritageClauses.length) { + return classDeclaration; + } + + const firstHeritageClause = classDeclaration.heritageClauses[0]; + + const newFirstHeritageClauseTypes = helpers.replaceItem( + firstHeritageClause.types, + firstHeritageClause.types[0], + ts.updateExpressionWithTypeArguments( + firstHeritageClause.types[0], + [propTypeRef, stateTypeRef], + firstHeritageClause.types[0].expression, + ), + ); + + const newHeritageClauses = helpers.replaceItem( + classDeclaration.heritageClauses, + firstHeritageClause, + ts.updateHeritageClause(firstHeritageClause, newFirstHeritageClauseTypes), + ); + + return ts.updateClassDeclaration( + classDeclaration, + classDeclaration.decorators, + classDeclaration.modifiers, + classDeclaration.name, + classDeclaration.typeParameters, + newHeritageClauses, + classDeclaration.members, + ); +} + +function getPropsTypeOfReactComponentClass( + classDeclaration: ts.ClassDeclaration, + sourceFile: ts.SourceFile, +): ts.TypeLiteralNode { + const staticPropTypesMember = _.find(classDeclaration.members, member => { + return ( + ts.isPropertyDeclaration(member) && + helpers.hasStaticModifier(member) && + helpers.isPropTypesMember(member, sourceFile) + ); + }); + + if ( + staticPropTypesMember !== undefined && + ts.isPropertyDeclaration(staticPropTypesMember) && // check to satisfy type checker + staticPropTypesMember.initializer && + ts.isObjectLiteralExpression(staticPropTypesMember.initializer) + ) { + return helpers.buildInterfaceFromPropTypeObjectLiteral(staticPropTypesMember.initializer); + } + + const staticPropTypesGetterMember = _.find(classDeclaration.members, member => { + return ( + ts.isGetAccessorDeclaration(member) && + helpers.hasStaticModifier(member) && + helpers.isPropTypesMember(member, sourceFile) + ); + }); + + if ( + staticPropTypesGetterMember !== undefined && + ts.isGetAccessorDeclaration(staticPropTypesGetterMember) // check to satisfy typechecker + ) { + const returnStatement = _.find(staticPropTypesGetterMember.body!.statements, statement => + ts.isReturnStatement(statement), + ); + if ( + returnStatement !== undefined && + ts.isReturnStatement(returnStatement) && // check to satisfy typechecker + returnStatement.expression && + ts.isObjectLiteralExpression(returnStatement.expression) + ) { + return helpers.buildInterfaceFromPropTypeObjectLiteral(returnStatement.expression); + } + } + + return ts.createTypeLiteralNode([]); +} + +function getStateTypeOfReactComponentClass( + classDeclaration: ts.ClassDeclaration, + typeChecker: ts.TypeChecker, +): ts.TypeNode { + const initialState = getInitialStateFromClassDeclaration(classDeclaration, typeChecker); + const initialStateIsVoid = initialState.kind === ts.SyntaxKind.VoidKeyword; + const collectedStateTypes = getStateLookingForSetStateCalls(classDeclaration, typeChecker); + if (!collectedStateTypes.length && initialStateIsVoid) { + return ts.createTypeLiteralNode([]); + } + if (!initialStateIsVoid) { + collectedStateTypes.push(initialState); + } + + return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.IntersectionType, collectedStateTypes); +} - function visitor(node: ts.Node) { - if (helpers.isClassDeclaration(node)) { - return visitClassDeclaration(node); - } - - return node; - } - - function visitClassDeclaration(classDeclaration: ts.ClassDeclaration) { - if (!helpers.isReactComponent(classDeclaration, typeChecker)) { - return classDeclaration; - } - - if (!classDeclaration.heritageClauses || !classDeclaration.heritageClauses.length) { - return classDeclaration; - } - - const firstHeritageClauses = classDeclaration.heritageClauses[0]; - const expressionWithTypeArguments = firstHeritageClauses.types[0]; - - firstHeritageClauses.types[0] = ts.updateExpressionWithTypeArguments( - expressionWithTypeArguments, - [ - getPropsTypeOfReactComponentClass(classDeclaration), - getStateTypeOfReactComponentClass(classDeclaration), - ], - expressionWithTypeArguments.expression, - ) - - return ts.updateClassDeclaration( - classDeclaration, - classDeclaration.decorators, - classDeclaration.modifiers, - classDeclaration.name, - classDeclaration.typeParameters, - classDeclaration.heritageClauses, - classDeclaration.members, - ); - - function getPropsTypeOfReactComponentClass(classDeclaration: ts.ClassDeclaration): ts.TypeNode { - const staticPropTypesMember = helpers.find(classDeclaration.members, (member) => { - return helpers.isPropertyDeclaration(member) && - helpers.hasStaticModifier(member) && - helpers.isPropTypesMember(member, sourceFile); - }); - - if ( - staticPropTypesMember !== undefined - && helpers.isPropertyDeclaration(staticPropTypesMember) // check to satisfy type checker - && staticPropTypesMember.initializer - && helpers.isObjectLiteralExpression(staticPropTypesMember.initializer) - ) { - return buildInterfaceFromPropTypeObjectLiteral(staticPropTypesMember.initializer) - } - - const staticPropTypesGetterMember = helpers.find(classDeclaration.members, (member) => { - return helpers.isGetAccessorDeclaration(member) && - helpers.hasStaticModifier(member) && - helpers.isPropTypesMember(member, sourceFile); - }); - - if ( - staticPropTypesGetterMember !== undefined - && helpers.isGetAccessorDeclaration(staticPropTypesGetterMember) // check to satisfy typechecker - ) { - const returnStatement = helpers.find( - staticPropTypesGetterMember.body.statements, - (statement) => helpers.isReturnStatement(statement), - ); - if ( - returnStatement !== undefined - && helpers.isReturnStatement(returnStatement) // check to satisfy typechecker - && returnStatement.expression - && helpers.isObjectLiteralExpression(returnStatement.expression) - ) { - return buildInterfaceFromPropTypeObjectLiteral( - returnStatement.expression - ) - } - } - - return ts.createTypeLiteralNode([]); - } - - function getStateTypeOfReactComponentClass(classDeclaration: ts.ClassDeclaration): ts.TypeNode { - const initialState = getInitialStateFromClassDeclaration(classDeclaration, typeChecker); - const initialStateIsVoid = initialState.kind === ts.SyntaxKind.VoidKeyword; - const collectedStateTypes = getStateLookingForSetStateCalls(classDeclaration, typeChecker); - if (!collectedStateTypes.length && initialStateIsVoid) { - return ts.createTypeLiteralNode([]); - } - if (!initialStateIsVoid) { - collectedStateTypes.push(initialState) - } - - return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.IntersectionType, collectedStateTypes); - } - } - - /** - * Get initial state of a React component looking for state value initially set - * @param classDeclaration - * @param typeChecker - */ - function getInitialStateFromClassDeclaration( - classDeclaration: ts.ClassDeclaration, - typeChecker: ts.TypeChecker, - ): ts.TypeNode { - // initial state class member - - const initialStateMember = helpers.find(classDeclaration.members, (member) => { - try { - return helpers.isPropertyDeclaration(member) && - member.name && - member.name.getText() === 'state'; - } catch(e) { - return false; - } - }); - - if (initialStateMember - && helpers.isPropertyDeclaration(initialStateMember) - && initialStateMember.initializer - ) { - const type = typeChecker.getTypeAtLocation(initialStateMember.initializer)! - - return typeChecker.typeToTypeNode(type); - } - - // Initial state in constructor - const constructor = helpers.find( - classDeclaration.members, - (member) => member.kind === ts.SyntaxKind.Constructor, - ) as ts.ConstructorDeclaration | undefined; - - if (constructor && constructor.body) { - for (const statement of constructor.body.statements) { - if ( - helpers.isExpressionStatement(statement) && - helpers.isBinaryExpression(statement.expression) && - statement.expression.left.getText() === 'this.state' - ) { - return typeChecker.typeToTypeNode( - typeChecker.getTypeAtLocation(statement.expression.right) - ); - } - } - } - - // No initial state, fall back to void - return ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); - } - - /** - * Look for setState() function calls to collect the state interface in a React class component - * @param classDeclaration - * @param typeChecker - */ - function getStateLookingForSetStateCalls( - classDeclaration: ts.ClassDeclaration, - typeChecker: ts.TypeChecker, - ): ts.TypeNode[] { - const typeNodes: ts.TypeNode[] = []; - for (const member of classDeclaration.members) { - if (member && helpers.isMethodDeclaration(member) && member.body) { - lookForSetState(member.body) - } - } - - return typeNodes; - - function lookForSetState(node: ts.Node) { - ts.forEachChild(node, lookForSetState) - if ( - helpers.isExpressionStatement(node) && - helpers.isCallExpression(node.expression) && - node.expression.expression.getText().match(/setState/) - ) { - const type = typeChecker.getTypeAtLocation(node.expression.arguments[0]) - typeNodes.push(typeChecker.typeToTypeNode(type)); - } - } - } - - /** - * Build props interface from propTypes object - * @example - * { - * foo: React.PropTypes.string.isRequired - * } - * - * becomes - * { - * foo: string; - * } - * @param objectLiteral - */ - function buildInterfaceFromPropTypeObjectLiteral(objectLiteral: ts.ObjectLiteralExpression) { - const resultObjectLiteral = objectLiteral.properties.reduce( - (result, propertyAssignment: ts.PropertyAssignment) => { - const name = propertyAssignment.name.getText(); - if (!helpers.isPropertyAccessExpression(propertyAssignment.initializer)) { - console.warn('Bad value for propType', name, 'at', propertyAssignment.getStart()); - return result; - } - - // Ignore children, React types have it - if (propertyAssignment.name.getText() === 'children') { - return result; - } - - // Ignore children, React types have it - if (propertyAssignment.name.getText() === 'children') { - return result; - } - - const typeValue = getTypeFromReactPropTypeExpression(propertyAssignment.initializer); - const isOptional = isPropTypeOptional(propertyAssignment.initializer); - const propertySignature = ts.createPropertySignature( - [], - name, - isOptional ? ts.createToken(ts.SyntaxKind.QuestionToken): undefined, - typeValue, - undefined, - ); - result.members.push(propertySignature) - return result; - }, ts.createTypeLiteralNode([])); - - - return resultObjectLiteral; +/** + * Get initial state of a React component looking for state value initially set + * @param classDeclaration + * @param typeChecker + */ +function getInitialStateFromClassDeclaration( + classDeclaration: ts.ClassDeclaration, + typeChecker: ts.TypeChecker, +): ts.TypeNode { + // initial state class member + + const initialStateMember = _.find(classDeclaration.members, member => { + try { + return ts.isPropertyDeclaration(member) && member.name && member.name.getText() === 'state'; + } catch (e) { + return false; + } + }); + + if (initialStateMember && ts.isPropertyDeclaration(initialStateMember) && initialStateMember.initializer) { + const type = typeChecker.getTypeAtLocation(initialStateMember.initializer)!; + + return typeChecker.typeToTypeNode(type); + } + + // Initial state in constructor + const constructor = _.find(classDeclaration.members, member => member.kind === ts.SyntaxKind.Constructor) as + | ts.ConstructorDeclaration + | undefined; + + if (constructor && constructor.body) { + for (const statement of constructor.body.statements) { + if ( + ts.isExpressionStatement(statement) && + ts.isBinaryExpression(statement.expression) && + statement.expression.left.getText() === 'this.state' + ) { + return typeChecker.typeToTypeNode(typeChecker.getTypeAtLocation(statement.expression.right)); } + } + } - /** - * Turns React.PropTypes.* into TypeScript type value - * - * @param node React propTypes value - */ - function getTypeFromReactPropTypeExpression(node: ts.PropertyAccessExpression) { - const text = node.getText().replace(/React\.PropTypes\./, ''); - let result = null; - if (/string/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); - } else if (/any/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); - } else if (/array/.test(text)) { - result = ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); - } else if (/bool/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); - } else if (/number/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); - } else if (/object/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword); - } else if (/node/.test(text)) { - result = ts.createTypeReferenceNode('React.ReactNode', []); - } else if (/element/.test(text)) { - result = ts.createTypeReferenceNode('JSX.Element', []); - } else if (/func/.test(text)) { - const arrayOfAny = ts.createParameter( - [], - [], - ts.createToken(ts.SyntaxKind.DotDotDotToken), - 'args', - undefined, - ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), - undefined, - ); - result = ts.createFunctionTypeNode( - [], - [arrayOfAny], - ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), - ); - } else { - result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); - } - return result; - } + // No initial state, fall back to void + return ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); +} - /** - * Decide if node is optional - * @param node React propTypes member node - */ - function isPropTypeOptional(node: ts.PropertyAccessExpression) { - const text = node.getText().replace(/React\.PropTypes\./, ''); - return !/\.isRequired/.test(text) - } - }; - }; -}; +/** + * Look for setState() function calls to collect the state interface in a React class component + * @param classDeclaration + * @param typeChecker + */ +function getStateLookingForSetStateCalls( + classDeclaration: ts.ClassDeclaration, + typeChecker: ts.TypeChecker, +): ts.TypeNode[] { + const typeNodes: ts.TypeNode[] = []; + for (const member of classDeclaration.members) { + if (member && ts.isMethodDeclaration(member) && member.body) { + lookForSetState(member.body); + } + } + + return typeNodes; + + function lookForSetState(node: ts.Node) { + ts.forEachChild(node, lookForSetState); + if ( + ts.isExpressionStatement(node) && + ts.isCallExpression(node.expression) && + node.expression.expression.getText().match(/setState/) + ) { + const type = typeChecker.getTypeAtLocation(node.expression.arguments[0]); + typeNodes.push(typeChecker.typeToTypeNode(type)); + } + } +} + +function isStateTypeMemberEmpty(stateType: ts.TypeNode): boolean { + // Only need to handle TypeLiteralNode & IntersectionTypeNode + if (ts.isTypeLiteralNode(stateType)) { + return stateType.members.length === 0; + } + + if (!ts.isIntersectionTypeNode(stateType)) { + return true; + } + + return stateType.types.every(isStateTypeMemberEmpty); +} diff --git a/src/transforms/react-move-prop-types-to-class-transform.ts b/src/transforms/react-move-prop-types-to-class-transform.ts index 327e011..d954a11 100644 --- a/src/transforms/react-move-prop-types-to-class-transform.ts +++ b/src/transforms/react-move-prop-types-to-class-transform.ts @@ -1,8 +1,9 @@ import * as ts from 'typescript'; +import * as _ from 'lodash'; import * as helpers from '../helpers'; -export type Factory = ts.TransformerFactory<ts.Node>; +export type Factory = ts.TransformerFactory<ts.SourceFile>; /** * Move Component.propTypes statements into class as a static member of the class @@ -32,7 +33,9 @@ export type Factory = ts.TransformerFactory<ts.Node>; export function reactMovePropTypesToClassTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { return function reactMovePropTypesToClassTransformFactory(context: ts.TransformationContext) { return function reactMovePropTypesToClassTransform(sourceFile: ts.SourceFile) { - return visitSourceFile(sourceFile, typeChecker); + const visited = visitSourceFile(sourceFile, typeChecker); + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; }; }; } @@ -46,50 +49,36 @@ function visitSourceFile(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker) let statements = sourceFile.statements; // Look for propType assignment statements - const propTypeAssignments = statements.filter( - (statement) => helpers.isReactPropTypeAssignmentStatement(statement) + const propTypeAssignments = statements.filter(statement => + helpers.isReactPropTypeAssignmentStatement(statement), ) as ts.ExpressionStatement[]; - for (const propTypeAssignment of propTypeAssignments) { - // Look for the class declarations with the same name - const componentName = getComponentName(propTypeAssignment, sourceFile); + const componentName = helpers.getComponentName(propTypeAssignment, sourceFile); - const classStatement = helpers.find( + const classStatement = (_.find( statements, - (statement) => helpers.isClassDeclaration(statement) && + statement => + ts.isClassDeclaration(statement) && statement.name !== undefined && statement.name.getText(sourceFile) === componentName, - ) as {} as ts.ClassDeclaration; // Type weirdness + ) as {}) as ts.ClassDeclaration; // Type weirdness // && helpers.isBinaryExpression(propTypeAssignment.expression) is redundant to satisfy the type checker - if (classStatement && helpers.isBinaryExpression(propTypeAssignment.expression)) { + if (classStatement && ts.isBinaryExpression(propTypeAssignment.expression)) { const newClassStatement = addStaticMemberToClass( classStatement, 'propTypes', propTypeAssignment.expression.right, ); - statements = ts.createNodeArray( - helpers.replaceItem(sourceFile.statements, classStatement, newClassStatement), - ); + statements = ts.createNodeArray(helpers.replaceItem(statements, classStatement, newClassStatement)); } } return ts.updateSourceFileNode(sourceFile, statements); } - -/** - * Get component name off of a propType assignment statement - * @param propTypeAssignment - * @param sourceFile - */ -function getComponentName(propTypeAssignment: ts.Statement, sourceFile: ts.SourceFile) { - const text = propTypeAssignment.getText(sourceFile); - return text.substr(0, text.indexOf('.')); -} - /** * Insert a new static member into a class * @param classDeclaration @@ -97,7 +86,7 @@ function getComponentName(propTypeAssignment: ts.Statement, sourceFile: ts.Sourc * @param value */ function addStaticMemberToClass(classDeclaration: ts.ClassDeclaration, name: string, value: ts.Expression) { - const staticModifier = ts.createToken(ts.SyntaxKind.StaticKeyword) + const staticModifier = ts.createToken(ts.SyntaxKind.StaticKeyword); const propertyDeclaration = ts.createProperty([], [staticModifier], name, undefined, undefined, value); return ts.updateClassDeclaration( classDeclaration, @@ -106,6 +95,6 @@ function addStaticMemberToClass(classDeclaration: ts.ClassDeclaration, name: str classDeclaration.name, classDeclaration.typeParameters, ts.createNodeArray(classDeclaration.heritageClauses), - ts.createNodeArray([propertyDeclaration, ...classDeclaration.members]) - ) + ts.createNodeArray([propertyDeclaration, ...classDeclaration.members]), + ); } diff --git a/src/transforms/react-remove-prop-types-assignment-transform.ts b/src/transforms/react-remove-prop-types-assignment-transform.ts index f87b671..4b57fa9 100644 --- a/src/transforms/react-remove-prop-types-assignment-transform.ts +++ b/src/transforms/react-remove-prop-types-assignment-transform.ts @@ -2,7 +2,7 @@ import * as ts from 'typescript'; import * as helpers from '../helpers'; -export type Factory = ts.TransformerFactory<ts.Node>; +export type Factory = ts.TransformerFactory<ts.SourceFile>; /** * Remove Component.propTypes statements @@ -15,13 +15,15 @@ export type Factory = ts.TransformerFactory<ts.Node>; * After * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {} */ -export function reactRemovePropTypesAssignmentTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory{ +export function reactRemovePropTypesAssignmentTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { return function reactRemovePropTypesAssignmentTransformFactory(context: ts.TransformationContext) { return function reactRemovePropTypesAssignmentTransform(sourceFile: ts.SourceFile) { - return ts.updateSourceFileNode( + const visited = ts.updateSourceFileNode( sourceFile, sourceFile.statements.filter(s => !helpers.isReactPropTypeAssignmentStatement(s)), ); - } - } + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; + }; + }; } diff --git a/src/transforms/react-remove-prop-types-import.ts b/src/transforms/react-remove-prop-types-import.ts new file mode 100644 index 0000000..8644b8c --- /dev/null +++ b/src/transforms/react-remove-prop-types-import.ts @@ -0,0 +1,76 @@ +import * as ts from 'typescript'; +import * as _ from 'lodash'; + +import * as helpers from '../helpers'; + +export type Factory = ts.TransformerFactory<ts.SourceFile>; + +/** + * Remove `import PropTypes from 'prop-types'` or + * `import { PropTypes } from 'react'` + * + * @example + * Before: + * import PropTypes from 'prop-types' + * import React, { PropTypes } from 'react' + * + * After: + * import React from 'react' + */ +export function reactRemovePropTypesImportTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { + return function reactRemovePropTypesImportTransformFactory(context: ts.TransformationContext) { + return function reactRemovePropTypesImportTransform(sourceFile: ts.SourceFile) { + const visited = ts.updateSourceFileNode( + sourceFile, + sourceFile.statements + .filter(s => { + return !( + ts.isImportDeclaration(s) && + ts.isStringLiteral(s.moduleSpecifier) && + s.moduleSpecifier.text === 'prop-types' + ); + }) + .map(updateReactImportIfNeeded), + ); + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; + }; + }; +} + +function updateReactImportIfNeeded(statement: ts.Statement) { + if ( + !ts.isImportDeclaration(statement) || + !ts.isStringLiteral(statement.moduleSpecifier) || + statement.moduleSpecifier.text !== 'react' || + !statement.importClause || + !statement.importClause.namedBindings || + !ts.isNamedImports(statement.importClause.namedBindings) + ) { + return statement; + } + + const namedBindings = statement.importClause.namedBindings; + const newNamedBindingElements = namedBindings.elements.filter(elm => elm.name.text !== 'PropTypes'); + + if (newNamedBindingElements.length === namedBindings.elements.length) { + // Means it has no 'PropTypes' named import + return statement; + } + + const newImportClause = ts.updateImportClause( + statement.importClause, + statement.importClause.name, + newNamedBindingElements.length === 0 + ? undefined + : ts.updateNamedImports(namedBindings, newNamedBindingElements), + ); + + return ts.updateImportDeclaration( + statement, + statement.decorators, + statement.modifiers, + newImportClause, + statement.moduleSpecifier, + ); +} diff --git a/src/transforms/react-remove-static-prop-types-member-transform.ts b/src/transforms/react-remove-static-prop-types-member-transform.ts index 6aa579d..7054884 100644 --- a/src/transforms/react-remove-static-prop-types-member-transform.ts +++ b/src/transforms/react-remove-static-prop-types-member-transform.ts @@ -2,7 +2,7 @@ import * as ts from 'typescript'; import * as helpers from '../helpers'; -export type Factory = ts.TransformerFactory<ts.Node>; +export type Factory = ts.TransformerFactory<ts.SourceFile>; /** * Remove static propTypes @@ -21,10 +21,12 @@ export type Factory = ts.TransformerFactory<ts.Node>; export function reactRemoveStaticPropTypesMemberTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { return function reactRemoveStaticPropTypesMemberTransformFactory(context: ts.TransformationContext) { return function reactRemoveStaticPropTypesMemberTransform(sourceFile: ts.SourceFile) { - return ts.visitEachChild(sourceFile, visitor, context); + const visited = ts.visitEachChild(sourceFile, visitor, context); + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; function visitor(node: ts.Node) { - if (helpers.isClassDeclaration(node) && helpers.isReactComponent(node, typeChecker)) { + if (ts.isClassDeclaration(node) && helpers.isReactComponent(node, typeChecker)) { return ts.updateClassDeclaration( node, node.decorators, @@ -32,29 +34,29 @@ export function reactRemoveStaticPropTypesMemberTransformFactoryFactory(typeChec node.name, node.typeParameters, ts.createNodeArray(node.heritageClauses), - node.members.filter((member) => { + node.members.filter(member => { if ( - helpers.isPropertyDeclaration(member) - && helpers.hasStaticModifier(member) - && helpers.isPropTypesMember(member, sourceFile) + ts.isPropertyDeclaration(member) && + helpers.hasStaticModifier(member) && + helpers.isPropTypesMember(member, sourceFile) ) { return false; } // propTypes getter if ( - helpers.isGetAccessorDeclaration(member) - && helpers.hasStaticModifier(member) - && helpers.isPropTypesMember(member, sourceFile) + ts.isGetAccessorDeclaration(member) && + helpers.hasStaticModifier(member) && + helpers.isPropTypesMember(member, sourceFile) ) { return false; } return true; }), - ) + ); } return node; } - } - } + }; + }; } diff --git a/src/transforms/react-stateless-function-make-props-transform.ts b/src/transforms/react-stateless-function-make-props-transform.ts new file mode 100644 index 0000000..0222cec --- /dev/null +++ b/src/transforms/react-stateless-function-make-props-transform.ts @@ -0,0 +1,117 @@ +import * as ts from 'typescript'; +import * as _ from 'lodash'; + +import * as helpers from '../helpers'; + +export type Factory = ts.TransformerFactory<ts.SourceFile>; + +/** + * Transform react stateless components + * + * @example + * Before: + * const Hello = ({ message }) => { + * return <div>hello {message}</div> + * } + * // Or: + * // const Hello = ({ message }) => <div>hello {message}</div> + * + * Hello.propTypes = { + * message: React.PropTypes.string, + * } + * + * After: + * Type HelloProps = { + * message: string; + * } + * + * const Hello: React.SFC<HelloProps> = ({ message }) => { + * return <div>hello {message}</div> + * } + * + * Hello.propTypes = { + * message: React.PropTypes.string, + * } + */ +export function reactStatelessFunctionMakePropsTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { + return function reactStatelessFunctionMakePropsTransformFactory(context: ts.TransformationContext) { + return function reactStatelessFunctionMakePropsTransform(sourceFile: ts.SourceFile) { + const visited = visitSourceFile(sourceFile, typeChecker); + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; + }; + }; +} + +function visitSourceFile(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker) { + // Look for propType assignment statements + const propTypeAssignments = sourceFile.statements.filter(statement => + helpers.isReactPropTypeAssignmentStatement(statement), + ) as ts.ExpressionStatement[]; + + let newSourceFile = sourceFile; + for (const propTypeAssignment of propTypeAssignments) { + const componentName = helpers.getComponentName(propTypeAssignment, newSourceFile); + + const funcComponent = (_.find(newSourceFile.statements, s => { + return ( + (ts.isFunctionDeclaration(s) && s.name !== undefined && s.name.getText() === componentName) || + (ts.isVariableStatement(s) && s.declarationList.declarations[0].name.getText() === componentName) + ); + }) as {}) as ts.FunctionDeclaration | ts.VariableStatement; // Type weirdness + + if (funcComponent) { + newSourceFile = visitReactStatelessComponent(funcComponent, propTypeAssignment, newSourceFile); + } + } + + return newSourceFile; +} + +function visitReactStatelessComponent( + component: ts.FunctionDeclaration | ts.VariableStatement, + propTypesExpressionStatement: ts.ExpressionStatement, + sourceFile: ts.SourceFile, +) { + let arrowFuncComponent = helpers.convertReactStatelessFunctionToArrowFunction(component); + let componentName = arrowFuncComponent.declarationList.declarations[0].name.getText(); + let componentInitializer = arrowFuncComponent.declarationList.declarations[0].initializer; + + const propType = getPropTypesFromTypeAssignment(propTypesExpressionStatement); + const shouldMakePropTypeDeclaration = propType.members.length > 0; + const propTypeName = `${componentName}Props`; + const propTypeDeclaration = ts.createTypeAliasDeclaration([], [], propTypeName, [], propType); + const propTypeRef = ts.createTypeReferenceNode(propTypeName, []); + + let componentType = ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier('React'), 'SFC'), [ + shouldMakePropTypeDeclaration ? propTypeRef : propType, + ]); + + // replace component with ts stateless component + const typedComponent = ts.createVariableStatement( + arrowFuncComponent.modifiers, + ts.createVariableDeclarationList( + [ts.createVariableDeclaration(componentName, componentType, componentInitializer)], + arrowFuncComponent.declarationList.flags, + ), + ); + + let statements = shouldMakePropTypeDeclaration + ? helpers.insertBefore(sourceFile.statements, component, [propTypeDeclaration]) + : sourceFile.statements; + + statements = helpers.replaceItem(statements, component, typedComponent); + return ts.updateSourceFileNode(sourceFile, statements); +} + +function getPropTypesFromTypeAssignment(propTypesExpressionStatement: ts.ExpressionStatement) { + if ( + propTypesExpressionStatement !== undefined && + ts.isBinaryExpression(propTypesExpressionStatement.expression) && + ts.isObjectLiteralExpression(propTypesExpressionStatement.expression.right) + ) { + return helpers.buildInterfaceFromPropTypeObjectLiteral(propTypesExpressionStatement.expression.right); + } + + return ts.createTypeLiteralNode([]); +} diff --git a/src/untyped-modules.d.ts b/src/untyped-modules.d.ts new file mode 100644 index 0000000..f187021 --- /dev/null +++ b/src/untyped-modules.d.ts @@ -0,0 +1 @@ +declare module 'dedent'; diff --git a/test/collapse-intersection-interfaces-transform/advanced/output.tsx b/test/collapse-intersection-interfaces-transform/advanced/output.tsx index a272d5a..a579223 100644 --- a/test/collapse-intersection-interfaces-transform/advanced/output.tsx +++ b/test/collapse-intersection-interfaces-transform/advanced/output.tsx @@ -1,7 +1,7 @@ type Foo = { - foo: string; - stuff: boolean; - other: () => void; - bar: number; - [key: string]: number; + foo: string, + stuff: boolean, + other: () => void, + bar: number, + [key: string]: number, }; diff --git a/test/collapse-intersection-interfaces-transform/multiple/input.tsx b/test/collapse-intersection-interfaces-transform/multiple/input.tsx new file mode 100644 index 0000000..1854a03 --- /dev/null +++ b/test/collapse-intersection-interfaces-transform/multiple/input.tsx @@ -0,0 +1,3 @@ +type Foo = {foo: string} & {bar: number}; + +type Bar = {foo: number} & {bar: string}; diff --git a/test/collapse-intersection-interfaces-transform/multiple/output.tsx b/test/collapse-intersection-interfaces-transform/multiple/output.tsx new file mode 100644 index 0000000..f6d0c1d --- /dev/null +++ b/test/collapse-intersection-interfaces-transform/multiple/output.tsx @@ -0,0 +1,8 @@ +type Foo = { + foo: string, + bar: number, +}; +type Bar = { + foo: number, + bar: string, +}; diff --git a/test/collapse-intersection-interfaces-transform/repeated/input.tsx b/test/collapse-intersection-interfaces-transform/repeated/input.tsx new file mode 100644 index 0000000..2bfb4e6 --- /dev/null +++ b/test/collapse-intersection-interfaces-transform/repeated/input.tsx @@ -0,0 +1,5 @@ +type A = { foo: string; } & { foo: string; }; + +type B = { foo: string; bar: number; } & { foo: number; bar: number; } + +type C = { foo: string; bar: number; } & { foo: number; bar: number; } & { foo: string; } diff --git a/test/collapse-intersection-interfaces-transform/repeated/output.tsx b/test/collapse-intersection-interfaces-transform/repeated/output.tsx new file mode 100644 index 0000000..5dc0eec --- /dev/null +++ b/test/collapse-intersection-interfaces-transform/repeated/output.tsx @@ -0,0 +1,13 @@ +type A = { + foo: string, +}; + +type B = { + foo: string | number, + bar: number, +}; + +type C = { + foo: string | number, + bar: number, +}; diff --git a/test/collapse-intersection-interfaces-transform/simple/output.tsx b/test/collapse-intersection-interfaces-transform/simple/output.tsx index b845331..d4374e3 100644 --- a/test/collapse-intersection-interfaces-transform/simple/output.tsx +++ b/test/collapse-intersection-interfaces-transform/simple/output.tsx @@ -1,4 +1,4 @@ type Foo = { - foo: string; - bar: number; -}; \ No newline at end of file + foo: string, + bar: number, +}; diff --git a/test/end-to-end/basic/input.tsx b/test/end-to-end/basic/input.tsx index 881a680..53750ee 100644 --- a/test/end-to-end/basic/input.tsx +++ b/test/end-to-end/basic/input.tsx @@ -1,7 +1,8 @@ +import PropTypes from 'prop-types'; import * as React from 'react'; export default class MyComponent extends React.Component { render() { return <div />; } -} \ No newline at end of file +} diff --git a/test/end-to-end/basic/output.tsx b/test/end-to-end/basic/output.tsx index c1c9a80..c98cfbd 100644 --- a/test/end-to-end/basic/output.tsx +++ b/test/end-to-end/basic/output.tsx @@ -1,9 +1,5 @@ import * as React from 'react'; - -type MyComponentProps = {}; -type MyComponentState = {}; - -export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> { +export default class MyComponent extends React.Component<{}, {}> { render() { return <div />; } diff --git a/test/end-to-end/initial-state-and-proprypes-and-set-state/output.tsx b/test/end-to-end/initial-state-and-proprypes-and-set-state/output.tsx index 64338c6..95fae0f 100644 --- a/test/end-to-end/initial-state-and-proprypes-and-set-state/output.tsx +++ b/test/end-to-end/initial-state-and-proprypes-and-set-state/output.tsx @@ -1,12 +1,11 @@ import * as React from 'react'; - type MyComponentProps = { - baz: string; + baz: string, }; type MyComponentState = { - dynamicState: number; - foo: number; - bar: string; + dynamicState: number, + foo: number, + bar: string, }; export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> { state = { foo: 1, bar: 'str' }; diff --git a/test/end-to-end/initial-state-and-proprypes/output.tsx b/test/end-to-end/initial-state-and-proprypes/output.tsx index 4a358b2..912e3b8 100644 --- a/test/end-to-end/initial-state-and-proprypes/output.tsx +++ b/test/end-to-end/initial-state-and-proprypes/output.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; - type MyComponentProps = { - baz: string; + baz: string, }; type MyComponentState = { - foo: number; - bar: string; + foo: number, + bar: string, }; export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> { state = { foo: 1, bar: 'str' }; diff --git a/test/end-to-end/multiple-components/input.tsx b/test/end-to-end/multiple-components/input.tsx new file mode 100644 index 0000000..9cb8345 --- /dev/null +++ b/test/end-to-end/multiple-components/input.tsx @@ -0,0 +1,34 @@ +const Hello = ({ message }) => { + return <div>hello {message}</div> +}; + +const Hey = ({ name }) => { + return <div>hey, {name}</div> +} + +Hey.propTypes = { + message: React.PropTypes.string, +} + +Hello.propTypes = { + message: React.PropTypes.string, +} + +export default class MyComponent extends React.Component { + render() { + return <button onClick={this.onclick.bind(this)} />; + } + + onclick() { + this.setState({foo: 1, bar: 2}) + } +} + +export class AnotherComponent extends React.Component { + static propTypes = { + foo: React.PropTypes.string.isRequired, + }; + render() { + return <div />; + } +} diff --git a/test/end-to-end/multiple-components/output.tsx b/test/end-to-end/multiple-components/output.tsx new file mode 100644 index 0000000..5495538 --- /dev/null +++ b/test/end-to-end/multiple-components/output.tsx @@ -0,0 +1,32 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; +type HeyProps = { + message?: string, +}; +const Hey: React.SFC<HeyProps> = ({ name }) => { + return <div>hey, {name}</div>; +}; +type MyComponentState = { + foo: number, + bar: number, +}; +export default class MyComponent extends React.Component<{}, MyComponentState> { + render() { + return <button onClick={this.onclick.bind(this)} />; + } + onclick() { + this.setState({ foo: 1, bar: 2 }); + } +} +type AnotherComponentProps = { + foo: string, +}; +export class AnotherComponent extends React.Component<AnotherComponentProps, {}> { + render() { + return <div />; + } +} diff --git a/test/end-to-end/non-react/output.tsx b/test/end-to-end/non-react/output.tsx index 9111b26..50db235 100644 --- a/test/end-to-end/non-react/output.tsx +++ b/test/end-to-end/non-react/output.tsx @@ -4,6 +4,5 @@ class Foo { } } class Bar extends Foo { - baz() { - } -} \ No newline at end of file + baz() {} +} diff --git a/test/end-to-end/stateless-arrow-function/input.tsx b/test/end-to-end/stateless-arrow-function/input.tsx new file mode 100644 index 0000000..9ddb8b7 --- /dev/null +++ b/test/end-to-end/stateless-arrow-function/input.tsx @@ -0,0 +1,7 @@ +const Hello = ({ message }) => { + return <div>hello {message}</div> +}; + +Hello.propTypes = { + message: React.PropTypes.string, +} diff --git a/test/end-to-end/stateless-arrow-function/output.tsx b/test/end-to-end/stateless-arrow-function/output.tsx new file mode 100644 index 0000000..b80083c --- /dev/null +++ b/test/end-to-end/stateless-arrow-function/output.tsx @@ -0,0 +1,6 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; diff --git a/test/end-to-end/stateless-function/input.tsx b/test/end-to-end/stateless-function/input.tsx new file mode 100644 index 0000000..402c686 --- /dev/null +++ b/test/end-to-end/stateless-function/input.tsx @@ -0,0 +1,7 @@ +export function Hello({ message }) { + return <div>hello {message}</div> +} + +Hello.propTypes = { + message: React.PropTypes.string, +} diff --git a/test/end-to-end/stateless-function/output.tsx b/test/end-to-end/stateless-function/output.tsx new file mode 100644 index 0000000..2028009 --- /dev/null +++ b/test/end-to-end/stateless-function/output.tsx @@ -0,0 +1,6 @@ +type HelloProps = { + message?: string, +}; +export const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; diff --git a/test/react-hoist-generics-transform/non-react/input.tsx b/test/react-hoist-generics-transform/non-react/input.tsx deleted file mode 100644 index c0e4a28..0000000 --- a/test/react-hoist-generics-transform/non-react/input.tsx +++ /dev/null @@ -1,18 +0,0 @@ -interface IFoo { - -} -class Foo { - -} - -class Bar extends Foo { - -} - -class Foo2 implements IFoo { - -} - -class Bar2 extends Foo implements IFoo { - -} diff --git a/test/react-hoist-generics-transform/non-react/output.tsx b/test/react-hoist-generics-transform/non-react/output.tsx deleted file mode 100644 index 8b8eec9..0000000 --- a/test/react-hoist-generics-transform/non-react/output.tsx +++ /dev/null @@ -1,18 +0,0 @@ -interface IFoo { - -} -class Foo { - -} - -class Bar extends Foo { - -} - -class Foo2 implements IFoo { - -} - -class Bar2 extends Foo implements IFoo { - -} diff --git a/test/react-hoist-generics-transform/propless-stateless/input.tsx b/test/react-hoist-generics-transform/propless-stateless/input.tsx deleted file mode 100644 index ab0d702..0000000 --- a/test/react-hoist-generics-transform/propless-stateless/input.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; - -export default class MyComponent extends React.Component<{}, {}> { - render() { - return <div />; - } -} diff --git a/test/react-hoist-generics-transform/propless-stateless/output.tsx b/test/react-hoist-generics-transform/propless-stateless/output.tsx deleted file mode 100644 index 22548c4..0000000 --- a/test/react-hoist-generics-transform/propless-stateless/output.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -type MyComponentProps = {}; -type MyComponentState = {}; -export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> { - render() { - return <div />; - } -} diff --git a/test/react-hoist-generics-transform/props-and-state/input.tsx b/test/react-hoist-generics-transform/props-and-state/input.tsx deleted file mode 100644 index c1e13db..0000000 --- a/test/react-hoist-generics-transform/props-and-state/input.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; - -export default class MyComponent extends React.Component<{foo: string; bar: object;}, {baz: string; [k: string]: string}> { - render() { - return <div />; - } -} diff --git a/test/react-hoist-generics-transform/props-and-state/output.tsx b/test/react-hoist-generics-transform/props-and-state/output.tsx deleted file mode 100644 index dbebeed..0000000 --- a/test/react-hoist-generics-transform/props-and-state/output.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - -type MyComponentProps = { - foo: string; - bar: object; -}; -type MyComponentState = { - baz: string; - [k: string]: string; -}; -export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> { - render() { - return <div />; - } -} diff --git a/test/react-js-make-props-and-state-transform/multiple-components/input.tsx b/test/react-js-make-props-and-state-transform/multiple-components/input.tsx new file mode 100644 index 0000000..179806b --- /dev/null +++ b/test/react-js-make-props-and-state-transform/multiple-components/input.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +export default class MyComponent extends React.Component { + render() { + return <button onClick={this.onclick.bind(this)} />; + } + + onclick() { + this.setState({foo: 1, bar: 2}) + } +} + +export class AnotherComponent extends React.Component { + static propTypes = { + foo: React.PropTypes.string.isRequired, + }; + render() { + return <div />; + } +} diff --git a/test/react-js-make-props-and-state-transform/multiple-components/output.tsx b/test/react-js-make-props-and-state-transform/multiple-components/output.tsx new file mode 100644 index 0000000..c5fdde8 --- /dev/null +++ b/test/react-js-make-props-and-state-transform/multiple-components/output.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +type MyComponentState = { foo: number, bar: number }; +export default class MyComponent extends React.Component<{}, MyComponentState> { + render() { + return <button onClick={this.onclick.bind(this)} />; + } + onclick() { + this.setState({ foo: 1, bar: 2 }); + } +} +type AnotherComponentProps = { + foo: string, +}; +export class AnotherComponent extends React.Component<AnotherComponentProps, {}> { + static propTypes = { + foo: React.PropTypes.string.isRequired, + }; + render() { + return <div />; + } +} diff --git a/test/react-js-make-props-and-state-transform/non-react/output.tsx b/test/react-js-make-props-and-state-transform/non-react/output.tsx index 8b8eec9..a0b04ce 100644 --- a/test/react-js-make-props-and-state-transform/non-react/output.tsx +++ b/test/react-js-make-props-and-state-transform/non-react/output.tsx @@ -1,18 +1,5 @@ -interface IFoo { - -} -class Foo { - -} - -class Bar extends Foo { - -} - -class Foo2 implements IFoo { - -} - -class Bar2 extends Foo implements IFoo { - -} +interface IFoo {} +class Foo {} +class Bar extends Foo {} +class Foo2 implements IFoo {} +class Bar2 extends Foo implements IFoo {} diff --git a/test/react-js-make-props-and-state-transform/propless-stateless/output.tsx b/test/react-js-make-props-and-state-transform/propless-stateless/output.tsx index ab0d702..c98cfbd 100644 --- a/test/react-js-make-props-and-state-transform/propless-stateless/output.tsx +++ b/test/react-js-make-props-and-state-transform/propless-stateless/output.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; - export default class MyComponent extends React.Component<{}, {}> { render() { return <div />; diff --git a/test/react-js-make-props-and-state-transform/set-state-advanced/output.tsx b/test/react-js-make-props-and-state-transform/set-state-advanced/output.tsx index a254578..f8dc221 100644 --- a/test/react-js-make-props-and-state-transform/set-state-advanced/output.tsx +++ b/test/react-js-make-props-and-state-transform/set-state-advanced/output.tsx @@ -1,17 +1,17 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{}, { foo: number; bar: number; } & { baz: number; } & { something: { big: number; here: string; of: { a: number; }[]; }; }> { +type MyComponentState = { foo: number, bar: number } & { baz: number } & { + something: { big: number, here: string, of: { a: number }[] }, +}; +export default class MyComponent extends React.Component<{}, MyComponentState> { render() { - return <button onClick={this.onclick.bind(this)}/>; + return <button onClick={this.onclick.bind(this)} />; } - onclick() { if (Math.random() > 0.5) { this.setState({ foo: 1, bar: 2 }); } this.otherMethod(); } - otherMethod() { for (const foo of [1, 2, 3]) { if (foo > 2) { @@ -19,14 +19,13 @@ export default class MyComponent extends React.Component<{}, { foo: number; bar: } } } - addLargeObjectToState() { this.setState({ something: { big: 123, here: 'string', - of: [{ a: 1 }, { a: 2 }] - } + of: [{ a: 1 }, { a: 2 }], + }, }); } } diff --git a/test/react-js-make-props-and-state-transform/set-state-only/output.tsx b/test/react-js-make-props-and-state-transform/set-state-only/output.tsx index 3795804..ef4e928 100644 --- a/test/react-js-make-props-and-state-transform/set-state-only/output.tsx +++ b/test/react-js-make-props-and-state-transform/set-state-only/output.tsx @@ -1,10 +1,9 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{}, { foo: number; bar: number; }> { +type MyComponentState = { foo: number, bar: number }; +export default class MyComponent extends React.Component<{}, MyComponentState> { render() { - return <button onClick={this.onclick.bind(this)}/>; + return <button onClick={this.onclick.bind(this)} />; } - onclick() { this.setState({ foo: 1, bar: 2 }); } diff --git a/test/react-js-make-props-and-state-transform/state-in-class-member/output.tsx b/test/react-js-make-props-and-state-transform/state-in-class-member/output.tsx index d9b4578..760b6bd 100644 --- a/test/react-js-make-props-and-state-transform/state-in-class-member/output.tsx +++ b/test/react-js-make-props-and-state-transform/state-in-class-member/output.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{}, { foo: number; }> { +type MyComponentState = { foo: number }; +export default class MyComponent extends React.Component<{}, MyComponentState> { state = { foo: 1 }; render() { return <div />; diff --git a/test/react-js-make-props-and-state-transform/state-in-constructor/output.tsx b/test/react-js-make-props-and-state-transform/state-in-constructor/output.tsx index 0ee6051..338bd8d 100644 --- a/test/react-js-make-props-and-state-transform/state-in-constructor/output.tsx +++ b/test/react-js-make-props-and-state-transform/state-in-constructor/output.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{}, { foo: number; }> { +type MyComponentState = { foo: number }; +export default class MyComponent extends React.Component<{}, MyComponentState> { constructor(props, context) { super(props, context); this.state = { foo: 1 }; } - render() { return <div />; } diff --git a/test/react-js-make-props-and-state-transform/static-proptypes-getter-simple/output.tsx b/test/react-js-make-props-and-state-transform/static-proptypes-getter-simple/output.tsx index 8f1e78d..b4206de 100644 --- a/test/react-js-make-props-and-state-transform/static-proptypes-getter-simple/output.tsx +++ b/test/react-js-make-props-and-state-transform/static-proptypes-getter-simple/output.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{ - foo: string; - }, {}> { +type MyComponentProps = { + foo: string, +}; +export default class MyComponent extends React.Component<MyComponentProps, {}> { static get propTypes() { return { foo: React.PropTypes.string.isRequired, diff --git a/test/react-js-make-props-and-state-transform/static-proptypes-many-props/input.tsx b/test/react-js-make-props-and-state-transform/static-proptypes-many-props/input.tsx index 1e491c3..e54d2f4 100644 --- a/test/react-js-make-props-and-state-transform/static-proptypes-many-props/input.tsx +++ b/test/react-js-make-props-and-state-transform/static-proptypes-many-props/input.tsx @@ -12,6 +12,17 @@ export default class MyComponent extends React.Component { string: React.PropTypes.string, node: React.PropTypes.node, element: React.PropTypes.element, + oneOf: React.PropTypes.oneOf(['a', 'b', 'c']), + oneOfType: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]), + arrayOf: React.PropTypes.arrayOf(React.PropTypes.string), + objectOf: React.PropTypes.objectOf(React.PropTypes.string), + shape: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number, + }), anyRequired: React.PropTypes.any.isRequired, arrayRequired: React.PropTypes.array.isRequired, boolRequired: React.PropTypes.bool.isRequired, @@ -21,6 +32,17 @@ export default class MyComponent extends React.Component { stringRequired: React.PropTypes.string.isRequired, nodeRequired: React.PropTypes.node.isRequired, elementRequired: React.PropTypes.element.isRequired, + oneOfRequired: React.PropTypes.oneOf(['a', 'b', 'c']).isRequired, + oneOfTypeRequired: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]).isRequired, + arrayOfRequired: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, + objectOfRequired: React.PropTypes.objectOf(React.PropTypes.string).isRequired, + shapeRequired: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number.isRequired, + }).isRequired, }; render() { return <div />; diff --git a/test/react-js-make-props-and-state-transform/static-proptypes-many-props/output.tsx b/test/react-js-make-props-and-state-transform/static-proptypes-many-props/output.tsx index ed66ed3..7604480 100644 --- a/test/react-js-make-props-and-state-transform/static-proptypes-many-props/output.tsx +++ b/test/react-js-make-props-and-state-transform/static-proptypes-many-props/output.tsx @@ -1,25 +1,45 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{ - any?: any; - array?: any[]; - bool?: boolean; - func?: (...args: any[]) => any; - number?: number; - object?: object; - string?: string; - node?: React.ReactNode; - element?: JSX.Element; - anyRequired: any; - arrayRequired: any[]; - boolRequired: boolean; - funcRequired: (...args: any[]) => any; - numberRequired: number; - objectRequired: object; - stringRequired: string; - nodeRequired: React.ReactNode; - elementRequired: JSX.Element; - }, {}> { +type MyComponentProps = { + any?: any, + array?: any[], + bool?: boolean, + func?: (...args: any[]) => any, + number?: number, + object?: object, + string?: string, + node?: React.ReactNode, + element?: JSX.Element, + oneOf?: 'a' | 'b' | 'c', + oneOfType?: string | number, + arrayOf?: string[], + objectOf?: { + [key: string]: string, + }, + shape?: { + color?: string, + fontSize?: number, + }, + anyRequired: any, + arrayRequired: any[], + boolRequired: boolean, + funcRequired: (...args: any[]) => any, + numberRequired: number, + objectRequired: object, + stringRequired: string, + nodeRequired: React.ReactNode, + elementRequired: JSX.Element, + oneOfRequired: 'a' | 'b' | 'c', + oneOfTypeRequired: string | number, + arrayOfRequired: string[], + objectOfRequired: { + [key: string]: string, + }, + shapeRequired: { + color?: string, + fontSize: number, + }, +}; +export default class MyComponent extends React.Component<MyComponentProps, {}> { static propTypes = { children: React.PropTypes.node, any: React.PropTypes.any, @@ -31,6 +51,14 @@ export default class MyComponent extends React.Component<{ string: React.PropTypes.string, node: React.PropTypes.node, element: React.PropTypes.element, + oneOf: React.PropTypes.oneOf(['a', 'b', 'c']), + oneOfType: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), + arrayOf: React.PropTypes.arrayOf(React.PropTypes.string), + objectOf: React.PropTypes.objectOf(React.PropTypes.string), + shape: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number, + }), anyRequired: React.PropTypes.any.isRequired, arrayRequired: React.PropTypes.array.isRequired, boolRequired: React.PropTypes.bool.isRequired, @@ -40,6 +68,14 @@ export default class MyComponent extends React.Component<{ stringRequired: React.PropTypes.string.isRequired, nodeRequired: React.PropTypes.node.isRequired, elementRequired: React.PropTypes.element.isRequired, + oneOfRequired: React.PropTypes.oneOf(['a', 'b', 'c']).isRequired, + oneOfTypeRequired: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, + arrayOfRequired: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, + objectOfRequired: React.PropTypes.objectOf(React.PropTypes.string).isRequired, + shapeRequired: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number.isRequired, + }).isRequired, }; render() { return <div />; diff --git a/test/react-js-make-props-and-state-transform/static-proptypes-simple/output.tsx b/test/react-js-make-props-and-state-transform/static-proptypes-simple/output.tsx index 2f06d43..1d7764e 100644 --- a/test/react-js-make-props-and-state-transform/static-proptypes-simple/output.tsx +++ b/test/react-js-make-props-and-state-transform/static-proptypes-simple/output.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; - -export default class MyComponent extends React.Component<{ - foo: string; - }, {}> { +type MyComponentProps = { + foo: string, +}; +export default class MyComponent extends React.Component<MyComponentProps, {}> { static propTypes = { foo: React.PropTypes.string.isRequired, }; diff --git a/test/react-move-prop-types-to-class-transform/multiple-components/input.tsx b/test/react-move-prop-types-to-class-transform/multiple-components/input.tsx new file mode 100644 index 0000000..ca3b71d --- /dev/null +++ b/test/react-move-prop-types-to-class-transform/multiple-components/input.tsx @@ -0,0 +1,19 @@ +class SomeComponent extends React.Component<{ + foo: number; + }, { + bar: string; + }> { + render() { + return null; + } +} +SomeComponent.propTypes = { foo: React.PropTypes.string }; + +class AnotherComponent extends React.Component<{ + baz: number; +}> { + render() { + return null; + } +} +AnotherComponent.propTypes = { baz: React.PropTypes.string }; diff --git a/test/react-move-prop-types-to-class-transform/multiple-components/output.tsx b/test/react-move-prop-types-to-class-transform/multiple-components/output.tsx new file mode 100644 index 0000000..561bc3e --- /dev/null +++ b/test/react-move-prop-types-to-class-transform/multiple-components/output.tsx @@ -0,0 +1,23 @@ +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> { + static propTypes = { foo: React.PropTypes.string }; + render() { + return null; + } +} +SomeComponent.propTypes = { foo: React.PropTypes.string }; +class AnotherComponent extends React.Component<{ + baz: number, +}> { + static propTypes = { baz: React.PropTypes.string }; + render() { + return null; + } +} +AnotherComponent.propTypes = { baz: React.PropTypes.string }; diff --git a/test/react-move-prop-types-to-class-transform/simple/output.tsx b/test/react-move-prop-types-to-class-transform/simple/output.tsx index 005ab76..df8498f 100644 --- a/test/react-move-prop-types-to-class-transform/simple/output.tsx +++ b/test/react-move-prop-types-to-class-transform/simple/output.tsx @@ -1,12 +1,14 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> { static propTypes = { foo: React.PropTypes.string }; render() { return null; } } - -SomeComponent.propTypes = { foo: React.PropTypes.string }; \ No newline at end of file +SomeComponent.propTypes = { foo: React.PropTypes.string }; diff --git a/test/react-remove-prop-types-assignment-transform/functional-components/output.tsx b/test/react-remove-prop-types-assignment-transform/functional-components/output.tsx index b7895a4..a2c1315 100644 --- a/test/react-remove-prop-types-assignment-transform/functional-components/output.tsx +++ b/test/react-remove-prop-types-assignment-transform/functional-components/output.tsx @@ -1,5 +1,2 @@ import * as React from 'react'; - -function Foo() { - -} +function Foo() {} diff --git a/test/react-remove-prop-types-assignment-transform/multiple/input.tsx b/test/react-remove-prop-types-assignment-transform/multiple/input.tsx index b5ce022..71e9e2f 100644 --- a/test/react-remove-prop-types-assignment-transform/multiple/input.tsx +++ b/test/react-remove-prop-types-assignment-transform/multiple/input.tsx @@ -1,8 +1,16 @@ class SomeComponent extends React.Component<{ - foo: number; + foo: string; + baz: string; }, { bar: string; }> { } SomeComponent.propTypes = { foo: React.PropTypes.string }; -SomeComponent.propTypes.baz = React.PropTypes.string.isRequired; \ No newline at end of file +SomeComponent.propTypes.baz = React.PropTypes.string.isRequired; + + +class AnotherComponent extends React.Component<{ + lol: number; + }> { +} +AnotherComponent.propTypes = { lol: React.PropTypes.number }; diff --git a/test/react-remove-prop-types-assignment-transform/multiple/output.tsx b/test/react-remove-prop-types-assignment-transform/multiple/output.tsx index 2f10f78..e9770db 100644 --- a/test/react-remove-prop-types-assignment-transform/multiple/output.tsx +++ b/test/react-remove-prop-types-assignment-transform/multiple/output.tsx @@ -1,6 +1,12 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { -} \ No newline at end of file +class SomeComponent extends React.Component< + { + foo: string, + baz: string, + }, + { + bar: string, + }, +> {} +class AnotherComponent extends React.Component<{ + lol: number, +}> {} diff --git a/test/react-remove-prop-types-assignment-transform/simple/output.tsx b/test/react-remove-prop-types-assignment-transform/simple/output.tsx index 2f10f78..f0cc47e 100644 --- a/test/react-remove-prop-types-assignment-transform/simple/output.tsx +++ b/test/react-remove-prop-types-assignment-transform/simple/output.tsx @@ -1,6 +1,8 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { -} \ No newline at end of file +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} diff --git a/test/react-remove-prop-types-import/from-prop-types/input.tsx b/test/react-remove-prop-types-import/from-prop-types/input.tsx new file mode 100644 index 0000000..97c16f2 --- /dev/null +++ b/test/react-remove-prop-types-import/from-prop-types/input.tsx @@ -0,0 +1,6 @@ +import PropTypes from 'prop-types' +import React from 'react' + +export const Hello = ({ message }) => { + return <div>hello {message}</div> +} diff --git a/test/react-remove-prop-types-import/from-prop-types/output.tsx b/test/react-remove-prop-types-import/from-prop-types/output.tsx new file mode 100644 index 0000000..b4a5929 --- /dev/null +++ b/test/react-remove-prop-types-import/from-prop-types/output.tsx @@ -0,0 +1,4 @@ +import React from 'react'; +export const Hello = ({ message }) => { + return <div>hello {message}</div>; +}; diff --git a/test/react-remove-prop-types-import/from-react-multi-named-import/input.tsx b/test/react-remove-prop-types-import/from-react-multi-named-import/input.tsx new file mode 100644 index 0000000..23cd15f --- /dev/null +++ b/test/react-remove-prop-types-import/from-react-multi-named-import/input.tsx @@ -0,0 +1,7 @@ +import React, { PropTypes, Component } from 'react'; + +export class MyComponent extends Component { + render() { + return <div>hello</div>; + } +} diff --git a/test/react-remove-prop-types-import/from-react-multi-named-import/output.tsx b/test/react-remove-prop-types-import/from-react-multi-named-import/output.tsx new file mode 100644 index 0000000..106ed51 --- /dev/null +++ b/test/react-remove-prop-types-import/from-react-multi-named-import/output.tsx @@ -0,0 +1,6 @@ +import React, { Component } from 'react'; +export class MyComponent extends Component { + render() { + return <div>hello</div>; + } +} diff --git a/test/react-remove-prop-types-import/from-react-simple/input.tsx b/test/react-remove-prop-types-import/from-react-simple/input.tsx new file mode 100644 index 0000000..a9b9848 --- /dev/null +++ b/test/react-remove-prop-types-import/from-react-simple/input.tsx @@ -0,0 +1,5 @@ +import React, { PropTypes } from 'react' + +export const Hello = ({ message }) => { + return <div>hello {message}</div> +} diff --git a/test/react-remove-prop-types-import/from-react-simple/output.tsx b/test/react-remove-prop-types-import/from-react-simple/output.tsx new file mode 100644 index 0000000..b4a5929 --- /dev/null +++ b/test/react-remove-prop-types-import/from-react-simple/output.tsx @@ -0,0 +1,4 @@ +import React from 'react'; +export const Hello = ({ message }) => { + return <div>hello {message}</div>; +}; diff --git a/test/react-remove-static-prop-types-member-transform/getter/output.tsx b/test/react-remove-static-prop-types-member-transform/getter/output.tsx index 2f10f78..f0cc47e 100644 --- a/test/react-remove-static-prop-types-member-transform/getter/output.tsx +++ b/test/react-remove-static-prop-types-member-transform/getter/output.tsx @@ -1,6 +1,8 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { -} \ No newline at end of file +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} diff --git a/test/react-remove-static-prop-types-member-transform/multiple-components/input.tsx b/test/react-remove-static-prop-types-member-transform/multiple-components/input.tsx new file mode 100644 index 0000000..b8deaa2 --- /dev/null +++ b/test/react-remove-static-prop-types-member-transform/multiple-components/input.tsx @@ -0,0 +1,20 @@ +class SomeComponent extends React.Component<{ + foo: number; + }, { + bar: string; + }> { + static propTypes = { + foo: React.PropTypes.string, + baz: React.PropTypes.string.isRequired, + }; +} + +class AnotherComponent extends React.Component<{ + foo: number; + }, { + bar: string; + }> { + static propTypes = { + baz: React.PropTypes.string.isRequired, + }; +} diff --git a/test/react-remove-static-prop-types-member-transform/multiple-components/output.tsx b/test/react-remove-static-prop-types-member-transform/multiple-components/output.tsx new file mode 100644 index 0000000..6d90eb5 --- /dev/null +++ b/test/react-remove-static-prop-types-member-transform/multiple-components/output.tsx @@ -0,0 +1,16 @@ +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} +class AnotherComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} diff --git a/test/react-remove-static-prop-types-member-transform/multiple/output.tsx b/test/react-remove-static-prop-types-member-transform/multiple/output.tsx index 2f10f78..f0cc47e 100644 --- a/test/react-remove-static-prop-types-member-transform/multiple/output.tsx +++ b/test/react-remove-static-prop-types-member-transform/multiple/output.tsx @@ -1,6 +1,8 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { -} \ No newline at end of file +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} diff --git a/test/react-remove-static-prop-types-member-transform/other-static-members/input.tsx b/test/react-remove-static-prop-types-member-transform/other-static-members/input.tsx new file mode 100644 index 0000000..ed98022 --- /dev/null +++ b/test/react-remove-static-prop-types-member-transform/other-static-members/input.tsx @@ -0,0 +1,8 @@ +class SomeComponent extends React.Component<{ + foo: number; +}, { + bar: string; +}> { + static propTypes = { foo: React.PropTypes.string }; + static defaultProps = { foo: 'bar' }; +} diff --git a/test/react-remove-static-prop-types-member-transform/other-static-members/output.tsx b/test/react-remove-static-prop-types-member-transform/other-static-members/output.tsx new file mode 100644 index 0000000..c37607e --- /dev/null +++ b/test/react-remove-static-prop-types-member-transform/other-static-members/output.tsx @@ -0,0 +1,10 @@ +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> { + static defaultProps = { foo: 'bar' }; +} diff --git a/test/react-remove-static-prop-types-member-transform/simple/output.tsx b/test/react-remove-static-prop-types-member-transform/simple/output.tsx index 2f10f78..f0cc47e 100644 --- a/test/react-remove-static-prop-types-member-transform/simple/output.tsx +++ b/test/react-remove-static-prop-types-member-transform/simple/output.tsx @@ -1,6 +1,8 @@ -class SomeComponent extends React.Component<{ - foo: number; - }, { - bar: string; - }> { -} \ No newline at end of file +class SomeComponent extends React.Component< + { + foo: number, + }, + { + bar: string, + }, +> {} diff --git a/test/react-stateless-function-make-props-transform/empty-prop/input.tsx b/test/react-stateless-function-make-props-transform/empty-prop/input.tsx new file mode 100644 index 0000000..6831632 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/empty-prop/input.tsx @@ -0,0 +1,6 @@ +function Hello() { + return <div /> +} + +Hello.propTypes = { +}; diff --git a/test/react-stateless-function-make-props-transform/empty-prop/output.tsx b/test/react-stateless-function-make-props-transform/empty-prop/output.tsx new file mode 100644 index 0000000..ecb8d4a --- /dev/null +++ b/test/react-stateless-function-make-props-transform/empty-prop/output.tsx @@ -0,0 +1,4 @@ +const Hello: React.SFC<{}> = () => { + return <div />; +}; +Hello.propTypes = {}; diff --git a/test/react-stateless-function-make-props-transform/multiple-components/input.tsx b/test/react-stateless-function-make-props-transform/multiple-components/input.tsx new file mode 100644 index 0000000..7b9d649 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/multiple-components/input.tsx @@ -0,0 +1,15 @@ +const Hello = ({ message }) => { + return <div>hello {message}</div> +}; + +function Hey({ name }) { + return <div>hey, {name}</div> +} + +Hey.propTypes = { + name: React.PropTypes.string.isRequired, +} + +Hello.propTypes = { + message: React.PropTypes.string, +} diff --git a/test/react-stateless-function-make-props-transform/multiple-components/output.tsx b/test/react-stateless-function-make-props-transform/multiple-components/output.tsx new file mode 100644 index 0000000..39f3039 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/multiple-components/output.tsx @@ -0,0 +1,18 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; +type HeyProps = { + name: string, +}; +const Hey: React.SFC<HeyProps> = ({ name }) => { + return <div>hey, {name}</div>; +}; +Hey.propTypes = { + name: React.PropTypes.string.isRequired, +}; +Hello.propTypes = { + message: React.PropTypes.string, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-arrow-function/input.tsx b/test/react-stateless-function-make-props-transform/stateless-arrow-function/input.tsx new file mode 100644 index 0000000..9ddb8b7 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-arrow-function/input.tsx @@ -0,0 +1,7 @@ +const Hello = ({ message }) => { + return <div>hello {message}</div> +}; + +Hello.propTypes = { + message: React.PropTypes.string, +} diff --git a/test/react-stateless-function-make-props-transform/stateless-arrow-function/output.tsx b/test/react-stateless-function-make-props-transform/stateless-arrow-function/output.tsx new file mode 100644 index 0000000..f706915 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-arrow-function/output.tsx @@ -0,0 +1,9 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; +Hello.propTypes = { + message: React.PropTypes.string, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-function-many-props/input.tsx b/test/react-stateless-function-make-props-transform/stateless-function-many-props/input.tsx new file mode 100644 index 0000000..6847265 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-function-many-props/input.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +function MyComponent() { + return <div /> +} + +MyComponent.propTypes = { + children: React.PropTypes.node, + any: React.PropTypes.any, + array: React.PropTypes.array, + bool: React.PropTypes.bool, + func: React.PropTypes.func, + number: React.PropTypes.number, + object: React.PropTypes.object, + string: React.PropTypes.string, + node: React.PropTypes.node, + element: React.PropTypes.element, + oneOf: React.PropTypes.oneOf(['a', 'b', 'c']), + oneOfType: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]), + arrayOf: React.PropTypes.arrayOf(React.PropTypes.string), + objectOf: React.PropTypes.objectOf(React.PropTypes.string), + shape: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number, + }), + anyRequired: React.PropTypes.any.isRequired, + arrayRequired: React.PropTypes.array.isRequired, + boolRequired: React.PropTypes.bool.isRequired, + funcRequired: React.PropTypes.func.isRequired, + numberRequired: React.PropTypes.number.isRequired, + objectRequired: React.PropTypes.object.isRequired, + stringRequired: React.PropTypes.string.isRequired, + nodeRequired: React.PropTypes.node.isRequired, + elementRequired: React.PropTypes.element.isRequired, + oneOfRequired: React.PropTypes.oneOf(['a', 'b', 'c']).isRequired, + oneOfTypeRequired: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]).isRequired, + arrayOfRequired: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, + objectOfRequired: React.PropTypes.objectOf(React.PropTypes.string).isRequired, + shapeRequired: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number.isRequired, + }).isRequired, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-function-many-props/output.tsx b/test/react-stateless-function-make-props-transform/stateless-function-many-props/output.tsx new file mode 100644 index 0000000..f68ac25 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-function-many-props/output.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +type MyComponentProps = { + any?: any, + array?: any[], + bool?: boolean, + func?: (...args: any[]) => any, + number?: number, + object?: object, + string?: string, + node?: React.ReactNode, + element?: JSX.Element, + oneOf?: 'a' | 'b' | 'c', + oneOfType?: string | number, + arrayOf?: string[], + objectOf?: { + [key: string]: string, + }, + shape?: { + color?: string, + fontSize?: number, + }, + anyRequired: any, + arrayRequired: any[], + boolRequired: boolean, + funcRequired: (...args: any[]) => any, + numberRequired: number, + objectRequired: object, + stringRequired: string, + nodeRequired: React.ReactNode, + elementRequired: JSX.Element, + oneOfRequired: 'a' | 'b' | 'c', + oneOfTypeRequired: string | number, + arrayOfRequired: string[], + objectOfRequired: { + [key: string]: string, + }, + shapeRequired: { + color?: string, + fontSize: number, + }, +}; +const MyComponent: React.SFC<MyComponentProps> = () => { + return <div />; +}; +MyComponent.propTypes = { + children: React.PropTypes.node, + any: React.PropTypes.any, + array: React.PropTypes.array, + bool: React.PropTypes.bool, + func: React.PropTypes.func, + number: React.PropTypes.number, + object: React.PropTypes.object, + string: React.PropTypes.string, + node: React.PropTypes.node, + element: React.PropTypes.element, + oneOf: React.PropTypes.oneOf(['a', 'b', 'c']), + oneOfType: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), + arrayOf: React.PropTypes.arrayOf(React.PropTypes.string), + objectOf: React.PropTypes.objectOf(React.PropTypes.string), + shape: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number, + }), + anyRequired: React.PropTypes.any.isRequired, + arrayRequired: React.PropTypes.array.isRequired, + boolRequired: React.PropTypes.bool.isRequired, + funcRequired: React.PropTypes.func.isRequired, + numberRequired: React.PropTypes.number.isRequired, + objectRequired: React.PropTypes.object.isRequired, + stringRequired: React.PropTypes.string.isRequired, + nodeRequired: React.PropTypes.node.isRequired, + elementRequired: React.PropTypes.element.isRequired, + oneOfRequired: React.PropTypes.oneOf(['a', 'b', 'c']).isRequired, + oneOfTypeRequired: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, + arrayOfRequired: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, + objectOfRequired: React.PropTypes.objectOf(React.PropTypes.string).isRequired, + shapeRequired: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number.isRequired, + }).isRequired, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-function/input.tsx b/test/react-stateless-function-make-props-transform/stateless-function/input.tsx new file mode 100644 index 0000000..fd1d4ce --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-function/input.tsx @@ -0,0 +1,7 @@ +function Hello({ message }) { + return <div>hello {message}</div>; +} + +Hello.propTypes = { + message: React.PropTypes.string, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-function/output.tsx b/test/react-stateless-function-make-props-transform/stateless-function/output.tsx new file mode 100644 index 0000000..f706915 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-function/output.tsx @@ -0,0 +1,9 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC<HelloProps> = ({ message }) => { + return <div>hello {message}</div>; +}; +Hello.propTypes = { + message: React.PropTypes.string, +}; diff --git a/test/react-stateless-function-make-props-transform/stateless-propless/input.tsx b/test/react-stateless-function-make-props-transform/stateless-propless/input.tsx new file mode 100644 index 0000000..40da377 --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-propless/input.tsx @@ -0,0 +1,6 @@ +const Hello1 = ({ message }) => { + return <div>hello {message}</div>; +}; +function Hello2({ message }) { + return <div>hello {message}</div>; +} diff --git a/test/react-stateless-function-make-props-transform/stateless-propless/output.tsx b/test/react-stateless-function-make-props-transform/stateless-propless/output.tsx new file mode 100644 index 0000000..c0f444c --- /dev/null +++ b/test/react-stateless-function-make-props-transform/stateless-propless/output.tsx @@ -0,0 +1,6 @@ +const Hello1 = ({ message }) => { + return <div>hello {message}</div>; +}; +function Hello2({ message }) { + return <div>hello {message}</div>; +} diff --git a/test/runner.ts b/test/transformers.test.ts similarity index 65% rename from test/runner.ts rename to test/transformers.test.ts index 6b6e725..8b845d4 100644 --- a/test/runner.ts +++ b/test/transformers.test.ts @@ -7,14 +7,17 @@ import * as path from 'path'; import * as fs from 'fs'; import * as ts from 'typescript'; import * as chalk from 'chalk'; +import * as _ from 'lodash'; + import { - reactHoistGenericsTransformFactoryFactory, reactJSMakePropsAndStateInterfaceTransformFactoryFactory, + reactStatelessFunctionMakePropsTransformFactoryFactory, reactMovePropTypesToClassTransformFactoryFactory, reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, - allTransforms, collapseIntersectionInterfacesTransformFactoryFactory, + reactRemovePropTypesImportTransformFactoryFactory, + allTransforms, compile, TransformFactoryFactory } from '../src'; @@ -23,14 +26,17 @@ import { /** Map between a transform and its test folder */ const transformToFolderMap: [string, TransformFactoryFactory[]][] = [ ['react-js-make-props-and-state-transform', [reactJSMakePropsAndStateInterfaceTransformFactoryFactory]], - ['react-hoist-generics-transform', [reactHoistGenericsTransformFactoryFactory]], + ['react-stateless-function-make-props-transform', [reactStatelessFunctionMakePropsTransformFactoryFactory]], ['react-remove-static-prop-types-member-transform', [reactRemoveStaticPropTypesMemberTransformFactoryFactory]], ['react-remove-prop-types-assignment-transform', [reactRemovePropTypesAssignmentTransformFactoryFactory]], ['collapse-intersection-interfaces-transform', [collapseIntersectionInterfacesTransformFactoryFactory]], ['react-move-prop-types-to-class-transform', [reactMovePropTypesToClassTransformFactoryFactory]], + ['react-remove-prop-types-import', [reactRemovePropTypesImportTransformFactoryFactory]], ['end-to-end', allTransforms], ]; +const isJestUpdateSnapshotEnabled = !!_.intersection(process.argv, ['-u', '--updateSnapshot']).length; + for (const [testFolderName, getFactory] of transformToFolderMap) { describe(testFolderName.replace(/\-/g, ' ').replace('transform', ''), () => { for (const folderName of fs.readdirSync(path.join(__dirname, testFolderName))) { @@ -38,8 +44,17 @@ for (const [testFolderName, getFactory] of transformToFolderMap) { if (fs.statSync(folder).isDirectory()) { it(`${testFolderName} ${folderName}`, async () => { const inputPath = path.join(folder, 'input.tsx'); - const output = await readFile(path.join(folder, 'output.tsx')); - const result = compile(inputPath, getFactory); + const outputPath = path.join(folder, 'output.tsx'); + const result = compile(inputPath, getFactory, { + singleQuote: true, + printWidth: 120, + tabWidth: 4, + trailingComma: 'all', + }); + if (isJestUpdateSnapshotEnabled) { + await writeFile(outputPath, result); + } + const output = await readFile(outputPath); expect(stripEmptyLines(result)).toEqual(stripEmptyLines(output)); }); } @@ -68,3 +83,17 @@ function readFile(pathToFile: string) { }); }); } + +/** + * Read a file + * @param pathToFile Path to a string file + * @param contents Contents of the file + */ +function writeFile(pathToFile: string, contents: string) { + return new Promise<string>((resolve, reject) => { + fs.writeFile(pathToFile, contents, (error) => { + if (error) { return reject(error); } + resolve(); + }); + }); +} diff --git a/tsconfig.json b/tsconfig.json index 61d9587..0a2ed71 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,19 +7,12 @@ "module": "commonjs", "emitDecoratorMetadata": true, "experimentalDecorators": true, + "downlevelIteration": true, "sourceMap": true, "outDir": "dist", - "sourceRoot": "../src" + "sourceRoot": "../src", + "lib": ["dom", "es2015"] }, - "exclude": [ - "node_modules", - "test" - ], - "types": [ - "node", - "jest" - ], - "lib": [ - "es2017" - ] + "exclude": ["node_modules", "test", "dist"], + "types": ["node", "jest"] } diff --git a/tslint.json b/tslint.json index e4fe9c4..47497f9 100644 --- a/tslint.json +++ b/tslint.json @@ -4,25 +4,11 @@ }, "defaultSeverity": "warning", "rules": { - "quotemark": [ - true, - "single", - "avoid-escape" - ], - "max-line-length": [ - true, - 120 - ], - "indent": [ - "error", - 4 - ], - "only-arrow-functions": [ - false - ], + "quotemark": [true, "single", "avoid-escape"], + "max-line-length": [false], + "indent": ["error", 4], + "only-arrow-functions": [false], // Disabled rules - "typedef": [ - false - ] + "typedef": [false] } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..fcb2ae6 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3896 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.47" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.47.tgz#d18c2f4c4ba8d093a2bcfab5616593bfe2441a27" + dependencies: + "@babel/highlight" "7.0.0-beta.47" + +"@babel/highlight@7.0.0-beta.47": + version "7.0.0-beta.47" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.47.tgz#8fbc83fb2a21f0bd2b95cdbeb238cf9689cad494" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@types/chalk@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-2.2.0.tgz#b7f6e446f4511029ee8e3f43075fb5b73fbaa0ba" + dependencies: + chalk "*" + +"@types/commander@^2.9.1": + version "2.12.2" + resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" + dependencies: + commander "*" + +"@types/detect-indent@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/detect-indent/-/detect-indent-5.0.0.tgz#8b1bbd7891268d5ed20d23ecd23ae333d33934cd" + +"@types/events@*": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02" + +"@types/glob@^5.0.35": + version "5.0.35" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/jest@^22.2.3": + version "22.2.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d" + +"@types/lodash@^4.14.109": + version "4.14.109" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.109.tgz#b1c4442239730bf35cabaf493c772b18c045886d" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + +"@types/node@*": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-9.3.0.tgz#3a129cda7c4e5df2409702626892cb4b96546dd5" + +"@types/node@^10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.1.2.tgz#1b928a0baa408fc8ae3ac012cc81375addc147c6" + +"@types/prettier@^1.12.2": + version "1.12.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.12.2.tgz#4a37f0aa8ed20366ada6fa7994b1c6dfe787fdd1" + +"@types/react@^16.3.14": + version "16.3.14" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.14.tgz#f90ac6834de172e13ecca430dcb6814744225d36" + dependencies: + csstype "^2.2.0" + +abab@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.3.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escapes@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0, ansi-styles@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +any-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +app-root-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.1.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-22.4.4.tgz#977259240420e227444ebe49e226a61e49ea659d" + dependencies: + babel-plugin-istanbul "^4.1.5" + babel-preset-jest "^22.4.4" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.5, babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz#b9851906eab34c7bf6f8c895a2b08bea1a844c0b" + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-transform-es2015-modules-commonjs@^6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-jest@^22.4.3, babel-preset-jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.4.tgz#ec9fbd8bcd7dfd24b8b5320e0e688013235b7c39" + dependencies: + babel-plugin-jest-hoist "^22.4.4" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.2: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + dependencies: + resolve "1.1.7" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + dependencies: + rsvp "^3.3.3" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@*, chalk@^2.3.1, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +chokidar@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +ci-info@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@*, commander@^2.12.1, commander@^2.9.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +commander@^2.14.1, commander@^2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + +compare-versions@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.2.1.tgz#a49eb7689d4caaf0b6db5220173fd279614000f7" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + +cpx@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cpx/-/cpx-1.5.0.tgz#185be018511d87270dedccc293171e37655ab88f" + dependencies: + babel-runtime "^6.9.2" + chokidar "^1.6.0" + duplexer "^0.1.1" + glob "^7.0.5" + glob2base "^0.0.12" + minimatch "^3.0.2" + mkdirp "^0.5.1" + resolve "^1.1.7" + safe-buffer "^5.0.1" + shell-quote "^1.6.1" + subarg "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" + +"cssstyle@>= 0.2.37 < 0.3.0": + version "0.2.37" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + dependencies: + cssom "0.3.x" + +csstype@^2.2.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.5.2.tgz#4534308476ceede8fbe148b9b99f9baf1c80fa06" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f" + dependencies: + abab "^1.0.4" + whatwg-mimetype "^2.0.0" + whatwg-url "^6.4.0" + +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + +debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +decamelize@^1.0.0, decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + +deep-extend@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +diff@^3.1.0, diff@^3.2.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" + +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.5.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +exec-sh@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" + dependencies: + merge "^1.1.3" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expect@^22.4.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^22.4.3" + jest-get-type "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-regex-util "^22.4.3" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +fs-extra@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0, fsevents@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-own-enumerable-property-symbols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob2base@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + dependencies: + find-index "^0.1.1" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +handlebars@^4.0.3: + version "4.0.11" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +husky@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" + dependencies: + is-ci "^1.0.10" + normalize-path "^1.0.0" + strip-indent "^2.0.0" + +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +iconv-lite@^0.4.4: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.0" + +is-plain-object@^2.0.1, 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" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-api@^1.1.14: + version "1.3.1" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.1.tgz#4c3b05d18c0016d1022e079b98dc82c40f488954" + dependencies: + async "^2.1.4" + compare-versions "^3.1.0" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-hook "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-report "^1.1.4" + istanbul-lib-source-maps "^1.2.4" + istanbul-reports "^1.3.0" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-coverage@^1.1.2, istanbul-lib-coverage@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" + +istanbul-lib-hook@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz#ae556fd5a41a6e8efa0b1002b1e416dfeaf9816c" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.8.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.0" + semver "^5.3.0" + +istanbul-lib-report@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5" + dependencies: + istanbul-lib-coverage "^1.2.0" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.1.2" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-lib-source-maps@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz#cc7ccad61629f4efff8e2f78adb8c522c9976ec7" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.0" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554" + dependencies: + handlebars "^4.0.3" + +jest-changed-files@^22.2.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2" + dependencies: + throat "^4.0.0" + +jest-cli@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-22.4.4.tgz#68cd2a2aae983adb1e6638248ca21082fd6d9e90" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.1.14" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-instrument "^1.8.0" + istanbul-lib-source-maps "^1.2.1" + jest-changed-files "^22.2.0" + jest-config "^22.4.4" + jest-environment-jsdom "^22.4.1" + jest-get-type "^22.1.0" + jest-haste-map "^22.4.2" + jest-message-util "^22.4.0" + jest-regex-util "^22.1.0" + jest-resolve-dependencies "^22.1.0" + jest-runner "^22.4.4" + jest-runtime "^22.4.4" + jest-snapshot "^22.4.0" + jest-util "^22.4.1" + jest-validate "^22.4.4" + jest-worker "^22.2.2" + micromatch "^2.3.11" + node-notifier "^5.2.1" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^10.0.3" + +jest-config@^22.4.3, jest-config@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.4.tgz#72a521188720597169cd8b4ff86934ef5752d86a" + dependencies: + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^22.4.1" + jest-environment-node "^22.4.1" + jest-get-type "^22.1.0" + jest-jasmine2 "^22.4.4" + jest-regex-util "^22.1.0" + jest-resolve "^22.4.2" + jest-util "^22.4.1" + jest-validate "^22.4.4" + pretty-format "^22.4.0" + +jest-diff@^22.4.0, jest-diff@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-docblock@^22.4.0, jest-docblock@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.3.tgz#50886f132b42b280c903c592373bb6e93bb68b19" + dependencies: + detect-newline "^2.1.0" + +jest-environment-jsdom@^22.4.1: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + jsdom "^11.5.1" + +jest-environment-node@^22.4.1: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + +jest-get-type@^22.1.0, jest-get-type@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + +jest-haste-map@^22.4.2: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.3.tgz#25842fa2ba350200767ac27f658d58b9d5c2e20b" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^22.4.3" + jest-serializer "^22.4.3" + jest-worker "^22.4.3" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.4.tgz#c55f92c961a141f693f869f5f081a79a10d24e23" + dependencies: + chalk "^2.0.1" + co "^4.6.0" + expect "^22.4.0" + graceful-fs "^4.1.11" + is-generator-fn "^1.0.0" + jest-diff "^22.4.0" + jest-matcher-utils "^22.4.0" + jest-message-util "^22.4.0" + jest-snapshot "^22.4.0" + jest-util "^22.4.1" + source-map-support "^0.5.0" + +jest-leak-detector@^22.4.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-22.4.3.tgz#2b7b263103afae8c52b6b91241a2de40117e5b35" + dependencies: + pretty-format "^22.4.3" + +jest-matcher-utils@^22.4.0, jest-matcher-utils@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-message-util@^22.4.0, jest-message-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" + +jest-regex-util@^22.1.0, jest-regex-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" + +jest-resolve-dependencies@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-22.4.3.tgz#e2256a5a846732dc3969cb72f3c9ad7725a8195e" + dependencies: + jest-regex-util "^22.4.3" + +jest-resolve@^22.4.2: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" + dependencies: + browser-resolve "^1.11.2" + chalk "^2.0.1" + +jest-runner@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-22.4.4.tgz#dfca7b7553e0fa617e7b1291aeb7ce83e540a907" + dependencies: + exit "^0.1.2" + jest-config "^22.4.4" + jest-docblock "^22.4.0" + jest-haste-map "^22.4.2" + jest-jasmine2 "^22.4.4" + jest-leak-detector "^22.4.0" + jest-message-util "^22.4.0" + jest-runtime "^22.4.4" + jest-util "^22.4.1" + jest-worker "^22.2.2" + throat "^4.0.0" + +jest-runtime@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-22.4.4.tgz#9ba7792fc75582a5be0f79af6f8fe8adea314048" + dependencies: + babel-core "^6.0.0" + babel-jest "^22.4.4" + babel-plugin-istanbul "^4.1.5" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^22.4.4" + jest-haste-map "^22.4.2" + jest-regex-util "^22.1.0" + jest-resolve "^22.4.2" + jest-util "^22.4.1" + jest-validate "^22.4.4" + json-stable-stringify "^1.0.1" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^10.0.3" + +jest-serializer@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.3.tgz#a679b81a7f111e4766235f4f0c46d230ee0f7436" + +jest-snapshot@^22.4.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" + dependencies: + chalk "^2.0.1" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^22.4.3" + +jest-util@^22.4.1, jest-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^22.4.3" + mkdirp "^0.5.1" + source-map "^0.6.0" + +jest-validate@^22.4.0, jest-validate@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.4.tgz#1dd0b616ef46c995de61810d85f57119dbbcec4d" + dependencies: + chalk "^2.0.1" + jest-config "^22.4.4" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^22.4.0" + +jest-worker@^22.2.2, jest-worker@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.4.3.tgz#5c421417cba1c0abf64bf56bd5fb7968d79dd40b" + dependencies: + merge-stream "^1.0.1" + +jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest/-/jest-22.4.4.tgz#ffb36c9654b339a13e10b3d4b338eb3e9d49f6eb" + dependencies: + import-local "^1.0.0" + jest-cli "^22.4.4" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.7.0, js-yaml@^3.9.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdom@^11.5.1: + version "11.10.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.10.0.tgz#a42cd54e88895dc765f03f15b807a474962ac3b5" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.2.37 < 0.3.0" + data-urls "^1.0.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwmatcher "^1.4.3" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.0" + ws "^4.0.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +json-parse-better-errors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +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" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lint-staged@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.1.1.tgz#bcdb5de76a6b52db6b2cf83fce62aee95baf7fa0" + dependencies: + app-root-path "^2.0.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^4.0.0" + debug "^3.1.0" + dedent "^0.7.0" + execa "^0.9.0" + find-parent-dir "^0.3.0" + is-glob "^4.0.0" + is-windows "^1.0.2" + jest-validate "^22.4.0" + listr "^0.13.0" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.1" + string-argv "^0.0.2" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + +listr-update-renderer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + figures "^1.7.0" + indent-string "^2.1.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.4.0" + listr-verbose-renderer "^0.4.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + ora "^0.2.3" + p-map "^1.1.1" + rxjs "^5.4.2" + stream-to-observable "^0.2.0" + strip-ansi "^3.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.5: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +lodash@^4.14.0, lodash@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-error@^1.1.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.2.tgz#8762ffad2444dd8ff1f7c819629fa28e24fea1c4" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@^2.1.12, mime-types@~2.1.17: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minipass@^2.2.1, minipass@^2.2.4: + version "2.3.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.1.tgz#4e872b959131a672837ab3cb554962bc84b1537d" + dependencies: + safe-buffer "^5.1.1" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +nan@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-odd "^2.0.0" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +needle@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-notifier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz#6e4ef5bb5c5203c6552448828c852c40111aac46" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.0" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.1.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-bundled@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + +npm-packlist@^1.1.6: + version "1.1.10" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + dependencies: + which "^1.2.10" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nwmatcher@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + +oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ora@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + +please-upgrade-node@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.2.tgz#7b9eaeca35aa4a43d6ebdfd10616c042f9a83acc" + dependencies: + semver-compare "^1.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" + +pretty-format@^22.4.0, pretty-format@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +private@^0.1.7, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +rc@^1.1.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.7.tgz#8a10ca30d588d00464360372b890d06dacd02297" + dependencies: + deep-extend "^0.5.1" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +realpath-native@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.0.tgz#7885721a83b43bd5327609f0ddecb2482305fdf0" + dependencies: + util.promisify "^1.0.0" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.83.0: + version "2.86.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.86.0.tgz#2b9497f449b0a32654c081a5cf426bbfb5bf5b69" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-from-string@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.7: + version "1.7.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" + dependencies: + path-parse "^1.0.5" + +resolve@^1.3.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@^2.5.4, rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + +rxjs@^5.4.2: + version "5.5.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02" + dependencies: + symbol-observable "1.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.0, source-map-support@^0.5.3, source-map-support@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +staged-git-files@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +stream-to-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10" + dependencies: + any-observable "^0.2.0" + +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" + dependencies: + get-own-enumerable-property-symbols "^2.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +subarg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + dependencies: + minimist "^1.1.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +supports-color@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +tar@^4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.2.tgz#60685211ba46b38847b1ae7ee1a24d744a2cd462" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.2.4" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +test-exclude@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" + dependencies: + arrify "^1.0.1" + micromatch "^3.1.8" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@>=2.3.3, tough-cookie@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + +tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + dependencies: + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +ts-jest@^22.4.6: + version "22.4.6" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-22.4.6.tgz#a5d7f5e8b809626d1f4143209d301287472ec344" + dependencies: + babel-core "^6.26.3" + babel-plugin-istanbul "^4.1.6" + babel-plugin-transform-es2015-modules-commonjs "^6.26.2" + babel-preset-jest "^22.4.3" + cpx "^1.5.0" + fs-extra "6.0.0" + jest-config "^22.4.3" + lodash "^4.17.10" + pkg-dir "^2.0.0" + source-map-support "^0.5.5" + yargs "^11.0.0" + +ts-node@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-6.0.3.tgz#28bf74bcad134fad17f7469dad04638ece03f0f4" + dependencies: + arrify "^1.0.0" + chalk "^2.3.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.3" + yn "^2.0.0" + +tslib@^1.8.0, tslib@^1.8.1: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + +tslint@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3" + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.12.1" + +tsutils@^2.12.1: + version "2.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.19.1.tgz#76d7ebdea9d7a7bf4a05f50ead3701b0168708d7" + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typescript@2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.3.tgz#5d817f9b6f31bb871835f4edf0089f21abe6c170" + +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +universalify@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +use@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" + dependencies: + kind-of "^6.0.2" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + dependencies: + iconv-lite "0.4.19" + +whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + +whatwg-url@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.1.tgz#fdb94b440fd4ad836202c16e9737d511f012fd67" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.10, which@^1.2.12, which@^1.2.9, which@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" + dependencies: + camelcase "^4.1.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + dependencies: + camelcase "^4.1.0" + +yargs@^10.0.3: + version "10.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.1.0" + +yargs@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"