From 66fa209f8f4f4ae54b556062ea91279010b14eae Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Thu, 18 Jun 2020 15:40:07 +0200 Subject: [PATCH] [typescript-to-proptypes] Integrate into monorepo --- .circleci/config.yml | 15 + .eslintignore | 2 + package.json | 1 - packages/typescript-to-proptypes/.mocharc.js | 3 + packages/typescript-to-proptypes/README.md | 8 - .../typescript-to-proptypes/jest.config.js | 13 - packages/typescript-to-proptypes/package.json | 106 +- .../typescript-to-proptypes/src/config.ts | 22 +- .../typescript-to-proptypes/src/generator.ts | 514 ++-- .../typescript-to-proptypes/src/injector.ts | 695 +++-- .../typescript-to-proptypes/src/parser.ts | 1054 +++---- .../src/types/nodes/baseNodes.ts | 4 +- .../src/types/nodes/component.ts | 24 +- .../src/types/nodes/program.ts | 12 +- .../src/types/nodes/proptype.ts | 44 +- .../src/types/props/DOMElement.ts | 12 +- .../src/types/props/any.ts | 8 +- .../src/types/props/array.ts | 12 +- .../src/types/props/boolean.ts | 8 +- .../src/types/props/element.ts | 12 +- .../src/types/props/function.ts | 8 +- .../src/types/props/instanceOf.ts | 12 +- .../src/types/props/interface.ts | 10 +- .../src/types/props/literal.ts | 16 +- .../src/types/props/numeric.ts | 8 +- .../src/types/props/object.ts | 8 +- .../src/types/props/string.ts | 8 +- .../src/types/props/undefined.ts | 8 +- .../src/types/props/union.ts | 68 +- .../test/boolean-values/optional/input.d.ts | 6 +- .../test/boolean-values/optional/output.js | 6 +- .../test/boolean-values/optional/output.json | 39 - .../test/boolean-values/required/input.d.ts | 6 +- .../test/boolean-values/required/output.js | 6 +- .../test/boolean-values/required/output.json | 32 - .../test/code-order/input.d.ts | 2 +- .../test/code-order/input.js | 6 +- .../test/code-order/options.ts | 6 +- .../test/code-order/output.js | 6 +- .../test/code-order/output.json | 10 - .../test/generator/html-elements/input.d.ts | 8 +- .../test/generator/html-elements/output.js | 56 +- .../test/generator/html-elements/output.json | 22 - .../test/index.test.ts | 134 +- .../test/injector/all-props-ignored/input.tsx | 2 +- .../injector/all-props-ignored/options.ts | 10 +- .../test/injector/all-props-ignored/output.js | 2 +- .../injector/all-props-ignored/output.json | 12 - .../should-include-component-based/input.tsx | 20 +- .../should-include-component-based/options.ts | 14 +- .../should-include-component-based/output.js | 12 +- .../output.json | 43 - .../should-include-filename-based/input.tsx | 12 +- .../should-include-filename-based/options.ts | 24 +- .../should-include-filename-based/output.js | 14 +- .../should-include-filename-based/output.json | 2566 ----------------- .../test/injector/string-props/input.tsx | 4 +- .../test/injector/string-props/output.js | 6 +- .../test/injector/string-props/output.json | 12 - .../test/injector/whitelisted-props/input.tsx | 2 +- .../injector/whitelisted-props/options.ts | 10 +- .../test/injector/whitelisted-props/output.js | 4 +- .../injector/whitelisted-props/output.json | 12 - .../test/mixed-literals/input.tsx | 6 +- .../test/mixed-literals/output.js | 6 +- .../test/mixed-literals/output.json | 29 - .../test/options-test/input.tsx | 16 +- .../test/options-test/options.ts | 22 +- .../test/options-test/output.js | 10 +- .../test/options-test/output.json | 18 - .../overloaded-function-component/input.d.ts | 6 +- .../overloaded-function-component/options.ts | 6 +- .../overloaded-function-component/output.js | 6 +- .../overloaded-function-component/output.json | 41 - .../test/reconcile-prop-types/input.d.ts | 2 +- .../test/reconcile-prop-types/input.js | 32 +- .../test/reconcile-prop-types/options.ts | 20 +- .../test/reconcile-prop-types/output.js | 32 +- .../test/reconcile-prop-types/output.json | 19 - .../typescript-to-proptypes/test/testSetup.js | 1 + .../test/type-unknown/input.tsx | 4 +- .../test/type-unknown/output.js | 8 +- .../test/type-unknown/output.json | 20 - .../typescript-to-proptypes/test/types.d.ts | 6 +- .../test/union-props/input.d.ts | 8 +- .../test/union-props/input.js | 12 +- .../test/union-props/output.js | 16 +- .../test/union-props/output.json | 34 - .../test/unused-prop/input.tsx | 18 +- .../test/unused-prop/output.js | 16 +- .../test/unused-prop/output.json | 14 - .../typescript-to-proptypes/tsconfig.json | 31 +- tsconfig.json | 3 +- yarn.lock | 114 +- 94 files changed, 1729 insertions(+), 4688 deletions(-) create mode 100644 packages/typescript-to-proptypes/.mocharc.js delete mode 100644 packages/typescript-to-proptypes/jest.config.js delete mode 100644 packages/typescript-to-proptypes/test/boolean-values/optional/output.json delete mode 100644 packages/typescript-to-proptypes/test/boolean-values/required/output.json delete mode 100644 packages/typescript-to-proptypes/test/code-order/output.json delete mode 100644 packages/typescript-to-proptypes/test/generator/html-elements/output.json delete mode 100644 packages/typescript-to-proptypes/test/injector/all-props-ignored/output.json delete mode 100644 packages/typescript-to-proptypes/test/injector/should-include-component-based/output.json delete mode 100644 packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.json delete mode 100644 packages/typescript-to-proptypes/test/injector/string-props/output.json delete mode 100644 packages/typescript-to-proptypes/test/injector/whitelisted-props/output.json delete mode 100644 packages/typescript-to-proptypes/test/mixed-literals/output.json delete mode 100644 packages/typescript-to-proptypes/test/options-test/output.json delete mode 100644 packages/typescript-to-proptypes/test/overloaded-function-component/output.json delete mode 100644 packages/typescript-to-proptypes/test/reconcile-prop-types/output.json create mode 100644 packages/typescript-to-proptypes/test/testSetup.js delete mode 100644 packages/typescript-to-proptypes/test/type-unknown/output.json delete mode 100644 packages/typescript-to-proptypes/test/union-props/output.json delete mode 100644 packages/typescript-to-proptypes/test/unused-prop/output.json diff --git a/.circleci/config.yml b/.circleci/config.yml index bab9855e789cf4..538b2cdee9e8ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -98,6 +98,21 @@ jobs: else echo "no changes" fi + - run: + name: typescript-to-proptypes + command: | + # latest commit + LATEST_COMMIT=$(git rev-parse HEAD) + + # latest commit where packages/typescript-to-proptypes was changed + FOLDER_COMMIT=$(git log -1 --format=format:%H --full-diff packages/typescript-to-proptypes) + + if [ $FOLDER_COMMIT = $LATEST_COMMIT ]; then + echo "changes, let's run the tests" + yarn workspace typescript-to-proptypes test + else + echo "no changes" + fi - run: name: Coverage command: bash <(curl -s https://codecov.io/bash) -Z -C $CIRCLE_SHA1 diff --git a/.eslintignore b/.eslintignore index 62c2a85ac7f86a..7f162a87aead56 100644 --- a/.eslintignore +++ b/.eslintignore @@ -14,6 +14,8 @@ /packages/material-ui-icons/src /packages/material-ui-icons/legacy /packages/material-ui-icons/templateSvgIcon.js +# Ignore fixtures +/packages/typescript-to-proptypes/test/**/*.js /tmp build node_modules diff --git a/package.json b/package.json index 54d2b0b9733bc7..e1669b178bc35b 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,6 @@ "ts-node": "^8.3.0", "tslint": "5.14.0", "typescript": "^3.8.2", - "typescript-to-proptypes": "^2.0.1", "unist-util-visit": "^2.0.2", "vrtest-mui": "^0.3.3", "webpack": "^4.41.0", diff --git a/packages/typescript-to-proptypes/.mocharc.js b/packages/typescript-to-proptypes/.mocharc.js new file mode 100644 index 00000000000000..a5a315bba3984b --- /dev/null +++ b/packages/typescript-to-proptypes/.mocharc.js @@ -0,0 +1,3 @@ +module.exports = { + require: [require.resolve('./test/testSetup')], +}; diff --git a/packages/typescript-to-proptypes/README.md b/packages/typescript-to-proptypes/README.md index cf5feae83057c3..551e8a0069463e 100644 --- a/packages/typescript-to-proptypes/README.md +++ b/packages/typescript-to-proptypes/README.md @@ -2,14 +2,6 @@ An API for converting [TypeScript](https://www.npmjs.com/package/typescript) definitions to [PropTypes](https://www.npmjs.com/package/prop-types) using the TypeScript Compiler API -## Install - -``` -yarn add typescript-to-proptypes --dev -or -npm install typescript-to-proptypes --save-dev -``` - ## Support | Component type | | diff --git a/packages/typescript-to-proptypes/jest.config.js b/packages/typescript-to-proptypes/jest.config.js deleted file mode 100644 index aa9cb9208f2179..00000000000000 --- a/packages/typescript-to-proptypes/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -const { defaults } = require('ts-jest/presets'); -const path = require('path'); - -module.exports = { - testEnvironment: 'node', - transform: defaults.transform, - testRegex: `test/index.test.ts$`, - globals: { - 'ts-jest': { - packageJson: path.join(__dirname, 'package.json'), - }, - }, -}; diff --git a/packages/typescript-to-proptypes/package.json b/packages/typescript-to-proptypes/package.json index 80da3657e1942f..c10dee1409d5a8 100644 --- a/packages/typescript-to-proptypes/package.json +++ b/packages/typescript-to-proptypes/package.json @@ -1,56 +1,54 @@ { - "name": "typescript-to-proptypes", - "version": "2.0.1", - "description": "Generate proptypes from typescript declarations", - "main": "dist/index.js", - "engines": { - "node": ">=10.3.0" - }, - "files": [ - "dist" - ], - "repository": { - "type": "git", - "url": "https://github.com/merceyz/typescript-to-proptypes.git" - }, - "author": "merceyz ", - "license": "MIT", - "keywords": [ - "proptypes", - "typescript", - "react" - ], - "scripts": { - "test": "jest", - "build": "rm -rf dist && tsc", - "release": "run build && standard-version", - "prepack": "run build" - }, - "devDependencies": { - "@types/babel__core": "^7.1.2", - "@types/doctrine": "^0.0.3", - "@types/glob": "^7.1.1", - "@types/jest": "^24.0.15", - "@types/lodash": "^4.14.136", - "@types/node": "^12.6.2", - "@types/prettier": "^1.19.1", - "@types/react": "^16.8.23", - "@types/uuid": "^8.0.0", - "glob": "^7.1.6", - "jest": "^26.0.1", - "react": "^16.8.6", - "standard-version": "^8.0.0", - "ts-jest": "^26.1.0" - }, - "dependencies": { - "@babel/core": "^7.5.4", - "@babel/plugin-syntax-class-properties": "^7.2.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@babel/types": "^7.5.0", - "doctrine": "^3.0.0", - "lodash": "^4.17.14", - "tslib": "^1.13.0", - "typescript": "3.5.2", - "uuid": "^8.1.0" - } + "name": "typescript-to-proptypes", + "version": "2.0.1", + "private": true, + "description": "Generate proptypes from typescript declarations", + "main": "build/index.js", + "engines": { + "node": ">=10.3.0" + }, + "files": [ + "build" + ], + "repository": { + "type": "git", + "url": "https://github.com/mui-org/material-ui.git", + "directory": "packages/typescript-to-proptypes" + }, + "author": "merceyz ", + "license": "MIT", + "keywords": [ + "proptypes", + "typescript", + "react" + ], + "scripts": { + "build": "rimraf build && tsc", + "postinstall": "yarn build", + "test": "cd ../../ && cross-env NODE_ENV=test mocha --config packages/typescript-to-proptypes/.mocharc.js 'packages/typescript-to-proptypes/**/*.test.ts' --exclude '**/node_modules/**'" + }, + "devDependencies": { + "@types/babel__core": "^7.1.2", + "@types/doctrine": "^0.0.3", + "@types/glob": "^7.1.1", + "@types/lodash": "^4.14.136", + "@types/node": "^12.6.2", + "@types/prettier": "^2.0.1", + "@types/react": "^16.8.23", + "@types/uuid": "^8.0.0", + "glob": "^7.1.6", + "prettier": "^2.0.5", + "react": "^16.8.6", + "rimraf": "^3.0.2" + }, + "dependencies": { + "@babel/core": "^7.5.4", + "@babel/plugin-syntax-class-properties": "^7.2.0", + "@babel/plugin-syntax-jsx": "^7.2.0", + "@babel/types": "^7.5.0", + "doctrine": "^3.0.0", + "lodash": "^4.17.14", + "typescript": "3.5.2", + "uuid": "^8.1.0" + } } diff --git a/packages/typescript-to-proptypes/src/config.ts b/packages/typescript-to-proptypes/src/config.ts index cb162dd7337a72..765af3e54de336 100644 --- a/packages/typescript-to-proptypes/src/config.ts +++ b/packages/typescript-to-proptypes/src/config.ts @@ -7,19 +7,19 @@ import path from 'path'; * @param tsConfigPath The location for a `tsconfig.json` file */ export function loadConfig(tsConfigPath: string) { - const { config, error } = ts.readConfigFile(tsConfigPath, (filePath) => - fs.readFileSync(filePath).toString() - ); + const { config, error } = ts.readConfigFile(tsConfigPath, (filePath) => + fs.readFileSync(filePath).toString(), + ); - if (error) throw error; + if (error) throw error; - const { options, errors } = ts.parseJsonConfigFileContent( - config, - ts.sys, - path.dirname(tsConfigPath) - ); + const { options, errors } = ts.parseJsonConfigFileContent( + config, + ts.sys, + path.dirname(tsConfigPath), + ); - if (errors.length > 0) throw errors[0]; + if (errors.length > 0) throw errors[0]; - return options; + return options; } diff --git a/packages/typescript-to-proptypes/src/generator.ts b/packages/typescript-to-proptypes/src/generator.ts index 1bcca65336ab66..b8a1de26ab479f 100644 --- a/packages/typescript-to-proptypes/src/generator.ts +++ b/packages/typescript-to-proptypes/src/generator.ts @@ -2,55 +2,55 @@ import * as t from './types'; import _ from 'lodash'; export interface GenerateOptions { - /** - * Enable/disable the default sorting (ascending) or provide your own sort function - * @default true - */ - sortProptypes?: boolean | ((a: t.PropTypeNode, b: t.PropTypeNode) => 0 | -1 | 1); - - /** - * The name used when importing prop-types - * @default 'PropTypes' - */ - importedName?: string; - - /** - * Enable/disable including JSDoc comments - * @default true - */ - includeJSDoc?: boolean; - - /** - * Previous source code of the validator for each prop type - */ - previousPropTypesSource?: Map; - - /** - * Given the `prop`, the `previous` source of the validator and the `generated` source: - * What source should be injected? `previous` is `undefined` if the validator - * didn't exist before - * @default Uses `generated` source - */ - reconcilePropTypes?( - proptype: t.PropTypeNode, - previous: string | undefined, - generated: string - ): string; - - /** - * Control which PropTypes are included in the final result - * @param proptype The current PropType about to be converted to text - */ - shouldInclude?(proptype: t.PropTypeNode): boolean | undefined; - - /** - * A comment that will be added to the start of the PropTypes code block - * @example - * foo.propTypes = { - * // Comment goes here - * } - */ - comment?: string; + /** + * Enable/disable the default sorting (ascending) or provide your own sort function + * @default true + */ + sortProptypes?: boolean | ((a: t.PropTypeNode, b: t.PropTypeNode) => 0 | -1 | 1); + + /** + * The name used when importing prop-types + * @default 'PropTypes' + */ + importedName?: string; + + /** + * Enable/disable including JSDoc comments + * @default true + */ + includeJSDoc?: boolean; + + /** + * Previous source code of the validator for each prop type + */ + previousPropTypesSource?: Map; + + /** + * Given the `prop`, the `previous` source of the validator and the `generated` source: + * What source should be injected? `previous` is `undefined` if the validator + * didn't exist before + * @default Uses `generated` source + */ + reconcilePropTypes?( + proptype: t.PropTypeNode, + previous: string | undefined, + generated: string, + ): string; + + /** + * Control which PropTypes are included in the final result + * @param proptype The current PropType about to be converted to text + */ + shouldInclude?(proptype: t.PropTypeNode): boolean | undefined; + + /** + * A comment that will be added to the start of the PropTypes code block + * @example + * foo.propTypes = { + * // Comment goes here + * } + */ + comment?: string; } /** @@ -59,217 +59,217 @@ export interface GenerateOptions { * @param options The options used to control the way the code gets generated */ export function generate(node: t.Node | t.PropTypeNode[], options: GenerateOptions = {}): string { - const { - sortProptypes = true, - importedName = 'PropTypes', - includeJSDoc = true, - previousPropTypesSource = new Map(), - reconcilePropTypes = (_prop: t.PropTypeNode, _previous: string, generated: string) => generated, - shouldInclude, - } = options; - - function jsDoc(node: t.PropTypeNode | t.LiteralNode) { - if (!includeJSDoc || !node.jsDoc) { - return ''; - } - return `/**\n* ${node.jsDoc.split(/\r?\n/).reduce((prev, curr) => prev + '\n* ' + curr)}\n*/\n`; - } - - if (Array.isArray(node)) { - let propTypes = node; - - if (typeof sortProptypes === 'function') { - propTypes = propTypes.sort(sortProptypes); - } else if (sortProptypes === true) { - propTypes = propTypes.sort((a, b) => a.name.localeCompare(b.name)); - } - - let filteredNodes = node; - if (shouldInclude) { - filteredNodes = filteredNodes.filter((x) => shouldInclude(x)); - } - - if (filteredNodes.length === 0) { - return ''; - } - - return filteredNodes - .map((prop) => generate(prop, options)) - .reduce((prev, curr) => `${prev}\n${curr}`); - } - - if (t.isProgramNode(node)) { - return node.body - .map((prop) => generate(prop, options)) - .reduce((prev, curr) => `${prev}\n${curr}`); - } - - if (t.isComponentNode(node)) { - const generated = generate(node.types, options); - if (generated.length === 0) { - return ''; - } - - const comment = - options.comment && - `// ${options.comment.split(/\r?\n/gm).reduce((prev, curr) => `${prev}\n// ${curr}`)}\n`; - - return `${node.name}.propTypes = {\n${comment ? comment : ''}${generated}\n}`; - } - - if (t.isPropTypeNode(node)) { - let isOptional = false; - let propType = { ...node.propType }; - - if (t.isUnionNode(propType) && propType.types.some(t.isUndefinedNode)) { - isOptional = true; - propType.types = propType.types.filter( - (prop) => !t.isUndefinedNode(prop) && !(t.isLiteralNode(prop) && prop.value === 'null') - ); - if (propType.types.length === 1 && t.isLiteralNode(propType.types[0]) === false) { - propType = propType.types[0]; - } - } - - if (t.isDOMElementNode(propType)) { - propType.optional = isOptional; - // Handled internally in the validate function - isOptional = true; - } - - const validatorSource = reconcilePropTypes( - node, - previousPropTypesSource.get(node.name), - `${generate(propType, options)}${isOptional ? '' : '.isRequired'}` - ); - - return `${jsDoc(node)}"${node.name}": ${validatorSource},`; - } - - if (t.isInterfaceNode(node)) { - return `${importedName}.shape({\n${generate(node.types, { - ...options, - shouldInclude: undefined, - })}\n})`; - } - - if (t.isFunctionNode(node)) { - return `${importedName}.func`; - } - - if (t.isStringNode(node)) { - return `${importedName}.string`; - } - - if (t.isBooleanNode(node)) { - return `${importedName}.bool`; - } - - if (t.isNumericNode(node)) { - return `${importedName}.number`; - } - - if (t.isLiteralNode(node)) { - return `${importedName}.oneOf([${jsDoc(node)}${node.value}])`; - } - - if (t.isObjectNode(node)) { - return `${importedName}.object`; - } - - if (t.isAnyNode(node)) { - return `${importedName}.any`; - } - - if (t.isElementNode(node)) { - return `${importedName}.${node.elementType}`; - } - - if (t.isInstanceOfNode(node)) { - return `${importedName}.instanceOf(${node.instance})`; - } - - if (t.isDOMElementNode(node)) { - return `function (props, propName) { + const { + sortProptypes = true, + importedName = 'PropTypes', + includeJSDoc = true, + previousPropTypesSource = new Map(), + reconcilePropTypes = (_prop: t.PropTypeNode, _previous: string, generated: string) => generated, + shouldInclude, + } = options; + + function jsDoc(node: t.PropTypeNode | t.LiteralNode) { + if (!includeJSDoc || !node.jsDoc) { + return ''; + } + return `/**\n* ${node.jsDoc.split(/\r?\n/).reduce((prev, curr) => `${prev}\n* ${curr}`)}\n*/\n`; + } + + if (Array.isArray(node)) { + let propTypes = node; + + if (typeof sortProptypes === 'function') { + propTypes = propTypes.sort(sortProptypes); + } else if (sortProptypes === true) { + propTypes = propTypes.sort((a, b) => a.name.localeCompare(b.name)); + } + + let filteredNodes = node; + if (shouldInclude) { + filteredNodes = filteredNodes.filter((x) => shouldInclude(x)); + } + + if (filteredNodes.length === 0) { + return ''; + } + + return filteredNodes + .map((prop) => generate(prop, options)) + .reduce((prev, curr) => `${prev}\n${curr}`); + } + + if (t.isProgramNode(node)) { + return node.body + .map((prop) => generate(prop, options)) + .reduce((prev, curr) => `${prev}\n${curr}`); + } + + if (t.isComponentNode(node)) { + const generated = generate(node.types, options); + if (generated.length === 0) { + return ''; + } + + const comment = + options.comment && + `// ${options.comment.split(/\r?\n/gm).reduce((prev, curr) => `${prev}\n// ${curr}`)}\n`; + + return `${node.name}.propTypes = {\n${comment ? comment : ''}${generated}\n}`; + } + + if (t.isPropTypeNode(node)) { + let isOptional = false; + let propType = { ...node.propType }; + + if (t.isUnionNode(propType) && propType.types.some(t.isUndefinedNode)) { + isOptional = true; + propType.types = propType.types.filter( + (prop) => !t.isUndefinedNode(prop) && !(t.isLiteralNode(prop) && prop.value === 'null'), + ); + if (propType.types.length === 1 && t.isLiteralNode(propType.types[0]) === false) { + propType = propType.types[0]; + } + } + + if (t.isDOMElementNode(propType)) { + propType.optional = isOptional; + // Handled internally in the validate function + isOptional = true; + } + + const validatorSource = reconcilePropTypes( + node, + previousPropTypesSource.get(node.name), + `${generate(propType, options)}${isOptional ? '' : '.isRequired'}`, + ); + + return `${jsDoc(node)}"${node.name}": ${validatorSource},`; + } + + if (t.isInterfaceNode(node)) { + return `${importedName}.shape({\n${generate(node.types, { + ...options, + shouldInclude: undefined, + })}\n})`; + } + + if (t.isFunctionNode(node)) { + return `${importedName}.func`; + } + + if (t.isStringNode(node)) { + return `${importedName}.string`; + } + + if (t.isBooleanNode(node)) { + return `${importedName}.bool`; + } + + if (t.isNumericNode(node)) { + return `${importedName}.number`; + } + + if (t.isLiteralNode(node)) { + return `${importedName}.oneOf([${jsDoc(node)}${node.value}])`; + } + + if (t.isObjectNode(node)) { + return `${importedName}.object`; + } + + if (t.isAnyNode(node)) { + return `${importedName}.any`; + } + + if (t.isElementNode(node)) { + return `${importedName}.${node.elementType}`; + } + + if (t.isInstanceOfNode(node)) { + return `${importedName}.instanceOf(${node.instance})`; + } + + if (t.isDOMElementNode(node)) { + return `function (props, propName) { if (props[propName] == null) { return ${ - node.optional - ? 'null' - : `new Error("Prop '" + propName + "' is required but wasn't specified")` - } + node.optional + ? 'null' + : `new Error("Prop '" + propName + "' is required but wasn't specified")` + } } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { return new Error("Expected prop '" + propName + "' to be of type Element") - } - }`; - } - - if (t.isArrayNode(node)) { - if (t.isAnyNode(node.arrayType)) { - return `${importedName}.array`; - } - - return `${importedName}.arrayOf(${generate(node.arrayType, options)})`; - } - - if (t.isUnionNode(node)) { - let [literals, rest] = _.partition(t.uniqueUnionTypes(node).types, t.isLiteralNode); - - literals = literals.sort((a, b) => { - const { value: valueA } = a; - const { value: valueB } = b; - // numbers ascending - if (typeof valueA === 'number' && typeof valueB === 'number') { - return valueA - valueB; - } - // numbers last - if (typeof valueA === 'number') { - return 1; - } - if (typeof valueB === 'number') { - return -1; - } - // sort anything else by their stringified value - return String(valueA).localeCompare(String(valueB)); - }); - - const nodeToStringName = (obj: t.Node): string => { - if (t.isInstanceOfNode(obj)) { - return `${obj.type}.${obj.instance}`; - } else if (t.isInterfaceNode(obj)) { - // An interface is PropTypes.shape - // Use `ShapeNode` to get it sorted in the correct order - return `ShapeNode`; } - - return obj.type; - }; - - rest = rest.sort((a, b) => nodeToStringName(a).localeCompare(nodeToStringName(b))); - - if (literals.find((x) => x.value === 'true') && literals.find((x) => x.value === 'false')) { - rest.push(t.booleanNode()); - literals = literals.filter((x) => x.value !== 'true' && x.value !== 'false'); - } - - const literalProps = - literals.length !== 0 - ? `${importedName}.oneOf([${literals - .map((x) => `${jsDoc(x)}${x.value}`) - .reduce((prev, curr) => `${prev},${curr}`)}])` - : ''; - - if (rest.length === 0) { - return literalProps; - } - - if (literals.length === 0 && rest.length === 1) { - return generate(rest[0], options); - } - - return `${importedName}.oneOfType([${literalProps ? literalProps + ', ' : ''}${rest - .map((x) => generate(x, options)) - .reduce((prev, curr) => `${prev},${curr}`)}])`; - } - - throw new Error(`Nothing to handle node of type "${node.type}"`); + }`; + } + + if (t.isArrayNode(node)) { + if (t.isAnyNode(node.arrayType)) { + return `${importedName}.array`; + } + + return `${importedName}.arrayOf(${generate(node.arrayType, options)})`; + } + + if (t.isUnionNode(node)) { + let [literals, rest] = _.partition(t.uniqueUnionTypes(node).types, t.isLiteralNode); + + literals = literals.sort((a, b) => { + const { value: valueA } = a; + const { value: valueB } = b; + // numbers ascending + if (typeof valueA === 'number' && typeof valueB === 'number') { + return valueA - valueB; + } + // numbers last + if (typeof valueA === 'number') { + return 1; + } + if (typeof valueB === 'number') { + return -1; + } + // sort anything else by their stringified value + return String(valueA).localeCompare(String(valueB)); + }); + + const nodeToStringName = (obj: t.Node): string => { + if (t.isInstanceOfNode(obj)) { + return `${obj.type}.${obj.instance}`; + } else if (t.isInterfaceNode(obj)) { + // An interface is PropTypes.shape + // Use `ShapeNode` to get it sorted in the correct order + return `ShapeNode`; + } + + return obj.type; + }; + + rest = rest.sort((a, b) => nodeToStringName(a).localeCompare(nodeToStringName(b))); + + if (literals.find((x) => x.value === 'true') && literals.find((x) => x.value === 'false')) { + rest.push(t.booleanNode()); + literals = literals.filter((x) => x.value !== 'true' && x.value !== 'false'); + } + + const literalProps = + literals.length !== 0 + ? `${importedName}.oneOf([${literals + .map((x) => `${jsDoc(x)}${x.value}`) + .reduce((prev, curr) => `${prev},${curr}`)}])` + : ''; + + if (rest.length === 0) { + return literalProps; + } + + if (literals.length === 0 && rest.length === 1) { + return generate(rest[0], options); + } + + return `${importedName}.oneOfType([${literalProps ? literalProps + ', ' : ''}${rest + .map((x) => generate(x, options)) + .reduce((prev, curr) => `${prev},${curr}`)}])`; + } + + throw new Error(`Nothing to handle node of type "${node.type}"`); } diff --git a/packages/typescript-to-proptypes/src/injector.ts b/packages/typescript-to-proptypes/src/injector.ts index b80b75a9cbecea..51a1bde5032af0 100644 --- a/packages/typescript-to-proptypes/src/injector.ts +++ b/packages/typescript-to-proptypes/src/injector.ts @@ -5,32 +5,32 @@ import { generate, GenerateOptions } from './generator'; import { v4 as uuid } from 'uuid'; export type InjectOptions = { - /** - * By default all unused props are omitted from the result. - * Set this to true to include them instead. - */ - includeUnusedProps?: boolean; - /** - * By default existing PropTypes are left alone, set this to true - * to have them removed before injecting the PropTypes - */ - removeExistingPropTypes?: boolean; - /** - * Used to control which props are includes in the result - * @return true to include the prop, false to skip it, or undefined to - * use the default behaviour - * @default includeUnusedProps ? true : data.usedProps.includes(data.prop.name) - */ - shouldInclude?(data: { - component: t.ComponentNode; - prop: t.PropTypeNode; - usedProps: string[]; - }): boolean | undefined; - - /** - * Options passed to babel.transformSync - */ - babelOptions?: babel.TransformOptions; + /** + * By default all unused props are omitted from the result. + * Set this to true to include them instead. + */ + includeUnusedProps?: boolean; + /** + * By default existing PropTypes are left alone, set this to true + * to have them removed before injecting the PropTypes + */ + removeExistingPropTypes?: boolean; + /** + * Used to control which props are includes in the result + * @return true to include the prop, false to skip it, or undefined to + * use the default behaviour + * @default includeUnusedProps ? true : data.usedProps.includes(data.prop.name) + */ + shouldInclude?(data: { + component: t.ComponentNode; + prop: t.PropTypeNode; + usedProps: string[]; + }): boolean | undefined; + + /** + * Options passed to babel.transformSync + */ + babelOptions?: babel.TransformOptions; } & Pick; /** @@ -40,281 +40,280 @@ export type InjectOptions = { * @param options Options controlling the final result */ export function inject( - propTypes: t.ProgramNode, - target: string, - options: InjectOptions = {} + propTypes: t.ProgramNode, + target: string, + options: InjectOptions = {}, ): string | null { - if (propTypes.body.length === 0) { - return target; - } - - const propTypesToInject = new Map(); - - const { plugins: babelPlugins = [], ...babelOptions } = options.babelOptions || {}; - - const result = babel.transformSync(target, { - plugins: [ - require.resolve('@babel/plugin-syntax-class-properties'), - require.resolve('@babel/plugin-syntax-jsx'), - plugin(propTypes, options, propTypesToInject), - ...(babelPlugins || []), - ], - configFile: false, - babelrc: false, - retainLines: true, - ...babelOptions, - }); - - let code = result && result.code; - if (!code) { - return null; - } - - // Replace the placeholders with the generated prop-types - // Workaround for issues with comments getting removed and malformed - propTypesToInject.forEach((value, key) => { - code = code!.replace(key, `\n\n${value}\n\n`); - }); - - return code; + if (propTypes.body.length === 0) { + return target; + } + + const propTypesToInject = new Map(); + + const { plugins: babelPlugins = [], ...babelOptions } = options.babelOptions || {}; + + const result = babel.transformSync(target, { + plugins: [ + require.resolve('@babel/plugin-syntax-class-properties'), + require.resolve('@babel/plugin-syntax-jsx'), + plugin(propTypes, options, propTypesToInject), + ...(babelPlugins || []), + ], + configFile: false, + babelrc: false, + retainLines: true, + ...babelOptions, + }); + + let code = result && result.code; + if (!code) { + return null; + } + + // Replace the placeholders with the generated prop-types + // Workaround for issues with comments getting removed and malformed + propTypesToInject.forEach((value, key) => { + code = code!.replace(key, `\n\n${value}\n\n`); + }); + + return code; } function plugin( - propTypes: t.ProgramNode, - options: InjectOptions = {}, - mapOfPropTypes: Map + propTypes: t.ProgramNode, + options: InjectOptions = {}, + mapOfPropTypes: Map, ): babel.PluginObj { - const { - includeUnusedProps = false, - reconcilePropTypes = ( - _prop: t.PropTypeNode, - _previous: string | undefined, - generated: string - ) => generated, - removeExistingPropTypes = false, - ...otherOptions - } = options; - const shouldInclude: Exclude = (data) => { - if (options.shouldInclude) { - const result = options.shouldInclude(data); - if (result !== undefined) { - return result; - } - } - - return includeUnusedProps ? true : data.usedProps.includes(data.prop.name); - }; - - let importName = ''; - let needImport = false; - let alreadyImported = false; - let originalPropTypesPath: null | babel.NodePath = null; - let previousPropTypesSource = new Map(); - - return { - visitor: { - Program: { - enter(path, state: any) { - if ( - !path.node.body.some((n) => { - if ( - babelTypes.isImportDeclaration(n) && - n.source.value === 'prop-types' && - n.specifiers.length - ) { - importName = n.specifiers[0].local.name; - alreadyImported = true; - return true; - } - }) - ) { - importName = 'PropTypes'; - } - - path.get('body').forEach((nodePath) => { - const { node } = nodePath; - if ( - babelTypes.isExpressionStatement(node) && - babelTypes.isAssignmentExpression(node.expression, { operator: '=' }) && - babelTypes.isMemberExpression(node.expression.left) && - babelTypes.isIdentifier(node.expression.left.property, { name: 'propTypes' }) - ) { - originalPropTypesPath = nodePath; - - if (babelTypes.isObjectExpression(node.expression.right)) { - const { code } = state.file; - - node.expression.right.properties.forEach((property) => { - if (babelTypes.isObjectProperty(property)) { - const validatorSource = code.slice(property.value.start, property.value.end); - previousPropTypesSource.set(property.key.name, validatorSource); - } - }); - } - } - }); - }, - exit(path) { - if (alreadyImported || !needImport) return; - - const propTypesImport = babel.template.ast( - `import ${importName} from 'prop-types'` - ) as babel.types.ImportDeclaration; - - const firstImport = path - .get('body') - .find((nodePath) => babelTypes.isImportDeclaration(nodePath.node)); - - // Insert import after the first one to avoid issues with comment flags - if (firstImport) { - firstImport.insertAfter(propTypesImport); - } else { - path.node.body = [propTypesImport, ...path.node.body]; - } - }, - }, - FunctionDeclaration(path) { - const { node } = path; - - // Prevent visiting again - if ((node as any).hasBeenVisited) { - path.skip(); - return; - } - - if (!node.id) return; - const props = propTypes.body.find((prop) => prop.name === node.id!.name); - if (!props) return; - - // Prevent visiting again - (node as any).hasBeenVisited = true; - path.skip(); - - const prop = node.params[0]; - injectPropTypes({ - nodeName: node.id.name, - usedProps: - babelTypes.isIdentifier(prop) || babelTypes.isObjectPattern(prop) - ? getUsedProps(path, prop) - : [], - path, - props, - }); - }, - VariableDeclarator(path) { - const { node } = path; - - // Prevent visiting again - if ((node as any).hasBeenVisited) { - path.skip(); - return; - } - - if (!babelTypes.isIdentifier(node.id)) return; - const nodeName = node.id.name; - - const props = propTypes.body.find((prop) => prop.name === nodeName); - if (!props) return; - - if ( - babelTypes.isArrowFunctionExpression(node.init) || - babelTypes.isFunctionExpression(node.init) - ) { - getFromProp(node.init.params[0]); - } - // x = react.memo(props =>
) - else if (babelTypes.isCallExpression(node.init)) { - const arg = node.init.arguments[0]; - if (babelTypes.isArrowFunctionExpression(arg) || babelTypes.isFunctionExpression(arg)) { - getFromProp(arg.params[0]); - } - } - - function getFromProp(prop: babelTypes.Node) { - // Prevent visiting again - (node as any).hasBeenVisited = true; - path.skip(); - - injectPropTypes({ - path: path.parentPath, - usedProps: - babelTypes.isIdentifier(prop) || babelTypes.isObjectPattern(prop) - ? getUsedProps(path, prop) - : [], - props: props!, - nodeName, - }); - } - }, - ClassDeclaration(path) { - const { node } = path; - - // Prevent visiting again - if ((node as any).hasBeenVisited) { - path.skip(); - return; - } - - if (!babelTypes.isIdentifier(node.id)) return; - const nodeName = node.id.name; - - const props = propTypes.body.find((prop) => prop.name === nodeName); - if (!props) return; - - // Prevent visiting again - (node as any).hasBeenVisited = true; - path.skip(); - - injectPropTypes({ - nodeName, - usedProps: getUsedProps(path, undefined), - path, - props, - }); - }, - }, - }; - - function injectPropTypes(options: { - path: babel.NodePath; - usedProps: string[]; - props: t.ComponentNode; - nodeName: string; - }) { - const { path, props, usedProps, nodeName } = options; - - const source = generate(props, { - ...otherOptions, - importedName: importName, - previousPropTypesSource, - reconcilePropTypes, - shouldInclude: (prop) => shouldInclude({ component: props, prop, usedProps }), - }); - - if (source.length === 0) { - return; - } - - needImport = true; - - const placeholder = `const a${uuid().replace(/\-/g, '_')} = null;`; - - mapOfPropTypes.set(placeholder, source); - - if (removeExistingPropTypes && originalPropTypesPath !== null) { - originalPropTypesPath.replaceWith(babel.template.ast(placeholder) as babelTypes.Statement); - } else if (babelTypes.isExportNamedDeclaration(path.parent)) { - path.insertAfter(babel.template.ast(`export { ${nodeName} };`)); - path.insertAfter(babel.template.ast(placeholder)); - path.parentPath.replaceWith(path.node); - } else if (babelTypes.isExportDefaultDeclaration(path.parent)) { - path.insertAfter(babel.template.ast(`export default ${nodeName};`)); - path.insertAfter(babel.template.ast(placeholder)); - path.parentPath.replaceWith(path.node); - } else { - path.insertAfter(babel.template.ast(placeholder)); - } - } + const { + includeUnusedProps = false, + reconcilePropTypes = ( + _prop: t.PropTypeNode, + _previous: string | undefined, + generated: string, + ) => generated, + removeExistingPropTypes = false, + ...otherOptions + } = options; + const shouldInclude: Exclude = (data) => { + if (options.shouldInclude) { + const result = options.shouldInclude(data); + if (result !== undefined) { + return result; + } + } + + return includeUnusedProps ? true : data.usedProps.includes(data.prop.name); + }; + + let importName = ''; + let needImport = false; + let alreadyImported = false; + let originalPropTypesPath: null | babel.NodePath = null; + const previousPropTypesSource = new Map(); + + return { + visitor: { + Program: { + enter(path, state: any) { + if ( + !path.node.body.some((n) => { + if ( + babelTypes.isImportDeclaration(n) && + n.source.value === 'prop-types' && + n.specifiers.length + ) { + importName = n.specifiers[0].local.name; + alreadyImported = true; + return true; + } + }) + ) { + importName = 'PropTypes'; + } + + path.get('body').forEach((nodePath) => { + const { node } = nodePath; + if ( + babelTypes.isExpressionStatement(node) && + babelTypes.isAssignmentExpression(node.expression, { operator: '=' }) && + babelTypes.isMemberExpression(node.expression.left) && + babelTypes.isIdentifier(node.expression.left.property, { name: 'propTypes' }) + ) { + originalPropTypesPath = nodePath as babel.NodePath; + + if (babelTypes.isObjectExpression(node.expression.right)) { + const { code } = state.file; + + node.expression.right.properties.forEach((property) => { + if (babelTypes.isObjectProperty(property)) { + const validatorSource = code.slice(property.value.start, property.value.end); + previousPropTypesSource.set(property.key.name, validatorSource); + } + }); + } + } + }); + }, + exit(path) { + if (alreadyImported || !needImport) return; + + const propTypesImport = babel.template.ast( + `import ${importName} from 'prop-types'`, + ) as babel.types.ImportDeclaration; + + const firstImport = path + .get('body') + .find((nodePath) => babelTypes.isImportDeclaration(nodePath.node)); + + // Insert import after the first one to avoid issues with comment flags + if (firstImport) { + firstImport.insertAfter(propTypesImport); + } else { + path.node.body = [propTypesImport, ...path.node.body]; + } + }, + }, + FunctionDeclaration(path) { + const { node } = path; + + // Prevent visiting again + if ((node as any).hasBeenVisited) { + path.skip(); + return; + } + + if (!node.id) return; + const props = propTypes.body.find((prop) => prop.name === node.id!.name); + if (!props) return; + + // Prevent visiting again + (node as any).hasBeenVisited = true; + path.skip(); + + const prop = node.params[0]; + injectPropTypes({ + nodeName: node.id.name, + usedProps: + babelTypes.isIdentifier(prop) || babelTypes.isObjectPattern(prop) + ? getUsedProps(path as babel.NodePath, prop) + : [], + path: path as babel.NodePath, + props, + }); + }, + VariableDeclarator(path) { + const { node } = path; + + // Prevent visiting again + if ((node as any).hasBeenVisited) { + path.skip(); + return; + } + + if (!babelTypes.isIdentifier(node.id)) return; + const nodeName = node.id.name; + + const props = propTypes.body.find((prop) => prop.name === nodeName); + if (!props) return; + + if ( + babelTypes.isArrowFunctionExpression(node.init) || + babelTypes.isFunctionExpression(node.init) + ) { + getFromProp(node.init.params[0]); + } else if (babelTypes.isCallExpression(node.init)) { + // x = react.memo(props =>
) + const arg = node.init.arguments[0]; + if (babelTypes.isArrowFunctionExpression(arg) || babelTypes.isFunctionExpression(arg)) { + getFromProp(arg.params[0]); + } + } + + function getFromProp(prop: babelTypes.Node) { + // Prevent visiting again + (node as any).hasBeenVisited = true; + path.skip(); + + injectPropTypes({ + path: path.parentPath, + usedProps: + babelTypes.isIdentifier(prop) || babelTypes.isObjectPattern(prop) + ? getUsedProps(path as babel.NodePath, prop) + : [], + props: props!, + nodeName, + }); + } + }, + ClassDeclaration(path) { + const { node } = path; + + // Prevent visiting again + if ((node as any).hasBeenVisited) { + path.skip(); + return; + } + + if (!babelTypes.isIdentifier(node.id)) return; + const nodeName = node.id.name; + + const props = propTypes.body.find((prop) => prop.name === nodeName); + if (!props) return; + + // Prevent visiting again + (node as any).hasBeenVisited = true; + path.skip(); + + injectPropTypes({ + nodeName, + usedProps: getUsedProps(path as babel.NodePath, undefined), + path: path as babel.NodePath, + props, + }); + }, + }, + }; + + function injectPropTypes(options: { + path: babel.NodePath; + usedProps: string[]; + props: t.ComponentNode; + nodeName: string; + }) { + const { path, props, usedProps, nodeName } = options; + + const source = generate(props, { + ...otherOptions, + importedName: importName, + previousPropTypesSource, + reconcilePropTypes, + shouldInclude: (prop) => shouldInclude({ component: props, prop, usedProps }), + }); + + if (source.length === 0) { + return; + } + + needImport = true; + + const placeholder = `const a${uuid().replace(/\-/g, '_')} = null;`; + + mapOfPropTypes.set(placeholder, source); + + if (removeExistingPropTypes && originalPropTypesPath !== null) { + originalPropTypesPath.replaceWith(babel.template.ast(placeholder) as babelTypes.Statement); + } else if (babelTypes.isExportNamedDeclaration(path.parent)) { + path.insertAfter(babel.template.ast(`export { ${nodeName} };`)); + path.insertAfter(babel.template.ast(placeholder)); + path.parentPath.replaceWith(path.node); + } else if (babelTypes.isExportDefaultDeclaration(path.parent)) { + path.insertAfter(babel.template.ast(`export default ${nodeName};`)); + path.insertAfter(babel.template.ast(placeholder)); + path.parentPath.replaceWith(path.node); + } else { + path.insertAfter(babel.template.ast(placeholder)); + } + } } /** @@ -323,57 +322,57 @@ function plugin( * @param rootNode The node to start the search, if undefined searches for `this.props` */ function getUsedProps( - rootPath: babel.NodePath, - rootNode: babelTypes.ObjectPattern | babelTypes.Identifier | undefined + rootPath: babel.NodePath, + rootNode: babelTypes.ObjectPattern | babelTypes.Identifier | undefined, ) { - const usedProps: string[] = []; - getUsedPropsInternal(rootNode); - return usedProps; - - function getUsedPropsInternal( - node: babelTypes.ObjectPattern | babelTypes.Identifier | undefined - ) { - if (node && babelTypes.isObjectPattern(node)) { - node.properties.forEach((x) => { - if (babelTypes.isObjectProperty(x)) { - if (babelTypes.isStringLiteral(x.key)) { - usedProps.push(x.key.value); - } else { - usedProps.push(x.key.name); - } - } else if (babelTypes.isIdentifier(x.argument)) { - getUsedPropsInternal(x.argument); - } - }); - } else { - rootPath.traverse({ - VariableDeclarator(path) { - const init = path.node.init; - if ( - (node - ? babelTypes.isIdentifier(init, { name: node.name }) - : babelTypes.isMemberExpression(init) && - babelTypes.isThisExpression(init.object) && - babelTypes.isIdentifier(init.property, { name: 'props' })) && - babelTypes.isObjectPattern(path.node.id) - ) { - getUsedPropsInternal(path.node.id); - } - }, - MemberExpression(path) { - if ( - (node - ? babelTypes.isIdentifier(path.node.object, { name: node.name }) - : babelTypes.isMemberExpression(path.node.object) && - babelTypes.isMemberExpression(path.node.object.object) && - babelTypes.isThisExpression(path.node.object.object.object) && - babelTypes.isIdentifier(path.node.object.object.property, { name: 'props' })) && - babelTypes.isIdentifier(path.node.property) - ) { - usedProps.push(path.node.property.name); - } - }, - }); - } - } + const usedProps: string[] = []; + getUsedPropsInternal(rootNode); + return usedProps; + + function getUsedPropsInternal( + node: babelTypes.ObjectPattern | babelTypes.Identifier | undefined, + ) { + if (node && babelTypes.isObjectPattern(node)) { + node.properties.forEach((x) => { + if (babelTypes.isObjectProperty(x)) { + if (babelTypes.isStringLiteral(x.key)) { + usedProps.push(x.key.value); + } else { + usedProps.push(x.key.name); + } + } else if (babelTypes.isIdentifier(x.argument)) { + getUsedPropsInternal(x.argument); + } + }); + } else { + rootPath.traverse({ + VariableDeclarator(path) { + const init = path.node.init; + if ( + (node + ? babelTypes.isIdentifier(init, { name: node.name }) + : babelTypes.isMemberExpression(init) && + babelTypes.isThisExpression(init.object) && + babelTypes.isIdentifier(init.property, { name: 'props' })) && + babelTypes.isObjectPattern(path.node.id) + ) { + getUsedPropsInternal(path.node.id); + } + }, + MemberExpression(path) { + if ( + (node + ? babelTypes.isIdentifier(path.node.object, { name: node.name }) + : babelTypes.isMemberExpression(path.node.object) && + babelTypes.isMemberExpression(path.node.object.object) && + babelTypes.isThisExpression(path.node.object.object.object) && + babelTypes.isIdentifier(path.node.object.object.property, { name: 'props' })) && + babelTypes.isIdentifier(path.node.property) + ) { + usedProps.push(path.node.property.name); + } + }, + }); + } + } } diff --git a/packages/typescript-to-proptypes/src/parser.ts b/packages/typescript-to-proptypes/src/parser.ts index d21322e713bd6e..5f974a2b2f7251 100644 --- a/packages/typescript-to-proptypes/src/parser.ts +++ b/packages/typescript-to-proptypes/src/parser.ts @@ -6,30 +6,30 @@ import * as doctrine from 'doctrine'; * Options that specify how the parser should act */ export interface ParserOptions { - /** - * Called before a PropType is added to a component/object - * @return true to include the PropType, false to skip it, or undefined to - * use the default behaviour - * @default name !== 'ref' - */ - shouldInclude: (data: { name: string; depth: number }) => boolean | undefined; - /** - * Called before the shape of an object is resolved - * @return true to resolve the shape of the object, false to just use a object, or undefined to - * use the default behaviour - * @default propertyCount <= 50 && depth <= 3 - */ - shouldResolveObject: (data: { - name: string; - propertyCount: number; - depth: number; - }) => boolean | undefined; - /** - * Control if const declarations should be checked - * @default false - * @example declare const Component: React.ComponentType; - */ - checkDeclarations?: boolean; + /** + * Called before a PropType is added to a component/object + * @return true to include the PropType, false to skip it, or undefined to + * use the default behaviour + * @default name !== 'ref' + */ + shouldInclude: (data: { name: string; depth: number }) => boolean | undefined; + /** + * Called before the shape of an object is resolved + * @return true to resolve the shape of the object, false to just use a object, or undefined to + * use the default behaviour + * @default propertyCount <= 50 && depth <= 3 + */ + shouldResolveObject: (data: { + name: string; + propertyCount: number; + depth: number; + }) => boolean | undefined; + /** + * Control if const declarations should be checked + * @default false + * @example declare const Component: React.ComponentType; + */ + checkDeclarations?: boolean; } /** @@ -38,7 +38,7 @@ export interface ParserOptions { * @param options The options to pass to the compiler */ export function createProgram(files: string[], options: ts.CompilerOptions) { - return ts.createProgram(files, options); + return ts.createProgram(files, options); } /** @@ -49,12 +49,12 @@ export function createProgram(files: string[], options: ts.CompilerOptions) { * @param parserOptions Options that specify how the parser should act */ export function parseFile( - filePath: string, - options: ts.CompilerOptions, - parserOptions: Partial = {} + filePath: string, + options: ts.CompilerOptions, + parserOptions: Partial = {}, ) { - const program = ts.createProgram([filePath], options); - return parseFromProgram(filePath, program, parserOptions); + const program = ts.createProgram([filePath], options); + return parseFromProgram(filePath, program, parserOptions); } /** @@ -64,502 +64,502 @@ export function parseFile( * @param parserOptions Options that specify how the parser should act */ export function parseFromProgram( - filePath: string, - program: ts.Program, - parserOptions: Partial = {} + filePath: string, + program: ts.Program, + parserOptions: Partial = {}, ) { - const { checkDeclarations = false } = parserOptions; - - const shouldInclude: ParserOptions['shouldInclude'] = (data) => { - if (parserOptions.shouldInclude) { - const result = parserOptions.shouldInclude(data); - if (result !== undefined) { - return result; - } - } - - return data.name !== 'ref'; - }; - - const shouldResolveObject: ParserOptions['shouldResolveObject'] = (data) => { - if (parserOptions.shouldResolveObject) { - const result = parserOptions.shouldResolveObject(data); - if (result !== undefined) { - return result; - } - } - - return data.propertyCount <= 50 && data.depth <= 3; - }; - - const checker = program.getTypeChecker(); - const sourceFile = program.getSourceFile(filePath); - - const programNode = t.programNode(); - const reactImports: string[] = []; - - if (sourceFile) { - ts.forEachChild(sourceFile, visitImports); - ts.forEachChild(sourceFile, visit); - } else { - throw new Error(`Program doesn't contain file "${filePath}"`); - } - - return programNode; - - function visitImports(node: ts.Node) { - if ( - ts.isImportDeclaration(node) && - ts.isStringLiteral(node.moduleSpecifier) && - node.moduleSpecifier.text === 'react' && - node.importClause - ) { - const imports = ['Component', 'PureComponent', 'memo', 'forwardRef']; - - // import x from 'react' - if (node.importClause.name) { - const nameText = node.importClause.name.text; - reactImports.push(...imports.map((x) => `${nameText}.${x}`)); - } - - // import {x, y as z} from 'react' - const bindings = node.importClause.namedBindings; - if (bindings) { - if (ts.isNamedImports(bindings)) { - bindings.elements.forEach((spec) => { - const nameIdentifier = spec.propertyName || spec.name; - const nameText = nameIdentifier.getText(); - if (imports.includes(nameText)) { - reactImports.push(spec.name.getText()); - } - }); - } - // import * as x from 'react' - else { - const nameText = bindings.name.text; - reactImports.push(...imports.map((x) => `${nameText}.${x}`)); - } - } - } - } - - function visit(node: ts.Node) { - // function x(props: type) { return
} - if (ts.isFunctionDeclaration(node) && node.name && node.parameters.length === 1) { - parseFunctionComponent(node); - } - // const x = ... - else if (ts.isVariableStatement(node)) { - ts.forEachChild(node.declarationList, (variableNode) => { - // x = (props: type) => { return
} - // x = function(props: type) { return
} - // x = function y(props: type) { return
} - // x = react.memo((props:type) { return
}) - - if (ts.isVariableDeclaration(variableNode) && variableNode.name) { - const type = checker.getTypeAtLocation(variableNode.name); - if (!variableNode.initializer) { - if ( - checkDeclarations && - type.aliasSymbol && - type.aliasTypeArguments && - checker.getFullyQualifiedName(type.aliasSymbol) === 'React.ComponentType' - ) { - parsePropsType( - variableNode.name.getText(), - type.aliasTypeArguments[0], - node.getSourceFile() - ); - } else if (checkDeclarations) { - parseFunctionComponent(variableNode); - } - } else if ( - (ts.isArrowFunction(variableNode.initializer) || - ts.isFunctionExpression(variableNode.initializer)) && - variableNode.initializer.parameters.length === 1 - ) { - parseFunctionComponent(variableNode); - } - // x = react.memo((props:type) { return
}) - else if ( - ts.isCallExpression(variableNode.initializer) && - variableNode.initializer.arguments.length > 0 - ) { - const callString = variableNode.initializer.expression.getText(); - const arg = variableNode.initializer.arguments[0]; - if ( - reactImports.includes(callString) && - (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) && - arg.parameters.length > 0 - ) { - const symbol = checker.getSymbolAtLocation(arg.parameters[0].name); - if (symbol) { - parsePropsType( - variableNode.name.getText(), - checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration), - node.getSourceFile() - ); - } - } - } - } - }); - } else if ( - ts.isClassDeclaration(node) && - node.name && - node.heritageClauses && - node.heritageClauses.length === 1 - ) { - const heritage = node.heritageClauses[0]; - if (heritage.types.length !== 1) return; - - const arg = heritage.types[0]; - if (!arg.typeArguments) return; - - if (reactImports.includes(arg.expression.getText())) { - parsePropsType( - node.name.getText(), - checker.getTypeAtLocation(arg.typeArguments[0]), - node.getSourceFile() - ); - } - } - } - - function isTypeJSXElementLike(type: ts.Type): boolean { - if (type.isUnion()) { - return type.types.every( - (subType) => subType.flags & ts.TypeFlags.Null || isTypeJSXElementLike(subType) - ); - } else if (type.symbol) { - const name = checker.getFullyQualifiedName(type.symbol); - return name === 'global.JSX.Element' || name === 'React.ReactElement'; - } - - return false; - } - - function parseFunctionComponent(node: ts.VariableDeclaration | ts.FunctionDeclaration) { - if (!node.name) { - return; - } - - const symbol = checker.getSymbolAtLocation(node.name); - if (!symbol) { - return; - } - const componentName = node.name.getText(); - - const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration); - type.getCallSignatures().forEach((signature) => { - if (!isTypeJSXElementLike(signature.getReturnType())) { - return; - } - - const propsType = checker.getTypeOfSymbolAtLocation( - signature.parameters[0], - signature.parameters[0].valueDeclaration - ); - - parsePropsType(componentName, propsType, node.getSourceFile()); - }); - - // squash props - // { variant: 'a', href: string } & { variant: 'b' } - // to - // { variant: 'a' | 'b', href?: string } - const props: Record = {}; - const usedPropsPerSignature: Set[] = []; - programNode.body = programNode.body.filter((node) => { - if (node.name === componentName) { - const usedProps: Set = new Set(); - // squash props - node.types.forEach((typeNode) => { - usedProps.add(typeNode.name); - - let { [typeNode.name]: currentTypeNode } = props; - if (currentTypeNode === undefined) { - currentTypeNode = typeNode; - } else if (currentTypeNode.$$id !== typeNode.$$id) { - currentTypeNode = t.propTypeNode( - currentTypeNode.name, - currentTypeNode.jsDoc, - t.unionNode([currentTypeNode.propType, typeNode.propType]), - new Set(Array.from(currentTypeNode.filenames).concat(Array.from(typeNode.filenames))), - undefined - ); - } - - props[typeNode.name] = currentTypeNode; - }); - - usedPropsPerSignature.push(usedProps); - - // delete each signature, we'll add it later unionized - return false; - } - return true; - }); - - programNode.body.push( - t.componentNode( - componentName, - Object.entries(props).map(([name, propType]) => { - const onlyUsedInSomeSignatures = usedPropsPerSignature.some((props) => !props.has(name)); - if (onlyUsedInSomeSignatures) { - // mark as optional - return { - ...propType, - propType: t.unionNode([propType.propType, t.undefinedNode()]), - }; - } - return propType; - }), - node.getSourceFile().fileName - ) - ); - } - - function parsePropsType(name: string, type: ts.Type, sourceFile: ts.SourceFile | undefined) { - const properties = type - .getProperties() - .filter((symbol) => shouldInclude({ name: symbol.getName(), depth: 1 })); - if (properties.length === 0) { - return; - } - - const propsFilename = sourceFile !== undefined ? sourceFile.fileName : undefined; - - programNode.body.push( - t.componentNode( - name, - properties.map((x) => checkSymbol(x, [(type as any).id])), - propsFilename - ) - ); - } - - function checkSymbol(symbol: ts.Symbol, typeStack: number[]): t.PropTypeNode { - const declarations = symbol.getDeclarations(); - const declaration = declarations && declarations[0]; - - const symbolFilenames = getSymbolFileNames(symbol); - - // TypeChecker keeps the name for - // { a: React.ElementType, b: React.ReactElement | boolean } - // but not - // { a?: React.ElementType, b: React.ReactElement } - // get around this by not using the TypeChecker - if ( - declaration && - ts.isPropertySignature(declaration) && - declaration.type && - ts.isTypeReferenceNode(declaration.type) - ) { - const name = declaration.type.typeName.getText(); - if ( - name === 'React.ElementType' || - name === 'React.ComponentType' || - name === 'React.ReactElement' - ) { - const elementNode = t.elementNode( - name === 'React.ReactElement' ? 'element' : 'elementType' - ); - - return t.propTypeNode( - symbol.getName(), - getDocumentation(symbol), - declaration.questionToken ? t.unionNode([t.undefinedNode(), elementNode]) : elementNode, - symbolFilenames, - (symbol as any).id - ); - } - } - - const symbolType = declaration - ? // The proptypes aren't detailed enough that we need all the different combinations - // so we just pick the first and ignore the rest - checker.getTypeOfSymbolAtLocation(symbol, declaration) - : // The properties of Record<..., ...> don't have a declaration, but the symbol has a type property - ((symbol as any).type as ts.Type); - // get `React.ElementType` from `C extends React.ElementType` - const declaredType = - declaration !== undefined ? checker.getTypeAtLocation(declaration) : undefined; - const baseConstraintOfType = - declaredType !== undefined ? checker.getBaseConstraintOfType(declaredType) : undefined; - const type = - baseConstraintOfType !== undefined && baseConstraintOfType !== declaredType - ? baseConstraintOfType - : symbolType; - - if (!type) { - throw new Error('No types found'); - } - - // Typechecker only gives the type "any" if it's present in a union - // This means the type of "a" in {a?:any} isn't "any | undefined" - // So instead we check for the questionmark to detect optional types - let parsedType: t.Node | undefined = undefined; - if ( - (type.flags & ts.TypeFlags.Any || type.flags & ts.TypeFlags.Unknown) && - declaration && - ts.isPropertySignature(declaration) - ) { - parsedType = declaration.questionToken - ? t.unionNode([t.undefinedNode(), t.anyNode()]) - : t.anyNode(); - } else { - parsedType = checkType(type, typeStack, symbol.getName()); - } - - return t.propTypeNode( - symbol.getName(), - getDocumentation(symbol), - parsedType, - symbolFilenames, - (symbol as any).id - ); - } - - function checkType(type: ts.Type, typeStack: number[], name: string): t.Node { - // If the typeStack contains type.id we're dealing with an object that references itself. - // To prevent getting stuck in an infinite loop we just set it to an objectNode - if (typeStack.includes((type as any).id)) { - return t.objectNode(); - } - - { - const typeNode = type as any; - - const symbol = typeNode.aliasSymbol ? typeNode.aliasSymbol : typeNode.symbol; - const typeName = symbol ? checker.getFullyQualifiedName(symbol) : null; - switch (typeName) { - case 'global.JSX.Element': - case 'React.ReactElement': { - return t.elementNode('element'); - } - case 'React.ElementType': { - return t.elementNode('elementType'); - } - case 'React.ReactNode': { - return t.unionNode([t.elementNode('node'), t.undefinedNode()]); - } - case 'React.Component': { - return t.instanceOfNode(typeName); - } - case 'Element': - case 'HTMLElement': { - return t.DOMElementNode(); - } - } - } - - // @ts-ignore - Private method - if (checker.isArrayType(type)) { - // @ts-ignore - Private method - const arrayType: ts.Type = checker.getElementTypeOfArrayType(type); - return t.arrayNode(checkType(arrayType, typeStack, name)); - } - - if (type.isUnion()) { - const node = t.unionNode(type.types.map((x) => checkType(x, typeStack, name))); - - return node.types.length === 1 ? node.types[0] : node; - } - - if (type.flags & ts.TypeFlags.String) { - return t.stringNode(); - } - - if (type.flags & ts.TypeFlags.Number) { - return t.numericNode(); - } - - if (type.flags & ts.TypeFlags.Undefined) { - return t.undefinedNode(); - } - - if (type.flags & ts.TypeFlags.Any || type.flags & ts.TypeFlags.Unknown) { - return t.anyNode(); - } - - if (type.flags & ts.TypeFlags.Literal) { - if (type.isLiteral()) { - return t.literalNode( - type.isStringLiteral() ? `"${type.value}"` : type.value, - getDocumentation(type.symbol) - ); - } - return t.literalNode(checker.typeToString(type)); - } - - if (type.flags & ts.TypeFlags.Null) { - return t.literalNode('null'); - } - - if (type.getCallSignatures().length) { - return t.functionNode(); - } - - // Object-like type - { - const properties = type.getProperties(); - if (properties.length) { - if ( - shouldResolveObject({ name, propertyCount: properties.length, depth: typeStack.length }) - ) { - const filtered = properties.filter((symbol) => - shouldInclude({ name: symbol.getName(), depth: typeStack.length + 1 }) - ); - if (filtered.length > 0) { - return t.interfaceNode( - filtered.map((x) => checkSymbol(x, [...typeStack, (type as any).id])) - ); - } - } - - return t.objectNode(); - } - } - - // Object without properties or object keyword - if ( - type.flags & ts.TypeFlags.Object || - (type.flags & ts.TypeFlags.NonPrimitive && checker.typeToString(type) === 'object') - ) { - return t.objectNode(); - } - - console.warn( - `Unable to handle node of type "ts.TypeFlags.${ts.TypeFlags[type.flags]}", using any` - ); - return t.anyNode(); - } - - function getDocumentation(symbol?: ts.Symbol): string | undefined { - if (!symbol) { - return undefined; - } - - const decl = symbol.getDeclarations(); - if (decl) { - // @ts-ignore - Private method - const comments = ts.getJSDocCommentsAndTags(decl[0]) as any[]; - if (comments && comments.length === 1) { - const commentNode = comments[0]; - if (ts.isJSDoc(commentNode)) { - return doctrine.unwrapComment(commentNode.getText()).trim(); - } - } - } - - const comment = ts.displayPartsToString(symbol.getDocumentationComment(checker)); - return comment ? comment : undefined; - } - - function getSymbolFileNames(symbol: ts.Symbol): Set { - const declarations = symbol.getDeclarations() || []; - - return new Set(declarations.map((declaration) => declaration.getSourceFile().fileName)); - } + const { checkDeclarations = false } = parserOptions; + + const shouldInclude: ParserOptions['shouldInclude'] = (data) => { + if (parserOptions.shouldInclude) { + const result = parserOptions.shouldInclude(data); + if (result !== undefined) { + return result; + } + } + + return data.name !== 'ref'; + }; + + const shouldResolveObject: ParserOptions['shouldResolveObject'] = (data) => { + if (parserOptions.shouldResolveObject) { + const result = parserOptions.shouldResolveObject(data); + if (result !== undefined) { + return result; + } + } + + return data.propertyCount <= 50 && data.depth <= 3; + }; + + const checker = program.getTypeChecker(); + const sourceFile = program.getSourceFile(filePath); + + const programNode = t.programNode(); + const reactImports: string[] = []; + + if (sourceFile) { + ts.forEachChild(sourceFile, visitImports); + ts.forEachChild(sourceFile, visit); + } else { + throw new Error(`Program doesn't contain file "${filePath}"`); + } + + return programNode; + + function visitImports(node: ts.Node) { + if ( + ts.isImportDeclaration(node) && + ts.isStringLiteral(node.moduleSpecifier) && + node.moduleSpecifier.text === 'react' && + node.importClause + ) { + const imports = ['Component', 'PureComponent', 'memo', 'forwardRef']; + + // import x from 'react' + if (node.importClause.name) { + const nameText = node.importClause.name.text; + reactImports.push(...imports.map((x) => `${nameText}.${x}`)); + } + + // import {x, y as z} from 'react' + const bindings = node.importClause.namedBindings; + if (bindings) { + if (ts.isNamedImports(bindings)) { + bindings.elements.forEach((spec) => { + const nameIdentifier = spec.propertyName || spec.name; + const nameText = nameIdentifier.getText(); + if (imports.includes(nameText)) { + reactImports.push(spec.name.getText()); + } + }); + } + // import * as x from 'react' + else { + const nameText = bindings.name.text; + reactImports.push(...imports.map((x) => `${nameText}.${x}`)); + } + } + } + } + + function visit(node: ts.Node) { + // function x(props: type) { return
} + if (ts.isFunctionDeclaration(node) && node.name && node.parameters.length === 1) { + parseFunctionComponent(node); + } + // const x = ... + else if (ts.isVariableStatement(node)) { + ts.forEachChild(node.declarationList, (variableNode) => { + // x = (props: type) => { return
} + // x = function(props: type) { return
} + // x = function y(props: type) { return
} + // x = react.memo((props:type) { return
}) + + if (ts.isVariableDeclaration(variableNode) && variableNode.name) { + const type = checker.getTypeAtLocation(variableNode.name); + if (!variableNode.initializer) { + if ( + checkDeclarations && + type.aliasSymbol && + type.aliasTypeArguments && + checker.getFullyQualifiedName(type.aliasSymbol) === 'React.ComponentType' + ) { + parsePropsType( + variableNode.name.getText(), + type.aliasTypeArguments[0], + node.getSourceFile(), + ); + } else if (checkDeclarations) { + parseFunctionComponent(variableNode); + } + } else if ( + (ts.isArrowFunction(variableNode.initializer) || + ts.isFunctionExpression(variableNode.initializer)) && + variableNode.initializer.parameters.length === 1 + ) { + parseFunctionComponent(variableNode); + } + // x = react.memo((props:type) { return
}) + else if ( + ts.isCallExpression(variableNode.initializer) && + variableNode.initializer.arguments.length > 0 + ) { + const callString = variableNode.initializer.expression.getText(); + const arg = variableNode.initializer.arguments[0]; + if ( + reactImports.includes(callString) && + (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) && + arg.parameters.length > 0 + ) { + const symbol = checker.getSymbolAtLocation(arg.parameters[0].name); + if (symbol) { + parsePropsType( + variableNode.name.getText(), + checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration), + node.getSourceFile(), + ); + } + } + } + } + }); + } else if ( + ts.isClassDeclaration(node) && + node.name && + node.heritageClauses && + node.heritageClauses.length === 1 + ) { + const heritage = node.heritageClauses[0]; + if (heritage.types.length !== 1) return; + + const arg = heritage.types[0]; + if (!arg.typeArguments) return; + + if (reactImports.includes(arg.expression.getText())) { + parsePropsType( + node.name.getText(), + checker.getTypeAtLocation(arg.typeArguments[0]), + node.getSourceFile(), + ); + } + } + } + + function isTypeJSXElementLike(type: ts.Type): boolean { + if (type.isUnion()) { + return type.types.every( + (subType) => subType.flags & ts.TypeFlags.Null || isTypeJSXElementLike(subType), + ); + } else if (type.symbol) { + const name = checker.getFullyQualifiedName(type.symbol); + return name === 'global.JSX.Element' || name === 'React.ReactElement'; + } + + return false; + } + + function parseFunctionComponent(node: ts.VariableDeclaration | ts.FunctionDeclaration) { + if (!node.name) { + return; + } + + const symbol = checker.getSymbolAtLocation(node.name); + if (!symbol) { + return; + } + const componentName = node.name.getText(); + + const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration); + type.getCallSignatures().forEach((signature) => { + if (!isTypeJSXElementLike(signature.getReturnType())) { + return; + } + + const propsType = checker.getTypeOfSymbolAtLocation( + signature.parameters[0], + signature.parameters[0].valueDeclaration, + ); + + parsePropsType(componentName, propsType, node.getSourceFile()); + }); + + // squash props + // { variant: 'a', href: string } & { variant: 'b' } + // to + // { variant: 'a' | 'b', href?: string } + const props: Record = {}; + const usedPropsPerSignature: Set[] = []; + programNode.body = programNode.body.filter((node) => { + if (node.name === componentName) { + const usedProps: Set = new Set(); + // squash props + node.types.forEach((typeNode) => { + usedProps.add(typeNode.name); + + let { [typeNode.name]: currentTypeNode } = props; + if (currentTypeNode === undefined) { + currentTypeNode = typeNode; + } else if (currentTypeNode.$$id !== typeNode.$$id) { + currentTypeNode = t.propTypeNode( + currentTypeNode.name, + currentTypeNode.jsDoc, + t.unionNode([currentTypeNode.propType, typeNode.propType]), + new Set(Array.from(currentTypeNode.filenames).concat(Array.from(typeNode.filenames))), + undefined, + ); + } + + props[typeNode.name] = currentTypeNode; + }); + + usedPropsPerSignature.push(usedProps); + + // delete each signature, we'll add it later unionized + return false; + } + return true; + }); + + programNode.body.push( + t.componentNode( + componentName, + Object.entries(props).map(([name, propType]) => { + const onlyUsedInSomeSignatures = usedPropsPerSignature.some((props) => !props.has(name)); + if (onlyUsedInSomeSignatures) { + // mark as optional + return { + ...propType, + propType: t.unionNode([propType.propType, t.undefinedNode()]), + }; + } + return propType; + }), + node.getSourceFile().fileName, + ), + ); + } + + function parsePropsType(name: string, type: ts.Type, sourceFile: ts.SourceFile | undefined) { + const properties = type + .getProperties() + .filter((symbol) => shouldInclude({ name: symbol.getName(), depth: 1 })); + if (properties.length === 0) { + return; + } + + const propsFilename = sourceFile !== undefined ? sourceFile.fileName : undefined; + + programNode.body.push( + t.componentNode( + name, + properties.map((x) => checkSymbol(x, [(type as any).id])), + propsFilename, + ), + ); + } + + function checkSymbol(symbol: ts.Symbol, typeStack: number[]): t.PropTypeNode { + const declarations = symbol.getDeclarations(); + const declaration = declarations && declarations[0]; + + const symbolFilenames = getSymbolFileNames(symbol); + + // TypeChecker keeps the name for + // { a: React.ElementType, b: React.ReactElement | boolean } + // but not + // { a?: React.ElementType, b: React.ReactElement } + // get around this by not using the TypeChecker + if ( + declaration && + ts.isPropertySignature(declaration) && + declaration.type && + ts.isTypeReferenceNode(declaration.type) + ) { + const name = declaration.type.typeName.getText(); + if ( + name === 'React.ElementType' || + name === 'React.ComponentType' || + name === 'React.ReactElement' + ) { + const elementNode = t.elementNode( + name === 'React.ReactElement' ? 'element' : 'elementType', + ); + + return t.propTypeNode( + symbol.getName(), + getDocumentation(symbol), + declaration.questionToken ? t.unionNode([t.undefinedNode(), elementNode]) : elementNode, + symbolFilenames, + (symbol as any).id, + ); + } + } + + const symbolType = declaration + ? // The proptypes aren't detailed enough that we need all the different combinations + // so we just pick the first and ignore the rest + checker.getTypeOfSymbolAtLocation(symbol, declaration) + : // The properties of Record<..., ...> don't have a declaration, but the symbol has a type property + ((symbol as any).type as ts.Type); + // get `React.ElementType` from `C extends React.ElementType` + const declaredType = + declaration !== undefined ? checker.getTypeAtLocation(declaration) : undefined; + const baseConstraintOfType = + declaredType !== undefined ? checker.getBaseConstraintOfType(declaredType) : undefined; + const type = + baseConstraintOfType !== undefined && baseConstraintOfType !== declaredType + ? baseConstraintOfType + : symbolType; + + if (!type) { + throw new Error('No types found'); + } + + // Typechecker only gives the type "any" if it's present in a union + // This means the type of "a" in {a?:any} isn't "any | undefined" + // So instead we check for the questionmark to detect optional types + let parsedType: t.Node | undefined = undefined; + if ( + (type.flags & ts.TypeFlags.Any || type.flags & ts.TypeFlags.Unknown) && + declaration && + ts.isPropertySignature(declaration) + ) { + parsedType = declaration.questionToken + ? t.unionNode([t.undefinedNode(), t.anyNode()]) + : t.anyNode(); + } else { + parsedType = checkType(type, typeStack, symbol.getName()); + } + + return t.propTypeNode( + symbol.getName(), + getDocumentation(symbol), + parsedType, + symbolFilenames, + (symbol as any).id, + ); + } + + function checkType(type: ts.Type, typeStack: number[], name: string): t.Node { + // If the typeStack contains type.id we're dealing with an object that references itself. + // To prevent getting stuck in an infinite loop we just set it to an objectNode + if (typeStack.includes((type as any).id)) { + return t.objectNode(); + } + + { + const typeNode = type as any; + + const symbol = typeNode.aliasSymbol ? typeNode.aliasSymbol : typeNode.symbol; + const typeName = symbol ? checker.getFullyQualifiedName(symbol) : null; + switch (typeName) { + case 'global.JSX.Element': + case 'React.ReactElement': { + return t.elementNode('element'); + } + case 'React.ElementType': { + return t.elementNode('elementType'); + } + case 'React.ReactNode': { + return t.unionNode([t.elementNode('node'), t.undefinedNode()]); + } + case 'React.Component': { + return t.instanceOfNode(typeName); + } + case 'Element': + case 'HTMLElement': { + return t.DOMElementNode(); + } + } + } + + // @ts-ignore - Private method + if (checker.isArrayType(type)) { + // @ts-ignore - Private method + const arrayType: ts.Type = checker.getElementTypeOfArrayType(type); + return t.arrayNode(checkType(arrayType, typeStack, name)); + } + + if (type.isUnion()) { + const node = t.unionNode(type.types.map((x) => checkType(x, typeStack, name))); + + return node.types.length === 1 ? node.types[0] : node; + } + + if (type.flags & ts.TypeFlags.String) { + return t.stringNode(); + } + + if (type.flags & ts.TypeFlags.Number) { + return t.numericNode(); + } + + if (type.flags & ts.TypeFlags.Undefined) { + return t.undefinedNode(); + } + + if (type.flags & ts.TypeFlags.Any || type.flags & ts.TypeFlags.Unknown) { + return t.anyNode(); + } + + if (type.flags & ts.TypeFlags.Literal) { + if (type.isLiteral()) { + return t.literalNode( + type.isStringLiteral() ? `"${type.value}"` : type.value, + getDocumentation(type.symbol), + ); + } + return t.literalNode(checker.typeToString(type)); + } + + if (type.flags & ts.TypeFlags.Null) { + return t.literalNode('null'); + } + + if (type.getCallSignatures().length) { + return t.functionNode(); + } + + // Object-like type + { + const properties = type.getProperties(); + if (properties.length) { + if ( + shouldResolveObject({ name, propertyCount: properties.length, depth: typeStack.length }) + ) { + const filtered = properties.filter((symbol) => + shouldInclude({ name: symbol.getName(), depth: typeStack.length + 1 }), + ); + if (filtered.length > 0) { + return t.interfaceNode( + filtered.map((x) => checkSymbol(x, [...typeStack, (type as any).id])), + ); + } + } + + return t.objectNode(); + } + } + + // Object without properties or object keyword + if ( + type.flags & ts.TypeFlags.Object || + (type.flags & ts.TypeFlags.NonPrimitive && checker.typeToString(type) === 'object') + ) { + return t.objectNode(); + } + + console.warn( + `Unable to handle node of type "ts.TypeFlags.${ts.TypeFlags[type.flags]}", using any`, + ); + return t.anyNode(); + } + + function getDocumentation(symbol?: ts.Symbol): string | undefined { + if (!symbol) { + return undefined; + } + + const decl = symbol.getDeclarations(); + if (decl) { + // @ts-ignore - Private method + const comments = ts.getJSDocCommentsAndTags(decl[0]) as any[]; + if (comments && comments.length === 1) { + const commentNode = comments[0]; + if (ts.isJSDoc(commentNode)) { + return doctrine.unwrapComment(commentNode.getText()).trim(); + } + } + } + + const comment = ts.displayPartsToString(symbol.getDocumentationComment(checker)); + return comment ? comment : undefined; + } + + function getSymbolFileNames(symbol: ts.Symbol): Set { + const declarations = symbol.getDeclarations() || []; + + return new Set(declarations.map((declaration) => declaration.getSourceFile().fileName)); + } } diff --git a/packages/typescript-to-proptypes/src/types/nodes/baseNodes.ts b/packages/typescript-to-proptypes/src/types/nodes/baseNodes.ts index 06312938c01eaf..f898e3eaabb711 100644 --- a/packages/typescript-to-proptypes/src/types/nodes/baseNodes.ts +++ b/packages/typescript-to-proptypes/src/types/nodes/baseNodes.ts @@ -1,9 +1,9 @@ import { PropTypeNode } from './proptype'; export interface Node { - type: string; + type: string; } export interface DefinitionHolder extends Node { - types: PropTypeNode[]; + types: PropTypeNode[]; } diff --git a/packages/typescript-to-proptypes/src/types/nodes/component.ts b/packages/typescript-to-proptypes/src/types/nodes/component.ts index 479f8afd3c1706..5e083097e9c56b 100644 --- a/packages/typescript-to-proptypes/src/types/nodes/component.ts +++ b/packages/typescript-to-proptypes/src/types/nodes/component.ts @@ -4,23 +4,23 @@ import { PropTypeNode } from './proptype'; const typeString = 'ComponentNode'; export interface ComponentNode extends DefinitionHolder { - name: string; - propsFilename?: string; + name: string; + propsFilename?: string; } export function componentNode( - name: string, - types: PropTypeNode[], - propsFilename: string | undefined + name: string, + types: PropTypeNode[], + propsFilename: string | undefined, ): ComponentNode { - return { - type: typeString, - name: name, - types: types || [], - propsFilename, - }; + return { + type: typeString, + name: name, + types: types || [], + propsFilename, + }; } export function isComponentNode(node: Node): node is ComponentNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/nodes/program.ts b/packages/typescript-to-proptypes/src/types/nodes/program.ts index abffd398a250a4..599141b36a3431 100644 --- a/packages/typescript-to-proptypes/src/types/nodes/program.ts +++ b/packages/typescript-to-proptypes/src/types/nodes/program.ts @@ -4,16 +4,16 @@ import { ComponentNode } from './component'; const typeString = 'ProgramNode'; export interface ProgramNode extends Node { - body: ComponentNode[]; + body: ComponentNode[]; } export function programNode(body?: ComponentNode[]): ProgramNode { - return { - type: typeString, - body: body || [], - }; + return { + type: typeString, + body: body || [], + }; } export function isProgramNode(node: Node): node is ProgramNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/nodes/proptype.ts b/packages/typescript-to-proptypes/src/types/nodes/proptype.ts index 53b048924eeb68..28b13ab5217d12 100644 --- a/packages/typescript-to-proptypes/src/types/nodes/proptype.ts +++ b/packages/typescript-to-proptypes/src/types/nodes/proptype.ts @@ -3,33 +3,33 @@ import { Node } from './baseNodes'; const typeString = 'PropTypeNode'; export interface PropTypeNode extends Node { - name: string; - jsDoc?: string; - propType: Node; - filenames: Set; - /** - * @internal - */ - $$id: number | undefined; + name: string; + jsDoc?: string; + propType: Node; + filenames: Set; + /** + * @internal + */ + $$id: number | undefined; } export function propTypeNode( - name: string, - jsDoc: string | undefined, - propType: Node, - filenames: Set, - id: number | undefined + name: string, + jsDoc: string | undefined, + propType: Node, + filenames: Set, + id: number | undefined, ): PropTypeNode { - return { - type: typeString, - name, - jsDoc, - propType, - filenames, - $$id: id, - }; + return { + type: typeString, + name, + jsDoc, + propType, + filenames, + $$id: id, + }; } export function isPropTypeNode(node: Node): node is PropTypeNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/DOMElement.ts b/packages/typescript-to-proptypes/src/types/props/DOMElement.ts index aa32a6daa59c67..94c18a95e0d161 100644 --- a/packages/typescript-to-proptypes/src/types/props/DOMElement.ts +++ b/packages/typescript-to-proptypes/src/types/props/DOMElement.ts @@ -3,16 +3,16 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'DOMElementNode'; interface DOMElementNode extends Node { - optional?: boolean; + optional?: boolean; } export function DOMElementNode(optional?: boolean): DOMElementNode { - return { - type: typeString, - optional, - }; + return { + type: typeString, + optional, + }; } export function isDOMElementNode(node: Node): node is DOMElementNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/any.ts b/packages/typescript-to-proptypes/src/types/props/any.ts index 6efc5d447b393e..53d5ba1f767bda 100644 --- a/packages/typescript-to-proptypes/src/types/props/any.ts +++ b/packages/typescript-to-proptypes/src/types/props/any.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'AnyNode'; export function anyNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isAnyNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/array.ts b/packages/typescript-to-proptypes/src/types/props/array.ts index 8ce7ec3a2b63d8..f4396c522b964d 100644 --- a/packages/typescript-to-proptypes/src/types/props/array.ts +++ b/packages/typescript-to-proptypes/src/types/props/array.ts @@ -3,16 +3,16 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'ArrayNode'; export interface ArrayNode extends Node { - arrayType: Node; + arrayType: Node; } export function arrayNode(arrayType: Node): ArrayNode { - return { - type: typeString, - arrayType, - }; + return { + type: typeString, + arrayType, + }; } export function isArrayNode(node: Node): node is ArrayNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/boolean.ts b/packages/typescript-to-proptypes/src/types/props/boolean.ts index 9b59b38bf26124..d3cb6c5f181812 100644 --- a/packages/typescript-to-proptypes/src/types/props/boolean.ts +++ b/packages/typescript-to-proptypes/src/types/props/boolean.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'BooleanNode'; export function booleanNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isBooleanNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/element.ts b/packages/typescript-to-proptypes/src/types/props/element.ts index 6b73d653fc87a9..f5d8facd987be9 100644 --- a/packages/typescript-to-proptypes/src/types/props/element.ts +++ b/packages/typescript-to-proptypes/src/types/props/element.ts @@ -4,16 +4,16 @@ const typeString = 'ElementNode'; type ElementType = 'element' | 'node' | 'elementType'; interface ElementNode extends Node { - elementType: ElementType; + elementType: ElementType; } export function elementNode(elementType: ElementType): ElementNode { - return { - type: typeString, - elementType, - }; + return { + type: typeString, + elementType, + }; } export function isElementNode(node: Node): node is ElementNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/function.ts b/packages/typescript-to-proptypes/src/types/props/function.ts index 74568cb1321976..c4dd374e1af42e 100644 --- a/packages/typescript-to-proptypes/src/types/props/function.ts +++ b/packages/typescript-to-proptypes/src/types/props/function.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'FunctionNode'; export function functionNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isFunctionNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/instanceOf.ts b/packages/typescript-to-proptypes/src/types/props/instanceOf.ts index 84ee8fe2c9a41b..6de0b19c878850 100644 --- a/packages/typescript-to-proptypes/src/types/props/instanceOf.ts +++ b/packages/typescript-to-proptypes/src/types/props/instanceOf.ts @@ -3,16 +3,16 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'InstanceOfNode'; export interface InstanceOfNode extends Node { - instance: string; + instance: string; } export function instanceOfNode(instance: string): InstanceOfNode { - return { - type: typeString, - instance, - }; + return { + type: typeString, + instance, + }; } export function isInstanceOfNode(node: Node): node is InstanceOfNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/interface.ts b/packages/typescript-to-proptypes/src/types/props/interface.ts index 5238fab741b9b8..04d706c3e4c9ed 100644 --- a/packages/typescript-to-proptypes/src/types/props/interface.ts +++ b/packages/typescript-to-proptypes/src/types/props/interface.ts @@ -6,12 +6,12 @@ const typeString = 'InterfaceNode'; export interface InterfaceNode extends DefinitionHolder {} export function interfaceNode(types?: PropTypeNode[]): InterfaceNode { - return { - type: typeString, - types: types || [], - }; + return { + type: typeString, + types: types || [], + }; } export function isInterfaceNode(node: Node): node is InterfaceNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/literal.ts b/packages/typescript-to-proptypes/src/types/props/literal.ts index 53ed47cfdaca22..61bf211ec166b5 100644 --- a/packages/typescript-to-proptypes/src/types/props/literal.ts +++ b/packages/typescript-to-proptypes/src/types/props/literal.ts @@ -3,18 +3,18 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'LiteralNode'; export interface LiteralNode extends Node { - value: unknown; - jsDoc?: string; + value: unknown; + jsDoc?: string; } export function literalNode(value: unknown, jsDoc?: string): LiteralNode { - return { - type: typeString, - value, - jsDoc, - }; + return { + type: typeString, + value, + jsDoc, + }; } export function isLiteralNode(node: Node): node is LiteralNode { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/numeric.ts b/packages/typescript-to-proptypes/src/types/props/numeric.ts index 8283e5daabfae1..ad4d5598d64574 100644 --- a/packages/typescript-to-proptypes/src/types/props/numeric.ts +++ b/packages/typescript-to-proptypes/src/types/props/numeric.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'NumericNode'; export function numericNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isNumericNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/object.ts b/packages/typescript-to-proptypes/src/types/props/object.ts index 6302c9ad5f274d..2404fcfbe506ff 100644 --- a/packages/typescript-to-proptypes/src/types/props/object.ts +++ b/packages/typescript-to-proptypes/src/types/props/object.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'ObjectNode'; export function objectNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isObjectNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/string.ts b/packages/typescript-to-proptypes/src/types/props/string.ts index 948cb9562615ed..3ee7f7278c5452 100644 --- a/packages/typescript-to-proptypes/src/types/props/string.ts +++ b/packages/typescript-to-proptypes/src/types/props/string.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'StringNode'; export function stringNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isStringNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/undefined.ts b/packages/typescript-to-proptypes/src/types/props/undefined.ts index 7fcae455db454b..7252f38fdbbd75 100644 --- a/packages/typescript-to-proptypes/src/types/props/undefined.ts +++ b/packages/typescript-to-proptypes/src/types/props/undefined.ts @@ -3,11 +3,11 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'UndefinedNode'; export function undefinedNode(): Node { - return { - type: typeString, - }; + return { + type: typeString, + }; } export function isUndefinedNode(node: Node) { - return node.type === typeString; + return node.type === typeString; } diff --git a/packages/typescript-to-proptypes/src/types/props/union.ts b/packages/typescript-to-proptypes/src/types/props/union.ts index f39cf2a4c6764d..2100202cfd0390 100644 --- a/packages/typescript-to-proptypes/src/types/props/union.ts +++ b/packages/typescript-to-proptypes/src/types/props/union.ts @@ -5,47 +5,47 @@ import { Node } from '../nodes/baseNodes'; const typeString = 'UnionNode'; export interface UnionNode extends Node { - types: Node[]; + types: Node[]; } export function unionNode(types: Node[]): UnionNode { - const flatTypes: Node[] = []; - - flattenTypes(types); - - function flattenTypes(nodes: Node[]) { - nodes.forEach((x) => { - if (isUnionNode(x)) { - flattenTypes(x.types); - } else { - flatTypes.push(x); - } - }); - } - - return uniqueUnionTypes({ - type: typeString, - types: flatTypes, - }); + const flatTypes: Node[] = []; + + flattenTypes(types); + + function flattenTypes(nodes: Node[]) { + nodes.forEach((x) => { + if (isUnionNode(x)) { + flattenTypes(x.types); + } else { + flatTypes.push(x); + } + }); + } + + return uniqueUnionTypes({ + type: typeString, + types: flatTypes, + }); } export function isUnionNode(node: Node): node is UnionNode { - return node.type === typeString; + return node.type === typeString; } export function uniqueUnionTypes(node: UnionNode): UnionNode { - return { - type: node.type, - types: _.uniqBy(node.types, (x) => { - if (t.isLiteralNode(x)) { - return x.value; - } - - if (t.isInstanceOfNode(x)) { - return `${x.type}.${x.instance}`; - } - - return x.type; - }), - }; + return { + type: node.type, + types: _.uniqBy(node.types, (x) => { + if (t.isLiteralNode(x)) { + return x.value; + } + + if (t.isInstanceOfNode(x)) { + return `${x.type}.${x.instance}`; + } + + return x.type; + }), + }; } diff --git a/packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts b/packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts index a243a4828aefbe..953ef5a74ea240 100644 --- a/packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts +++ b/packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts @@ -1,7 +1,7 @@ type Props = { - foo?: boolean; - bar?: true; - baz?: false; + foo?: boolean; + bar?: true; + baz?: false; }; export default function Foo(props: Props): JSX.Element; diff --git a/packages/typescript-to-proptypes/test/boolean-values/optional/output.js b/packages/typescript-to-proptypes/test/boolean-values/optional/output.js index cda8542ed988b1..aa079154014638 100644 --- a/packages/typescript-to-proptypes/test/boolean-values/optional/output.js +++ b/packages/typescript-to-proptypes/test/boolean-values/optional/output.js @@ -1,5 +1,5 @@ Foo.propTypes = { - bar: PropTypes.oneOf([true]), - baz: PropTypes.oneOf([false]), - foo: PropTypes.bool, + bar: PropTypes.oneOf([true]), + baz: PropTypes.oneOf([false]), + foo: PropTypes.bool, }; diff --git a/packages/typescript-to-proptypes/test/boolean-values/optional/output.json b/packages/typescript-to-proptypes/test/boolean-values/optional/output.json deleted file mode 100644 index 2fa74cb00d1dc1..00000000000000 --- a/packages/typescript-to-proptypes/test/boolean-values/optional/output.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { - "type": "PropTypeNode", - "name": "foo", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - } - }, - { - "type": "PropTypeNode", - "name": "bar", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "LiteralNode", "value": "true" }] - } - }, - { - "type": "PropTypeNode", - "name": "baz", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "LiteralNode", "value": "false" }] - } - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts b/packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts index 6097b727fbda70..5567ba9073b92c 100644 --- a/packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts +++ b/packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts @@ -1,7 +1,7 @@ type Props = { - foo: boolean; - bar: true; - baz: false; + foo: boolean; + bar: true; + baz: false; }; export default function Foo(props: Props): JSX.Element; diff --git a/packages/typescript-to-proptypes/test/boolean-values/required/output.js b/packages/typescript-to-proptypes/test/boolean-values/required/output.js index b71cd916b5c60e..edda7e83e2c387 100644 --- a/packages/typescript-to-proptypes/test/boolean-values/required/output.js +++ b/packages/typescript-to-proptypes/test/boolean-values/required/output.js @@ -1,5 +1,5 @@ Foo.propTypes = { - bar: PropTypes.oneOf([true]).isRequired, - baz: PropTypes.oneOf([false]).isRequired, - foo: PropTypes.bool.isRequired, + bar: PropTypes.oneOf([true]).isRequired, + baz: PropTypes.oneOf([false]).isRequired, + foo: PropTypes.bool.isRequired, }; diff --git a/packages/typescript-to-proptypes/test/boolean-values/required/output.json b/packages/typescript-to-proptypes/test/boolean-values/required/output.json deleted file mode 100644 index 6ebd42d3e26de4..00000000000000 --- a/packages/typescript-to-proptypes/test/boolean-values/required/output.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { - "type": "PropTypeNode", - "name": "foo", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - } - }, - { - "type": "PropTypeNode", - "name": "bar", - "propType": { "type": "LiteralNode", "value": "true" } - }, - { - "type": "PropTypeNode", - "name": "baz", - "propType": { "type": "LiteralNode", "value": "false" } - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/code-order/input.d.ts b/packages/typescript-to-proptypes/test/code-order/input.d.ts index 8514adb4b518e6..4aeb223970ab39 100644 --- a/packages/typescript-to-proptypes/test/code-order/input.d.ts +++ b/packages/typescript-to-proptypes/test/code-order/input.d.ts @@ -1,7 +1,7 @@ import * as React from 'react'; export interface Props { - value: unknown; + value: unknown; } export default function Component(props: Props): JSX.Element; diff --git a/packages/typescript-to-proptypes/test/code-order/input.js b/packages/typescript-to-proptypes/test/code-order/input.js index 17888ed5f76939..705d857ec6b9fe 100644 --- a/packages/typescript-to-proptypes/test/code-order/input.js +++ b/packages/typescript-to-proptypes/test/code-order/input.js @@ -2,14 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; function Component(props) { - const { value } = props; - return
{value}
; + const { value } = props; + return
{value}
; } const someValidator = () => new Error(); Component.propTypes = { - value: PropTypes.any, + value: PropTypes.any, }; export default Component; diff --git a/packages/typescript-to-proptypes/test/code-order/options.ts b/packages/typescript-to-proptypes/test/code-order/options.ts index 3bc4ff628ba340..ff62741ad38997 100644 --- a/packages/typescript-to-proptypes/test/code-order/options.ts +++ b/packages/typescript-to-proptypes/test/code-order/options.ts @@ -1,9 +1,9 @@ import { TestOptions } from '../types'; const options: TestOptions = { - injector: { - removeExistingPropTypes: true, - }, + injector: { + removeExistingPropTypes: true, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/code-order/output.js b/packages/typescript-to-proptypes/test/code-order/output.js index 81bed5618f6d2a..4e89c18b1f7913 100644 --- a/packages/typescript-to-proptypes/test/code-order/output.js +++ b/packages/typescript-to-proptypes/test/code-order/output.js @@ -2,14 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; function Component(props) { - const { value } = props; - return
{value}
; + const { value } = props; + return
{value}
; } const someValidator = () => new Error(); Component.propTypes = { - value: PropTypes.any.isRequired, + value: PropTypes.any.isRequired, }; export default Component; diff --git a/packages/typescript-to-proptypes/test/code-order/output.json b/packages/typescript-to-proptypes/test/code-order/output.json deleted file mode 100644 index 2e7bbf419ab8fa..00000000000000 --- a/packages/typescript-to-proptypes/test/code-order/output.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Component", - "types": [{ "type": "PropTypeNode", "name": "value", "propType": { "type": "AnyNode" } }] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts b/packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts index bead446ee4055c..ae12666f21c37d 100644 --- a/packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts +++ b/packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts @@ -1,6 +1,6 @@ export function Foo(props: { - element: Element; - optional?: Element; - htmlElement: HTMLElement; - bothTypes: Element | HTMLElement; + element: Element; + optional?: Element; + htmlElement: HTMLElement; + bothTypes: Element | HTMLElement; }): JSX.Element; diff --git a/packages/typescript-to-proptypes/test/generator/html-elements/output.js b/packages/typescript-to-proptypes/test/generator/html-elements/output.js index 2f83837d4bdff3..b3d973dd409bb6 100644 --- a/packages/typescript-to-proptypes/test/generator/html-elements/output.js +++ b/packages/typescript-to-proptypes/test/generator/html-elements/output.js @@ -1,30 +1,30 @@ Foo.propTypes = { - bothTypes: function (props, propName) { - if (props[propName] == null) { - return new Error("Prop '" + propName + "' is required but wasn't specified"); - } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error("Expected prop '" + propName + "' to be of type Element"); - } - }, - element: function (props, propName) { - if (props[propName] == null) { - return new Error("Prop '" + propName + "' is required but wasn't specified"); - } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error("Expected prop '" + propName + "' to be of type Element"); - } - }, - htmlElement: function (props, propName) { - if (props[propName] == null) { - return new Error("Prop '" + propName + "' is required but wasn't specified"); - } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error("Expected prop '" + propName + "' to be of type Element"); - } - }, - optional: function (props, propName) { - if (props[propName] == null) { - return null; - } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error("Expected prop '" + propName + "' to be of type Element"); - } - }, + bothTypes: function (props, propName) { + if (props[propName] == null) { + return new Error("Prop '" + propName + "' is required but wasn't specified"); + } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error("Expected prop '" + propName + "' to be of type Element"); + } + }, + element: function (props, propName) { + if (props[propName] == null) { + return new Error("Prop '" + propName + "' is required but wasn't specified"); + } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error("Expected prop '" + propName + "' to be of type Element"); + } + }, + htmlElement: function (props, propName) { + if (props[propName] == null) { + return new Error("Prop '" + propName + "' is required but wasn't specified"); + } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error("Expected prop '" + propName + "' to be of type Element"); + } + }, + optional: function (props, propName) { + if (props[propName] == null) { + return null; + } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error("Expected prop '" + propName + "' to be of type Element"); + } + }, }; diff --git a/packages/typescript-to-proptypes/test/generator/html-elements/output.json b/packages/typescript-to-proptypes/test/generator/html-elements/output.json deleted file mode 100644 index 8f7ff7184116d3..00000000000000 --- a/packages/typescript-to-proptypes/test/generator/html-elements/output.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { "type": "PropTypeNode", "name": "element", "propType": { "type": "DOMElementNode" } }, - { - "type": "PropTypeNode", - "name": "optional", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "DOMElementNode" }] - } - }, - { "type": "PropTypeNode", "name": "htmlElement", "propType": { "type": "DOMElementNode" } }, - { "type": "PropTypeNode", "name": "bothTypes", "propType": { "type": "DOMElementNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/index.test.ts b/packages/typescript-to-proptypes/test/index.test.ts index 29bb25037c9ea8..e1e53b2e1ab21d 100644 --- a/packages/typescript-to-proptypes/test/index.test.ts +++ b/packages/typescript-to-proptypes/test/index.test.ts @@ -1,6 +1,6 @@ import path from 'path'; import fs from 'fs'; - +import { expect } from 'chai'; import glob from 'glob'; import prettier from 'prettier'; import * as ttp from '../src'; @@ -12,97 +12,63 @@ const testCases = glob.sync('**/input.{d.ts,ts,tsx}', { absolute: true, cwd: __d // Create program for all files to speed up tests const program = ttp.createProgram( - testCases, - ttp.loadConfig(path.resolve(__dirname, '../tsconfig.json')) + testCases, + ttp.loadConfig(path.resolve(__dirname, '../tsconfig.json')), ); for (const testCase of testCases) { - const dirname = path.dirname(testCase); - const testName = dirname.substr(__dirname.length + 1); - const astPath = path.join(dirname, 'output.json'); - const outputPath = path.join(dirname, 'output.js'); - const optionsPath = path.join(dirname, 'options.ts'); - const inputJS = path.join(dirname, 'input.js'); - - it(testName, () => { - const options: TestOptions = fs.existsSync(optionsPath) ? require(optionsPath).default : {}; - - const ast = ttp.parseFromProgram(testCase, program, options.parser); + const dirname = path.dirname(testCase); + const testName = dirname.substr(__dirname.length + 1); + const outputPath = path.join(dirname, 'output.js'); + const optionsPath = path.join(dirname, 'options.ts'); + const inputJS = path.join(dirname, 'input.js'); - //#region Check AST matches - // propsFilename will be different depending on where the project is on disk - // Manually check that it's correct and then delete it - const newAST = ttp.programNode( - ast.body.map((component) => { - expect(component.propsFilename).toBe(testCase); - return { ...component, propsFilename: undefined }; - }) - ); + it(testName, () => { + const options: TestOptions = fs.existsSync(optionsPath) ? require(optionsPath).default : {}; - if (fs.existsSync(astPath)) { - expect(newAST).toMatchObject(JSON.parse(fs.readFileSync(astPath, 'utf8'))); - } else { - fs.writeFileSync( - astPath, - prettier.format( - JSON.stringify(newAST, (key, value) => { - // These are TypeScript internals that change depending on the number of symbols created during test - if (key === '$$id') { - return undefined; - } - return value; - }), - { - ...prettierConfig, - filepath: astPath, - } - ) - ); - } - //#endregion + const ast = ttp.parseFromProgram(testCase, program, options.parser); - let inputSource = null; - if (testCase.endsWith('.d.ts')) { - try { - inputSource = fs.readFileSync(inputJS, 'utf8'); - } catch (error) {} - } else { - inputSource = ttp.ts.transpileModule(fs.readFileSync(testCase, 'utf8'), { - compilerOptions: { - target: ttp.ts.ScriptTarget.ESNext, - jsx: ttp.ts.JsxEmit.Preserve, - }, - }).outputText; - } + let inputSource = null; + if (testCase.endsWith('.d.ts')) { + try { + inputSource = fs.readFileSync(inputJS, 'utf8'); + } catch (error) { + // ignore + } + } else { + inputSource = ttp.ts.transpileModule(fs.readFileSync(testCase, 'utf8'), { + compilerOptions: { + target: ttp.ts.ScriptTarget.ESNext, + jsx: ttp.ts.JsxEmit.Preserve, + }, + }).outputText; + } - let result = ''; - // For d.ts files we just generate the AST - if (!inputSource) { - result = ttp.generate(ast, options.generator); - } - // For .tsx? files we transpile them and inject the proptypes - else { - const injected = ttp.inject(ast, inputSource, options.injector); - if (!injected) { - throw new Error('Injection failed'); - } + let result = ''; + // For d.ts files we just generate the AST + if (!inputSource) { + result = ttp.generate(ast, options.generator); + } else { + // For .tsx? files we transpile them and inject the proptypesu + const injected = ttp.inject(ast, inputSource, options.injector); + if (!injected) { + throw new Error('Injection failed'); + } - result = injected; - } + result = injected; + } - //#region Check generated and/or injected proptypes - const propTypes = prettier.format(result, { - ...prettierConfig, - filepath: outputPath, - }); + const propTypes = prettier.format(result, { + ...prettierConfig, + filepath: outputPath, + }); - if (fs.existsSync(outputPath)) { - expect(propTypes.replace(/\r?\n/, '\n')).toMatch( - fs.readFileSync(outputPath, 'utf8').replace(/\r?\n/, '\n') - ); - } else { - fs.writeFileSync(outputPath, propTypes); - } - //#endregion - }); + if (fs.existsSync(outputPath)) { + expect(propTypes.replace(/\r?\n/, '\n')).to.include( + fs.readFileSync(outputPath, 'utf8').replace(/\r?\n/, '\n'), + ); + } else { + fs.writeFileSync(outputPath, propTypes); + } + }); } diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx b/packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx index 24427c15153f51..7c645be5e97c97 100644 --- a/packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx +++ b/packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx @@ -1,3 +1,3 @@ export function Foo(props: { className: string }) { - return
; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts b/packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts index 836db5a3419ce2..d35ea30af4d3a1 100644 --- a/packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts +++ b/packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts @@ -1,11 +1,11 @@ import { TestOptions } from '../../types'; const options: TestOptions = { - injector: { - shouldInclude() { - return false; - }, - }, + injector: { + shouldInclude() { + return false; + }, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js b/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js index 90c2037bff0645..8990d420a23320 100644 --- a/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js +++ b/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js @@ -1,3 +1,3 @@ export function Foo(props) { - return
; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.json b/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.json deleted file mode 100644 index e2ca53b64d00dd..00000000000000 --- a/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { "type": "PropTypeNode", "name": "className", "propType": { "type": "StringNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx b/packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx index 080f829d9a42e4..e673ba883b533e 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx +++ b/packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx @@ -1,20 +1,20 @@ import * as React from 'react'; export interface SnackBarProps { - /** - * Some hints about why this is useful - */ - id?: string; - /** - * some prop that is inherited which we don't care about here - */ - onChange?: () => void; + /** + * Some hints about why this is useful + */ + id?: string; + /** + * some prop that is inherited which we don't care about here + */ + onChange?: () => void; } export function Snackbar(props: SnackBarProps) { - return
; + return
; } export function SomeOtherComponent(props: { id?: string }) { - return
; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts b/packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts index c6f61990c70872..4f2b75b3f6572a 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts +++ b/packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts @@ -1,13 +1,13 @@ import { TestOptions } from '../../types'; const options: TestOptions = { - injector: { - shouldInclude({ component, prop }) { - if (component.name === 'Snackbar' && prop.name === 'id') { - return true; - } - }, - }, + injector: { + shouldInclude({ component, prop }) { + if (component.name === 'Snackbar' && prop.name === 'id') { + return true; + } + }, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js b/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js index 420ca08e569d8d..637bce8c10f4ba 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js +++ b/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js @@ -1,17 +1,17 @@ import * as React from 'react'; import PropTypes from 'prop-types'; function Snackbar(props) { - return
; + return
; } Snackbar.propTypes = { - /** - * Some hints about why this is useful - */ - id: PropTypes.string, + /** + * Some hints about why this is useful + */ + id: PropTypes.string, }; export { Snackbar }; export function SomeOtherComponent(props) { - return
; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.json b/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.json deleted file mode 100644 index 666f8ac3cdc478..00000000000000 --- a/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Snackbar", - "types": [ - { - "type": "PropTypeNode", - "name": "id", - "jsDoc": "Some hints about why this is useful", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - } - }, - { - "type": "PropTypeNode", - "name": "onChange", - "jsDoc": "some prop that is inherited which we don't care about here", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - } - } - ] - }, - { - "type": "ComponentNode", - "name": "SomeOtherComponent", - "types": [ - { - "type": "PropTypeNode", - "name": "id", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - } - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx index 628f1d55d1d854..2a539680c93ca9 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx +++ b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx @@ -4,17 +4,17 @@ import * as React from 'react'; // sees not just the one available to the user. We're abusing this to provide // some concrete documentation for `key` regarding this component export interface SnackBarProps extends React.HTMLAttributes { - /** - * some hints about state reset that relates to prop of this component - */ - key?: any; + /** + * some hints about state reset that relates to prop of this component + */ + key?: any; } export function Snackbar(props: SnackBarProps) { - return
; + return
; } // here we don't care about `key` export function SomeOtherComponent(props: { children?: React.ReactNode }) { - return
{props.children}
; + return
{props.children}
; } diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts index 02899675b6bc62..9adc283b899f15 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts +++ b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts @@ -2,18 +2,18 @@ import * as path from 'path'; import { TestOptions } from '../../types'; const options: TestOptions = { - injector: { - includeUnusedProps: true, - shouldInclude: ({ prop }) => { - let isLocallyTyped = false; - prop.filenames.forEach((filename) => { - if (!path.relative(__dirname, filename).startsWith('..')) { - isLocallyTyped = true; - } - }); - return isLocallyTyped; - }, - }, + injector: { + includeUnusedProps: true, + shouldInclude: ({ prop }) => { + let isLocallyTyped = false; + prop.filenames.forEach((filename) => { + if (!path.relative(__dirname, filename).startsWith('..')) { + isLocallyTyped = true; + } + }); + return isLocallyTyped; + }, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js index 30863cd1af15c4..ed64a09559357f 100644 --- a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js +++ b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js @@ -1,24 +1,24 @@ import * as React from 'react'; import PropTypes from 'prop-types'; function Snackbar(props) { - return
; + return
; } // here we don't care about `key` Snackbar.propTypes = { - /** - * some hints about state reset that relates to prop of this component - */ - key: PropTypes.any, + /** + * some hints about state reset that relates to prop of this component + */ + key: PropTypes.any, }; export { Snackbar }; function SomeOtherComponent(props) { - return
{props.children}
; + return
{props.children}
; } SomeOtherComponent.propTypes = { - children: PropTypes.node, + children: PropTypes.node, }; export { SomeOtherComponent }; diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.json b/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.json deleted file mode 100644 index bec47bd13276a5..00000000000000 --- a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.json +++ /dev/null @@ -1,2566 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Snackbar", - "types": [ - { - "type": "PropTypeNode", - "name": "key", - "jsDoc": "some hints about state reset that relates to prop of this component", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "AnyNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "defaultChecked", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "defaultValue", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "StringNode" }, - { "type": "ArrayNode", "arrayType": { "type": "StringNode" } } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "suppressContentEditableWarning", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "suppressHydrationWarning", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "accessKey", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "className", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "contentEditable", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "contextMenu", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "dir", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "draggable", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "hidden", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "id", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "lang", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "placeholder", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "slot", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "spellCheck", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "style", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "ObjectNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "tabIndex", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "title", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "inputMode", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "is", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "radioGroup", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "role", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "about", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "datatype", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "inlist", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "AnyNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "prefix", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "property", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "resource", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "typeof", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "vocab", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "autoCapitalize", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "autoCorrect", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "autoSave", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "color", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "itemProp", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "itemScope", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "itemType", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "itemID", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "itemRef", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "results", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "security", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "unselectable", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"on\"" }, - { "type": "LiteralNode", "value": "\"off\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-activedescendant", - "jsDoc": "Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-atomic", - "jsDoc": "Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-autocomplete", - "jsDoc": "Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"none\"" }, - { "type": "LiteralNode", "value": "\"inline\"" }, - { "type": "LiteralNode", "value": "\"list\"" }, - { "type": "LiteralNode", "value": "\"both\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-busy", - "jsDoc": "Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-checked", - "jsDoc": "Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets.\n@see aria-pressed @see aria-selected.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" }, - { "type": "LiteralNode", "value": "\"mixed\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-colcount", - "jsDoc": "Defines the total number of columns in a table, grid, or treegrid.\n@see aria-colindex.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-colindex", - "jsDoc": "Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid.\n@see aria-colcount @see aria-colspan.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-colspan", - "jsDoc": "Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.\n@see aria-colindex @see aria-rowspan.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-controls", - "jsDoc": "Identifies the element (or elements) whose contents or presence are controlled by the current element.\n@see aria-owns.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-current", - "jsDoc": "Indicates the element that represents the current item within a container or set of related elements.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" }, - { "type": "LiteralNode", "value": "\"page\"" }, - { "type": "LiteralNode", "value": "\"step\"" }, - { "type": "LiteralNode", "value": "\"location\"" }, - { "type": "LiteralNode", "value": "\"date\"" }, - { "type": "LiteralNode", "value": "\"time\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-describedby", - "jsDoc": "Identifies the element (or elements) that describes the object.\n@see aria-labelledby", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-details", - "jsDoc": "Identifies the element that provides a detailed, extended description for the object.\n@see aria-describedby.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-disabled", - "jsDoc": "Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.\n@see aria-hidden @see aria-readonly.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-dropeffect", - "jsDoc": "Indicates what functions can be performed when a dragged object is released on the drop target.\n@deprecated in ARIA 1.1", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"none\"" }, - { "type": "LiteralNode", "value": "\"copy\"" }, - { "type": "LiteralNode", "value": "\"execute\"" }, - { "type": "LiteralNode", "value": "\"link\"" }, - { "type": "LiteralNode", "value": "\"move\"" }, - { "type": "LiteralNode", "value": "\"popup\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-errormessage", - "jsDoc": "Identifies the element that provides an error message for the object.\n@see aria-invalid @see aria-describedby.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-expanded", - "jsDoc": "Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-flowto", - "jsDoc": "Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,\nallows assistive technology to override the general default of reading in document source order.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-grabbed", - "jsDoc": "Indicates an element's \"grabbed\" state in a drag-and-drop operation.\n@deprecated in ARIA 1.1", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-haspopup", - "jsDoc": "Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" }, - { "type": "LiteralNode", "value": "\"menu\"" }, - { "type": "LiteralNode", "value": "\"listbox\"" }, - { "type": "LiteralNode", "value": "\"tree\"" }, - { "type": "LiteralNode", "value": "\"grid\"" }, - { "type": "LiteralNode", "value": "\"dialog\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-hidden", - "jsDoc": "Indicates whether the element is exposed to an accessibility API.\n@see aria-disabled.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-invalid", - "jsDoc": "Indicates the entered value does not conform to the format expected by the application.\n@see aria-errormessage.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" }, - { "type": "LiteralNode", "value": "\"grammar\"" }, - { "type": "LiteralNode", "value": "\"spelling\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-keyshortcuts", - "jsDoc": "Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-label", - "jsDoc": "Defines a string value that labels the current element.\n@see aria-labelledby.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-labelledby", - "jsDoc": "Identifies the element (or elements) that labels the current element.\n@see aria-describedby.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-level", - "jsDoc": "Defines the hierarchical level of an element within a structure.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-live", - "jsDoc": "Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"off\"" }, - { "type": "LiteralNode", "value": "\"assertive\"" }, - { "type": "LiteralNode", "value": "\"polite\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-modal", - "jsDoc": "Indicates whether an element is modal when displayed.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-multiline", - "jsDoc": "Indicates whether a text box accepts multiple lines of input or only a single line.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-multiselectable", - "jsDoc": "Indicates that the user may select more than one item from the current selectable descendants.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-orientation", - "jsDoc": "Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"horizontal\"" }, - { "type": "LiteralNode", "value": "\"vertical\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-owns", - "jsDoc": "Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship\nbetween DOM elements where the DOM hierarchy cannot be used to represent the relationship.\n@see aria-controls.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-placeholder", - "jsDoc": "Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.\nA hint could be a sample value or a brief description of the expected format.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-posinset", - "jsDoc": "Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n@see aria-setsize.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-pressed", - "jsDoc": "Indicates the current \"pressed\" state of toggle buttons.\n@see aria-checked @see aria-selected.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" }, - { "type": "LiteralNode", "value": "\"mixed\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-readonly", - "jsDoc": "Indicates that the element is not editable, but is otherwise operable.\n@see aria-disabled.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-relevant", - "jsDoc": "Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.\n@see aria-atomic.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"additions\"" }, - { "type": "LiteralNode", "value": "\"additions text\"" }, - { "type": "LiteralNode", "value": "\"all\"" }, - { "type": "LiteralNode", "value": "\"removals\"" }, - { "type": "LiteralNode", "value": "\"text\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-required", - "jsDoc": "Indicates that user input is required on the element before a form may be submitted.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-roledescription", - "jsDoc": "Defines a human-readable, author-localized description for the role of an element.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-rowcount", - "jsDoc": "Defines the total number of rows in a table, grid, or treegrid.\n@see aria-rowindex.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-rowindex", - "jsDoc": "Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid.\n@see aria-rowcount @see aria-rowspan.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-rowspan", - "jsDoc": "Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.\n@see aria-rowindex @see aria-colspan.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-selected", - "jsDoc": "Indicates the current \"selected\" state of various widgets.\n@see aria-checked @see aria-pressed.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "false" }, - { "type": "LiteralNode", "value": "true" }, - { "type": "LiteralNode", "value": "\"false\"" }, - { "type": "LiteralNode", "value": "\"true\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-setsize", - "jsDoc": "Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n@see aria-posinset.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-sort", - "jsDoc": "Indicates if items in a table or grid are sorted in ascending or descending order.", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"none\"" }, - { "type": "LiteralNode", "value": "\"ascending\"" }, - { "type": "LiteralNode", "value": "\"descending\"" }, - { "type": "LiteralNode", "value": "\"other\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-valuemax", - "jsDoc": "Defines the maximum allowed value for a range widget.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-valuemin", - "jsDoc": "Defines the minimum allowed value for a range widget.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-valuenow", - "jsDoc": "Defines the current value for a range widget.\n@see aria-valuetext.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "NumericNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "aria-valuetext", - "jsDoc": "Defines the human readable text alternative of aria-valuenow for a range widget.", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "children", - "propType": { - "type": "UnionNode", - "types": [{ "type": "ElementNode", "elementType": "node" }, { "type": "UndefinedNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "dangerouslySetInnerHTML", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { - "type": "InterfaceNode", - "types": [ - { - "type": "PropTypeNode", - "name": "__html", - "propType": { "type": "StringNode" }, - "filenames": {} - } - ] - } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCopy", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCopyCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCut", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCutCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPaste", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPasteCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionEnd", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionEndCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionStart", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionStartCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionUpdate", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCompositionUpdateCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onFocus", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onFocusCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onBlur", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onBlurCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onChange", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onChangeCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onBeforeInput", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onBeforeInputCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onInput", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onInputCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onReset", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onResetCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSubmit", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSubmitCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onInvalid", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onInvalidCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoad", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onError", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onErrorCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyDown", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyDownCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyPress", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyPressCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyUp", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onKeyUpCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAbort", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAbortCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCanPlay", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCanPlayCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCanPlayThrough", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onCanPlayThroughCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDurationChange", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDurationChangeCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEmptied", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEmptiedCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEncrypted", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEncryptedCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEnded", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onEndedCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadedData", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadedDataCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadedMetadata", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadedMetadataCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadStart", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLoadStartCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPause", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPauseCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPlay", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPlayCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPlaying", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPlayingCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onProgress", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onProgressCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onRateChange", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onRateChangeCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSeeked", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSeekedCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSeeking", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSeekingCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onStalled", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onStalledCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSuspend", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSuspendCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTimeUpdate", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTimeUpdateCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onVolumeChange", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onVolumeChangeCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onWaiting", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onWaitingCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAuxClick", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAuxClickCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onClick", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onClickCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onContextMenu", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onContextMenuCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDoubleClick", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDoubleClickCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDrag", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragEnd", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragEndCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragEnter", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragEnterCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragExit", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragExitCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragLeave", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragLeaveCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragOver", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragOverCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragStart", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDragStartCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDrop", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onDropCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseDown", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseDownCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseEnter", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseLeave", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseMove", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseMoveCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseOut", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseOutCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseOver", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseOverCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseUp", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onMouseUpCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSelect", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onSelectCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchCancel", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchCancelCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchEnd", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchEndCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchMove", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchMoveCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchStart", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTouchStartCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerDown", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerDownCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerMove", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerMoveCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerUp", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerUpCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerCancel", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerCancelCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerEnter", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerEnterCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerLeave", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerLeaveCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerOver", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerOverCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerOut", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onPointerOutCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onGotPointerCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onGotPointerCaptureCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLostPointerCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onLostPointerCaptureCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onScroll", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onScrollCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onWheel", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onWheelCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationStart", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationStartCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationEnd", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationEndCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationIteration", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onAnimationIterationCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTransitionEnd", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "onTransitionEndCapture", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "FunctionNode" }] - }, - "filenames": {} - } - ] - }, - { - "type": "ComponentNode", - "name": "SomeOtherComponent", - "types": [ - { - "type": "PropTypeNode", - "name": "children", - "propType": { - "type": "UnionNode", - "types": [{ "type": "ElementNode", "elementType": "node" }, { "type": "UndefinedNode" }] - }, - "filenames": {} - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/injector/string-props/input.tsx b/packages/typescript-to-proptypes/test/injector/string-props/input.tsx index ef31a4d008db88..f9a9f6d74272ed 100644 --- a/packages/typescript-to-proptypes/test/injector/string-props/input.tsx +++ b/packages/typescript-to-proptypes/test/injector/string-props/input.tsx @@ -1,4 +1,4 @@ export default function Dialog(props: { 'aria-describedby': string }) { - const { 'aria-describedby': ariaDescribedby } = props; - return
; + const { 'aria-describedby': ariaDescribedby } = props; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/string-props/output.js b/packages/typescript-to-proptypes/test/injector/string-props/output.js index 9a6404d36d2ed2..3f647392c304e4 100644 --- a/packages/typescript-to-proptypes/test/injector/string-props/output.js +++ b/packages/typescript-to-proptypes/test/injector/string-props/output.js @@ -1,11 +1,11 @@ import PropTypes from 'prop-types'; function Dialog(props) { - const { 'aria-describedby': ariaDescribedby } = props; - return
; + const { 'aria-describedby': ariaDescribedby } = props; + return
; } Dialog.propTypes = { - 'aria-describedby': PropTypes.string.isRequired, + 'aria-describedby': PropTypes.string.isRequired, }; export default Dialog; diff --git a/packages/typescript-to-proptypes/test/injector/string-props/output.json b/packages/typescript-to-proptypes/test/injector/string-props/output.json deleted file mode 100644 index 977d521f82cca8..00000000000000 --- a/packages/typescript-to-proptypes/test/injector/string-props/output.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Dialog", - "types": [ - { "type": "PropTypeNode", "name": "aria-describedby", "propType": { "type": "StringNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx b/packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx index 7693638e252629..065a1e8559bad2 100644 --- a/packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx +++ b/packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx @@ -1,3 +1,3 @@ export default function Foo(props: { className: string }) { - return
; + return
; } diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts b/packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts index ef9fdf4a386f20..933d5e31648e14 100644 --- a/packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts +++ b/packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts @@ -1,11 +1,11 @@ import { TestOptions } from '../../types'; const options: TestOptions = { - injector: { - shouldInclude() { - return true; - }, - }, + injector: { + shouldInclude() { + return true; + }, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js b/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js index 9c0ae142649f54..6ecb9fe098fa5a 100644 --- a/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js +++ b/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js @@ -1,10 +1,10 @@ import PropTypes from 'prop-types'; function Foo(props) { - return
; + return
; } Foo.propTypes = { - className: PropTypes.string.isRequired, + className: PropTypes.string.isRequired, }; export default Foo; diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.json b/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.json deleted file mode 100644 index e2ca53b64d00dd..00000000000000 --- a/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { "type": "PropTypeNode", "name": "className", "propType": { "type": "StringNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/mixed-literals/input.tsx b/packages/typescript-to-proptypes/test/mixed-literals/input.tsx index 5da4df9362da20..29bbe4e1e032a0 100644 --- a/packages/typescript-to-proptypes/test/mixed-literals/input.tsx +++ b/packages/typescript-to-proptypes/test/mixed-literals/input.tsx @@ -1,8 +1,8 @@ interface GridProps { - spacing?: 'initial' | 1 | 2 | 3 | 4 | 5 | 'auto'; + spacing?: 'initial' | 1 | 2 | 3 | 4 | 5 | 'auto'; } export default function Grid(props: GridProps) { - const { spacing } = props; - return
spacing: {spacing}
; + const { spacing } = props; + return
spacing: {spacing}
; } diff --git a/packages/typescript-to-proptypes/test/mixed-literals/output.js b/packages/typescript-to-proptypes/test/mixed-literals/output.js index 18c69f178bce33..b9a1d965d45fe1 100644 --- a/packages/typescript-to-proptypes/test/mixed-literals/output.js +++ b/packages/typescript-to-proptypes/test/mixed-literals/output.js @@ -1,11 +1,11 @@ import PropTypes from 'prop-types'; function Grid(props) { - const { spacing } = props; - return
spacing: {spacing}
; + const { spacing } = props; + return
spacing: {spacing}
; } Grid.propTypes = { - spacing: PropTypes.oneOf(['auto', 'initial', 1, 2, 3, 4, 5]), + spacing: PropTypes.oneOf(['auto', 'initial', 1, 2, 3, 4, 5]), }; export default Grid; diff --git a/packages/typescript-to-proptypes/test/mixed-literals/output.json b/packages/typescript-to-proptypes/test/mixed-literals/output.json deleted file mode 100644 index d891f271f13b4c..00000000000000 --- a/packages/typescript-to-proptypes/test/mixed-literals/output.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Grid", - "types": [ - { - "type": "PropTypeNode", - "name": "spacing", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"initial\"" }, - { "type": "LiteralNode", "value": 1 }, - { "type": "LiteralNode", "value": 2 }, - { "type": "LiteralNode", "value": 3 }, - { "type": "LiteralNode", "value": 4 }, - { "type": "LiteralNode", "value": 5 }, - { "type": "LiteralNode", "value": "\"auto\"" } - ] - }, - "filenames": {} - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/options-test/input.tsx b/packages/typescript-to-proptypes/test/options-test/input.tsx index cd74a9390058f9..0fe38e0880b241 100644 --- a/packages/typescript-to-proptypes/test/options-test/input.tsx +++ b/packages/typescript-to-proptypes/test/options-test/input.tsx @@ -1,16 +1,16 @@ type DeepOptions = { - PropB: string; + PropB: string; }; type Options = { - /** - * This jsdoc will be ignored - */ - PropA: string; - TestProps: DeepOptions; + /** + * This jsdoc will be ignored + */ + PropA: string; + TestProps: DeepOptions; }; export default function Foo(props: Options) { - const { PropA, TestProps } = props; - return
; + const { PropA, TestProps } = props; + return
; } diff --git a/packages/typescript-to-proptypes/test/options-test/options.ts b/packages/typescript-to-proptypes/test/options-test/options.ts index 477b17888d547e..85f340a76c7db1 100644 --- a/packages/typescript-to-proptypes/test/options-test/options.ts +++ b/packages/typescript-to-proptypes/test/options-test/options.ts @@ -1,17 +1,17 @@ import { TestOptions } from '../types'; const options: TestOptions = { - parser: { - shouldResolveObject({ name }) { - if (name.endsWith('Props')) { - return false; - } - }, - }, - injector: { - includeJSDoc: false, - comment: 'Proptypes generated automatically', - }, + parser: { + shouldResolveObject({ name }) { + if (name.endsWith('Props')) { + return false; + } + }, + }, + injector: { + includeJSDoc: false, + comment: 'Proptypes generated automatically', + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/options-test/output.js b/packages/typescript-to-proptypes/test/options-test/output.js index 326b8997ded043..2c641173d924f9 100644 --- a/packages/typescript-to-proptypes/test/options-test/output.js +++ b/packages/typescript-to-proptypes/test/options-test/output.js @@ -1,13 +1,13 @@ import PropTypes from 'prop-types'; function Foo(props) { - const { PropA, TestProps } = props; - return
; + const { PropA, TestProps } = props; + return
; } Foo.propTypes = { - // Proptypes generated automatically - PropA: PropTypes.string.isRequired, - TestProps: PropTypes.object.isRequired, + // Proptypes generated automatically + PropA: PropTypes.string.isRequired, + TestProps: PropTypes.object.isRequired, }; export default Foo; diff --git a/packages/typescript-to-proptypes/test/options-test/output.json b/packages/typescript-to-proptypes/test/options-test/output.json deleted file mode 100644 index 818a51ecb1539e..00000000000000 --- a/packages/typescript-to-proptypes/test/options-test/output.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { - "type": "PropTypeNode", - "name": "PropA", - "jsDoc": "This jsdoc will be ignored", - "propType": { "type": "StringNode" } - }, - { "type": "PropTypeNode", "name": "TestProps", "propType": { "type": "ObjectNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts b/packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts index c9550605c41489..5e9d3028d4404d 100644 --- a/packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts +++ b/packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts @@ -1,11 +1,11 @@ import * as React from 'react'; interface ButtonProps { - variant?: string; + variant?: string; } interface Component { - (props: ButtonProps): JSX.Element; - (props: { component: C } & ButtonProps): JSX.Element; + (props: ButtonProps): JSX.Element; + (props: { component: C } & ButtonProps): JSX.Element; } // a component using overloading and intersection of function signature diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts b/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts index c91ca64d1e3900..2fa9ca8cddac8b 100644 --- a/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts +++ b/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts @@ -1,9 +1,9 @@ import { TestOptions } from '../types'; const options: TestOptions = { - parser: { - checkDeclarations: true, - }, + parser: { + checkDeclarations: true, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/output.js b/packages/typescript-to-proptypes/test/overloaded-function-component/output.js index f743a62f06973f..14bedffffb7061 100644 --- a/packages/typescript-to-proptypes/test/overloaded-function-component/output.js +++ b/packages/typescript-to-proptypes/test/overloaded-function-component/output.js @@ -1,5 +1,5 @@ ButtonBase.propTypes = { - component: PropTypes.elementType, - href: PropTypes.string, - variant: PropTypes.string, + component: PropTypes.elementType, + href: PropTypes.string, + variant: PropTypes.string, }; diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/output.json b/packages/typescript-to-proptypes/test/overloaded-function-component/output.json deleted file mode 100644 index c463f8550597b6..00000000000000 --- a/packages/typescript-to-proptypes/test/overloaded-function-component/output.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "ButtonBase", - "types": [ - { - "type": "PropTypeNode", - "name": "variant", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "StringNode" }] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "component", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "ElementNode", "elementType": "elementType" }, - { "type": "UndefinedNode" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "href", - "propType": { - "type": "UnionNode", - "types": [{ "type": "StringNode" }, { "type": "UndefinedNode" }] - }, - "filenames": {} - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts b/packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts index dd871cb7becd0c..355b4294e0857f 100644 --- a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts +++ b/packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts @@ -1,7 +1,7 @@ import * as React from 'react'; interface Props { - children: React.ReactNode; + children: React.ReactNode; } export default function Component(props: Props): JSX.Element; diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.js b/packages/typescript-to-proptypes/test/reconcile-prop-types/input.js index 8323a3442421b4..7adc38f157a388 100644 --- a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.js +++ b/packages/typescript-to-proptypes/test/reconcile-prop-types/input.js @@ -3,27 +3,27 @@ import * as PropTypes from 'prop-types'; import { chainPropTypes } from 'some-utils-module'; function Component(props) { - const { children } = props; - return ( - - ); + const { children } = props; + return ( + + ); } Component.propTypes = { - children: chainPropTypes(PropTypes.node.isRequired, (props) => { - const summary = React.Children.toArray(props.children)[0]; - if (isFragment(summary)) { - return new Error('Not accepting Fragments'); - } + children: chainPropTypes(PropTypes.node.isRequired, (props) => { + const summary = React.Children.toArray(props.children)[0]; + if (isFragment(summary)) { + return new Error('Not accepting Fragments'); + } - if (!React.isValidElement(summary)) { - return new Error('First child must be an element'); - } + if (!React.isValidElement(summary)) { + return new Error('First child must be an element'); + } - return null; - }), + return null; + }), }; export default Component; diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts b/packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts index d6570a70900614..1a884c2b931372 100644 --- a/packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts +++ b/packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts @@ -1,17 +1,17 @@ import { TestOptions } from '../types'; const options: TestOptions = { - injector: { - removeExistingPropTypes: true, - reconcilePropTypes: (prop, previous: any, generated) => { - const isCustomValidator = previous !== undefined && !previous.startsWith('PropTypes'); + injector: { + removeExistingPropTypes: true, + reconcilePropTypes: (prop, previous: any, generated) => { + const isCustomValidator = previous !== undefined && !previous.startsWith('PropTypes'); - if (isCustomValidator) { - return previous; - } - return generated; - }, - }, + if (isCustomValidator) { + return previous; + } + return generated; + }, + }, }; export default options; diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/output.js b/packages/typescript-to-proptypes/test/reconcile-prop-types/output.js index 8323a3442421b4..7adc38f157a388 100644 --- a/packages/typescript-to-proptypes/test/reconcile-prop-types/output.js +++ b/packages/typescript-to-proptypes/test/reconcile-prop-types/output.js @@ -3,27 +3,27 @@ import * as PropTypes from 'prop-types'; import { chainPropTypes } from 'some-utils-module'; function Component(props) { - const { children } = props; - return ( - - ); + const { children } = props; + return ( + + ); } Component.propTypes = { - children: chainPropTypes(PropTypes.node.isRequired, (props) => { - const summary = React.Children.toArray(props.children)[0]; - if (isFragment(summary)) { - return new Error('Not accepting Fragments'); - } + children: chainPropTypes(PropTypes.node.isRequired, (props) => { + const summary = React.Children.toArray(props.children)[0]; + if (isFragment(summary)) { + return new Error('Not accepting Fragments'); + } - if (!React.isValidElement(summary)) { - return new Error('First child must be an element'); - } + if (!React.isValidElement(summary)) { + return new Error('First child must be an element'); + } - return null; - }), + return null; + }), }; export default Component; diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/output.json b/packages/typescript-to-proptypes/test/reconcile-prop-types/output.json deleted file mode 100644 index e4d71445261175..00000000000000 --- a/packages/typescript-to-proptypes/test/reconcile-prop-types/output.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Component", - "types": [ - { - "type": "PropTypeNode", - "name": "children", - "propType": { - "type": "UnionNode", - "types": [{ "type": "ElementNode", "elementType": "node" }, { "type": "UndefinedNode" }] - } - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/testSetup.js b/packages/typescript-to-proptypes/test/testSetup.js new file mode 100644 index 00000000000000..87e48ab8f0257c --- /dev/null +++ b/packages/typescript-to-proptypes/test/testSetup.js @@ -0,0 +1 @@ +require('@babel/register')({ extensions: ['.js', '.ts'] }); diff --git a/packages/typescript-to-proptypes/test/type-unknown/input.tsx b/packages/typescript-to-proptypes/test/type-unknown/input.tsx index 46ac8f61875ba3..22f48d384631a5 100644 --- a/packages/typescript-to-proptypes/test/type-unknown/input.tsx +++ b/packages/typescript-to-proptypes/test/type-unknown/input.tsx @@ -1,4 +1,4 @@ export default function Select(props: { value?: unknown; variant: unknown }) { - const { value, variant } = props; - return
; + const { value, variant } = props; + return
; } diff --git a/packages/typescript-to-proptypes/test/type-unknown/output.js b/packages/typescript-to-proptypes/test/type-unknown/output.js index ab8fd36014d7d0..242f21a23c77bd 100644 --- a/packages/typescript-to-proptypes/test/type-unknown/output.js +++ b/packages/typescript-to-proptypes/test/type-unknown/output.js @@ -1,12 +1,12 @@ import PropTypes from 'prop-types'; function Select(props) { - const { value, variant } = props; - return
; + const { value, variant } = props; + return
; } Select.propTypes = { - value: PropTypes.any, - variant: PropTypes.any.isRequired, + value: PropTypes.any, + variant: PropTypes.any.isRequired, }; export default Select; diff --git a/packages/typescript-to-proptypes/test/type-unknown/output.json b/packages/typescript-to-proptypes/test/type-unknown/output.json deleted file mode 100644 index 46ea6d53471992..00000000000000 --- a/packages/typescript-to-proptypes/test/type-unknown/output.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Select", - "types": [ - { - "type": "PropTypeNode", - "name": "value", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "AnyNode" }] - } - }, - { "type": "PropTypeNode", "name": "variant", "propType": { "type": "AnyNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/types.d.ts b/packages/typescript-to-proptypes/test/types.d.ts index e13cf5083592ad..16200bbc2e8177 100644 --- a/packages/typescript-to-proptypes/test/types.d.ts +++ b/packages/typescript-to-proptypes/test/types.d.ts @@ -1,7 +1,7 @@ import { ParserOptions, GenerateOptions, InjectOptions } from '../src'; export type TestOptions = { - parser?: Partial; - generator?: Partial; - injector?: Partial; + parser?: Partial; + generator?: Partial; + injector?: Partial; }; diff --git a/packages/typescript-to-proptypes/test/union-props/input.d.ts b/packages/typescript-to-proptypes/test/union-props/input.d.ts index 05c56d16150b55..a4b6a03347078d 100644 --- a/packages/typescript-to-proptypes/test/union-props/input.d.ts +++ b/packages/typescript-to-proptypes/test/union-props/input.d.ts @@ -1,19 +1,19 @@ import * as React from 'react'; export interface BaseProps { - value?: unknown; + value?: unknown; } export interface StandardProps extends BaseProps { - variant?: 'standard'; + variant?: 'standard'; } export interface OutlinedProps extends BaseProps { - variant: 'outlined'; + variant: 'outlined'; } export interface FilledProps extends BaseProps { - variant: 'filled'; + variant: 'filled'; } export type TextFieldProps = StandardProps | OutlinedProps | FilledProps; diff --git a/packages/typescript-to-proptypes/test/union-props/input.js b/packages/typescript-to-proptypes/test/union-props/input.js index 65c2d58c6b810f..0f407175c75af4 100644 --- a/packages/typescript-to-proptypes/test/union-props/input.js +++ b/packages/typescript-to-proptypes/test/union-props/input.js @@ -1,11 +1,11 @@ import * as React from 'react'; export default function TextField(props) { - const { value, variant } = props; + const { value, variant } = props; - return ( - - {variant}: - - ); + return ( + + {variant}: + + ); } diff --git a/packages/typescript-to-proptypes/test/union-props/output.js b/packages/typescript-to-proptypes/test/union-props/output.js index 77872fa2554e34..f7581caf24fe11 100644 --- a/packages/typescript-to-proptypes/test/union-props/output.js +++ b/packages/typescript-to-proptypes/test/union-props/output.js @@ -2,18 +2,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; function TextField(props) { - const { value, variant } = props; + const { value, variant } = props; - return ( - - {variant}: - - ); + return ( + + {variant}: + + ); } TextField.propTypes = { - value: PropTypes.any, - variant: PropTypes.oneOf(['filled', 'outlined', 'standard']), + value: PropTypes.any, + variant: PropTypes.oneOf(['filled', 'outlined', 'standard']), }; export default TextField; diff --git a/packages/typescript-to-proptypes/test/union-props/output.json b/packages/typescript-to-proptypes/test/union-props/output.json deleted file mode 100644 index cc3e48027175b0..00000000000000 --- a/packages/typescript-to-proptypes/test/union-props/output.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "TextField", - "types": [ - { - "type": "PropTypeNode", - "name": "variant", - "propType": { - "type": "UnionNode", - "types": [ - { "type": "UndefinedNode" }, - { "type": "LiteralNode", "value": "\"standard\"" }, - { "type": "LiteralNode", "value": "\"outlined\"" }, - { "type": "LiteralNode", "value": "\"filled\"" } - ] - }, - "filenames": {} - }, - { - "type": "PropTypeNode", - "name": "value", - "propType": { - "type": "UnionNode", - "types": [{ "type": "UndefinedNode" }, { "type": "AnyNode" }] - }, - "filenames": {} - } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/test/unused-prop/input.tsx b/packages/typescript-to-proptypes/test/unused-prop/input.tsx index d3cdd82561848e..f802738d21e761 100644 --- a/packages/typescript-to-proptypes/test/unused-prop/input.tsx +++ b/packages/typescript-to-proptypes/test/unused-prop/input.tsx @@ -1,17 +1,17 @@ import * as React from 'react'; type Props = { - foo: string; - bar: string; - baz: string; + foo: string; + bar: string; + baz: string; }; export default function Foo(props: Props) { - const { foo, ...rest } = props; + const { foo, ...rest } = props; - return ( -
- {foo} -
- ); + return ( +
+ {foo} +
+ ); } diff --git a/packages/typescript-to-proptypes/test/unused-prop/output.js b/packages/typescript-to-proptypes/test/unused-prop/output.js index f2fba1c271780c..7bbebdd468ff92 100644 --- a/packages/typescript-to-proptypes/test/unused-prop/output.js +++ b/packages/typescript-to-proptypes/test/unused-prop/output.js @@ -1,17 +1,17 @@ import * as React from 'react'; import PropTypes from 'prop-types'; function Foo(props) { - const { foo, ...rest } = props; - return ( -
- {foo} -
- ); + const { foo, ...rest } = props; + return ( +
+ {foo} +
+ ); } Foo.propTypes = { - bar: PropTypes.string.isRequired, - foo: PropTypes.string.isRequired, + bar: PropTypes.string.isRequired, + foo: PropTypes.string.isRequired, }; export default Foo; diff --git a/packages/typescript-to-proptypes/test/unused-prop/output.json b/packages/typescript-to-proptypes/test/unused-prop/output.json deleted file mode 100644 index 62aabf933d9495..00000000000000 --- a/packages/typescript-to-proptypes/test/unused-prop/output.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "ProgramNode", - "body": [ - { - "type": "ComponentNode", - "name": "Foo", - "types": [ - { "type": "PropTypeNode", "name": "foo", "propType": { "type": "StringNode" } }, - { "type": "PropTypeNode", "name": "bar", "propType": { "type": "StringNode" } }, - { "type": "PropTypeNode", "name": "baz", "propType": { "type": "StringNode" } } - ] - } - ] -} diff --git a/packages/typescript-to-proptypes/tsconfig.json b/packages/typescript-to-proptypes/tsconfig.json index 540ed84fb027ab..bddfb16bc3713d 100644 --- a/packages/typescript-to-proptypes/tsconfig.json +++ b/packages/typescript-to-proptypes/tsconfig.json @@ -1,17 +1,18 @@ { - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "ES2018", - "lib": ["ES2018"], - "noImplicitAny": true, - "strict": true, - "moduleResolution": "node", - "sourceMap": true, - "declaration": true, - "outDir": "dist", - "jsx": "preserve", - "importHelpers": true - }, - "include": ["src"] + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "target": "ES2018", + "lib": ["ES2018"], + "noImplicitAny": true, + "strict": true, + "moduleResolution": "node", + "sourceMap": true, + "declaration": true, + "outDir": "build", + "jsx": "preserve", + "importHelpers": true, + "types": ["node"] + }, + "include": ["src"] } diff --git a/tsconfig.json b/tsconfig.json index ad603806525f5b..02706632598887 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,8 @@ "@material-ui/styles/*": ["./packages/material-ui-styles/src/*"], "@material-ui/system": ["./packages/material-ui-system/src"], "@material-ui/types": ["./packages/material-ui-types"], - "test/*": ["./test/*"] + "test/*": ["./test/*"], + "typescript-to-proptypes": ["./packages/typescript-to-proptypes/src"] } }, "exclude": ["**/build/"] diff --git a/yarn.lock b/yarn.lock index 3c970660af89fd..338b49584918ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2426,10 +2426,10 @@ "@types/babel__core" "*" "@types/prettier" "*" -"@types/babel__core@*": - version "7.1.7" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" - integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw== +"@types/babel__core@*", "@types/babel__core@^7.1.2": + version "7.1.8" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.8.tgz#057f725aca3641f49fc11c7a87a9de5ec588a5d7" + integrity sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -2453,9 +2453,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.11.tgz#1ae3010e8bf8851d324878b42acec71986486d18" - integrity sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q== + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.12.tgz#22f49a028e69465390f87bb103ebd61bd086b8f5" + integrity sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA== dependencies: "@babel/types" "^7.3.0" @@ -2488,6 +2488,11 @@ resolved "https://registry.yarnpkg.com/@types/css-mediaquery/-/css-mediaquery-0.1.0.tgz#61d439d8163880e90b61d19aba24f7b778c4e77d" integrity sha512-jzZ9bRw8fTgCEllDvE7GHR1zTP5LsDHJbAX6BCwD9qdxIOq/Le5TTsdteoCIdEQaFpDMvudLHU/hLo1Lmfcy0Q== +"@types/doctrine@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.3.tgz#e892d293c92c9c1d3f9af72c15a554fbc7e0895a" + integrity sha1-6JLSk8ksnB0/mvcsFaVU+8fgiVo= + "@types/enzyme@^3.10.3": version "3.10.5" resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0" @@ -2538,9 +2543,9 @@ hoist-non-react-statics "^3.3.0" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" - integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== "@types/istanbul-lib-report@*": version "1.1.1" @@ -2581,7 +2586,7 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/lodash@^4.14.138": +"@types/lodash@^4.14.136", "@types/lodash@^4.14.138": version "4.14.155" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.155.tgz#e2b4514f46a261fd11542e47519c20ebce7bc23a" integrity sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg== @@ -2606,10 +2611,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== -"@types/node@^12.12.29": - version "12.12.38" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.38.tgz#58841a382f231ad005dbb935c36d44aa1118a26b" - integrity sha512-75eLjX0pFuTcUXnnWmALMzzkYorjND0ezNEycaKesbUBg9eGZp4GHPuDmkRc4mQQvIpe29zrzATNRA6hkYqwmA== +"@types/node@^12.12.29", "@types/node@^12.6.2": + version "12.12.47" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.47.tgz#5007b8866a2f9150de82335ca7e24dd1d59bdfb5" + integrity sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2631,7 +2636,7 @@ resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.1.tgz#d46015ad91128fce06a1a688ab39a2516507f740" integrity sha512-MoF2IC9oGSgArJwlxdst4XsvWuoYfNUWtBw0kpnCi6K05kV+Ecl7siEeJ40tgCbI9uqEMGQL/NlPMRv6KVkY5Q== -"@types/prettier@*", "@types/prettier@^2.0.0": +"@types/prettier@*", "@types/prettier@^2.0.0", "@types/prettier@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.1.tgz#b6e98083f13faa1e5231bfa3bdb1b0feff536b6d" integrity sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ== @@ -2730,10 +2735,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.9.3": - version "16.9.36" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.36.tgz#ade589ff51e2a903e34ee4669e05dbfa0c1ce849" - integrity sha512-mGgUb/Rk/vGx4NCvquRuSH0GHBQKb1OqpGS9cT9lFxlTLHZgkksgI60TuIxubmn7JuCb+sENHhQciqa0npm0AQ== +"@types/react@*", "@types/react@^16.8.23", "@types/react@^16.9.3": + version "16.9.38" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680" + integrity sha512-pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA== dependencies: "@types/prop-types" "*" csstype "^2.2.0" @@ -2792,6 +2797,11 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== +"@types/uuid@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" + integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== + "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -7562,9 +7572,9 @@ fast-json-patch@^3.0.0-1: integrity sha512-6pdFb07cknxvPzCeLsFHStEy+MysPJPgZQ9LbQ/2O67unQF93SNqfdSqnPPl71YMHX+AD8gbl7iuoGFzHEdDuw== fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + 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== fast-levenshtein@~2.0.6: version "2.0.6" @@ -8006,9 +8016,9 @@ fsevents@^1.2.7: node-pre-gyp "^0.12.0" fsevents@~2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fstream@^1.0.12: version "1.0.12" @@ -9885,9 +9895,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.0, json5@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" - integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: minimist "^1.2.5" @@ -10744,9 +10754,9 @@ make-dir@^3.0.0, make-dir@^3.0.2: semver "^6.0.0" make-error@^1.1.1: - version "1.3.5" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" - integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== make-fetch-happen@^5.0.0: version "5.0.0" @@ -11245,9 +11255,9 @@ mkdirp-promise@^5.0.1: mkdirp "*" mkdirp@*, mkdirp@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" - integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mkdirp@0.3.0: version "0.3.0" @@ -12536,9 +12546,9 @@ path-key@^2.0.0, path-key@^2.0.1: integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-key@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" - integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: version "1.0.6" @@ -13407,7 +13417,7 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^2.0.1: +prettier@^2.0.1, prettier@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== @@ -14083,7 +14093,7 @@ react-window@^1.8.5: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@^16.13.0: +react@^16.13.0, react@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== @@ -15048,7 +15058,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.1.3, semver@^7.1.3: +semver@7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== @@ -15058,6 +15068,11 @@ semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.1.3: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -16482,7 +16497,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.13.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== @@ -16597,21 +16612,6 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript-to-proptypes@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/typescript-to-proptypes/-/typescript-to-proptypes-2.0.1.tgz#0d33bc690cfb585f8b8d323c42cda63746328bb0" - integrity sha512-+Z5jXIy2xzKN/ZOm7Z8CoI8ONCsG8bxPaEOShiW4jF440DyGNba1FmOEe9c55XwFbI0TmjNBzxVp25+rOp8ZiA== - dependencies: - "@babel/core" "^7.5.4" - "@babel/plugin-syntax-class-properties" "^7.2.0" - "@babel/plugin-syntax-jsx" "^7.2.0" - "@babel/types" "^7.5.0" - doctrine "^3.0.0" - lodash "^4.17.14" - tslib "^1.13.0" - typescript "3.5.2" - uuid "^8.1.0" - typescript@3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c"