diff --git a/.eslintignore b/.eslintignore index 42061c0..9f83d64 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ -README.md \ No newline at end of file +README.md +scripts/* \ No newline at end of file diff --git a/package.json b/package.json index def121b..0f468a2 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,12 @@ "release": "yarn build --filter=!@react-awesome/docs && changeset publish", "docs": "yarn workspace @react-awesome/docs", "eslint": "yarn workspace @react-awesome/eslint-config", - "prepare": "husky" + "prepare": "husky", + "gen:repo": "node ./scripts/create-new-repo.js" }, "devDependencies": { "@changesets/cli": "2.26.2", + "@inquirer/prompts": "^3.3.2", "@react-awesome/eslint-config": "*", "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", @@ -26,11 +28,15 @@ "@vitejs/plugin-react": "^4.2.1", "@vitest/coverage-istanbul": "^1.2.1", "@vitest/ui": "^1.2.1", + "chalk": "^4.1.2", + "cli-spinner": "^0.2.10", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", "eslint": "^8.56.0", + "figlet": "^1.7.0", "husky": "^9.0.6", "jsdom": "^24.0.0", + "lodash": "^4.17.21", "prettier": "^3.1.1", "rimraf": "^5.0.5", "tty-table": "^4.2.3", diff --git a/scripts/create-new-repo.js b/scripts/create-new-repo.js new file mode 100644 index 0000000..8087aef --- /dev/null +++ b/scripts/create-new-repo.js @@ -0,0 +1,61 @@ +const figlet = require("figlet") +const { input} = require("@inquirer/prompts") +const chalk = require("chalk") +const Spinner = require('cli-spinner').Spinner; +const fs = require("node:fs") +const path = require("node:path") +const _ = require("lodash") + +const run = async () => { + console.log(figlet.textSync("React Awesome Components")) + const packageName = await input({ message: 'Enter package name (write in camel case): ' }); + const description = await input({ message: 'Enter package description: ' }); + const keywordStr = await input({ message: 'Enter package keywords (separate by whitespace): ' }); + + const keywords = keywordStr.split(" ").map(str => JSON.stringify(str)).join(",\n") + + const spinner = new Spinner(chalk.yellow(`Creating new package ${packageName}... %s `)); + spinner.setSpinnerString('⣾⣽⣻⢿⡿⣟⣯⣷'); + spinner.start(); + + const kebabName = _.kebabCase(packageName) + + const packageFolder = path.resolve(__dirname, "../packages/" + kebabName) + + // Create new folder with kebab case + fs.mkdirSync(packageFolder) + + // Copy contents to new folder + fs.cpSync(path.resolve(__dirname, "./template"), packageFolder, { recursive: true }) + + // Replace package name + + const replaceFiles = [ + path.resolve(packageFolder, "./README.md"), + path.resolve(packageFolder, "./package.json") + ] + + for(const filePath of replaceFiles) { + const content = fs.readFileSync(filePath).toString('utf8') + const kebabRegex = new RegExp("", 'g') + const camelRegex = new RegExp("", 'g') + const descriptionRegex = new RegExp("", "g") + const keywordRegex = new RegExp("\"\"", "g") + let updatedContent = content.replace(kebabRegex, kebabName) + updatedContent = updatedContent.replace(camelRegex, packageName) + updatedContent = updatedContent.replace(descriptionRegex, description) + updatedContent = updatedContent.replace(keywordRegex, keywords) + fs.writeFileSync(filePath, updatedContent, 'utf8') + } + + spinner.stop(); + + console.log(chalk.green(`\nYour new package is located at ${packageFolder}. Happy Hacking!!`)) + + console.log(chalk.yellow("Remember to do the following steps:")) + console.log(chalk.blue("- Ignore newly created package in vite.config.ts file.")) + console.log(chalk.blue("- Add Codecov step for newly created package in test.yml workflow.")) + console.log(chalk.blue("- Add new package to the @react-awesome/components's package.json dependencies.")) +} + +run() \ No newline at end of file diff --git a/scripts/template/.eslintrc.js b/scripts/template/.eslintrc.js new file mode 100644 index 0000000..19f3ed1 --- /dev/null +++ b/scripts/template/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + root: true, + extends: ["@react-awesome/eslint-config/library.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, +}; diff --git a/scripts/template/README.md b/scripts/template/README.md new file mode 100644 index 0000000..67063dc --- /dev/null +++ b/scripts/template/README.md @@ -0,0 +1,32 @@ +# @react-awesome/ + +

+ version + coverage + license + build status + size +

+ +**** tracks the previous value of a variable. + +Please refer to the [documentation](https://react-awesome-components.vercel.app/docs/) for more information. + +## Installation + +```sh +yarn add @react-awesome/ +# or +npm i @react-awesome/ +``` + +## Contribution + +Yes please! See the +[contributing guidelines](https://github.com/trinhthinh388/react-awesome-components/blob/master/CONTRIBUTING.md) +for details. + +## Licence + +This project is licensed under the terms of the +[MIT license](https://github.com/trinhthinh388/react-awesome-components/blob/master/LICENSE). diff --git a/scripts/template/package.json b/scripts/template/package.json new file mode 100644 index 0000000..5b1db65 --- /dev/null +++ b/scripts/template/package.json @@ -0,0 +1,41 @@ +{ + "name": "@react-awesome/", + "version": "0.0.3", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "sideEffects": false, + "license": "MIT", + "description": "", + "keywords": [ + "react", + "" + ], + "repository": { + "url": "https://github.com/trinhthinh388/react-awesome-components" + }, + "files": [ + "dist/**" + ], + "scripts": { + "build": "vite --config ../../vite.config.ts build", + "dev": "vite --watch --config ../../vite.config.ts build", + "lint": "eslint \"src/**/*.ts*\"", + "clean": "rimraf .turbo && rimraf node_modules && rimraf dist", + "test": "vitest --config ../../vite.config.ts --coverage --run", + "test:ui": "vitest --config ../../vite.config.ts --coverage --ui", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@react-awesome/eslint-config": "*", + "@react-awesome/tsconfig": "*", + "@types/react": "^18.2.46", + "@types/react-dom": "^18.2.18", + "eslint": "^8.56.0", + "react": "^18.2.0", + "typescript": "^5.3.3" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/scripts/template/src/index.ts b/scripts/template/src/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/scripts/template/tsconfig.json b/scripts/template/tsconfig.json new file mode 100644 index 0000000..a09969e --- /dev/null +++ b/scripts/template/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@react-awesome/tsconfig/react-library.json", + "compilerOptions": { + "types": ["vitest/globals"], + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules"], +} diff --git a/yarn.lock b/yarn.lock index 537526d..995d859 100644 --- a/yarn.lock +++ b/yarn.lock @@ -667,6 +667,125 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== +"@inquirer/checkbox@^1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-1.5.2.tgz#043ca370ebbc0b92691c2309bc12e8716ed701c4" + integrity sha512-CifrkgQjDkUkWexmgYYNyB5603HhTHI91vLFeQXh6qrTKiCMVASol01Rs1cv6LP/A2WccZSRlJKZhbaBIs/9ZA== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + figures "^3.2.0" + +"@inquirer/confirm@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-2.0.17.tgz#a45eb1b973c51c993a3c093a0114e960b1cf09a4" + integrity sha512-EqzhGryzmGpy2aJf6LxJVhndxYmFs+m8cxXzf8nejb1DE3sabf6mUgBcp4J0jAUEiAcYzqmkqRr7LPFh/WdnXA== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + chalk "^4.1.2" + +"@inquirer/core@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-6.0.0.tgz#d44ccd8ae09a4879a78f09cca35bf1ab894b95f4" + integrity sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw== + dependencies: + "@inquirer/type" "^1.1.6" + "@types/mute-stream" "^0.0.4" + "@types/node" "^20.10.7" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + cli-spinners "^2.9.2" + cli-width "^4.1.0" + figures "^3.2.0" + mute-stream "^1.0.0" + run-async "^3.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + +"@inquirer/editor@^1.2.15": + version "1.2.15" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-1.2.15.tgz#28de2dabbcf1e07a37149320093798e3f4856f91" + integrity sha512-gQ77Ls09x5vKLVNMH9q/7xvYPT6sIs5f7URksw+a2iJZ0j48tVS6crLqm2ugG33tgXHIwiEqkytY60Zyh5GkJQ== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + chalk "^4.1.2" + external-editor "^3.1.0" + +"@inquirer/expand@^1.1.16": + version "1.1.16" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-1.1.16.tgz#63dce81240e5f7b2b1d7942b3e3cae18f4f03d07" + integrity sha512-TGLU9egcuo+s7PxphKUCnJnpCIVY32/EwPCLLuu+gTvYiD8hZgx8Z2niNQD36sa6xcfpdLY6xXDBiL/+g1r2XQ== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + chalk "^4.1.2" + figures "^3.2.0" + +"@inquirer/input@^1.2.16": + version "1.2.16" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-1.2.16.tgz#94d8765a47689e799fd55ed0361dedc8f554341b" + integrity sha512-Ou0LaSWvj1ni+egnyQ+NBtfM1885UwhRCMtsRt2bBO47DoC1dwtCa+ZUNgrxlnCHHF0IXsbQHYtIIjFGAavI4g== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + chalk "^4.1.2" + +"@inquirer/password@^1.1.16": + version "1.1.16" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-1.1.16.tgz#37ddebbe37c6e76f8ad27d1f726aacdd7c423558" + integrity sha512-aZYZVHLUXZ2gbBot+i+zOJrks1WaiI95lvZCn1sKfcw6MtSSlYC8uDX8sTzQvAsQ8epHoP84UNvAIT0KVGOGqw== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + +"@inquirer/prompts@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-3.3.2.tgz#0c3a44bbf7e560439590f2fcb769cd8392b0f555" + integrity sha512-k52mOMRvTUejrqyF1h8Z07chC+sbaoaUYzzr1KrJXyj7yaX7Nrh0a9vktv8TuocRwIJOQMaj5oZEmkspEcJFYQ== + dependencies: + "@inquirer/checkbox" "^1.5.2" + "@inquirer/confirm" "^2.0.17" + "@inquirer/core" "^6.0.0" + "@inquirer/editor" "^1.2.15" + "@inquirer/expand" "^1.1.16" + "@inquirer/input" "^1.2.16" + "@inquirer/password" "^1.1.16" + "@inquirer/rawlist" "^1.2.16" + "@inquirer/select" "^1.3.3" + +"@inquirer/rawlist@^1.2.16": + version "1.2.16" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-1.2.16.tgz#ac6cc0bb2a60d51dccdfe2c3ea624185f1fbd5bc" + integrity sha512-pZ6TRg2qMwZAOZAV6TvghCtkr53dGnK29GMNQ3vMZXSNguvGqtOVc4j/h1T8kqGJFagjyfBZhUPGwNS55O5qPQ== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + chalk "^4.1.2" + +"@inquirer/select@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-1.3.3.tgz#7d832ee603c15b706148e47cda29cdf6634cd94b" + integrity sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg== + dependencies: + "@inquirer/core" "^6.0.0" + "@inquirer/type" "^1.1.6" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + figures "^3.2.0" + +"@inquirer/type@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.1.6.tgz#f2656456e58fb93c7b73d5aad583b928c77b9206" + integrity sha512-OCKOpn0CrFDslR8s3who7hlr823zXTb1iShGCaaWgEJFfkIV0T9aLZV2QGnOuU78IrsPYLkr3oKx9dZwwCH3Rw== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -1343,6 +1462,20 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^20.10.7": + version "20.11.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.15.tgz#b853a86cfedbc768360c552b4653302b4e7417bf" + integrity sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A== + dependencies: + undici-types "~5.26.4" + "@types/node@^12.7.1": version "12.20.55" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" @@ -1401,6 +1534,11 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + "@typescript-eslint/eslint-plugin@^6.17.0", "@typescript-eslint/eslint-plugin@^6.5.0": version "6.19.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz#bb0676af940bc23bf299ca58dbdc6589c2548c2e" @@ -1756,7 +1894,7 @@ ansi-colors@^4.1.1, ansi-colors@^4.1.3: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -2267,7 +2405,12 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.5.0: +cli-spinner@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47" + integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q== + +cli-spinners@^2.5.0, cli-spinners@^2.9.2: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== @@ -2277,6 +2420,11 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + client-only@0.0.1, client-only@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" @@ -3735,7 +3883,12 @@ fflate@^0.8.1: resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.1.tgz#1ed92270674d2ad3c73f077cd0acf26486dae6c9" integrity sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ== -figures@^3.0.0: +figlet@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.7.0.tgz#46903a04603fd19c3e380358418bb2703587a72e" + integrity sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg== + +figures@^3.0.0, figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -6136,6 +6289,11 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mute-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + mz@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -7218,6 +7376,11 @@ run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-async@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" + integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"