From 87edd0e1a8e6651065ad37bdd852842955438896 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 18 Jul 2023 14:51:48 -0700 Subject: [PATCH] Add shared monorepo build setup (#38240) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38240 ## Context RFC: Decoupling Flipper from React Native core: https://github.com/react-native-community/discussions-and-proposals/pull/641 ## Changes To support incoming new React Native packages around debugging (including migrating over [`react-native-community/cli-plugin-metro`](https://github.com/react-native-community/cli/tree/main/packages/cli-plugin-metro)) — which target Node.js and require a build step, this PR adds a minimal shared build setup across the `react-native` monorepo. The setup is closely inspired/based on the build scripts in Jest, Metro, and React Native CLI — and is a simple set of script wrappers around Babel and Chokidar. These are available as build commands at the root of the repo: - `yarn build` - `yarn clean` - `yarn watch` Build configuration (i.e. Babel config) is shared as a set standard across the monorepo, and **packages are opted-in to requiring a build**, configured in `scripts/build.config.js`. ``` const buildConfig /*: BuildConfig */ = { // The packages to include for build and their build options packages: { 'dev-middleware': {target: 'node'}, }, }; ``` For now, there is a single `target: 'node'` option — this is necessary as `react-native`, unlike the above other projects, is a repository with packages targeting several runtimes. We may, in future, introduce a build step for other, non-Node, packages — which may be useful for things such as auto-generated TypeScript definitions. {F1043312771} ## Current integration points - `.circleci/config.yml` — Added to `run_yarn` (with project install). - Root `yarn start` — Convenience for local developers. - `yarn start` within `packages/rn-tester` — Convenience for local developers. **Planned**: I will be adding notes on `yarn build` to the following "Contributing" website pages: - https://reactnative.dev/contributing/overview#contributing-code - https://reactnative.dev/contributing/how-to-open-a-pull-request#chapter-ii-implementing-your-changes **This is not load bearing quite yet**: There are not yet any built packages added to the dependencies of `packages/react-native/`, so this will be further tested in a later PR. ### Alternative designs **Per-package config file** Replace `scripts/build/config.js` with a package-defined key in in `package.json`, similar to Jest's [`publishConfig`](https://github.com/jestjs/jest/blob/1f019afdcdfc54a6664908bb45f343db4e3d0848/packages/jest-cli/package.json#L87C3-L89C4). ``` "buildConfig": { "type": "node" }, ``` This would be the only customisation required, with a single Babel config still standardised. Another option this might receive in future is `enableTypeScriptCodgeen`. **Rollup** More sophisticated build tool for Node.js, used by the React codebase (albeit within a custom script setup as well). **Lerna and Nx** - Most sophisticated setup enabling caching and optimised cloud runs. - Probably the most likely thing we'll move towards at a later stage. Changelog: [Internal] Differential Revision: D46759508 fbshipit-source-id: 4206f213caf6961969dcbdc6a6143cd938e33326 --- .circleci/config.yml | 3 + flow-typed/npm/chokidar_v3.x.x.js | 202 +++++++++++++++++++++++++++ flow-typed/npm/parseargs_v0.11.x.js | 40 ++++++ package.json | 11 +- packages/dev-middleware/.babelrc | 13 -- packages/dev-middleware/package.json | 13 -- packages/rn-tester/package.json | 2 +- scripts/build/build.js | 146 +++++++++++++++++++ scripts/build/clean.js | 51 +++++++ scripts/build/config.js | 59 ++++++++ scripts/build/watch.js | 81 +++++++++++ yarn.lock | 30 +++- 12 files changed, 617 insertions(+), 34 deletions(-) create mode 100644 flow-typed/npm/chokidar_v3.x.x.js create mode 100644 flow-typed/npm/parseargs_v0.11.x.js delete mode 100644 packages/dev-middleware/.babelrc create mode 100644 scripts/build/build.js create mode 100644 scripts/build/clean.js create mode 100644 scripts/build/config.js create mode 100644 scripts/build/watch.js diff --git a/.circleci/config.yml b/.circleci/config.yml index ac8d9532a775..91aea3d4aef1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -237,6 +237,9 @@ commands: paths: - ~/.cache/yarn key: << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }} + - run: + name: Build packages + command: yarn build brew_install: parameters: diff --git a/flow-typed/npm/chokidar_v3.x.x.js b/flow-typed/npm/chokidar_v3.x.x.js new file mode 100644 index 000000000000..2fa5dbf7c539 --- /dev/null +++ b/flow-typed/npm/chokidar_v3.x.x.js @@ -0,0 +1,202 @@ +/** + * @flow strict + * @format + */ + +declare module 'chokidar' { + import type {Stats} from 'fs'; + + declare export class FSWatcher extends events$EventEmitter { + options: WatchOptions; + + /** + * Constructs a new FSWatcher instance with optional WatchOptions parameter. + */ + constructor(options?: WatchOptions): this; + + /** + * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one + * string. + */ + add(paths: string | $ReadOnlyArray): this; + + /** + * Stop watching files, directories, or glob patterns. Takes an array of strings or just one + * string. + */ + unwatch(paths: string | $ReadOnlyArray): this; + + /** + * Returns an object representing all the paths on the file system being watched by this + * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless + * the `cwd` option was used), and the values are arrays of the names of the items contained in + * each directory. + */ + getWatched(): { + [directory: string]: string[], + }; + + /** + * Removes all listeners from watched files. + */ + close(): Promise; + + on( + event: 'add' | 'addDir' | 'change', + listener: (path: string, stats?: Stats) => void, + ): this; + + on( + event: 'all', + listener: ( + eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', + path: string, + stats?: Stats, + ) => void, + ): this; + + /** + * Error occurred + */ + on(event: 'error', listener: (error: Error) => void): this; + + /** + * Exposes the native Node `fs.FSWatcher events` + */ + on( + event: 'raw', + listener: (eventName: string, path: string, details: any) => void, + ): this; + + /** + * Fires when the initial scan is complete + */ + on(event: 'ready', listener: () => void): this; + + on(event: 'unlink' | 'unlinkDir', listener: (path: string) => void): this; + + on(event: string, listener: (...args: any[]) => void): this; + } + + declare export interface WatchOptions { + /** + * Indicates whether the process should continue to run as long as files are being watched. If + * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`, + * even if the process continues to run. + */ + persistent?: boolean; + + /** + * ([anymatch](https://github.com/micromatch/anymatch)-compatible definition) Defines files/paths to + * be ignored. The whole relative or absolute path is tested, not just filename. If a function + * with two arguments is provided, it gets called twice per path - once with a single argument + * (the path), second time with two arguments (the path and the + * [`Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path). + */ + ignored?: string | Array; + + /** + * If set to `false` then `add`/`addDir` events are also emitted for matching paths while + * instantiating the watching as chokidar discovers these file paths (before the `ready` event). + */ + ignoreInitial?: boolean; + + /** + * When `false`, only the symlinks themselves will be watched for changes instead of following + * the link references and bubbling events through the link's path. + */ + followSymlinks?: boolean; + + /** + * The base directory from which watch `paths` are to be derived. Paths emitted with events will + * be relative to this. + */ + cwd?: string; + + /** + * If set to true then the strings passed to .watch() and .add() are treated as literal path + * names, even if they look like globs. Default: false. + */ + disableGlobbing?: boolean; + + /** + * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU + * utilization, consider setting this to `false`. It is typically necessary to **set this to + * `true` to successfully watch files over a network**, and it may be necessary to successfully + * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides + * the `useFsEvents` default. + */ + usePolling?: boolean; + + /** + * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly + * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on + * OS X, `usePolling: true` becomes the default. + */ + useFsEvents?: boolean; + + /** + * If relying upon the [`Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that + * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is + * provided even in cases where it wasn't already available from the underlying watch events. + */ + alwaysStat?: boolean; + + /** + * If set, limits how many levels of subdirectories will be traversed. + */ + depth?: number; + + /** + * Interval of file system polling. + */ + interval?: number; + + /** + * Interval of file system polling for binary files. ([see list of binary extensions](https://gi + * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json)) + */ + binaryInterval?: number; + + /** + * Indicates whether to watch files that don't have read permissions if possible. If watching + * fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed + * silently. + */ + ignorePermissionErrors?: boolean; + + /** + * `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts + * that occur when using editors that use "atomic writes" instead of writing directly to the + * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change` + * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you, + * you can override it by setting `atomic` to a custom value, in milliseconds. + */ + atomic?: boolean | number; + + /** + * can be set to an object in order to adjust timing params: + */ + awaitWriteFinish?: AwaitWriteFinishOptions | boolean; + } + + declare export interface AwaitWriteFinishOptions { + /** + * Amount of time in milliseconds for a file size to remain constant before emitting its event. + */ + stabilityThreshold?: number; + + /** + * File size polling interval. + */ + pollInterval?: number; + } + + /** + * produces an instance of `FSWatcher`. + */ + declare export function watch( + paths: string | $ReadOnlyArray, + options?: WatchOptions, + ): FSWatcher; +} diff --git a/flow-typed/npm/parseargs_v0.11.x.js b/flow-typed/npm/parseargs_v0.11.x.js new file mode 100644 index 000000000000..396865dca4fc --- /dev/null +++ b/flow-typed/npm/parseargs_v0.11.x.js @@ -0,0 +1,40 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + * @oncall react_native + */ + +declare module '@pkgjs/parseargs' { + declare type ParseArgsOptionConfig = { + type: 'string' | 'boolean', + short?: string, + multiple?: boolean, + }; + + declare type ParseArgsOptionsConfig = { + [longOption: string]: ParseArgsOptionConfig, + }; + + declare export type ParseArgsConfig = { + strict?: boolean, + allowPositionals?: boolean, + tokens?: boolean, + options?: ParseArgsOptionsConfig, + args?: string[], + }; + + declare type ParsedResults = { + values: { + [longOption: string]: void | string | boolean | Array, + }, + positionals: string[], + ... + }; + + declare export function parseArgs(config: ParseArgsConfig): ParsedResults; +} diff --git a/package.json b/package.json index f20eb972052a..b6a924b1f27d 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,12 @@ "outputName": "js-test-results.xml" }, "scripts": { - "start": "cd packages/rn-tester && npm run start", + "postinstall": "yarn build", + "start": "yarn build && cd packages/rn-tester && npm run start", "android": "cd packages/rn-tester && npm run android", + "build": "node ./scripts/build/build.js", + "clean": "node ./scripts/build/clean.js", + "watch": "yarn build && node ./scripts/build/watch.js", "test": "jest", "test-ci": "jest --maxWorkers=2 --ci --reporters=\"default\" --reporters=\"jest-junit\"", "flow": "flow", @@ -57,11 +61,14 @@ "@babel/plugin-transform-regenerator": "^7.20.0", "@definitelytyped/dtslint": "^0.0.127", "@jest/create-cache-key-function": "^29.2.1", + "@pkgjs/parseargs": "^0.11.0", "@react-native/metro-config": "^0.73.0", "@types/react": "^18.0.18", "@typescript-eslint/parser": "^5.57.1", "async": "^3.2.2", "babel-plugin-transform-flow-enums": "^0.0.2", + "chalk": "^4.0.0", + "chokidar": "^3.5.3", "clang-format": "^1.8.0", "connect": "^3.6.5", "eslint": "^8.19.0", @@ -79,6 +86,7 @@ "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", "flow-bin": "^0.212.0", + "glob": "^7.1.1", "hermes-eslint": "0.14.0", "inquirer": "^7.1.0", "jest": "^29.2.1", @@ -87,6 +95,7 @@ "metro-babel-register": "0.76.2", "metro-memory-fs": "0.76.2", "metro-react-native-babel-transformer": "0.76.2", + "micromatch": "^4.0.4", "mkdirp": "^0.5.1", "mock-fs": "^5.1.4", "prettier": "2.8.8", diff --git a/packages/dev-middleware/.babelrc b/packages/dev-middleware/.babelrc deleted file mode 100644 index e6ab061db791..000000000000 --- a/packages/dev-middleware/.babelrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "presets": [ - "@babel/preset-flow", - [ - "@babel/preset-env", - { - "targets": { - "node": "16" - } - } - ] - ] -} diff --git a/packages/dev-middleware/package.json b/packages/dev-middleware/package.json index 5fc0b5b79bc1..f1ff46f01a2b 100644 --- a/packages/dev-middleware/package.json +++ b/packages/dev-middleware/package.json @@ -18,25 +18,12 @@ "files": [ "dist" ], - "scripts": { - "build": "yarn clean && babel src --out-dir dist", - "dev": "babel src --out-dir dist --source-maps --watch", - "clean": "rimraf dist", - "prepare": "yarn build" - }, "dependencies": { "chrome-launcher": "^0.15.2", "connect": "^3.6.5", "node-fetch": "^2.2.0", "temp-dir": "^2.0.0" }, - "devDependencies": { - "@babel/cli": "^7.20.0", - "@babel/core": "^7.20.0", - "@babel/preset-env": "^7.20.0", - "@babel/preset-flow": "^7.20.0", - "rimraf": "^3.0.2" - }, "engines": { "node": ">=18" } diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json index 2adbba48dd38..47fda9fb7ed9 100644 --- a/packages/rn-tester/package.json +++ b/packages/rn-tester/package.json @@ -13,7 +13,7 @@ "node": ">=18" }, "scripts": { - "start": "react-native start", + "start": "yarn --cwd ../.. build && react-native start", "android": "react-native run-android --mode HermesDebug --appId 'com.facebook.react.uiapp' --main-activity 'com.facebook.react.uiapp.RNTesterActivity'", "install-android-jsc": "../../gradlew :packages:rn-tester:android:app:installJscDebug", "install-android-hermes": "../../gradlew :packages:rn-tester:android:app:installHermesDebug", diff --git a/scripts/build/build.js b/scripts/build/build.js new file mode 100644 index 000000000000..19ff401e0a54 --- /dev/null +++ b/scripts/build/build.js @@ -0,0 +1,146 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + * @oncall react_native + */ + +const babel = require('@babel/core'); +const {parseArgs} = require('@pkgjs/parseargs'); +const chalk = require('chalk'); +const glob = require('glob'); +const micromatch = require('micromatch'); +const fs = require('fs'); +const path = require('path'); +const prettier = require('prettier'); +const {buildConfig, getBabelConfig} = require('./config'); + +const PACKAGES_DIR /*: string */ = path.resolve(__dirname, '../../packages'); +const SRC_DIR = 'src'; +const BUILD_DIR = 'dist'; +const JS_FILES_PATTERN = '**/*.js'; +const IGNORE_PATTERN = '**/__{tests,mocks,fixtures}__/**'; + +const config = { + allowPositionals: true, + options: { + help: {type: 'boolean'}, + }, +}; + +function build() { + const { + positionals: packageNames, + values: {help}, + } = parseArgs(config); + + if (help) { + console.log(` + Usage: node ./scripts/build/build.js + + Build packages (shared monorepo build setup). + + By default, builds all packages defined in ./scripts/build/config.js. If a + a package list is provided, builds only those specified. + `); + process.exitCode = 0; + return; + } + + console.log('\n' + chalk.bold.inverse('Building packages') + '\n'); + + if (packageNames.length) { + packageNames + .filter(packageName => packageName in buildConfig.packages) + .forEach(buildPackage); + } else { + Object.keys(buildConfig.packages).forEach(buildPackage); + } + + console.log( + '\nTip: Use ' + + chalk.bold.inverse('yarn watch') + + ' to build continuously when working on these packages.\n', + ); + process.exitCode = 0; +} + +function buildPackage(packageName /*: string */) { + const files = glob.sync( + path.resolve(PACKAGES_DIR, packageName, SRC_DIR, '**/*'), + {nodir: true}, + ); + + process.stdout.write( + `${packageName} ${chalk.dim('.').repeat(72 - packageName.length)} `, + ); + files.forEach(file => buildFile(path.normalize(file), true)); + process.stdout.write(chalk.reset.inverse.bold.green(' DONE ') + '\n'); +} + +function buildFile(file /*: string */, silent /*: boolean */ = false) { + const packageName = getPackageName(file); + const buildPath = getBuildPath(file); + + const logResult = ({copied, desc} /*: {copied: boolean, desc?: string} */) => + silent || + console.log( + chalk.dim(' - ') + + path.relative(PACKAGES_DIR, file) + + (copied ? ' -> ' + path.relative(PACKAGES_DIR, buildPath) : ' ') + + (desc != null ? ' (' + desc + ')' : ''), + ); + + if (micromatch.isMatch(file, IGNORE_PATTERN)) { + logResult({copied: false, desc: 'ignore'}); + return; + } + + fs.mkdirSync(path.dirname(buildPath), {recursive: true}); + + if (!micromatch.isMatch(file, JS_FILES_PATTERN)) { + fs.copyFileSync(file, buildPath); + logResult({copied: true, desc: 'copy'}); + } else { + const transformed = prettier.format( + babel.transformFileSync(file, getBabelConfig(packageName)).code, + {parser: 'babel'}, + ); + fs.writeFileSync(buildPath, transformed); + + if (/@flow/.test(fs.readFileSync(file, 'utf-8'))) { + fs.copyFileSync(file, buildPath + '.flow'); + } + + logResult({copied: true}); + } +} + +function getPackageName(file /*: string */) /*: string */ { + return path.relative(PACKAGES_DIR, file).split(path.sep)[0]; +} + +function getBuildPath(file /*: string */) /*: string */ { + const packageDir = path.join(PACKAGES_DIR, getPackageName(file)); + + return path.join( + packageDir, + file.replace(path.join(packageDir, SRC_DIR), BUILD_DIR), + ); +} + +module.exports = { + buildFile, + getBuildPath, + BUILD_DIR, + PACKAGES_DIR, + SRC_DIR, +}; + +if (require.main === module) { + build(); +} diff --git a/scripts/build/clean.js b/scripts/build/clean.js new file mode 100644 index 000000000000..15296f06556b --- /dev/null +++ b/scripts/build/clean.js @@ -0,0 +1,51 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + * @oncall react_native + */ + +const {parseArgs} = require('@pkgjs/parseargs'); +const fs = require('fs'); +const path = require('path'); +const {BUILD_DIR, PACKAGES_DIR} = require('./build'); +const {buildConfig} = require('./config'); + +const config = { + options: { + help: {type: 'boolean'}, + }, +}; + +function clean() { + const { + values: {help}, + } = parseArgs(config); + + if (help) { + console.log(` + Usage: node ./scripts/build/clean.js + + Clean build directories for all packages defined in ./scripts/build/config.js. + `); + process.exitCode = 0; + return; + } + + for (const packageName of Object.keys(buildConfig.packages)) { + fs.rmSync(path.join(PACKAGES_DIR, packageName, BUILD_DIR), { + force: true, + recursive: true, + }); + } + + process.exitCode = 0; +} + +if (require.main === module) { + clean(); +} diff --git a/scripts/build/config.js b/scripts/build/config.js new file mode 100644 index 000000000000..3b244a5790da --- /dev/null +++ b/scripts/build/config.js @@ -0,0 +1,59 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + * @oncall react_native + */ + +/*:: +import type {BabelCoreOptions} from '@babel/core'; + +export type BuildOptions = $ReadOnly<{ + target: 'node', +}>; + +export type BuildConfig = $ReadOnly<{ + packages: $ReadOnly<{[packageName: string]: BuildOptions}>, +}>; +*/ + +const TARGET_NODE_VERSION = '18'; + +const buildConfig /*: BuildConfig */ = { + // The packages to include for build and their build options + packages: { + 'dev-middleware': {target: 'node'}, + }, +}; + +function getBabelConfig( + packageName /*: $Keys */, +) /*: BabelCoreOptions */ { + const {target} = buildConfig.packages[packageName]; + + switch (target) { + case 'node': + return { + presets: [ + '@babel/preset-flow', + [ + '@babel/preset-env', + { + targets: { + node: TARGET_NODE_VERSION, + }, + }, + ], + ], + }; + } +} + +module.exports = { + buildConfig, + getBabelConfig, +}; diff --git a/scripts/build/watch.js b/scripts/build/watch.js new file mode 100644 index 000000000000..90a6918b43db --- /dev/null +++ b/scripts/build/watch.js @@ -0,0 +1,81 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + * @oncall react_native + */ + +const {parseArgs} = require('@pkgjs/parseargs'); +const chalk = require('chalk'); +const chokidar = require('chokidar'); +const fs = require('fs'); +const path = require('path'); +const {getBuildPath, buildFile, PACKAGES_DIR, SRC_DIR} = require('./build'); +const {buildConfig} = require('./config'); + +const config = { + options: { + help: {type: 'boolean'}, + }, +}; + +let changedFiles /*: Set */ = new Set(); + +function watch() { + const { + values: {help}, + } = parseArgs(config); + + if (help) { + console.log(` + Usage: node ./scripts/build/watch.js + + Watch files for changes and rebuild on change (development). Watches all + packages defined in ./scripts/build/config.js. + `); + process.exitCode = 0; + return; + } + + const watcher = chokidar.watch( + Object.keys(buildConfig.packages).map(packageName => + path.resolve(PACKAGES_DIR, packageName, SRC_DIR), + ), + ); + + watcher.on('ready', () => { + watcher.on('change', handleChange); + watcher.on('add', handleChange); + watcher.on('unlink', handleUnlink); + }); + + setInterval(() => { + const files = Array.from(changedFiles.values()); + + if (files.length) { + changedFiles = new Set(); + files.forEach(file => buildFile(file)); + } + }, 100); + + console.log('\n' + chalk.bold.inverse('Watching for changes...') + '\n'); + process.exitCode = 0; +} + +function handleChange(filePath /*: string */) { + changedFiles.add(filePath); +} + +function handleUnlink(filePath /*: string */) { + const buildPath = getBuildPath(filePath); + fs.rm(buildPath, {force: true}); + fs.rm(buildPath + '.flow', {force: true}); +} + +if (require.main === module) { + watch(); +} diff --git a/yarn.lock b/yarn.lock index 433b884164c6..ab18c70e9755 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11,9 +11,9 @@ "@jridgewell/trace-mapping" "^0.3.9" "@babel/cli@^7.20.0": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.5.tgz#a685a5b50b785f2edfbf6e042c1265c653547d9d" - integrity sha512-TOKytQ9uQW9c4np8F+P7ZfPINy5Kv+pizDIUwSVH8X5zHgYHV4AA8HE5LA450xXeu4jEfmUckTYvv1I4S26M/g== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.22.6.tgz#63f5be2a0abd587ccfbdc93424fa85f43142cc53" + integrity sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw== dependencies: "@jridgewell/trace-mapping" "^0.3.17" commander "^4.0.1" @@ -2332,6 +2332,11 @@ dependencies: "@octokit/openapi-types" "^12.11.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -3162,7 +3167,7 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -anymatch@^3.0.3, anymatch@~3.1.2: +anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -3170,6 +3175,14 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + appdirsjs@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.4.tgz#3ab582acc9fdfaaa0c1f81b3a25422ad4d95f9d4" @@ -3674,7 +3687,7 @@ charm@^1.0.2: dependencies: inherits "^2.0.1" -chokidar@^3.4.0: +chokidar@^3.4.0, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3929,7 +3942,12 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.1.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==