diff --git a/.eslintrc.js b/.eslintrc.js index a4afc873..a5919e54 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = { - parser: 'babel-eslint', + parser: '@typescript-eslint/parser', extends: './node_modules/fbjs-scripts/eslint/.eslintrc.js', diff --git a/LEGACY.md b/LEGACY.md new file mode 100644 index 00000000..06f2f899 --- /dev/null +++ b/LEGACY.md @@ -0,0 +1,279 @@ +## Legacy `react-codemod` + +All codemods in this repo can be run using the legacy `react-codemod` command, which runs the codemods via jscodeshift directly. + +### Usage + +We recommend using the [`codemod`](github.com/reactjs/react-codemod) command for improved experience and support. + +To use `react-codemod` directly: + +`npx react-codemod [...options]` +* `transform` - name of transform, see available transforms below. +* `path` - files or directory to transform +* use the `--dry` option for a dry-run and use `--print` to print the output for comparison + +This will start an interactive wizard, and then run the specified transform. + +### Included Transforms + +#### `remove-context-provider` + +Converts `Context.Provider` JSX opening and closing elements into `Context`. + +```sh +npx react-codemod remove-context-provider +``` + +#### `remove-forward-ref` + +Removes usages of `forwardRef`. + +```sh +npx react-codemod remove-forward-ref +``` + +#### `use-context-hook` + +```sh +npx react-codemod use-context-hook +``` + +#### `replace-act-import` + +```sh +npx react-codemod replace-act-import +``` + +#### `replace-string-ref` + +Replaces deprecated string refs with callback refs. + +```sh +npx react-codemod replace-string-ref +``` + +#### `replace-use-form-state` + +Replaces usages of useFormState() to use useActionState(). + +```sh +npx react-codemod replace-use-form-state +``` + +#### `replace-reactdom-render` + +Replaces usages of ReactDom.render() with createRoot(node).render(). + +```sh +npx react-codemod replace-reactdom-render +``` + +#### `create-element-to-jsx` + +Converts calls to `React.createElement` into JSX elements. + +```sh +npx react-codemod create-element-to-jsx +``` + +#### `error-boundaries` + +Renames the experimental `unstable_handleError` lifecycle hook to `componentDidCatch`. + +```sh +npx react-codemod error-boundaries +``` + +#### `findDOMNode` + +Updates `this.getDOMNode()` or `this.refs.foo.getDOMNode()` calls inside of +`React.createClass` components to `React.findDOMNode(foo)`. Note that it will +only look at code inside of `React.createClass` calls and only update calls on +the component instance or its refs. You can use this script to update most calls +to `getDOMNode` and then manually go through the remaining calls. + +```sh +npx react-codemod findDOMNode +``` + +#### `manual-bind-to-arrow` + +Converts manual function bindings in a class (e.g., `this.f = this.f.bind(this)`) to arrow property initializer functions (e.g., `f = () => {}`). + +```sh +npx react-codemod manual-bind-to-arrow +``` + +#### `pure-component` + +Converts ES6 classes that only have a render method, only have safe properties +(statics and props), and do not have refs to Functional Components. + +The wizard will ask for 2 options - + +* **Use arrow functions?**: converts to arrow function. Converts to `function` by default. +* **Destructure props?**: will destructure props in the argument where it is safe to do so. + +```sh +npx react-codemod pure-component +``` + +#### `pure-render-mixin` + +Removes `PureRenderMixin` and inlines `shouldComponentUpdate` so that the ES2015 +class transform can pick up the React component and turn it into an ES2015 +class. NOTE: This currently only works if you are using the master version +(>0.13.1) of React as it is using `React.addons.shallowCompare` + +```sh +npx react-codemod pure-render-mixin +``` + +* The wizard will ask to optionally override `mixin-name`, and look for it + instead of `PureRenderMixin`. Note that it is not possible to use a + namespaced name for the mixin. `mixins: [React.addons.PureRenderMixin]` will + not currently work. + +#### `React-PropTypes-to-prop-types` + +Replaces `React.PropTypes` references with `prop-types` and adds the appropriate `import` or `require` statement. This codemod is intended for React 15.5+. + +```sh +npx react-codemod React-PropTypes-to-prop-types +``` + +* In addition to running the above codemod you will also need to install the `prop-types` NPM package. + +#### `rename-unsafe-lifecycles` + +Adds `UNSAFE_` prefix for deprecated lifecycle hooks. (For more information about this codemod, see [React RFC #6](https://github.com/reactjs/rfcs/pull/6)) + +```sh +npx react-codemod rename-unsafe-lifecycles +``` + +#### `react-to-react-dom` + +Updates code for the split of the `react` and `react-dom` packages (e.g., +`React.render` to `ReactDOM.render`). It looks for `require('react')` and +replaces the appropriate property accesses using `require('react-dom')`. It does +not support ES6 modules or other non-CommonJS systems. We recommend performing +the `findDOMNode` conversion first. + + +```sh +npx react-codemod react-to-react-dom +``` + +* After running the automated codemod, you may want to run a regex-based + find-and-replace to remove extra whitespace between the added requires, such + as `codemod.py -m -d src --extensions js '(var + React\s*=\s*require\(.react.\);)\n\n(\s*var ReactDOM)' '\1\n\2'` using + https://github.com/facebook/codemod. + +#### `React-DOM-to-react-dom-factories` + +Converts calls like `React.DOM.div(...)` to `React.createElement('div', ...)`. + +```sh +npx react-codemod React-DOM-to-react-dom-factories +``` + +#### `ReactNative-View-propTypes` + +Replaces `View.propTypes` references with `ViewPropTypes` and adds the appropriate `import` or `require` statement. This codemod is intended for ReactNative 44+. + +```sh +npx react-codemod ReactNative-View-propTypes +``` + +#### `sort-comp` + +Reorders React component methods to match the [ESLint](http://eslint.org/) +[react/sort-comp +rule](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md). (Defaults to ordering of the [Airbnb style +guide](https://github.com/airbnb/javascript/blob/7684892951ef663e1c4e62ad57d662e9b2748b9e/packages/eslint-config-airbnb/rules/react.js#L122-L134). + +`react-codemod`: +```sh +npx react-codemod sort-comp +``` + +#### `update-react-imports` + +[As of Babel 7.9.0](https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154), when using `runtime: automatic` in `@babel/preset-react` or `@babel/plugin-transform-react-jsx`, you will not need to explicitly import React for compiling jsx. This codemod removes the redundant import statements. It also converts default imports (`import React from 'react'`) to named imports (e.g. `import { useState } from 'react'`). + +The wizard will ask for 1 option - + +* **Destructure namespace imports as well?**: If chosen, *namespace* imports like `import * as React` will *also* be converted. By default, it's false, so only default imports (`import React`) are converted. + +```sh +npx react-codemod update-react-imports +``` + +### Explanation of the new ES2015 class transform with property initializers +1. Determine if mixins are convertible. We only transform a `createClass` call to an ES6 class component when: +- There are no mixins on the class, or +- `options['pure-component']` is true, the `mixins` property is an array and it _only_ contains pure render mixin (the specific module name can be specified using `options['mixin-module-name']`, which defaults to `react-addons-pure-render-mixin`) +2. Ignore components that: +- Call deprecated APIs. This is very defensive, if the script finds any identifiers called `isMounted`, `getDOMNode`, `replaceProps`, `replaceState` or `setProps` it will skip the component +- Explicitly call `this.getInitialState()` and/or `this.getDefaultProps()` since an ES6 class component will no longer have these methods +- Use `arguments` in methods since arrow functions don't have `arguments`. Also please notice that `arguments` should be [very carefully used](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments) and it's generally better to switch to spread (`...args`) instead +- Have inconvertible `getInitialState()`. Specifically if you have variable declarations like `var props = ...` and the right hand side is not `this.props` then we can't inline the state initialization in the `constructor` due to variable shadowing issues +- Have non-primitive right hand side values (like `foo: getStuff()`) in the class spec +3. Transform it to an ES6 class component +1. Replace `var A = React.createClass(spec)` with `class A extends React.Component {spec}`. If a component uses pure render mixin and passes the mixins test (as described above), it will extend `React.PureComponent` instead + - Remove the `require`/`import` statement that imports pure render mixin when it's no longer being referenced +2. Pull out all statics defined on `statics` plus the few special cased statics like `childContextTypes`, `contextTypes`, `displayName`, `getDefaultProps()`, and `propTypes` and transform them to `static` properties (`static propTypes = {...};`) + - If `getDefaultProps()` is simple (i.e. it only contains a return statement that returns something) it will be converted to a simple assignment (`static defaultProps = ...;`). Otherwise an IIFE (immediately-invoked function expression) will be created (`static defaultProps = function() { ... }();`). Note that this means that the function will be executed only a single time per app-lifetime. In practice this hasn't caused any issues — `getDefaultProps` should not contain any side-effects +3. Transform `getInitialState()` + - If there's no `getInitialState()` or the `getInitialState()` function is simple (i.e., it only contains a return statement that returns something) then we don't need a constructor; `state` will be lifted to a property initializer (`state = ...;`) + - However, if the RHS of `return` contains references to `this` other than `this.props` and/or `this.context`, we can't be sure about what you'll need from `this`. We need to ensure that our property initializers' evaluation order is safe, so we defer `state`'s initialization by moving it all the way down until all other property initializers have been initialized + - If `getInitialState()` is not simple, we create a `constructor` and convert `getInitialState()` to an assignment to `this.state` + - `constructor` always have `props` as the first parameter + - We only put `context` as the second parameter when (one of) the following things happen in `getInitialState()`: + - It accesses `this.context`, or + - There's a direct method call `this.x()`, or + - `this` is referenced alone + - Rewrite accesses to `this.props` to `props` and accesses to `this.context` to `context` since the values will be passed as `constructor` arguments + - Remove _simple_ variable declarations like `var props = this.props;` and `var context = this.context` + - Rewrite top-level return statements (`return {...};`) to `this.state = {...}` + - Add `return;` after the assignment when the return statement is part of a control flow statement (not a direct child of `getInitialState()`'s body) and not in an inner function declaration +4. Transform all non-lifecycle methods and fields to class property initializers (like `onClick = () => {};`). All your Flow annotations will be preserved + - It's actually not necessary to transform all methods to arrow functions (i.e., to bind them), but this behavior is the same as `createClass()` and we can make sure that we won't accidentally break stuff +4. Generate Flow annotations from `propTypes` and put it on the class (this only happens when there's `/* @flow */` in your code and `options['flow']` is `true`) +- Flow actually understands `propTypes` in `createClass` calls but not ES6 class components. Here the transformation logic is identical to [how](https://github.com/facebook/flow/blob/master/src/typing/statement.ml#L3526) Flow treats `propTypes` +- Notice that Flow treats an optional propType as non-nullable + - For example, `foo: React.PropTypes.number` is valid when you pass `{}`, `{foo: null}`, or `{foo: undefined}` as props at **runtime**. However, when Flow infers type from a `createClass` call, only `{}` and `{foo: undefined}` are valid; `{foo: null}` is not. Thus the equivalent type annotation in Flow is actually `{foo?: number}`. The question mark on the left hand side indicates `{}` and `{foo: undefined}` are fine, but when `foo` is present it must be a `number` +- For `propTypes` fields that can't be recognized by Flow, `$FlowFixMe` will be used +5. `React.createClass` is no longer present in React 16. So, if a `createClass` call cannot be converted to a plain class, the script will fallback to using the `create-react-class` package. +- Replaces `React.createClass` with `ReactCreateClass`. +- Adds a `require` or `import` statement for `create-react-class`. The import style is inferred from the import style of the `react` import. The default module name can be overridden with the `--create-class-module-name` option. +- Prunes the `react` import if there are no more references to it. + + +## `react-codemod` options + +### jscodeshift options + +To pass more options directly to jscodeshift, use `--jscodeshift="..."`. For example: +```sh +npx react-codemod --jscodeshift="--run-in-band --verbose=2" +``` + +See all available options [here](https://github.com/facebook/jscodeshift#usage-cli). + +### Recast Options + +Options to [recast](https://github.com/benjamn/recast)'s printer can be provided +through jscodeshift's `printOptions` command line argument + +```sh +npx react-codemod --jscodeshift="--printOptions='{\"quote\":\"double\"}'" +``` + +### `explicit-require=false` + +If you're not explicitly importing React in your files (eg: if you're loading React with a script tag), you should add `--explicit-require=false`. + diff --git a/README.md b/README.md index e3958cf7..449dc7f7 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,87 @@ -## react-codemod [![Build Status](https://travis-ci.org/reactjs/react-codemod.svg)](https://travis-ci.org/reactjs/react-codemod) +## React Codemods [![Build Status](https://travis-ci.org/reactjs/react-codemod.svg)](https://travis-ci.org/reactjs/react-codemod) -This repository contains a collection of codemod scripts for use with -[JSCodeshift](https://github.com/facebook/jscodeshift) that help update React -APIs. +This repository contains a collection of codemods to help update React apps. + +All codemods, whether you use the `codemod` CLI command or `react-codemod`, are free and open source, with the source code available in this repository. ### Usage -`npx react-codemod [...options]` - * `transform` - name of transform, see available transforms below. - * `path` - files or directory to transform - * use the `--dry` option for a dry-run and use `--print` to print the output for comparison -This will start an interactive wizard, and then run the specified transform. +We recommend using the [`codemod`](https://go.codemod.com/github) command for an enhanced experience and better support. + +`npx codemod // --target [...options]` +* `transform` - name of transform, see available transforms below. +* `path` - directory to transform + +Check [codemod docs](https://go.codemod.com/cli-docs) for the full list of available commands. + +For the legacy `react-codemod` command, see [LEGACY.md](https://github.com/reactjs/react-codemod/LEGACY.md). + +## Available Codemods + +All React codemods are also available in the [Codemod Registry](https://go.codemod.com/react-codemods). + +#### `remove-context-provider` + +Converts `Context.Provider` JSX opening and closing elements into `Context`. + +```sh +npx codemod react/19/remove-context-provider --target +``` + +#### `remove-forward-ref` + +Removes usages of `forwardRef`. + +```sh +npx codemod react/19/remove-forward-ref --target +``` + +#### `use-context-hook` + +Replaces usages of `React.useContext(...)` with `React.use(...)`. + +```sh +npx codemod react/19/use-context-hook --target +``` + +#### `replace-act-import` + +Updates `act` import path from `react-dom/test-utils` to `react`. + +```sh +npx codemod react/19/replace-act-import --target +``` + +#### `replace-string-ref` + +Replaces deprecated string refs with callback refs. + +```sh +npx codemod react/19/replace-string-ref --target +``` + +#### `replace-use-form-state` + +Replaces usages of useFormState() to use useActionState(). + +```sh +npx codemod react/19/replace-use-form-state --target +``` -### Included Transforms +#### `replace-reactdom-render` + +Replaces usages of ReactDom.render() with createRoot(node).render(). + +```sh +npx codemod react/19/replace-reactdom-render --target +``` #### `create-element-to-jsx` Converts calls to `React.createElement` into JSX elements. ```sh -npx react-codemod create-element-to-jsx +npx codemod react/create-element-to-jsx --target ``` #### `error-boundaries` @@ -27,7 +89,7 @@ npx react-codemod create-element-to-jsx Renames the experimental `unstable_handleError` lifecycle hook to `componentDidCatch`. ```sh -npx react-codemod error-boundaries +npx codemod react/error-boundaries --target ``` #### `findDOMNode` @@ -39,7 +101,7 @@ the component instance or its refs. You can use this script to update most calls to `getDOMNode` and then manually go through the remaining calls. ```sh -npx react-codemod findDOMNode +npx codemod react/findDOMNode --target ``` #### `manual-bind-to-arrow` @@ -47,7 +109,7 @@ npx react-codemod findDOMNode Converts manual function bindings in a class (e.g., `this.f = this.f.bind(this)`) to arrow property initializer functions (e.g., `f = () => {}`). ```sh -npx react-codemod manual-bind-to-arrow +npx codemod react/manual-bind-to-arrow --target ``` #### `pure-component` @@ -61,7 +123,7 @@ The wizard will ask for 2 options - * **Destructure props?**: will destructure props in the argument where it is safe to do so. ```sh -npx react-codemod pure-component +npx codemod react/pure-component --target ``` #### `pure-render-mixin` @@ -72,10 +134,10 @@ class. NOTE: This currently only works if you are using the master version (>0.13.1) of React as it is using `React.addons.shallowCompare` ```sh -npx react-codemod pure-render-mixin +npx codemod react/pure-render-mixin --target ``` - * The wizard will ask to optionally override `mixin-name`, and look for it + * The wizard will ask to optionally override `mixin-name`, and look for it instead of `PureRenderMixin`. Note that it is not possible to use a namespaced name for the mixin. `mixins: [React.addons.PureRenderMixin]` will not currently work. @@ -85,7 +147,7 @@ npx react-codemod pure-render-mixin Replaces `React.PropTypes` references with `prop-types` and adds the appropriate `import` or `require` statement. This codemod is intended for React 15.5+. ```sh -npx react-codemod React-PropTypes-to-prop-types +npx codemod react/React-PropTypes-to-prop-types --target ``` * In addition to running the above codemod you will also need to install the `prop-types` NPM package. @@ -95,7 +157,7 @@ npx react-codemod React-PropTypes-to-prop-types Adds `UNSAFE_` prefix for deprecated lifecycle hooks. (For more information about this codemod, see [React RFC #6](https://github.com/reactjs/rfcs/pull/6)) ```sh -npx react-codemod rename-unsafe-lifecycles +npx codemod react/rename-unsafe-lifecycles --target ``` #### `react-to-react-dom` @@ -107,7 +169,7 @@ not support ES6 modules or other non-CommonJS systems. We recommend performing the `findDOMNode` conversion first. ```sh -npx react-codemod react-to-react-dom +npx codemod react/react-to-react-dom --target ``` * After running the automated codemod, you may want to run a regex-based @@ -121,7 +183,7 @@ npx react-codemod react-to-react-dom Converts calls like `React.DOM.div(...)` to `React.createElement('div', ...)`. ```sh -npx react-codemod React-DOM-to-react-dom-factories +npx codemod react/React-DOM-to-react-dom-factories --target ``` #### `ReactNative-View-propTypes` @@ -129,18 +191,7 @@ npx react-codemod React-DOM-to-react-dom-factories Replaces `View.propTypes` references with `ViewPropTypes` and adds the appropriate `import` or `require` statement. This codemod is intended for ReactNative 44+. ```sh -npx react-codemod ReactNative-View-propTypes -``` - -#### `sort-comp` - -Reorders React component methods to match the [ESLint](http://eslint.org/) -[react/sort-comp -rule](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md). (Defaults to ordering of the [Airbnb style -guide](https://github.com/airbnb/javascript/blob/7684892951ef663e1c4e62ad57d662e9b2748b9e/packages/eslint-config-airbnb/rules/react.js#L122-L134). - -```sh -npx react-codemod sort-comp +npx codemod react/ReactNative-View-propTypes --target ``` #### `update-react-imports` @@ -152,87 +203,15 @@ The wizard will ask for 1 option - * **Destructure namespace imports as well?**: If chosen, *namespace* imports like `import * as React` will *also* be converted. By default, it's false, so only default imports (`import React`) are converted. ```sh -npx react-codemod update-react-imports +npx codemod react/update-react-imports --target ``` -### Explanation of the new ES2015 class transform with property initializers -1. Determine if mixins are convertible. We only transform a `createClass` call to an ES6 class component when: - - There are no mixins on the class, or - - `options['pure-component']` is true, the `mixins` property is an array and it _only_ contains pure render mixin (the specific module name can be specified using `options['mixin-module-name']`, which defaults to `react-addons-pure-render-mixin`) -2. Ignore components that: - - Call deprecated APIs. This is very defensive, if the script finds any identifiers called `isMounted`, `getDOMNode`, `replaceProps`, `replaceState` or `setProps` it will skip the component - - Explicitly call `this.getInitialState()` and/or `this.getDefaultProps()` since an ES6 class component will no longer have these methods - - Use `arguments` in methods since arrow functions don't have `arguments`. Also please notice that `arguments` should be [very carefully used](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments) and it's generally better to switch to spread (`...args`) instead - - Have inconvertible `getInitialState()`. Specifically if you have variable declarations like `var props = ...` and the right hand side is not `this.props` then we can't inline the state initialization in the `constructor` due to variable shadowing issues - - Have non-primitive right hand side values (like `foo: getStuff()`) in the class spec -3. Transform it to an ES6 class component - 1. Replace `var A = React.createClass(spec)` with `class A extends React.Component {spec}`. If a component uses pure render mixin and passes the mixins test (as described above), it will extend `React.PureComponent` instead - - Remove the `require`/`import` statement that imports pure render mixin when it's no longer being referenced - 2. Pull out all statics defined on `statics` plus the few special cased statics like `childContextTypes`, `contextTypes`, `displayName`, `getDefaultProps()`, and `propTypes` and transform them to `static` properties (`static propTypes = {...};`) - - If `getDefaultProps()` is simple (i.e. it only contains a return statement that returns something) it will be converted to a simple assignment (`static defaultProps = ...;`). Otherwise an IIFE (immediately-invoked function expression) will be created (`static defaultProps = function() { ... }();`). Note that this means that the function will be executed only a single time per app-lifetime. In practice this hasn't caused any issues — `getDefaultProps` should not contain any side-effects - 3. Transform `getInitialState()` - - If there's no `getInitialState()` or the `getInitialState()` function is simple (i.e., it only contains a return statement that returns something) then we don't need a constructor; `state` will be lifted to a property initializer (`state = ...;`) - - However, if the RHS of `return` contains references to `this` other than `this.props` and/or `this.context`, we can't be sure about what you'll need from `this`. We need to ensure that our property initializers' evaluation order is safe, so we defer `state`'s initialization by moving it all the way down until all other property initializers have been initialized - - If `getInitialState()` is not simple, we create a `constructor` and convert `getInitialState()` to an assignment to `this.state` - - `constructor` always have `props` as the first parameter - - We only put `context` as the second parameter when (one of) the following things happen in `getInitialState()`: - - It accesses `this.context`, or - - There's a direct method call `this.x()`, or - - `this` is referenced alone - - Rewrite accesses to `this.props` to `props` and accesses to `this.context` to `context` since the values will be passed as `constructor` arguments - - Remove _simple_ variable declarations like `var props = this.props;` and `var context = this.context` - - Rewrite top-level return statements (`return {...};`) to `this.state = {...}` - - Add `return;` after the assignment when the return statement is part of a control flow statement (not a direct child of `getInitialState()`'s body) and not in an inner function declaration - 4. Transform all non-lifecycle methods and fields to class property initializers (like `onClick = () => {};`). All your Flow annotations will be preserved - - It's actually not necessary to transform all methods to arrow functions (i.e., to bind them), but this behavior is the same as `createClass()` and we can make sure that we won't accidentally break stuff -4. Generate Flow annotations from `propTypes` and put it on the class (this only happens when there's `/* @flow */` in your code and `options['flow']` is `true`) - - Flow actually understands `propTypes` in `createClass` calls but not ES6 class components. Here the transformation logic is identical to [how](https://github.com/facebook/flow/blob/master/src/typing/statement.ml#L3526) Flow treats `propTypes` - - Notice that Flow treats an optional propType as non-nullable - - For example, `foo: React.PropTypes.number` is valid when you pass `{}`, `{foo: null}`, or `{foo: undefined}` as props at **runtime**. However, when Flow infers type from a `createClass` call, only `{}` and `{foo: undefined}` are valid; `{foo: null}` is not. Thus the equivalent type annotation in Flow is actually `{foo?: number}`. The question mark on the left hand side indicates `{}` and `{foo: undefined}` are fine, but when `foo` is present it must be a `number` - - For `propTypes` fields that can't be recognized by Flow, `$FlowFixMe` will be used -5. `React.createClass` is no longer present in React 16. So, if a `createClass` call cannot be converted to a plain class, the script will fallback to using the `create-react-class` package. - - Replaces `React.createClass` with `ReactCreateClass`. - - Adds a `require` or `import` statement for `create-react-class`. The import style is inferred from the import style of the `react` import. The default module name can be overridden with the `--create-class-module-name` option. - - Prunes the `react` import if there are no more references to it. - -#### Usage -```bash -npx react-codemod class -``` - -### jscodeshift options - -To pass more options directly to jscodeshift, use `--jscodeshift="..."`. For example: -```sh -npx react-codemod --jscodeshift="--run-in-band --verbose=2" -``` - -See all available options [here](https://github.com/facebook/jscodeshift#usage-cli). - -### Recast Options - -Options to [recast](https://github.com/benjamn/recast)'s printer can be provided -through jscodeshift's `printOptions` command line argument - -```sh -npx react-codemod --jscodeshift="--printOptions='{\"quote\":\"double\"}'" -``` - -#### `explicit-require=false` - -If you're not explicitly importing React in your files (eg: if you're loading React with a script tag), you should add `--explicit-require=false`. - -### Support and Contributing +## Support and Contributing -The scripts in this repository are provided in the hope that they are useful, -but they are not officially maintained, and we generally will not fix -community-reported issues. They are a collection of scripts that were previously -used internally within Facebook or were contributed by the community, and we -rely on community contributions to fix any issues discovered or make any -improvements. If you want to contribute, you're welcome to submit a pull -request. +The scripts in this repository are maintained by the React team in collaboration with the [Codemod.com](https://codemod.com) team. -### License +If you want to contribute, you're welcome to submit a pull request. +## License react-codemod is [MIT licensed](./LICENSE). diff --git a/bin/__tests__/react-codemod-test.js b/bin/__tests__/react-codemod-test.js index 8feaa90f..627a1407 100644 --- a/bin/__tests__/react-codemod-test.js +++ b/bin/__tests__/react-codemod-test.js @@ -96,20 +96,20 @@ describe('runTransform', () => { fs.lstatSync(jscodeshiftExecutable); }); - it('runs jscodeshift for the given transformer', () => { + it('runs jscodeshift for the given existing transformer', () => { execaReturnValue = { error: null }; console.log = jest.fn(); runTransform({ files: 'src', flags: {}, parser: 'flow', - transformer: 'rename-unsafe-xyz' + transformer: 'rename-unsafe-lifecycles' }); expect(console.log).toBeCalledWith( // eslint-disable-next-line max-len `Executing command: jscodeshift --verbose=2 --ignore-pattern=**/node_modules/** --parser flow --extensions=jsx,js --transform ${path.join( transformerDirectory, - 'rename-unsafe-xyz.js' + 'rename-unsafe-lifecycles.js' )} src` ); }); @@ -184,4 +184,21 @@ describe('runTransform', () => { }); }).toThrowError(transformerError); }); + + it('should correctly resolve typescript transform files', () => { + execaReturnValue = { error: null }; + console.log = jest.fn(); + runTransform({ + files: 'src', + flags: {}, + parser: 'flow', + transformer: 'remove-context-provider' + }); + expect(console.log).toBeCalledWith( + `Executing command: jscodeshift --verbose=2 --ignore-pattern=**/node_modules/** --parser flow --extensions=jsx,js --transform ${path.join( + transformerDirectory, + 'remove-context-provider.ts' + )} src` + ); + }); }); diff --git a/bin/cli.js b/bin/cli.js index 6640b376..0673c838 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -49,8 +49,13 @@ function checkGitStatus(force) { } } +function resolveTransformer(transformerDirectory, transformer) { + return globby.sync(`${transformerDirectory}/${transformer}.{js,ts}`)[0] || null; +} + function runTransform({ files, flags, parser, transformer, answers }) { - const transformerPath = path.join(transformerDirectory, `${transformer}.js`); + + const transformerPath = resolveTransformer(transformerDirectory, transformer); let args = []; @@ -191,7 +196,42 @@ const TRANSFORMER_INQUIRER_CHOICES = [ { name: 'update-react-imports: Removes redundant import statements from explicitly importing React to compile JSX and converts default imports to destructured named imports', value: 'update-react-imports', - } + }, + { + name: + 'remove-context-provider: Replaces Context.Provider with Context', + value: 'remove-context-provider' + }, + { + name: + 'remove-forward-ref: Removes forwardRef form functional components and passes ref as prop', + value: 'remove-forward-ref' + }, + { + name: + 'use-context-hook: Replaces useContext with React.use', + value: 'use-context-hook' + }, + { + name: + 'replace-use-form-state: Replaces useFormState with useActionState', + value: 'replace-use-form-state' + }, + { + name: + 'replace-act-import: Updates `act` import', + value: 'replace-act-import' + }, + { + name: + 'replace-string-ref: Replaces deprecated string ref with callback ref', + value: 'replace-string-ref' + }, + { + name: + 'replace-reactdom-render: Replaces deprecated ReactDom.render', + value: 'replace-reactdom-render' + }, ]; const PARSER_INQUIRER_CHOICES = [ diff --git a/package.json b/package.json index dfe2d52d..12053b0b 100644 --- a/package.json +++ b/package.json @@ -28,18 +28,26 @@ "roots": [ "transforms", "bin" - ] + ], + "transform": { + "^.+\\.jsx?$": "babel-jest", + "^.+\\.tsx?$": "ts-jest" + } }, "devDependencies": { "@babel/core": "^7.6.4", "@babel/plugin-proposal-object-rest-spread": "^7.6.2", "@babel/preset-env": "^7.6.3", + "@types/jest": "^24.9.0", + "@typescript-eslint/parser": "^7.8.0", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", "eslint": "^6.6.0", "eslint-plugin-react": "^7.16.0", "fbjs-scripts": "^0.7.1", - "jest": "^24.9.0" + "jest": "^24.9.0", + "ts-jest": "^24.3.0", + "typescript": "4.8.4" }, "resolutions": { "colors": "1.3.3" diff --git a/transforms/__testfixtures__/custom-sort-group/.eslintrc b/transforms/__testfixtures__/custom-sort-group/.eslintrc index 89b7e90b..5996239e 100644 --- a/transforms/__testfixtures__/custom-sort-group/.eslintrc +++ b/transforms/__testfixtures__/custom-sort-group/.eslintrc @@ -1,4 +1,5 @@ --- +parser: babel-eslint plugins: - react rules: diff --git a/transforms/__testfixtures__/custom-sort/.eslintrc b/transforms/__testfixtures__/custom-sort/.eslintrc index 3fd957f9..ab6e1bde 100644 --- a/transforms/__testfixtures__/custom-sort/.eslintrc +++ b/transforms/__testfixtures__/custom-sort/.eslintrc @@ -1,4 +1,5 @@ --- +parser: babel-eslint plugins: - react rules: diff --git a/transforms/__testfixtures__/remove-context-provider/no-provider.input.js b/transforms/__testfixtures__/remove-context-provider/no-provider.input.js new file mode 100644 index 00000000..9ef65738 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/no-provider.input.js @@ -0,0 +1,9 @@ +function App() { + const [theme, setTheme] = useState('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/no-provider.output.js b/transforms/__testfixtures__/remove-context-provider/no-provider.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/no-provider.input.js b/transforms/__testfixtures__/remove-context-provider/typescript/no-provider.input.js new file mode 100644 index 00000000..357cc7c7 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/typescript/no-provider.input.js @@ -0,0 +1,9 @@ +function App({ url }: { url: string }) { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/no-provider.output.js b/transforms/__testfixtures__/remove-context-provider/typescript/no-provider.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.input.js b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.input.js new file mode 100644 index 00000000..b8d72610 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.input.js @@ -0,0 +1,9 @@ +function App({ url }: { url: string }) { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.output.js b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.output.js new file mode 100644 index 00000000..357cc7c7 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider-2.output.js @@ -0,0 +1,9 @@ +function App({ url }: { url: string }) { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.input.js b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.input.js new file mode 100644 index 00000000..97872054 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.input.js @@ -0,0 +1,9 @@ +function App({ url }: { url: string }) { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.output.js b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.output.js new file mode 100644 index 00000000..f1d45694 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/typescript/with-provider.output.js @@ -0,0 +1,9 @@ +function App({ url }: { url: string }) { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/with-provider-2.input.js b/transforms/__testfixtures__/remove-context-provider/with-provider-2.input.js new file mode 100644 index 00000000..18cb6e6c --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/with-provider-2.input.js @@ -0,0 +1,9 @@ +function App() { + const [theme, setTheme] = useState('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/with-provider-2.output.js b/transforms/__testfixtures__/remove-context-provider/with-provider-2.output.js new file mode 100644 index 00000000..9ef65738 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/with-provider-2.output.js @@ -0,0 +1,9 @@ +function App() { + const [theme, setTheme] = useState('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/with-provider.input.js b/transforms/__testfixtures__/remove-context-provider/with-provider.input.js new file mode 100644 index 00000000..a066cc86 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/with-provider.input.js @@ -0,0 +1,9 @@ +function App() { + const [theme, setTheme] = useState('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-context-provider/with-provider.output.js b/transforms/__testfixtures__/remove-context-provider/with-provider.output.js new file mode 100644 index 00000000..84f317b8 --- /dev/null +++ b/transforms/__testfixtures__/remove-context-provider/with-provider.output.js @@ -0,0 +1,9 @@ +function App() { + const [theme, setTheme] = useState('light'); + + return ( + + + + ); +} \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.input.js b/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.input.js new file mode 100644 index 00000000..88af3bd7 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef((props, ref) => { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.output.js b/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.output.js new file mode 100644 index 00000000..53cb4167 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/arrow-function-expression.output.js @@ -0,0 +1,8 @@ +const MyInput = ( + { + ref, + ...props + } +) => { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.input.js b/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.input.js new file mode 100644 index 00000000..5f3f314b --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.input.js @@ -0,0 +1,5 @@ +import * as React1 from 'react'; + +const MyInput = React1.forwardRef((props, ref) => { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.output.js b/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.output.js new file mode 100644 index 00000000..05547f5a --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/callee-is-member-expression.output.js @@ -0,0 +1,10 @@ +import * as React1 from 'react'; + +const MyInput = ( + { + ref, + ...props + } +) => { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.input.js b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.input.js new file mode 100644 index 00000000..e6675dc4 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.input.js @@ -0,0 +1,5 @@ +import { forwardRef, useState } from 'react'; + +const MyInput = forwardRef(function MyInput(props, ref) { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.output.js b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.output.js new file mode 100644 index 00000000..6c2fb56a --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import-2.output.js @@ -0,0 +1,10 @@ +import { useState } from 'react'; + +const MyInput = function MyInput( + { + ref, + ...props + } +) { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.input.js b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.input.js new file mode 100644 index 00000000..6623c96f --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef(function MyInput(props, ref) { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.output.js b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.output.js new file mode 100644 index 00000000..033a974e --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/forward-ref-import.output.js @@ -0,0 +1,8 @@ +const MyInput = function MyInput( + { + ref, + ...props + } +) { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/function-expression.input.js b/transforms/__testfixtures__/remove-forward-ref/function-expression.input.js new file mode 100644 index 00000000..04662174 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/function-expression.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef(function A(props, ref) { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/function-expression.output.js b/transforms/__testfixtures__/remove-forward-ref/function-expression.output.js new file mode 100644 index 00000000..cf65821b --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/function-expression.output.js @@ -0,0 +1,8 @@ +const MyInput = function A( + { + ref, + ...props + } +) { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/props-identifier.input.js b/transforms/__testfixtures__/remove-forward-ref/props-identifier.input.js new file mode 100644 index 00000000..bb87e8c3 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/props-identifier.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef(function MyInput(props, ref) { + return +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/props-identifier.output.js b/transforms/__testfixtures__/remove-forward-ref/props-identifier.output.js new file mode 100644 index 00000000..297637ae --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/props-identifier.output.js @@ -0,0 +1,8 @@ +const MyInput = function MyInput( + { + ref, + ...props + } +) { + return +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.input.js b/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.input.js new file mode 100644 index 00000000..99b95108 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef(function MyInput({ onChange }, ref) { + return +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.output.js b/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.output.js new file mode 100644 index 00000000..651d5244 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/props-object-pattern.output.js @@ -0,0 +1,8 @@ +const MyInput = function MyInput( + { + ref, + onChange + } +) { + return +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.input.js b/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.input.js new file mode 100644 index 00000000..c242b87a --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.input.js @@ -0,0 +1,7 @@ +import { forwardRef } from 'react'; +const MyComponent = forwardRef(function Component( + myProps: { a: 1 }, + myRef +) { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.output.js b/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.output.js new file mode 100644 index 00000000..56fa6f5e --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/props-type-literal.output.js @@ -0,0 +1,10 @@ +const MyComponent = function Component( + { + ref: myRef, + ...myProps + }: { a: 1 } & { + ref: React.RefObject + } +) { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.input.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.input.js new file mode 100644 index 00000000..fd523ba2 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.input.js @@ -0,0 +1,8 @@ +import { forwardRef } from 'react'; + +const MyComponent = forwardRef(function Component( + myProps: Props, + myRef: React.ForwardedRef +) { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.output.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.output.js new file mode 100644 index 00000000..e868776f --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-custom-names.output.js @@ -0,0 +1,10 @@ +const MyComponent = function Component( + { + ref: myRef, + ...myProps + }: Props & { + ref: React.RefObject + } +) { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.input.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.input.js new file mode 100644 index 00000000..f4f4ac05 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.input.js @@ -0,0 +1,5 @@ +import { forwardRef } from 'react'; + +const MyInput = forwardRef((props, ref) => { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.output.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.output.js new file mode 100644 index 00000000..f569dfc8 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments-type-literals.output.js @@ -0,0 +1,10 @@ +const MyInput = ( + { + ref, + ...props + }: { a: string } & { + ref: React.RefObject + } +) => { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.input.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.input.js new file mode 100644 index 00000000..2a045b63 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.input.js @@ -0,0 +1,6 @@ +import { forwardRef } from 'react'; +type Props = { a: 1 }; + +const MyInput = forwardRef((props, ref) => { + return null; +}); \ No newline at end of file diff --git a/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.output.js b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.output.js new file mode 100644 index 00000000..23e1c165 --- /dev/null +++ b/transforms/__testfixtures__/remove-forward-ref/typescript/type-arguments.output.js @@ -0,0 +1,12 @@ +type Props = { a: 1 }; + +const MyInput = ( + { + ref, + ...props + }: Props & { + ref: React.RefObject + } +) => { + return null; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/replace-act-import/default-import.input.js b/transforms/__testfixtures__/replace-act-import/default-import.input.js new file mode 100644 index 00000000..1f1bda7f --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/default-import.input.js @@ -0,0 +1,2 @@ +import ReactTestUtils from "react-dom/test-utils"; +ReactTestUtils.act(); diff --git a/transforms/__testfixtures__/replace-act-import/default-import.output.js b/transforms/__testfixtures__/replace-act-import/default-import.output.js new file mode 100644 index 00000000..33db79c2 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/default-import.output.js @@ -0,0 +1,3 @@ + +import React from "react"; +React.act(); diff --git a/transforms/__testfixtures__/replace-act-import/named-import-2.input.js b/transforms/__testfixtures__/replace-act-import/named-import-2.input.js new file mode 100644 index 00000000..e41f6509 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/named-import-2.input.js @@ -0,0 +1,4 @@ +import { FC } from "react"; +import { act } from "react-dom/test-utils"; + +act(); diff --git a/transforms/__testfixtures__/replace-act-import/named-import-2.output.js b/transforms/__testfixtures__/replace-act-import/named-import-2.output.js new file mode 100644 index 00000000..dc7dd537 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/named-import-2.output.js @@ -0,0 +1,3 @@ +import { FC, act } from "react"; + +act(); diff --git a/transforms/__testfixtures__/replace-act-import/named-import.input.js b/transforms/__testfixtures__/replace-act-import/named-import.input.js new file mode 100644 index 00000000..e63437e3 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/named-import.input.js @@ -0,0 +1,2 @@ +import { act } from "react-dom/test-utils"; +act(); diff --git a/transforms/__testfixtures__/replace-act-import/named-import.output.js b/transforms/__testfixtures__/replace-act-import/named-import.output.js new file mode 100644 index 00000000..44ab638e --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/named-import.output.js @@ -0,0 +1,2 @@ +import { act } from "react"; +act(); diff --git a/transforms/__testfixtures__/replace-act-import/other-import.input.js b/transforms/__testfixtures__/replace-act-import/other-import.input.js new file mode 100644 index 00000000..3d8677c3 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/other-import.input.js @@ -0,0 +1,2 @@ +import { other } from "react-dom/test-utils"; +other.thing(); diff --git a/transforms/__testfixtures__/replace-act-import/other-import.output.js b/transforms/__testfixtures__/replace-act-import/other-import.output.js new file mode 100644 index 00000000..3d8677c3 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/other-import.output.js @@ -0,0 +1,2 @@ +import { other } from "react-dom/test-utils"; +other.thing(); diff --git a/transforms/__testfixtures__/replace-act-import/re-export.input.js b/transforms/__testfixtures__/replace-act-import/re-export.input.js new file mode 100644 index 00000000..e3707917 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/re-export.input.js @@ -0,0 +1 @@ +export * from "react-dom/test-utils"; \ No newline at end of file diff --git a/transforms/__testfixtures__/replace-act-import/re-export.output.js b/transforms/__testfixtures__/replace-act-import/re-export.output.js new file mode 100644 index 00000000..c6938606 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/re-export.output.js @@ -0,0 +1,2 @@ +export * from "react-dom/test-utils"; +export { act } from "react"; \ No newline at end of file diff --git a/transforms/__testfixtures__/replace-act-import/wildcard-import-2.input.js b/transforms/__testfixtures__/replace-act-import/wildcard-import-2.input.js new file mode 100644 index 00000000..54b869f2 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/wildcard-import-2.input.js @@ -0,0 +1,4 @@ +import * as React from "react"; +import * as ReactTestUtils from "react-dom/test-utils"; + +ReactTestUtils.act(); diff --git a/transforms/__testfixtures__/replace-act-import/wildcard-import-2.output.js b/transforms/__testfixtures__/replace-act-import/wildcard-import-2.output.js new file mode 100644 index 00000000..fc21df2f --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/wildcard-import-2.output.js @@ -0,0 +1,3 @@ +import * as React from "react"; + +React.act(); diff --git a/transforms/__testfixtures__/replace-act-import/wildcard-import.input.js b/transforms/__testfixtures__/replace-act-import/wildcard-import.input.js new file mode 100644 index 00000000..da818117 --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/wildcard-import.input.js @@ -0,0 +1,2 @@ +import * as ReactTestUtils from "react-dom/test-utils"; +ReactTestUtils.act(); diff --git a/transforms/__testfixtures__/replace-act-import/wildcard-import.output.js b/transforms/__testfixtures__/replace-act-import/wildcard-import.output.js new file mode 100644 index 00000000..4acf1aab --- /dev/null +++ b/transforms/__testfixtures__/replace-act-import/wildcard-import.output.js @@ -0,0 +1,2 @@ +import * as React from "react"; +React.act(); diff --git a/transforms/__testfixtures__/replace-reactdom-render/default.input.js b/transforms/__testfixtures__/replace-reactdom-render/default.input.js new file mode 100644 index 00000000..621acbe1 --- /dev/null +++ b/transforms/__testfixtures__/replace-reactdom-render/default.input.js @@ -0,0 +1,4 @@ +import ReactDom from "react-dom"; +import Component from "Component"; + +ReactDom.render(, document.getElementById("app")); diff --git a/transforms/__testfixtures__/replace-reactdom-render/default.output.js b/transforms/__testfixtures__/replace-reactdom-render/default.output.js new file mode 100644 index 00000000..7a3e5712 --- /dev/null +++ b/transforms/__testfixtures__/replace-reactdom-render/default.output.js @@ -0,0 +1,6 @@ +import { createRoot } from "react-dom/client"; +import ReactDom from "react-dom"; +import Component from "Component"; + +const root = createRoot(document.getElementById("app")); +root.render(); diff --git a/transforms/__testfixtures__/replace-reactdom-render/nested.input.js b/transforms/__testfixtures__/replace-reactdom-render/nested.input.js new file mode 100644 index 00000000..090aad73 --- /dev/null +++ b/transforms/__testfixtures__/replace-reactdom-render/nested.input.js @@ -0,0 +1,7 @@ +import { render } from "react-dom"; + +const fn = () => { + if (true) { + render(, theNode); + } +}; diff --git a/transforms/__testfixtures__/replace-reactdom-render/nested.output.js b/transforms/__testfixtures__/replace-reactdom-render/nested.output.js new file mode 100644 index 00000000..4f659df5 --- /dev/null +++ b/transforms/__testfixtures__/replace-reactdom-render/nested.output.js @@ -0,0 +1,9 @@ +import { createRoot } from "react-dom/client"; +import { render } from "react-dom"; + +const fn = () => { + if (true) { + const root = createRoot(theNode); + root.render(); + } +}; diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.input.js b/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.input.js new file mode 100644 index 00000000..4c5fed2c --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.input.js @@ -0,0 +1,13 @@ +import React1, { PureComponent as PureComponent1 } from "react"; + +class C extends React1.Component { + render() { + return
; + } +} + +class C1 extends PureComponent1 { + render() { + return
; + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.output.js b/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.output.js new file mode 100644 index 00000000..0fc2f0a4 --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-custom-import-names.output.js @@ -0,0 +1,21 @@ +import React1, { PureComponent as PureComponent1 } from "react"; + +class C extends React1.Component { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} + +class C1 extends PureComponent1 { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-default-import.input.js b/transforms/__testfixtures__/replace-string-ref/class-component-default-import.input.js new file mode 100644 index 00000000..29c16f79 --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-default-import.input.js @@ -0,0 +1,13 @@ +import React from "react"; + +class C extends React.Component { + render() { + return
; + } +} + +class C1 extends React.PureComponent { + render() { + return
; + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-default-import.output.js b/transforms/__testfixtures__/replace-string-ref/class-component-default-import.output.js new file mode 100644 index 00000000..a3b22fce --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-default-import.output.js @@ -0,0 +1,21 @@ +import React from "react"; + +class C extends React.Component { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} + +class C1 extends React.PureComponent { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-named-import.input.js b/transforms/__testfixtures__/replace-string-ref/class-component-named-import.input.js new file mode 100644 index 00000000..e741f109 --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-named-import.input.js @@ -0,0 +1,13 @@ +import { Component, PureComponent } from "react"; + +class C extends Component { + render() { + return
; + } +} + +class C1 extends PureComponent { + render() { + return
; + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/class-component-named-import.output.js b/transforms/__testfixtures__/replace-string-ref/class-component-named-import.output.js new file mode 100644 index 00000000..69da92ae --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/class-component-named-import.output.js @@ -0,0 +1,21 @@ +import { Component, PureComponent } from "react"; + +class C extends Component { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} + +class C1 extends PureComponent { + render() { + return ( +
{ + this.refs.refName = ref; + }} /> + ); + } +} diff --git a/transforms/__testfixtures__/replace-string-ref/function-component.input.js b/transforms/__testfixtures__/replace-string-ref/function-component.input.js new file mode 100644 index 00000000..4fc31786 --- /dev/null +++ b/transforms/__testfixtures__/replace-string-ref/function-component.input.js @@ -0,0 +1,3 @@ +const C = () => { + return
; +}; diff --git a/transforms/__testfixtures__/replace-string-ref/function-component.output.js b/transforms/__testfixtures__/replace-string-ref/function-component.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/replace-use-form-state/default-import.input.js b/transforms/__testfixtures__/replace-use-form-state/default-import.input.js new file mode 100644 index 00000000..9a83f5b3 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/default-import.input.js @@ -0,0 +1,6 @@ +import ReactDOM from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = ReactDOM.useFormState(increment, 0); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/default-import.output.js b/transforms/__testfixtures__/replace-use-form-state/default-import.output.js new file mode 100644 index 00000000..6fc27659 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/default-import.output.js @@ -0,0 +1,6 @@ +import ReactDOM from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = ReactDOM.useActionState(increment, 0); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import-2.input.js b/transforms/__testfixtures__/replace-use-form-state/named-import-2.input.js new file mode 100644 index 00000000..1f452502 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import-2.input.js @@ -0,0 +1,8 @@ +import { createPortal, useFormState } from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = useFormState(increment, 0); + + createPortal(); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import-2.output.js b/transforms/__testfixtures__/replace-use-form-state/named-import-2.output.js new file mode 100644 index 00000000..1fbd00d1 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import-2.output.js @@ -0,0 +1,8 @@ +import { createPortal, useActionState } from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = useActionState(increment, 0); + + createPortal(); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import-3.input.js b/transforms/__testfixtures__/replace-use-form-state/named-import-3.input.js new file mode 100644 index 00000000..1afa58eb --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import-3.input.js @@ -0,0 +1,8 @@ +import { useFormState as UFS, createPortal } from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = UFS(increment, 0); + + createPortal(); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import-3.output.js b/transforms/__testfixtures__/replace-use-form-state/named-import-3.output.js new file mode 100644 index 00000000..c36827df --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import-3.output.js @@ -0,0 +1,8 @@ +import { useActionState as UFS, createPortal } from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = UFS(increment, 0); + + createPortal(); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import.input.js b/transforms/__testfixtures__/replace-use-form-state/named-import.input.js new file mode 100644 index 00000000..c6a1e8a9 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import.input.js @@ -0,0 +1,15 @@ +import { useFormState } from "react-dom"; + +async function increment(previousState, formData) { + return previousState + 1; +} + +function StatefulForm({}) { + const [state, formAction] = useFormState(increment, 0); + return ( +
+ {state} + +
+ ); +} diff --git a/transforms/__testfixtures__/replace-use-form-state/named-import.output.js b/transforms/__testfixtures__/replace-use-form-state/named-import.output.js new file mode 100644 index 00000000..7d575060 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/named-import.output.js @@ -0,0 +1,15 @@ +import { useActionState } from "react-dom"; + +async function increment(previousState, formData) { + return previousState + 1; +} + +function StatefulForm({}) { + const [state, formAction] = useActionState(increment, 0); + return ( +
+ {state} + +
+ ); +} diff --git a/transforms/__testfixtures__/replace-use-form-state/other-import.input.js b/transforms/__testfixtures__/replace-use-form-state/other-import.input.js new file mode 100644 index 00000000..b2904014 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/other-import.input.js @@ -0,0 +1,6 @@ +import { other } from "react-dom"; + +function StatefulForm({}) { + const otherResult = other(); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/other-import.output.js b/transforms/__testfixtures__/replace-use-form-state/other-import.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/replace-use-form-state/wildcard-import.input.js b/transforms/__testfixtures__/replace-use-form-state/wildcard-import.input.js new file mode 100644 index 00000000..e1f5a202 --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/wildcard-import.input.js @@ -0,0 +1,6 @@ +import * as ReactDOM from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = ReactDOM.useFormState(increment, 0); + return
; +} diff --git a/transforms/__testfixtures__/replace-use-form-state/wildcard-import.output.js b/transforms/__testfixtures__/replace-use-form-state/wildcard-import.output.js new file mode 100644 index 00000000..cfcf7dca --- /dev/null +++ b/transforms/__testfixtures__/replace-use-form-state/wildcard-import.output.js @@ -0,0 +1,6 @@ +import * as ReactDOM from "react-dom"; + +function StatefulForm({}) { + const [state, formAction] = ReactDOM.useActionState(increment, 0); + return
; +} diff --git a/transforms/__testfixtures__/use-context-hook/any-use-context.input.js b/transforms/__testfixtures__/use-context-hook/any-use-context.input.js new file mode 100644 index 00000000..75bfeb59 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/any-use-context.input.js @@ -0,0 +1 @@ +const theme = trpc.useContext(); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/any-use-context.output.js b/transforms/__testfixtures__/use-context-hook/any-use-context.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/use-context-hook/mixed-import.input.js b/transforms/__testfixtures__/use-context-hook/mixed-import.input.js new file mode 100644 index 00000000..fb91bfd7 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/mixed-import.input.js @@ -0,0 +1,4 @@ +import React, { useContext } from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = useContext(ThemeContext); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/mixed-import.output.js b/transforms/__testfixtures__/use-context-hook/mixed-import.output.js new file mode 100644 index 00000000..79010801 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/mixed-import.output.js @@ -0,0 +1,4 @@ +import React, { use } from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = use(ThemeContext); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/typescript/any-use-context.input.js b/transforms/__testfixtures__/use-context-hook/typescript/any-use-context.input.js new file mode 100644 index 00000000..88397ec8 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/typescript/any-use-context.input.js @@ -0,0 +1,8 @@ +function Component({ + appUrl, +}: { + appUrl: string; +}) { + const theme = trpc.useContext(); + return
; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/typescript/any-use-context.output.js b/transforms/__testfixtures__/use-context-hook/typescript/any-use-context.output.js new file mode 100644 index 00000000..e69de29b diff --git a/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.input.js b/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.input.js new file mode 100644 index 00000000..062dab59 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.input.js @@ -0,0 +1,11 @@ +import React from "react"; +import ThemeContext from "./ThemeContext"; + +function Component({ + appUrl, +}: { + appUrl: string; +}) { + const theme = React.useContext(ThemeContext); + return
; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.output.js b/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.output.js new file mode 100644 index 00000000..a873ec9a --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/typescript/use-context-2.output.js @@ -0,0 +1,11 @@ +import React from "react"; +import ThemeContext from "./ThemeContext"; + +function Component({ + appUrl, +}: { + appUrl: string; +}) { + const theme = React.use(ThemeContext); + return
; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/typescript/use-context.input.js b/transforms/__testfixtures__/use-context-hook/typescript/use-context.input.js new file mode 100644 index 00000000..74640584 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/typescript/use-context.input.js @@ -0,0 +1,11 @@ +import { useContext } from "react"; +import ThemeContext from "./ThemeContext"; + +function Component({ + appUrl, +}: { + appUrl: string; +}) { + const theme = useContext(ThemeContext); + return
; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/typescript/use-context.output.js b/transforms/__testfixtures__/use-context-hook/typescript/use-context.output.js new file mode 100644 index 00000000..d44d7ae8 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/typescript/use-context.output.js @@ -0,0 +1,11 @@ +import { use } from "react"; +import ThemeContext from "./ThemeContext"; + +function Component({ + appUrl, +}: { + appUrl: string; +}) { + const theme = use(ThemeContext); + return
; +}; \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/use-context-2.input.js b/transforms/__testfixtures__/use-context-hook/use-context-2.input.js new file mode 100644 index 00000000..67718d98 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/use-context-2.input.js @@ -0,0 +1,4 @@ +import React from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = React.useContext(ThemeContext); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/use-context-2.output.js b/transforms/__testfixtures__/use-context-hook/use-context-2.output.js new file mode 100644 index 00000000..f7f504f5 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/use-context-2.output.js @@ -0,0 +1,4 @@ +import React from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = React.use(ThemeContext); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/use-context.input.js b/transforms/__testfixtures__/use-context-hook/use-context.input.js new file mode 100644 index 00000000..979a8e47 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/use-context.input.js @@ -0,0 +1,4 @@ +import { useContext } from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = useContext(ThemeContext); \ No newline at end of file diff --git a/transforms/__testfixtures__/use-context-hook/use-context.output.js b/transforms/__testfixtures__/use-context-hook/use-context.output.js new file mode 100644 index 00000000..e251b573 --- /dev/null +++ b/transforms/__testfixtures__/use-context-hook/use-context.output.js @@ -0,0 +1,4 @@ +import { use } from "react"; +import ThemeContext from "./ThemeContext"; + +const theme = use(ThemeContext); \ No newline at end of file diff --git a/transforms/__tests__/remove-context-provider.test.ts b/transforms/__tests__/remove-context-provider.test.ts new file mode 100644 index 00000000..e037037f --- /dev/null +++ b/transforms/__tests__/remove-context-provider.test.ts @@ -0,0 +1,51 @@ + +'use strict'; + +const tests = [ + 'with-provider', + 'with-provider-2', + 'no-provider', +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('remove-context-provider', () => { + + tests.forEach(test => + defineTest( + __dirname, + 'remove-context-provider', + null, + `remove-context-provider/${ test }` + ) + ); + + + describe('typescript', () => { + + beforeEach(() => { + jest.mock('../remove-context-provider', () => { + return Object.assign( + require.requireActual('../remove-context-provider'), + { + parser: 'tsx' + } + ); + }); + }); + + afterEach(() => { + jest.resetModules(); + }); + + tests.forEach(test => { + defineTest( + __dirname, + 'remove-context-provider', + null, + `remove-context-provider/typescript/${ test }` + ); + }); + + }); +}); diff --git a/transforms/__tests__/remove-forward-ref.test.ts b/transforms/__tests__/remove-forward-ref.test.ts new file mode 100644 index 00000000..9f76f620 --- /dev/null +++ b/transforms/__tests__/remove-forward-ref.test.ts @@ -0,0 +1,62 @@ + +'use strict'; + +const jsTests = [ + 'function-expression', + 'arrow-function-expression', + 'forward-ref-import', + 'forward-ref-import-2', + 'props-identifier', + 'props-object-pattern', + 'callee-is-member-expression' +]; + +const tsTests = [ + 'type-arguments', + 'type-arguments-custom-names', + 'type-arguments-type-literals', + 'props-type-literal' +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('remove-forward-ref', () => { + + jsTests.forEach(test => + defineTest( + __dirname, + 'remove-forward-ref', + null, + `remove-forward-ref/${ test }` + ) + ); + + + describe('typescript', () => { + + beforeEach(() => { + jest.mock('../remove-forward-ref', () => { + return Object.assign( + require.requireActual('../remove-forward-ref'), + { + parser: 'tsx' + } + ); + }); + }); + + afterEach(() => { + jest.resetModules(); + }); + + tsTests.forEach(test => { + defineTest( + __dirname, + 'remove-forward-ref', + null, + `remove-forward-ref/typescript/${ test }` + ); + }); + + }); +}); diff --git a/transforms/__tests__/replace-act-import.ts b/transforms/__tests__/replace-act-import.ts new file mode 100644 index 00000000..61c880f7 --- /dev/null +++ b/transforms/__tests__/replace-act-import.ts @@ -0,0 +1,28 @@ + + +'use strict'; + +const tests = [ + 'default-import', + 'named-import-2', + 'named-import', + 'other-import', + 'wildcard-import', + 'wildcard-import-2', + 're-export' +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('replace-act-import', () => { + + tests.forEach(test => + defineTest( + __dirname, + 'replace-act-import', + null, + `replace-act-import/${ test }` + ) + ); + +}); diff --git a/transforms/__tests__/replace-reactdom-render.test.js b/transforms/__tests__/replace-reactdom-render.test.js new file mode 100644 index 00000000..72cef3f9 --- /dev/null +++ b/transforms/__tests__/replace-reactdom-render.test.js @@ -0,0 +1,22 @@ + + +'use strict'; + +const tests = [ + 'default', + 'nested', +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('replace-reactdom-render', () => { + + tests.forEach(test => + defineTest( + __dirname, + 'replace-reactdom-render', + null, + `replace-reactdom-render/${ test }` + ) + ); +}); diff --git a/transforms/__tests__/replace-string-ref.test.js b/transforms/__tests__/replace-string-ref.test.js new file mode 100644 index 00000000..d15e9139 --- /dev/null +++ b/transforms/__tests__/replace-string-ref.test.js @@ -0,0 +1,25 @@ + + +'use strict'; + +const tests = [ + 'class-component-custom-import-names', + 'class-component-default-import', + 'class-component-named-import', + 'function-component', +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('replace-string-ref', () => { + + tests.forEach(test => + defineTest( + __dirname, + 'replace-string-ref', + null, + `replace-string-ref/${ test }` + ) + ); + +}); diff --git a/transforms/__tests__/replace-use-form-state.test.ts b/transforms/__tests__/replace-use-form-state.test.ts new file mode 100644 index 00000000..0e8ef939 --- /dev/null +++ b/transforms/__tests__/replace-use-form-state.test.ts @@ -0,0 +1,27 @@ + + +'use strict'; + +const tests = [ + 'default-import', + 'named-import-2', + 'named-import-3', + 'named-import', + 'other-import', + 'wildcard-import' +]; + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('replace-use-form-state', () => { + + tests.forEach(test => + defineTest( + __dirname, + 'replace-use-form-state', + null, + `replace-use-form-state/${ test }` + ) + ); + +}); diff --git a/transforms/__tests__/use-context-hook.test.ts b/transforms/__tests__/use-context-hook.test.ts new file mode 100644 index 00000000..8892ed7e --- /dev/null +++ b/transforms/__tests__/use-context-hook.test.ts @@ -0,0 +1,58 @@ + +'use strict'; + +const tsTests = [ + 'use-context', + 'use-context-2', + 'any-use-context', +]; + +const jsTests = [ + 'use-context', + 'use-context-2', + 'any-use-context', + 'mixed-import' +] + +const defineTest = require('jscodeshift/dist/testUtils').defineTest; + +describe('use-context-hook', () => { + + jsTests.forEach(test => + defineTest( + __dirname, + 'use-context-hook', + null, + `use-context-hook/${ test }` + ) + ); + + + describe('typescript', () => { + + beforeEach(() => { + jest.mock('../use-context-hook', () => { + return Object.assign( + require.requireActual('../use-context-hook'), + { + parser: 'tsx' + } + ); + }); + }); + + afterEach(() => { + jest.resetModules(); + }); + + tsTests.forEach(test => { + defineTest( + __dirname, + 'use-context-hook', + null, + `use-context-hook/typescript/${ test }` + ); + }); + + }); +}); diff --git a/transforms/manual-bind-to-arrow.js b/transforms/manual-bind-to-arrow.js index 9dec06a9..7afb09a8 100644 --- a/transforms/manual-bind-to-arrow.js +++ b/transforms/manual-bind-to-arrow.js @@ -181,4 +181,4 @@ export default function transformer(file, api, options) { return null; } -// module.exports.parser = 'flow'; +// module.exports.parser = 'flow'; \ No newline at end of file diff --git a/transforms/remove-context-provider.ts b/transforms/remove-context-provider.ts new file mode 100644 index 00000000..4aadfbea --- /dev/null +++ b/transforms/remove-context-provider.ts @@ -0,0 +1,40 @@ +import type { API, FileInfo } from 'jscodeshift'; + +export default function transform( + file: FileInfo, + api: API, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + let isDirty = false; + + root.findJSXElements().forEach((elementPath) => { + const { value } = elementPath; + const elements = [value.openingElement, value.closingElement]; + elements.forEach((element) => { + if (!element) { + return; + } + if ( + !j.JSXMemberExpression.check(element.name) || + !j.JSXIdentifier.check(element.name.object) + ) { + return; + } + + const objectName = element.name.object.name; + const propertyName = element.name.property.name; + + if ( + objectName.toLocaleLowerCase().includes('context') && + propertyName === 'Provider' + ) { + element.name = element.name.object; + isDirty = true; + } + }); + }); + + return isDirty ? root.toSource() : undefined; +} diff --git a/transforms/remove-forward-ref.ts b/transforms/remove-forward-ref.ts new file mode 100644 index 00000000..da7ad9d0 --- /dev/null +++ b/transforms/remove-forward-ref.ts @@ -0,0 +1,297 @@ +import type { + API, + ArrowFunctionExpression, + CallExpression, + FileInfo, + FunctionExpression, + Identifier, + JSCodeshift, + TSTypeLiteral, + TSTypeReference, +} from 'jscodeshift'; + +// Props & { ref: React.RefObject} +const buildPropsAndRefIntersectionTypeAnnotation = ( + j: JSCodeshift, + propType: TSTypeReference | TSTypeLiteral, + refType: TSTypeReference | TSTypeLiteral | null, +) => + j.tsTypeAnnotation( + j.tsIntersectionType([ + propType, + j.tsTypeLiteral([ + j.tsPropertySignature.from({ + key: j.identifier('ref'), + typeAnnotation: j.tsTypeAnnotation( + j.tsTypeReference.from({ + typeName: j.tsQualifiedName( + j.identifier('React'), + j.identifier('RefObject'), + ), + typeParameters: j.tsTypeParameterInstantiation([ + refType === null ? j.tsUnknownKeyword() : refType, + ]), + }), + ), + }), + ]), + ]), + ); + +// { ref: refName, ...propsName } +const buildRefAndPropsObjectPattern = ( + j: JSCodeshift, + refArgName: string, + propArgName: string, +) => + j.objectPattern([ + j.objectProperty.from({ + shorthand: true, + key: j.identifier('ref'), + value: j.identifier(refArgName), + }), + j.restProperty(j.identifier(propArgName)), + ]); + +// React.ForwardedRef => HTMLButtonElement +const getRefTypeFromRefArg = (j: JSCodeshift, refArg: Identifier) => { + const typeReference = refArg.typeAnnotation?.typeAnnotation; + if ( + !j.TSTypeReference.check(typeReference) || + !j.TSQualifiedName.check(typeReference.typeName) + ) { + return null; + } + + const { right } = typeReference.typeName; + + if (!j.Identifier.check(right) || right.name === 'forwardedRef') { + return null; + } + + const [firstTypeParameter] = typeReference.typeParameters?.params ?? []; + + if (!j.TSTypeReference.check(firstTypeParameter)) { + return null; + } + + return firstTypeParameter; +}; + +const getForwardRefRenderFunction = ( + j: JSCodeshift, + callExpression: CallExpression, +): FunctionExpression | ArrowFunctionExpression | null => { + const [renderFunction] = callExpression.arguments; + + if ( + !j.FunctionExpression.check(renderFunction) && + !j.ArrowFunctionExpression.check(renderFunction) + ) { + return null; + } + + return renderFunction; +}; + +const isLiteralOrReference = ( + j: JSCodeshift, + type: unknown, +): type is TSTypeReference | TSTypeLiteral => { + return j.TSTypeReference.check(type) || j.TSTypeLiteral.check(type); +}; + +export default function transform(file: FileInfo, api: API) { + const j = api.jscodeshift; + + const root = j(file.source); + + let isDirty = false; + + let reactForwardRefImportLocalName: string | null = null; + let reactDefaultImportName: string | null = null; + + root + .find(j.ImportDeclaration, { + source: { value: 'react' }, + }) + .forEach((path) => { + path.value.specifiers?.forEach((specifier) => { + // named import + if ( + j.ImportSpecifier.check(specifier) && + specifier.imported.name === 'forwardRef' + ) { + reactForwardRefImportLocalName = specifier.local?.name ?? null; + } + + // default and wildcard import + if ( + j.ImportDefaultSpecifier.check(specifier) || + j.ImportNamespaceSpecifier.check(specifier) + ) { + reactDefaultImportName = specifier.local?.name ?? null; + } + }); + }); + + root + .find(j.CallExpression) + .filter((path) => { + const { callee } = path.value; + + if ( + j.Identifier.check(callee) && + callee.name === reactForwardRefImportLocalName + ) { + return true; + } + + if ( + j.MemberExpression.check(callee) && + j.Identifier.check(callee.object) && + callee.object.name === reactDefaultImportName && + j.Identifier.check(callee.property) && + callee.property.name === 'forwardRef' + ) { + return true; + } + + return false; + }) + .replaceWith((callExpressionPath) => { + const originalCallExpression = callExpressionPath.value; + + const renderFunction = getForwardRefRenderFunction( + j, + callExpressionPath.node, + ); + + if (renderFunction === null) { + console.warn('Could not detect render function.'); + + return originalCallExpression; + } + + const [propsArg, refArg] = renderFunction.params; + + if ( + !j.Identifier.check(refArg) || + !(j.Identifier.check(propsArg) || j.ObjectPattern.check(propsArg)) + ) { + console.warn('Could not detect ref or props arguments.'); + + return originalCallExpression; + } + + const refArgTypeReference = getRefTypeFromRefArg(j, refArg); + const refArgName = refArg.name; + + const propsArgTypeReference = propsArg.typeAnnotation?.typeAnnotation; + // remove refArg + renderFunction.params.splice(1, 1); + + // if propsArg is ObjectPattern, add ref as new ObjectProperty + if (j.ObjectPattern.check(propsArg)) { + propsArg.properties.unshift( + j.objectProperty.from({ + shorthand: true, + key: j.identifier('ref'), + value: j.identifier(refArgName), + }), + ); + + isDirty = true; + } + + // if props arg is Identifier, push ref variable declaration to the function body + if (j.Identifier.check(propsArg)) { + renderFunction.params[0] = buildRefAndPropsObjectPattern( + j, + refArg.name, + propsArg.name, + ); + + isDirty = true; + } + + /** + * Transform ts types: render function props and ref are typed + */ + + if ( + isLiteralOrReference(j, propsArgTypeReference) && + renderFunction.params?.[0] && + 'typeAnnotation' in renderFunction.params[0] + ) { + renderFunction.params[0].typeAnnotation = + buildPropsAndRefIntersectionTypeAnnotation( + j, + propsArgTypeReference, + refArgTypeReference, + ); + isDirty = true; + } + + /** + * Transform ts types: forwardRef type arguments are used + */ + + const typeParameters = callExpressionPath.node.typeParameters; + + // if typeParameters are used in forwardRef generic, reuse them to annotate props type + // forwardRef((props) => { ... }) ====> (props: Props & { ref: React.RefObject }) => { ... } + if ( + j.TSTypeParameterInstantiation.check(typeParameters) && + renderFunction.params?.[0] && + 'typeAnnotation' in renderFunction.params[0] + ) { + const [refType, propType] = typeParameters.params; + + if ( + j.TSTypeReference.check(refType) && + isLiteralOrReference(j, propType) + ) { + renderFunction.params[0].typeAnnotation = + buildPropsAndRefIntersectionTypeAnnotation(j, propType, refType); + + isDirty = true; + } + } + + return renderFunction; + }); + + /** + * handle import + */ + if (isDirty) { + root + .find(j.ImportDeclaration, { + source: { + value: 'react', + }, + }) + .forEach((importDeclarationPath) => { + const { specifiers, importKind } = importDeclarationPath.node; + + if (importKind !== 'value') { + return; + } + + const specifiersWithoutForwardRef = + specifiers?.filter( + (s) => + !j.ImportSpecifier.check(s) || s.imported.name !== 'forwardRef', + ) ?? []; + + if (specifiersWithoutForwardRef.length === 0) { + j(importDeclarationPath).remove(); + } + + importDeclarationPath.node.specifiers = specifiersWithoutForwardRef; + }); + } + + return isDirty ? root.toSource() : undefined; +} diff --git a/transforms/replace-act-import.ts b/transforms/replace-act-import.ts new file mode 100644 index 00000000..9fdf70c0 --- /dev/null +++ b/transforms/replace-act-import.ts @@ -0,0 +1,142 @@ +import type { API, FileInfo, Options } from 'jscodeshift'; + +export default function transform( + file: FileInfo, + api: API, + options?: Options, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + // Get default import from test utils + const defaultUtilsImportName = root + .find(j.ImportDeclaration, { + source: { value: 'react-dom/test-utils' }, + specifiers: [{ type: 'ImportDefaultSpecifier' }], + }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name; + + // Get default import from test utils + const starUtilsImportName = root + .find(j.ImportDeclaration, { + source: { value: 'react-dom/test-utils' }, + specifiers: [{ type: 'ImportNamespaceSpecifier' }], + }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name; + + const utilsCalleeName = defaultUtilsImportName ?? starUtilsImportName; + const utilsCalleeType: any = defaultUtilsImportName + ? 'ImportDefaultSpecifier' + : 'ImportNamespaceSpecifier'; + + // For usages like `import * as ReactTestUtils from 'react-dom/test-utils'; ReactTestUtils.act()` + const actAccessExpressions = root.find(j.MemberExpression, { + object: { name: utilsCalleeName }, + property: { name: 'act' }, + }); + + if (actAccessExpressions.length > 0) { + // React import + const defaultReactImportName = root + .find(j.ImportDeclaration, { source: { value: 'react' } }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name; + + if (!defaultReactImportName) { + const importNode = + utilsCalleeType === 'ImportDefaultSpecifier' + ? j.importDefaultSpecifier + : j.importNamespaceSpecifier; + + const reactImport = j.importDeclaration( + [importNode(j.identifier('React'))], + j.literal('react'), + ); + + root.get().node.program.body.unshift(reactImport); + } + + actAccessExpressions.forEach((path) => { + const accessedPath = j(path) + .find(j.Identifier, { name: utilsCalleeName }) + .paths() + .at(0); + + const newIdentifier = j.identifier.from({ + name: defaultReactImportName ?? 'React', + }); + + accessedPath?.replace(newIdentifier); + }); + + // Remove the old import + root + .find(j.ImportDeclaration, { + source: { value: 'react-dom/test-utils' }, + specifiers: [{ type: utilsCalleeType }], + }) + .remove(); + } + + root + .find(j.ImportDeclaration, { + source: { value: 'react-dom/test-utils' }, + specifiers: [{ type: 'ImportSpecifier', imported: { name: 'act' } }], + }) + .forEach((path) => { + const newImportSpecifier = j.importSpecifier( + j.identifier('act'), + j.identifier('act'), + ); + + const existingReactImportCollection = root.find(j.ImportDeclaration, { + source: { value: 'react' }, + specifiers: [{ type: 'ImportSpecifier' }], + }); + + if (existingReactImportCollection.length > 0) { + existingReactImportCollection + .paths() + .at(0) + ?.node.specifiers?.push(newImportSpecifier); + + path.prune(); + } else { + const newImportDeclaration = j.importDeclaration( + [newImportSpecifier], + j.literal('react'), + ); + + path.replace(newImportDeclaration); + } + }); + + /** + * handle re-exports: + * export * from 'react-dom/test-utils'; + */ + root.find(j.ExportAllDeclaration).forEach((path) => { + if (path.node.source.value === 'react-dom/test-utils') { + const newExportDeclaration = j.exportNamedDeclaration.from({ + declaration: null, + specifiers: [ + j.exportSpecifier.from({ + local: j.identifier('act'), + exported: j.identifier('act'), + }), + ], + source: j.literal('react'), + }); + + // add export { act } from "react"; + path.insertAfter(newExportDeclaration); + } + }); + + return root.toSource(); +} diff --git a/transforms/replace-reactdom-render.ts b/transforms/replace-reactdom-render.ts new file mode 100644 index 00000000..f8837faa --- /dev/null +++ b/transforms/replace-reactdom-render.ts @@ -0,0 +1,97 @@ +import type { API, FileInfo, Options } from 'jscodeshift'; + +export default function transform( + file: FileInfo, + api: API, + options?: Options, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + let reactDomRenderNamedImportLocalName: string | null = null; + let reactDomDefaultImportName: string | null = null; + + let isDirty = false; + root + .find(j.ImportDeclaration, { + source: { value: 'react-dom' }, + }) + .forEach((path) => { + path.value.specifiers?.forEach((specifier) => { + // named import + if ( + j.ImportSpecifier.check(specifier) && + specifier.imported.name === 'render' + ) { + reactDomRenderNamedImportLocalName = specifier.local?.name ?? null; + } + + // default and wildcard import + if ( + j.ImportDefaultSpecifier.check(specifier) || + j.ImportNamespaceSpecifier.check(specifier) + ) { + reactDomDefaultImportName = specifier.local?.name ?? null; + } + }); + }); + + root + .find(j.CallExpression) + .filter((path) => { + const { callee } = path.value; + + if ( + j.Identifier.check(callee) && + callee.name === reactDomRenderNamedImportLocalName + ) { + return true; + } + + if ( + j.MemberExpression.check(callee) && + j.Identifier.check(callee.object) && + callee.object.name === reactDomDefaultImportName && + j.Identifier.check(callee.property) && + callee.property.name === 'render' + ) { + return true; + } + + return false; + }) + .forEach((path) => { + const args = path.value.arguments; + + const createRoot = j.variableDeclaration('const', [ + j.variableDeclarator( + j.identifier('root'), + j.callExpression(j.identifier('createRoot'), [args[1]]), + ), + ]); + + const render = j.expressionStatement( + j.callExpression( + j.memberExpression(j.identifier('root'), j.identifier('render')), + [args[0]], + ), + ); + + isDirty = true; + const body = root.get().node.program.body; + + const importStatement = j.importDeclaration( + [j.importSpecifier(j.identifier('createRoot'))], + j.literal('react-dom/client'), + ); + body.unshift(importStatement); + + path.parent.replace(createRoot); + path.parent.insertAfter(render); + }); + + if (isDirty) { + } + + return isDirty ? root.toSource() : undefined; +} diff --git a/transforms/replace-string-ref.ts b/transforms/replace-string-ref.ts new file mode 100644 index 00000000..0173238b --- /dev/null +++ b/transforms/replace-string-ref.ts @@ -0,0 +1,114 @@ +import type { API, FileInfo, JSCodeshift, Options } from 'jscodeshift'; + +const REACT_CLASS_COMPONENT_SUPERCLASS_NAMES = ['PureComponent', 'Component']; + +const buildCallbackRef = (j: JSCodeshift, refName: string) => + j.jsxAttribute( + j.jsxIdentifier('ref'), + j.jsxExpressionContainer( + j.arrowFunctionExpression( + [j.jsxIdentifier('ref')], + j.blockStatement([ + j.expressionStatement( + j.assignmentExpression( + '=', + j.memberExpression( + j.memberExpression(j.thisExpression(), j.identifier('refs')), + j.identifier(refName), + ), + j.identifier('ref'), + ), + ), + ]), + ), + ), + ); + +export default function transform( + file: FileInfo, + api: API, + options?: Options, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + let isDirty = false; + + const reactComponentNamedImportLocalNamesSet = new Set(); + let reactDefaultImportName: string | null = null; + + root + .find(j.ImportDeclaration, { + source: { value: 'react' }, + }) + .forEach((path) => { + path.value.specifiers?.forEach((specifier) => { + // named import + if ( + j.ImportSpecifier.check(specifier) && + REACT_CLASS_COMPONENT_SUPERCLASS_NAMES.includes( + specifier.imported.name, + ) + ) { + reactComponentNamedImportLocalNamesSet.add(specifier.local?.name); + } + + // default and wildcard import + if ( + j.ImportDefaultSpecifier.check(specifier) || + j.ImportNamespaceSpecifier.check(specifier) + ) { + reactDefaultImportName = specifier.local?.name ?? null; + } + }); + }); + + const reactComponentNamedImportLocalNames = [ + ...reactComponentNamedImportLocalNamesSet, + ]; + + const classComponentCollection = root + .find(j.ClassDeclaration) + .filter((path) => { + const superClass = path.value.superClass; + + if (j.Identifier.check(superClass)) { + return [...reactComponentNamedImportLocalNames].includes( + superClass.name, + ); + } + + if ( + j.MemberExpression.check(superClass) && + j.Identifier.check(superClass.object) && + superClass.object.name === reactDefaultImportName && + j.Identifier.check(superClass.property) + ) { + return REACT_CLASS_COMPONENT_SUPERCLASS_NAMES.includes( + superClass.property.name, + ); + } + + return false; + }); + + classComponentCollection + .find(j.JSXAttribute, { + name: { + type: 'JSXIdentifier', + name: 'ref', + }, + }) + .forEach((path) => { + const attributeValue = path.value.value; + if (!j.StringLiteral.check(attributeValue)) { + return; + } + + isDirty = true; + + path.replace(buildCallbackRef(j, attributeValue.value)); + }); + + return isDirty ? root.toSource() : undefined; +} diff --git a/transforms/replace-use-form-state.ts b/transforms/replace-use-form-state.ts new file mode 100644 index 00000000..29ff7299 --- /dev/null +++ b/transforms/replace-use-form-state.ts @@ -0,0 +1,98 @@ +import type { API, FileInfo, Options } from 'jscodeshift'; + +export default function transform( + file: FileInfo, + api: API, + options?: Options, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + let isDirty = false; + // Get default import from react-dom + const defaultImportName = root + .find(j.ImportDeclaration, { + source: { value: 'react-dom' }, + specifiers: [{ type: 'ImportDefaultSpecifier' }], + }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name; + + // Get default import from test utils + const starImportName = root + .find(j.ImportDeclaration, { + source: { value: 'react-dom' }, + specifiers: [{ type: 'ImportNamespaceSpecifier' }], + }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name; + + const utilsCalleeName = defaultImportName ?? starImportName; + const utilsCalleeType: any = defaultImportName + ? 'ImportDefaultSpecifier' + : 'ImportNamespaceSpecifier'; + + // For usages like `import * as ReactDOM from 'react-dom'; ReactDOM.useFormState()` + const actAccessExpressions = root.find(j.MemberExpression, { + object: { name: utilsCalleeName }, + property: { name: 'useFormState' }, + }); + + if (actAccessExpressions.length > 0) { + // React import + + actAccessExpressions.forEach((path) => { + j(path) + .find(j.Identifier, { name: 'useFormState' }) + .at(0) + ?.replaceWith(() => { + isDirty = true; + return j.identifier('useActionState'); + }); + }); + } + + // For direct imports, such as `import { useFormState } from 'react-dom';` + const reactDOMImportCollection = root.find(j.ImportDeclaration, { + source: { value: 'react-dom' }, + }); + + const reactDOMImportPath = reactDOMImportCollection.paths().at(0); + + if (!reactDOMImportPath) { + return isDirty ? root.toSource() : undefined; + } + + const specifier = reactDOMImportPath.node.specifiers?.find( + (s) => s.type === 'ImportSpecifier' && s.imported.name === 'useFormState', + ); + + if (!specifier || !j.ImportSpecifier.check(specifier)) { + return isDirty ? root.toSource() : undefined; + } + + const usedName = specifier.local?.name ?? specifier.imported.name; + + // Replace import name + reactDOMImportCollection + .find(j.ImportSpecifier, { imported: { name: 'useFormState' } }) + .replaceWith(() => { + isDirty = true; + return j.importSpecifier( + j.identifier('useActionState'), + j.identifier(usedName), + ); + }); + + // Means it's not aliased, so we also change identifier names, not only import + if (specifier?.local?.name === 'useFormState') { + root.find(j.Identifier, { name: 'useFormState' }).replaceWith(() => { + isDirty = true; + return j.identifier('useActionState'); + }); + } + + return isDirty ? root.toSource() : undefined; +} diff --git a/transforms/use-context-hook.ts b/transforms/use-context-hook.ts new file mode 100644 index 00000000..d1f0fc3d --- /dev/null +++ b/transforms/use-context-hook.ts @@ -0,0 +1,83 @@ +import type { API, FileInfo, Options } from 'jscodeshift'; + +export default function transform( + file: FileInfo, + api: API, + options?: Options, +): string | undefined { + const j = api.jscodeshift; + const root = j(file.source); + + let isDirty = false; + + // Get default import from react + const defaultReactImport = + root + .find(j.ImportDeclaration, { + source: { value: 'react' }, + specifiers: [{ type: 'ImportDefaultSpecifier' }], + }) + .paths() + .at(0) + ?.node.specifiers?.at(0)?.local?.name ?? 'React'; + + // For usages like `import React from 'react'; React.useContext(ThemeContext)` + root + .find(j.MemberExpression, { + object: { name: defaultReactImport }, + property: { name: 'useContext' }, + }) + .forEach((path) => { + const identifierPath = j(path) + .find(j.Identifier, { name: 'useContext' }) + .paths() + .at(0); + + const newIdentifier = j.identifier.from({ name: 'use' }); + + identifierPath?.replace(newIdentifier); + isDirty = true; + }); + + // Get useContext import name + let useContextImportLocalName: string | null = null; + + root + .find(j.ImportDeclaration, { + source: { value: 'react' }, + }) + .forEach((path) => { + const useContextSpecifier = path.node.specifiers + ?.filter( + (specifier) => + j.ImportSpecifier.check(specifier) && + specifier.imported.name === 'useContext', + ) + .at(0); + + useContextImportLocalName = useContextSpecifier?.local?.name ?? null; + }); + + if (useContextImportLocalName) { + // For usages like `import { useContext } from 'react'; useContext(ThemeContext)` + root + .find(j.Identifier, { name: useContextImportLocalName }) + .forEach((path) => { + // If parent is a member expression, we don't want that change, we handle React.useContext separately + if (path.parentPath.node.type === 'MemberExpression') { + return; + } + + // In all other cases, replace usages of imported useContext with use + if (path.node.type === 'Identifier') { + const newIdentifier = j.identifier.from({ name: 'use' }); + + path.replace(newIdentifier); + + isDirty = true; + } + }); + } + + return isDirty ? root.toSource() : undefined; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..0d6dcc73 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "moduleDetection": "force", + "target": "ES2015" + } + } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 03cceba7..d82bdc01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,14 @@ dependencies: "@babel/highlight" "^7.10.4" +"@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + "@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" @@ -49,6 +57,16 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" + integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA== + dependencies: + "@babel/types" "^7.24.5" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" @@ -105,6 +123,11 @@ "@babel/types" "^7.10.5" lodash "^4.17.19" +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-explode-assignable-expression@^7.10.4": version "7.11.4" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" @@ -121,6 +144,14 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-get-function-arity@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" @@ -135,6 +166,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" @@ -223,11 +261,28 @@ dependencies: "@babel/types" "^7.11.0" +"@babel/helper-split-export-declaration@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6" + integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q== + dependencies: + "@babel/types" "^7.24.5" + +"@babel/helper-string-parser@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== + "@babel/helper-validator-identifier@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== + "@babel/helper-wrap-function@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" @@ -256,11 +311,26 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0": version "7.11.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== +"@babel/parser@^7.24.0", "@babel/parser@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" @@ -862,7 +932,32 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0": +"@babel/template@^7.22.15": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + +"@babel/traverse@^7.1.0": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8" + integrity sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA== + dependencies: + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.24.5" + "@babel/parser" "^7.24.5" + "@babel/types" "^7.24.5" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0": version "7.11.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== @@ -886,6 +981,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" + integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ== + dependencies: + "@babel/helper-string-parser" "^7.24.1" + "@babel/helper-validator-identifier" "^7.24.5" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1042,6 +1146,38 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1129,6 +1265,13 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/jest@^24.9.0": + version "24.9.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" + integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== + dependencies: + jest-diff "^24.3.0" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1156,10 +1299,56 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/parser@^7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.8.0.tgz#1e1db30c8ab832caffee5f37e677dbcb9357ddc8" + integrity sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ== + dependencies: + "@typescript-eslint/scope-manager" "7.8.0" + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/typescript-estree" "7.8.0" + "@typescript-eslint/visitor-keys" "7.8.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz#bb19096d11ec6b87fb6640d921df19b813e02047" + integrity sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g== + dependencies: + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/visitor-keys" "7.8.0" + +"@typescript-eslint/types@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.8.0.tgz#1fd2577b3ad883b769546e2d1ef379f929a7091d" + integrity sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw== + +"@typescript-eslint/typescript-estree@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz#b028a9226860b66e623c1ee55cc2464b95d2987c" + integrity sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg== + dependencies: + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/visitor-keys" "7.8.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/visitor-keys@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz#7285aab991da8bee411a42edbd5db760d22fdd91" + integrity sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA== + dependencies: + "@typescript-eslint/types" "7.8.0" + eslint-visitor-keys "^3.4.3" + abab@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== acorn-globals@^4.1.0: version "4.3.4" @@ -1185,16 +1374,16 @@ acorn@^5.5.3: integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== acorn@^6.0.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^7.1.1: version "7.4.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: +ajv@^6.10.0, ajv@^6.10.2: version "6.12.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== @@ -1204,6 +1393,16 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -1229,11 +1428,16 @@ ansi-regex@^2.0.0: integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -1304,9 +1508,9 @@ array-differ@^1.0.0: integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.2.tgz#a8572e64e822358271250b9156d20d96ef5dec04" + integrity sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA== array-find-index@^1.0.1: version "1.0.2" @@ -1359,16 +1563,16 @@ arrify@^1.0.0, arrify@^1.0.1: integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== dependencies: safer-buffer "~2.1.0" 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" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== assign-symbols@^1.0.0: version "1.0.0" @@ -1395,7 +1599,7 @@ async-limiter@~1.0.0: asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== atob@^2.1.2: version "2.1.2" @@ -1405,12 +1609,12 @@ atob@^2.1.2: aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== aws4@^1.8.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" - integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== babel-code-frame@^6.26.0: version "6.26.0" @@ -1913,7 +2117,7 @@ base@^0.11.1: bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== dependencies: tweetnacl "^0.14.3" @@ -1937,6 +2141,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -1953,7 +2164,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -1982,6 +2193,13 @@ browserslist@^4.12.0, browserslist@^4.8.5: escalade "^3.1.0" node-releases "^1.1.61" +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -1989,6 +2207,11 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-from@1.x: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -2048,7 +2271,7 @@ capture-exit@^2.0.0: caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" @@ -2171,7 +2394,7 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -colors@1.3.3: +colors@1.3.3, colors@^1.1.2: version "1.3.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== @@ -2291,7 +2514,7 @@ currently-unhandled@^0.4.1: dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== dependencies: assert-plus "^1.0.0" @@ -2323,6 +2546,13 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@^4.3.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + decamelize-keys@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -2378,7 +2608,7 @@ define-property@^2.0.2: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== detect-indent@^4.0.0: version "4.0.0" @@ -2390,7 +2620,7 @@ detect-indent@^4.0.0: detect-newline@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + integrity sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg== diff-sequences@^24.9.0: version "24.9.0" @@ -2435,7 +2665,7 @@ duplexer2@0.0.2: ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== dependencies: jsbn "~0.1.0" safer-buffer "^2.1.0" @@ -2572,6 +2802,11 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== +eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + eslint@^6.6.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" @@ -2780,12 +3015,12 @@ extglob@^2.0.4: extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== fancy-log@^1.1.0: version "1.3.3" @@ -2814,7 +3049,18 @@ fast-glob@^3.0.3: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@^2.0.0: +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -2938,7 +3184,7 @@ for-in@^1.0.2: forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== form-data@~2.3.2: version "2.3.3" @@ -2974,6 +3220,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" @@ -3011,7 +3262,7 @@ get-value@^2.0.3, get-value@^2.0.6: getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== dependencies: assert-plus "^1.0.0" @@ -3022,7 +3273,26 @@ glob-parent@^5.0.0, glob-parent@^5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.1, glob@^7.1.2: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3065,6 +3335,18 @@ globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + glogg@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" @@ -3080,7 +3362,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4 growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw== gulp-util@^3.0.4: version "3.0.8" @@ -3116,7 +3398,7 @@ gulplog@^1.0.0: har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== har-validator@~5.1.3: version "5.1.5" @@ -3193,6 +3475,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + 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" @@ -3221,7 +3510,7 @@ html-escaper@^2.0.0: http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -3249,6 +3538,11 @@ ignore@^5.1.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + import-fresh@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -3359,6 +3653,13 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.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" @@ -3449,6 +3750,13 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-negative-zero@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" @@ -3515,7 +3823,7 @@ is-symbol@^1.0.2: is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== is-windows@^1.0.2: version "1.0.2" @@ -3525,7 +3833,7 @@ is-windows@^1.0.2: is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== isarray@0.0.1: version "0.0.1" @@ -3557,7 +3865,7 @@ isobject@^3.0.0, isobject@^3.0.1: isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: version "2.0.5" @@ -3655,7 +3963,7 @@ jest-config@^24.9.0: pretty-format "^24.9.0" realpath-native "^1.1.0" -jest-diff@^24.9.0: +jest-diff@^24.3.0, jest-diff@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== @@ -3792,9 +4100,9 @@ jest-mock@^24.9.0: "@jest/types" "^24.9.0" jest-pnp-resolver@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: version "24.9.0" @@ -3979,7 +4287,7 @@ js-yaml@^3.13.1: jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== jscodeshift@^0.11.0: version "0.11.0" @@ -4063,10 +4371,10 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -4076,7 +4384,12 @@ json-stable-stringify-without-jsonify@^1.0.1: 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" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@2.x: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== json5@^0.5.1: version "0.5.1" @@ -4091,13 +4404,13 @@ json5@^2.1.2: minimist "^1.2.5" jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" extsprintf "1.3.0" - json-schema "0.2.3" + json-schema "0.4.0" verror "1.10.0" jsx-ast-utils@^2.4.1: @@ -4259,6 +4572,11 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" @@ -4267,7 +4585,7 @@ lodash.restparam@^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" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== lodash.template@^3.0.0: version "3.6.2" @@ -4328,6 +4646,11 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" +make-error@1.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -4377,7 +4700,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0: +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -4409,17 +4732,25 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.44.0" + mime-db "1.52.0" mimic-fn@^2.1.0: version "2.1.0" @@ -4433,6 +4764,20 @@ minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" + integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== + dependencies: + brace-expansion "^2.0.1" + minimist-options@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" @@ -4446,6 +4791,11 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -4454,6 +4804,13 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp@0.x: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -4548,9 +4905,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + version "5.4.5" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.5.tgz#0cbc1a2b0f658493b4025775a13ad938e96091ef" + integrity sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ== dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -4602,9 +4959,9 @@ npm-run-path@^4.0.0: path-key "^3.0.0" nwsapi@^2.0.7: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + version "2.2.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.9.tgz#7f3303218372db2e9f27c27766bcfc59ae7e61c6" + integrity sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg== oauth-sign@~0.9.0: version "0.9.0" @@ -4740,7 +5097,7 @@ os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: p-each-series@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + integrity sha512-J/e9xiZZQNrt+958FFzJ+auItsBGq+UrQ7nE89AUP7UOTtjHnkISANXLdayhVzh538UnLMCSlf13lFfRIAKQOA== dependencies: p-reduce "^1.0.0" @@ -4785,7 +5142,7 @@ p-locate@^3.0.0: p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + integrity sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ== p-try@^1.0.0: version "1.0.0" @@ -4857,6 +5214,11 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -4872,13 +5234,23 @@ path-type@^4.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" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -4966,9 +5338,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== pump@^3.0.0: version "3.0.0" @@ -4978,15 +5350,20 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== quick-lru@^1.0.0: version "1.1.0" @@ -5228,14 +5605,14 @@ require-main-filename@^2.0.0: resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + integrity sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg== 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" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= + integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== resolve-from@^4.0.0: version "4.0.0" @@ -5250,7 +5627,16 @@ resolve-url@^0.2.1: resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== + +resolve@1.x: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" resolve@^1.10.0, resolve@^1.12.0, resolve@^1.17.0, resolve@^1.3.2: version "1.17.0" @@ -5351,9 +5737,9 @@ sane@^4.0.3: walker "~1.0.5" sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + version "1.3.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== "semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" @@ -5365,15 +5751,30 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^6.0.0, semver@^6.1.2, semver@^6.2.0: +semver@^5.5: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0, semver@^6.1.2: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.2.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.6.0: + version "7.6.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" @@ -5504,7 +5905,7 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map-support@^0.5.16, source-map-support@^0.5.6: +source-map-support@^0.5.16: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -5512,6 +5913,14 @@ source-map-support@^0.5.16, source-map-support@^0.5.6: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + 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" @@ -5571,9 +5980,9 @@ sprintf-js@~1.0.2: integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -5601,12 +6010,12 @@ static-extend@^0.1.1: stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + integrity sha512-Qka42GGrS8Mm3SZ+7cH8UXiIWI867/b/Z/feQSpQx/rbfB8UGknGEZVaUQMOUVj+soY6NpWAxily63HI1OckVQ== dependencies: astral-regex "^1.0.0" strip-ansi "^4.0.0" @@ -5679,7 +6088,7 @@ strip-ansi@^3.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" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== dependencies: ansi-regex "^3.0.0" @@ -5748,6 +6157,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -5788,7 +6202,7 @@ text-table@^0.2.0: throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + integrity sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA== through2@^2.0.0: version "2.0.5" @@ -5873,7 +6287,7 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== dependencies: punycode "^2.1.0" @@ -5887,6 +6301,27 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + +ts-jest@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" + integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + mkdirp "0.x" + resolve "1.x" + semver "^5.5" + yargs-parser "10.x" + tslib@^1.9.0: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" @@ -5900,14 +6335,14 @@ tslib@^2.0.1: tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== 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" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== type-check@~0.3.2: version "0.3.2" @@ -5926,6 +6361,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typescript@4.8.4: + version "4.8.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -6020,7 +6460,7 @@ validate-npm-package-license@^3.0.1: verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -6085,9 +6525,9 @@ whatwg-url@^7.0.0: 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" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== which@^1.2.8, which@^1.2.9, which@^1.3.0: version "1.3.1" @@ -6148,9 +6588,9 @@ write@1.0.3: mkdirp "^0.5.1" ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== dependencies: async-limiter "~1.0.0" @@ -6165,16 +6605,16 @@ xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yargs-parser@^10.0.0: +yargs-parser@10.x, yargs-parser@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==