├── .gitignore ├── .prettierrc ├── .editorconfig ├── src ├── fileSystemAsync.js └── runCommandAsync.js ├── package.json ├── README.md ├── bin └── isolate-workspace └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsxBracketSameLine": true, 3 | "printWidth": 120, 4 | "semi": false, 5 | "singleQuote": true, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /src/fileSystemAsync.js: -------------------------------------------------------------------------------- 1 | const copyDir = require('copy-dir') 2 | const fs = require('fs') 3 | 4 | function readFileAsync(file) { 5 | return new Promise((resolve, reject) => fs.readFile(file, 'utf8', (err, res) => (!err ? resolve(res) : reject(err)))) 6 | } 7 | 8 | function writeFileAsync(file, content) { 9 | return new Promise((resolve, reject) => fs.writeFile(file, content, err => (!err ? resolve() : reject(err)))) 10 | } 11 | 12 | function copyDirAsync(from, to, filter) { 13 | return new Promise((resolve, reject) => copyDir(from, to, filter, (err, res) => (!err ? resolve(res) : reject(err)))) 14 | } 15 | 16 | module.exports = { 17 | readFileAsync, 18 | writeFileAsync, 19 | copyDirAsync, 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yarn-workspace-isolator", 3 | "version": "0.1.0-rc1", 4 | "license": "MIT", 5 | "author": { 6 | "name": "Christian Hoffmeister", 7 | "email": "mail@choffmeister.de" 8 | }, 9 | "bin": { 10 | "isolate-workspace": "./bin/isolate-workspace" 11 | }, 12 | "scripts": { 13 | "lint-fix": "yarn prettier --write", 14 | "lint": "yarn prettier --list-different", 15 | "prettier": "prettier 'bin/*' 'src/**/*.js'", 16 | "test": "yarn lint" 17 | }, 18 | "dependencies": { 19 | "copy-dir": "^0.3.0", 20 | "lodash": "^4.17.13", 21 | "yargs": "^11.0.0" 22 | }, 23 | "devDependencies": { 24 | "prettier": "^1.11.1" 25 | }, 26 | "engines": { 27 | "node": ">=8.0.0", 28 | "yarn": ">=1.5.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yarn-workspace-isolator 2 | 3 | ## What it does 4 | 5 | This script isolates a single workspace by 6 | 7 | * Making a copy of the workspace to some `new-folder/` 8 | * Placing a copy for each needed workspace dependency into `new-folder/node_modules/{workspace-dependency}` 9 | * Rewriting the version of each workspace dependency to `file:new-folder/node_modules/{workspace-dependency}` 10 | 11 | Now you can simply run `yarn install` inside of `new-folder/` and yarn will install all dependencies as if you had not 12 | used workspaces at all without having to publish any workspace dependency. 13 | 14 | ## Example usage 15 | 16 | ``` 17 | npm install -g yarn-workspace-isolator 18 | cd my-project-using-yarn-workspaces 19 | isolate-workspace -w my-package-name -o ~/new-folder 20 | ``` 21 | 22 | Note: This needs `yarn@>=1.5.0`! 23 | -------------------------------------------------------------------------------- /src/runCommandAsync.js: -------------------------------------------------------------------------------- 1 | const childProcess = require('child_process') 2 | 3 | function runCommandAsyncPipe(cwd, command, args, stdin) { 4 | return new Promise((resolve, reject) => { 5 | const stdout = Buffer.alloc(1024 * 1024) 6 | let stdoutLength = 0 7 | const stderr = Buffer.alloc(1024) 8 | let stderrLength = 0 9 | 10 | const process = childProcess.spawn(command, args, { cwd, stdio: 'pipe' }) 11 | 12 | process.stdout.on('data', chunk => { 13 | chunk.copy(stdout, stdoutLength) 14 | stdoutLength += chunk.length 15 | }) 16 | 17 | process.stderr.on('data', chunk => { 18 | chunk.copy(stderr, stderrLength) 19 | stderrLength += chunk.length 20 | }) 21 | 22 | process.on('close', code => { 23 | if (code === 0) { 24 | resolve(stdout.slice(0, stdoutLength)) 25 | } else { 26 | reject(new Error(`exited with code ${code}:\n\n${stderr.slice(0, stderrLength).toString('utf8')}`)) 27 | } 28 | }) 29 | 30 | if (stdin) { 31 | process.stdin.write(stdin, () => process.stdin.end()) 32 | } else { 33 | process.stdin.end() 34 | } 35 | }) 36 | } 37 | 38 | function runCommandAsyncInherit(cwd, command, args) { 39 | return new Promise((resolve, reject) => { 40 | const process = childProcess.spawn(command, args, { cwd, stdio: 'inherit' }) 41 | 42 | process.on('close', code => { 43 | if (code === 0) { 44 | resolve(0) 45 | } else { 46 | reject(new Error(`exited with code ${code}`)) 47 | } 48 | }) 49 | }) 50 | } 51 | 52 | module.exports = { 53 | runCommandAsyncPipe, 54 | runCommandAsyncInherit, 55 | } 56 | -------------------------------------------------------------------------------- /bin/isolate-workspace: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { flatten, mapValues, uniq } = require('lodash') 4 | const path = require('path') 5 | const yargs = require('yargs') 6 | const { readFileAsync, writeFileAsync, copyDirAsync } = require('../src/fileSystemAsync') 7 | const { runCommandAsyncPipe } = require('../src/runCommandAsync') 8 | 9 | const cli = yargs 10 | .option('w', { alias: 'workspaceName', type: 'string' }) 11 | .option('o', { alias: 'outputFolder', type: 'string' }) 12 | .coerce('o', path.resolve) 13 | .demandOption(['w', 'o']) 14 | .strict() 15 | 16 | async function run({ workspaceName, outputFolder }) { 17 | const rootFolder = path.resolve('.') 18 | const workspaces = await getWorkspaceInfo(rootFolder) 19 | const workspace = workspaces[workspaceName] 20 | const workspaceDependencies = getWorkspaceDependencies(workspaces, workspaceName) 21 | 22 | await copyDirAsync(path.join(rootFolder, workspace.location), outputFolder, filterIgnored) 23 | await localizeWorkspaceDependencies( 24 | path.join(outputFolder, 'package.json'), 25 | workspaces, 26 | path.join(outputFolder, 'node_modules') 27 | ) 28 | 29 | await Promise.all( 30 | workspaceDependencies.map(async wd => { 31 | await copyDirAsync( 32 | path.join(rootFolder, workspaces[wd].location), 33 | path.join(outputFolder, 'node_modules', wd), 34 | filterIgnored 35 | ) 36 | await localizeWorkspaceDependencies( 37 | path.join(outputFolder, 'node_modules', wd, 'package.json'), 38 | workspaces, 39 | path.join(outputFolder, 'node_modules') 40 | ) 41 | }) 42 | ) 43 | } 44 | 45 | async function getWorkspaceInfo(rootFolder) { 46 | const stdout = await runCommandAsyncPipe(rootFolder, 'yarn', ['--silent', 'workspaces', 'info']) 47 | return JSON.parse(stdout.toString('utf8')) 48 | } 49 | 50 | function getWorkspaceDependencies(workspaces, workspaceName) { 51 | const workspace = workspaces[workspaceName] 52 | const subWorkspaceDependencies = flatten( 53 | workspace.workspaceDependencies.map(w => getWorkspaceDependencies(workspaces, w)) 54 | ) 55 | const { workspaceDependencies } = workspace 56 | return uniq([...subWorkspaceDependencies, ...workspaceDependencies]) 57 | } 58 | 59 | async function localizeWorkspaceDependencies(packageJsonFile, workspaces, localNodeModulesFolder) { 60 | const packageJson = JSON.parse(await readFileAsync(packageJsonFile)) 61 | const nextPackageJson = { 62 | ...packageJson, 63 | dependencies: mapValues(packageJson.dependencies || {}, (ver, dep) => { 64 | if (!!workspaces[dep]) { 65 | return 'file:' + path.join(localNodeModulesFolder, dep) 66 | } else { 67 | return ver 68 | } 69 | }), 70 | } 71 | await writeFileAsync(packageJsonFile, JSON.stringify(nextPackageJson, null, 2)) 72 | } 73 | 74 | function filterIgnored(stat, filepath, filename) { 75 | // TODO 76 | return true 77 | } 78 | 79 | run(cli.argv).catch(err => { 80 | console.error(err) 81 | process.exit(1) 82 | }) 83 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^2.0.0: 6 | version "2.1.1" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 8 | 9 | ansi-regex@^3.0.0: 10 | version "3.0.0" 11 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 12 | 13 | camelcase@^4.1.0: 14 | version "4.1.0" 15 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" 16 | 17 | cliui@^4.0.0: 18 | version "4.0.0" 19 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" 20 | dependencies: 21 | string-width "^2.1.1" 22 | strip-ansi "^4.0.0" 23 | wrap-ansi "^2.0.0" 24 | 25 | code-point-at@^1.0.0: 26 | version "1.1.0" 27 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 28 | 29 | copy-dir@^0.3.0: 30 | version "0.3.0" 31 | resolved "https://registry.yarnpkg.com/copy-dir/-/copy-dir-0.3.0.tgz#deb2dc2fa9c9290ed47c84155a999a6d45f5a358" 32 | dependencies: 33 | mkdir-p "~0.0.4" 34 | 35 | cross-spawn@^5.0.1: 36 | version "5.1.0" 37 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 38 | dependencies: 39 | lru-cache "^4.0.1" 40 | shebang-command "^1.2.0" 41 | which "^1.2.9" 42 | 43 | decamelize@^1.1.1: 44 | version "1.2.0" 45 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 46 | 47 | execa@^0.7.0: 48 | version "0.7.0" 49 | resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" 50 | dependencies: 51 | cross-spawn "^5.0.1" 52 | get-stream "^3.0.0" 53 | is-stream "^1.1.0" 54 | npm-run-path "^2.0.0" 55 | p-finally "^1.0.0" 56 | signal-exit "^3.0.0" 57 | strip-eof "^1.0.0" 58 | 59 | find-up@^2.1.0: 60 | version "2.1.0" 61 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" 62 | dependencies: 63 | locate-path "^2.0.0" 64 | 65 | get-caller-file@^1.0.1: 66 | version "1.0.2" 67 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" 68 | 69 | get-stream@^3.0.0: 70 | version "3.0.0" 71 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 72 | 73 | invert-kv@^1.0.0: 74 | version "1.0.0" 75 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 76 | 77 | is-fullwidth-code-point@^1.0.0: 78 | version "1.0.0" 79 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 80 | dependencies: 81 | number-is-nan "^1.0.0" 82 | 83 | is-fullwidth-code-point@^2.0.0: 84 | version "2.0.0" 85 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 86 | 87 | is-stream@^1.1.0: 88 | version "1.1.0" 89 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 90 | 91 | isexe@^2.0.0: 92 | version "2.0.0" 93 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 94 | 95 | lcid@^1.0.0: 96 | version "1.0.0" 97 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 98 | dependencies: 99 | invert-kv "^1.0.0" 100 | 101 | locate-path@^2.0.0: 102 | version "2.0.0" 103 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" 104 | dependencies: 105 | p-locate "^2.0.0" 106 | path-exists "^3.0.0" 107 | 108 | lodash@^4.17.13: 109 | version "4.17.13" 110 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" 111 | 112 | lru-cache@^4.0.1: 113 | version "4.1.1" 114 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" 115 | dependencies: 116 | pseudomap "^1.0.2" 117 | yallist "^2.1.2" 118 | 119 | mem@^1.1.0: 120 | version "1.1.0" 121 | resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" 122 | dependencies: 123 | mimic-fn "^1.0.0" 124 | 125 | mimic-fn@^1.0.0: 126 | version "1.2.0" 127 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" 128 | 129 | mkdir-p@~0.0.4: 130 | version "0.0.7" 131 | resolved "https://registry.yarnpkg.com/mkdir-p/-/mkdir-p-0.0.7.tgz#24c5dbe26da3a99ef158a1eef9a5c2dd9de5683c" 132 | 133 | npm-run-path@^2.0.0: 134 | version "2.0.2" 135 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" 136 | dependencies: 137 | path-key "^2.0.0" 138 | 139 | number-is-nan@^1.0.0: 140 | version "1.0.1" 141 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 142 | 143 | os-locale@^2.0.0: 144 | version "2.1.0" 145 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" 146 | dependencies: 147 | execa "^0.7.0" 148 | lcid "^1.0.0" 149 | mem "^1.1.0" 150 | 151 | p-finally@^1.0.0: 152 | version "1.0.0" 153 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" 154 | 155 | p-limit@^1.1.0: 156 | version "1.2.0" 157 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" 158 | dependencies: 159 | p-try "^1.0.0" 160 | 161 | p-locate@^2.0.0: 162 | version "2.0.0" 163 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" 164 | dependencies: 165 | p-limit "^1.1.0" 166 | 167 | p-try@^1.0.0: 168 | version "1.0.0" 169 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" 170 | 171 | path-exists@^3.0.0: 172 | version "3.0.0" 173 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 174 | 175 | path-key@^2.0.0: 176 | version "2.0.1" 177 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 178 | 179 | prettier@^1.11.1: 180 | version "1.11.1" 181 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" 182 | 183 | pseudomap@^1.0.2: 184 | version "1.0.2" 185 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 186 | 187 | require-directory@^2.1.1: 188 | version "2.1.1" 189 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 190 | 191 | require-main-filename@^1.0.1: 192 | version "1.0.1" 193 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" 194 | 195 | set-blocking@^2.0.0: 196 | version "2.0.0" 197 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 198 | 199 | shebang-command@^1.2.0: 200 | version "1.2.0" 201 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 202 | dependencies: 203 | shebang-regex "^1.0.0" 204 | 205 | shebang-regex@^1.0.0: 206 | version "1.0.0" 207 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 208 | 209 | signal-exit@^3.0.0: 210 | version "3.0.2" 211 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 212 | 213 | string-width@^1.0.1: 214 | version "1.0.2" 215 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 216 | dependencies: 217 | code-point-at "^1.0.0" 218 | is-fullwidth-code-point "^1.0.0" 219 | strip-ansi "^3.0.0" 220 | 221 | string-width@^2.0.0, string-width@^2.1.1: 222 | version "2.1.1" 223 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 224 | dependencies: 225 | is-fullwidth-code-point "^2.0.0" 226 | strip-ansi "^4.0.0" 227 | 228 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 229 | version "3.0.1" 230 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 231 | dependencies: 232 | ansi-regex "^2.0.0" 233 | 234 | strip-ansi@^4.0.0: 235 | version "4.0.0" 236 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 237 | dependencies: 238 | ansi-regex "^3.0.0" 239 | 240 | strip-eof@^1.0.0: 241 | version "1.0.0" 242 | resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" 243 | 244 | which-module@^2.0.0: 245 | version "2.0.0" 246 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 247 | 248 | which@^1.2.9: 249 | version "1.3.0" 250 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 251 | dependencies: 252 | isexe "^2.0.0" 253 | 254 | wrap-ansi@^2.0.0: 255 | version "2.1.0" 256 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 257 | dependencies: 258 | string-width "^1.0.1" 259 | strip-ansi "^3.0.1" 260 | 261 | y18n@^3.2.1: 262 | version "3.2.1" 263 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 264 | 265 | yallist@^2.1.2: 266 | version "2.1.2" 267 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 268 | 269 | yargs-parser@^9.0.2: 270 | version "9.0.2" 271 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" 272 | dependencies: 273 | camelcase "^4.1.0" 274 | 275 | yargs@^11.0.0: 276 | version "11.0.0" 277 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b" 278 | dependencies: 279 | cliui "^4.0.0" 280 | decamelize "^1.1.1" 281 | find-up "^2.1.0" 282 | get-caller-file "^1.0.1" 283 | os-locale "^2.0.0" 284 | require-directory "^2.1.1" 285 | require-main-filename "^1.0.1" 286 | set-blocking "^2.0.0" 287 | string-width "^2.0.0" 288 | which-module "^2.0.0" 289 | y18n "^3.2.1" 290 | yargs-parser "^9.0.2" 291 | --------------------------------------------------------------------------------