diff --git a/.eslintrc.js b/.eslintrc.js index c1e8f5e0e9b..d1335831550 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,7 @@ module.exports = { // overriding the JS config from @react-native/eslint-config to ensure // that we use hermes-eslint for all js files { - files: ['*.js', '*.js.flow'], + files: ['*.js', '*.js.flow', '*.jsx'], parser: 'hermes-eslint', rules: { // These rules are not required with hermes-eslint diff --git a/packages/community-cli-plugin/src/commands/start/runServer.js b/packages/community-cli-plugin/src/commands/start/runServer.js index 15820167a52..18540fa1e2c 100644 --- a/packages/community-cli-plugin/src/commands/start/runServer.js +++ b/packages/community-cli-plugin/src/commands/start/runServer.js @@ -38,7 +38,7 @@ export type StartCommandArgs = { https?: boolean, maxWorkers?: number, key?: string, - platforms?: string[], + platforms: string[], port?: number, resetCache?: boolean, sourceExts?: string[], diff --git a/packages/core-cli-utils/package.json b/packages/core-cli-utils/package.json index 9107b6fdbe3..04f7d25b7dd 100644 --- a/packages/core-cli-utils/package.json +++ b/packages/core-cli-utils/package.json @@ -2,7 +2,7 @@ "name": "@react-native/core-cli-utils", "version": "0.75.0-main", "description": "React Native CLI library for Frameworks to build on", - "main": "./src/index.js", + "main": "./src/index.flow.js", "license": "MIT", "repository": { "type": "git", @@ -10,11 +10,11 @@ "directory": "packages/core-cli-utils" }, "exports": { - ".": "./src/index.js", + ".": "./src/index.flow.js", "./package.json": "./package.json", "./version.js": "./src/public/version.js" }, - "types": "./dist/index.d.ts", + "types": "./dist/index.flow.d.ts", "homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/core-cli-utils#readme", "keywords": [ "cli-utils", @@ -25,8 +25,8 @@ "node": ">=18" }, "files": [ - "dist" + "src" ], "dependencies": {}, "devDependencies": {} -} +} \ No newline at end of file diff --git a/packages/core-cli-utils/src/index.js b/packages/core-cli-utils/src/index.js deleted file mode 100644 index 9d4c8354fc2..00000000000 --- a/packages/core-cli-utils/src/index.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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 path = require('path'); - -/*:: -export type * from './index.flow.js'; -*/ - -if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) { - // Handle internal cases when we call this from the monorepo, and external cases where users call it from a plain-old-node_modules - let {root, dir} = path.parse(__dirname); - while (dir !== root) { - try { - // $FlowFixMe[unsupported-syntax] we're doing magic here - require( - path.resolve(dir, 'scripts/build/babel-register'), - ).registerForMonorepo(); - break; - } catch { - dir = path.resolve(dir, '..'); - } - } -} - -export * from './index.flow.js'; diff --git a/packages/core-cli-utils/src/monorepo.js b/packages/core-cli-utils/src/monorepo.js new file mode 100644 index 00000000000..be8075fc7c4 --- /dev/null +++ b/packages/core-cli-utils/src/monorepo.js @@ -0,0 +1,23 @@ +/** + * 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. + * + * @format + * @oncall react_native + */ + +// Should only used when called in the monorepo when we don't want to use the `yarn run build` +// step to transpile to project. When used as a vanilla npm package, it should be built and +// exported with `dist/index.flow.js` as main. +// +// The reason for this workaround is that flow-api-translator can't understand ESM and CJS style +// exports in the same file. Throw in a bit of Flow in the mix and it all goes to hell. +// +// See packages/helloworld/cli.js for an example of how to swap this out in the monorepo. +if (process.env.BUILD_EXCLUDE_BABEL_REGISTER == null) { + require('../../../scripts/build/babel-register').registerForMonorepo(); +} + +module.exports = require('./index.flow.js'); diff --git a/packages/core-cli-utils/src/private/android.js b/packages/core-cli-utils/src/private/android.js index 83ec922c0ac..9117f9130f4 100644 --- a/packages/core-cli-utils/src/private/android.js +++ b/packages/core-cli-utils/src/private/android.js @@ -24,12 +24,8 @@ type AndroidBuild = { gradleArgs?: Array, }; -async function gradle( - cwd: string, - ...args: string[] -): ReturnType { +function gradle(cwd: string, ...args: string[]): ExecaPromise { const gradlew = isWindows ? 'gradlew.bat' : './gradlew'; - // $FlowFixMe[incompatible-return] Mismatch between flow and TypeScript types return execa(gradlew, args, { cwd, stdio: 'inherit', diff --git a/packages/core-cli-utils/src/private/apple.js b/packages/core-cli-utils/src/private/apple.js index ed3414da6ac..9ec6a0bc9c5 100644 --- a/packages/core-cli-utils/src/private/apple.js +++ b/packages/core-cli-utils/src/private/apple.js @@ -39,6 +39,7 @@ type AppleInstallApp = { // `xcrun simctl list devices` device: string, appPath: string, + bundleId: string, ...AppleOptions, }; diff --git a/packages/core-cli-utils/src/private/utils.js b/packages/core-cli-utils/src/private/utils.js index 396d29eed20..3c2f096b5cd 100644 --- a/packages/core-cli-utils/src/private/utils.js +++ b/packages/core-cli-utils/src/private/utils.js @@ -41,6 +41,7 @@ type PathCheckResult = { export function isOnPath(dep: string, description: string): PathCheckResult { const cmd = isWindows ? ['where', [dep]] : ['command', ['-v', dep]]; try { + const args = isWindows ? ['where', [dep]] : ['command', ['-v', dep]]; return { dep, description, diff --git a/packages/helloworld/.gitignore b/packages/helloworld/.gitignore index d5ae456695e..08e1a6b5935 100644 --- a/packages/helloworld/.gitignore +++ b/packages/helloworld/.gitignore @@ -1,9 +1,7 @@ # OSX -# .DS_Store # Xcode -# build/ *.pbxuser !default.pbxuser @@ -23,7 +21,6 @@ DerivedData **/.xcode.env.local # Android/IntelliJ -# build/ .idea .gradle @@ -35,36 +32,20 @@ local.properties !debug.keystore # node.js -# node_modules/ npm-debug.log yarn-error.log -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/ - -**/fastlane/report.xml -**/fastlane/Preview.html -**/fastlane/screenshots -**/fastlane/test_output - # Bundle artifact *.jsbundle # Ruby / CocoaPods -**/Pods/ -/vendor/bundle/ +ios/Pods/ +vendor/bundle/ # Temporary files created by Metro to check the health of the file watcher .metro-health-check* -# testing -/coverage - # Yarn .yarn/* !.yarn/patches diff --git a/packages/helloworld/App.tsx b/packages/helloworld/App.jsx similarity index 100% rename from packages/helloworld/App.tsx rename to packages/helloworld/App.jsx diff --git a/packages/helloworld/__tests__/App.test.tsx b/packages/helloworld/__tests__/App.test.tsx deleted file mode 100644 index 222e662c22c..00000000000 --- a/packages/helloworld/__tests__/App.test.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/** - * 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. - */ - -/** - * @format - */ - -import 'react-native'; -import React from 'react'; -import App from '../App'; - -// Note: import explicitly to use the types shipped with jest. -import {it} from '@jest/globals'; - -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - -it('renders correctly', () => { - renderer.create(); -}); diff --git a/packages/helloworld/__tests__/cli-skip.js b/packages/helloworld/__tests__/cli-skip.js new file mode 100644 index 00000000000..2b92acc1bc8 --- /dev/null +++ b/packages/helloworld/__tests__/cli-skip.js @@ -0,0 +1,69 @@ +/** + * 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-local + * @format + * @oncall react_native + */ + +// TODO(T187224491): js1 jest doesn't install the correct commander, instead +// using the one in xplat/js/node_modules/commander which is much older. +// Either roll back to that version or upgrade. +import cli from '../cli.flow.js'; +import fs from 'fs'; + +describe('cli.js', () => { + let pkgJson = { + name: 'helloworld-mock', + dependencies: { + 'react-native': '0.0.0', + }, + devDependencies: { + listr: '^1.2.3', + 'some-dev-dep': '1.0.0', + }, + }; + beforeEach(() => { + jest.resetAllMocks(); + }); + describe('set-version', () => { + it('without arguments this should not modify the package.json', () => { + const snapshot = JSON.stringify(pkgJson, null, 2); + jest.spyOn(fs, 'readFileSync').mockReturnValue(snapshot); + const spy = jest.spyOn(fs, 'writeFileSync'); + + cli.parse(['set-version'], {from: 'user'}); + + expect(spy.mock.lastCall[1]).toEqual(snapshot); + }); + + it('modified and adds dependencies', () => { + const snapshot = JSON.stringify(pkgJson, null, 2); + jest.spyOn(fs, 'readFileSync').mockReturnValue(snapshot); + const spy = jest.spyOn(fs, 'writeFileSync'); + + cli.parse( + [ + 'set-version', + 'react-native@^0.1.1', + 'foobar@file:/woot/berry', + 'some-dev-dep@*', + ], + {from: 'user'}, + ); + const updated = JSON.parse(spy.mock.lastCall[1]); + expect(updated).toMatchObject({ + dependencies: { + 'react-native': '^0.1.1', + foobar: 'file:/woot/berry', + }, + devDependencies: { + 'some-dev-dep': '*', + }, + }); + }); + }); +}); diff --git a/packages/helloworld/android/app/build.gradle b/packages/helloworld/android/app/build.gradle index 92894277ad9..f3db66d5ed3 100644 --- a/packages/helloworld/android/app/build.gradle +++ b/packages/helloworld/android/app/build.gradle @@ -123,4 +123,4 @@ dependencies { } // TODO: This needs to use the new autolinking code in the gradle-plugin instead -apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) +// apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/packages/helloworld/android/gradle.properties b/packages/helloworld/android/gradle.properties index b8bf0a51744..29fb5a6ad4f 100644 --- a/packages/helloworld/android/gradle.properties +++ b/packages/helloworld/android/gradle.properties @@ -1,42 +1,13 @@ -# Project-wide Gradle settings. +# 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. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn +org.gradle.parallel=true android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX android.enableJetifier=true - -# Use this property to specify which architecture you want to build. -# You can also override it from the CLI using -# ./gradlew -PreactNativeArchitectures=x86_64 -# TODO: Do we want to limit the architectures we test on? -reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 - -# Use this property to enable support to the new architecture. -# This will allow you to use TurboModules and the Fabric render in -# your application. You should enable this flag either if you want -# to write custom TurboModules/Fabric components OR use libraries that -# are providing them. +reactNativeArchitectures=arm64-v8a newArchEnabled=true - -# Use this property to enable or disable the Hermes JS engine. -# If set to false, you will be using JSC instead. hermesEnabled=true diff --git a/packages/helloworld/android/settings.gradle b/packages/helloworld/android/settings.gradle index d4b8bc5e713..0125930e708 100644 --- a/packages/helloworld/android/settings.gradle +++ b/packages/helloworld/android/settings.gradle @@ -6,7 +6,6 @@ */ rootProject.name = 'HelloWorld' -// TODO: Use the new autolinking feature in the gradle plugin (not that it's necessary as we don't have any native extensions here. Maybe we should have?) -// apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' -includeBuild('../../../../react-native-gradle-plugin') +// Autolinking has now moved into the React Native Gradle Plugin +includeBuild('../../react-native-gradle-plugin') diff --git a/packages/helloworld/app.json b/packages/helloworld/app.json deleted file mode 100644 index cbbc305181a..00000000000 --- a/packages/helloworld/app.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "HelloWorld", - "displayName": "HelloWorld" -} diff --git a/packages/helloworld/cli.flow.js b/packages/helloworld/cli.flow.js index 59cc2033d35..177f64ce1ac 100644 --- a/packages/helloworld/cli.flow.js +++ b/packages/helloworld/cli.flow.js @@ -41,21 +41,23 @@ type IOSDevice = { name: string, }; -function observe(result: ExecaPromise): Observable { +type ExecaPromiseMetaized = Promise & child_process$ChildProcess; + +function observe(result: ExecaPromiseMetaized): Observable { return new Observable(observer => { result.stderr.on('data', data => data .toString('utf8') .split('\n') .filter(line => line.length > 0) - .forEach(line => observer.next('🟢 ' + line)), + .forEach(line => observer.next('🟢 ' + line.trim())), ); result.stdout.on('data', data => data .toString('utf8') .split('\n') .filter(line => line.length > 0) - .forEach(line => observer.next('🟠 ' + line)), + .forEach(line => observer.next('🟠 ' + line.trim())), ); for (const event of ['close', 'end']) { result.stdout.on(event, () => observer.complete()); @@ -70,6 +72,26 @@ function observe(result: ExecaPromise): Observable { }); } +function getXcodeBuildSettings(iosProjectFolder: string) { + const {stdout} = execa.sync( + 'xcodebuild', + [ + '-workspace', + 'HelloWorld.xcworkspace', + '-scheme', + 'HelloWorld', + '-configuration', + 'Debug', + '-sdk', + 'iphonesimulator', + '-showBuildSettings', + '-json', + ], + {cwd: iosProjectFolder}, + ); + return JSON.parse(stdout); +} + async function getSimulatorDetails(nameOrUDID: string): Promise { const {stdout} = execa.sync('xcrun', [ 'simctl', @@ -164,7 +186,9 @@ function run( title: task.label, task: () => { const action = task.action(); - return action != null ? observe(action) : action; + if (action != null) { + return observe(action); + } }, })); return new Listr(spec).run(); @@ -209,7 +233,38 @@ build }), ); - // TODO: Install + const settings = { + appPath: '', + bundleId: '', + }; + + await run({ + buildSettings: { + order: 1, + label: 'Getting your build settings', + action: (): void => { + const xcode = getXcodeBuildSettings(cwd.ios)[0].buildSettings; + settings.appPath = path.join( + xcode.TARGET_BUILD_DIR, + xcode.EXECUTABLE_FOLDER_PATH, + ); + settings.bundleId = xcode.PRODUCT_BUNDLE_IDENTIFIER; + }, + }, + }); + + await run( + apple.ios.install({ + cwd: cwd.ios, + device: device.udid, + appPath: settings.appPath, + bundleId: settings.bundleId, + }), + ); }); -program.parse(); +if (require.main === module) { + program.parse(); +} + +export default program; diff --git a/packages/helloworld/cli.js b/packages/helloworld/cli.js index b7c213c3f0e..b5ba1ed3c55 100644 --- a/packages/helloworld/cli.js +++ b/packages/helloworld/cli.js @@ -9,9 +9,38 @@ * @oncall react_native */ +/*:: +import {Command} from 'commander'; +*/ + +// eslint-disable-next-line lint/sort-imports +const {patchCoreCLIUtilsPackageJSON} = require('./scripts/monorepo'); + +function injectCoreCLIUtilsRuntimePatch() { + patchCoreCLIUtilsPackageJSON(true); + const cleared = { + status: false, + }; + ['exit', 'SIGUSR1', 'SIGUSR2', 'uncaughtException'].forEach(event => { + if (cleared.status) { + return; + } + patchCoreCLIUtilsPackageJSON(false); + cleared.status = true; + }); +} + if (process.env.BUILD_EXCLUDE_BABEL_REGISTER == null) { // $FlowFixMe[cannot-resolve-module] require('../../scripts/build/babel-register').registerForMonorepo(); } -require('./cli.flow.js'); +injectCoreCLIUtilsRuntimePatch(); + +const program /*: Command */ = require('./cli.flow.js').default; + +if (require.main === module) { + program.parse(); +} + +module.exports = program; diff --git a/packages/helloworld/index.js b/packages/helloworld/index.js index 040d10d9660..19836486c82 100644 --- a/packages/helloworld/index.js +++ b/packages/helloworld/index.js @@ -7,8 +7,7 @@ * @format */ -import {name as appName} from './app.json'; -import App from './SectionProps'; +import App from './App'; import {AppRegistry} from 'react-native'; -AppRegistry.registerComponent(appName, () => App); +AppRegistry.registerComponent('HelloWorld', () => App); diff --git a/packages/helloworld/metro.config.js b/packages/helloworld/metro.config.js index ed129355727..50855d5a705 100644 --- a/packages/helloworld/metro.config.js +++ b/packages/helloworld/metro.config.js @@ -8,6 +8,7 @@ */ const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); +const path = require('path'); /** * Metro configuration @@ -15,6 +16,22 @@ const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); * * @type {import('metro-config').MetroConfig} */ -const config = {}; +const config = { + // Make Metro able to resolve required external dependencies + watchFolders: [ + path.resolve(__dirname, '../../node_modules'), + path.resolve(__dirname, '../assets'), + path.resolve(__dirname, '../normalize-color'), + path.resolve(__dirname, '../polyfills'), + path.resolve(__dirname, '../react-native'), + path.resolve(__dirname, '../virtualized-lists'), + ], + resolver: { + blockList: [/..\/react-native\/sdks\/hermes/], + extraNodeModules: { + 'react-native': path.resolve(__dirname, '../react-native'), + }, + }, +}; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/packages/helloworld/package.json b/packages/helloworld/package.json index 885ca571c30..4d1c986fade 100644 --- a/packages/helloworld/package.json +++ b/packages/helloworld/package.json @@ -5,7 +5,7 @@ "scripts": { "bootstrap": "node ./cli.js bootstrap", "build": "node ./cli.js build", - "launch": "node ./cli.js launch", + "launch": "node ./scripts/metro.js", "lint": "eslint .", "test": "jest" }, @@ -22,13 +22,13 @@ "@react-native/eslint-config": "0.75.0-main", "@react-native/metro-config": "0.75.0-main", "babel-jest": "^29.6.3", + "chalk": "4", "commander": "^12.0.0", "eslint": "^8.19.0", "jest": "^29.6.3", "listr": "^0.14.3", "react-test-renderer": "18.2.0", - "rxjs": "^7.8.1", - "typescript": "5.0.4" + "rxjs": "^7.8.1" }, "engines": { "node": ">=18" diff --git a/packages/helloworld/scripts/metro.js b/packages/helloworld/scripts/metro.js new file mode 100644 index 00000000000..54a2fd43d13 --- /dev/null +++ b/packages/helloworld/scripts/metro.js @@ -0,0 +1,37 @@ +/** + * 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. + * + * @noflow + * @format + * @oncall react_native + */ + +const {startCommand} = require('@react-native/community-cli-plugin'); +const {program} = require('commander'); +const path = require('path'); + +program + .description('Starts the React Native Metro bundler for internal testing app') + .action(async options => { + await startCommand.func( + [], + { + platforms: { + ios: {}, + android: {}, + }, + root: path.join(__dirname, '../'), + reactNativePath: path.join(__dirname, '../../react-native'), + }, + { + experimentalDebugger: false, + interactive: false, + projectRoot: options.projectRoot, + platforms: ['ios', 'android'], + }, + ); + }) + .parse(); diff --git a/packages/helloworld/scripts/monorepo.js b/packages/helloworld/scripts/monorepo.js new file mode 100644 index 00000000000..7911f764b59 --- /dev/null +++ b/packages/helloworld/scripts/monorepo.js @@ -0,0 +1,42 @@ +/** + * 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-local + * @format + * @oncall react_native + */ + +// To be able to execute the cli as a yarn script, we have to strip our yarn types. +// This causes problems for some of our dependencies, because they live in Meta internals, +// Github and in NPM: +// - Github and Meta: dynamicly transpile our dependencies. They each have to register on the monorepo +// - NPM: `yarn run build`, and it should update the package.json's exports, main and files +function patchCoreCLIUtilsPackageJSON(patch /*: boolean */) { + const fs = require('fs'); + const log = require('debug'); + const pkg = JSON.parse( + fs.readFileSync('../core-cli-utils/package.json', 'utf8'), + ); + const target = patch ? './src/monorepo.js' : './src/index.flow.js'; + if (pkg.main === target) { + return; + } + pkg.main = target; + pkg.exports['.'] = target; + log( + `Patched: ${JSON.stringify( + {main: pkg.main, exports: pkg.exports}, + null, + 2, + )}`, + ); + fs.writeFileSync( + '../core-cli-utils/package.json', + JSON.stringify(pkg, null, 2), + ); +} + +module.exports.patchCoreCLIUtilsPackageJSON = patchCoreCLIUtilsPackageJSON; diff --git a/packages/helloworld/template/index.js b/packages/helloworld/template/index.js deleted file mode 100644 index f0888064722..00000000000 --- a/packages/helloworld/template/index.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * 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. - * - * @format - */ - -import App from './App'; -import {name as appName} from './app.json'; -import {AppRegistry} from 'react-native'; - -AppRegistry.registerComponent(appName, () => App); diff --git a/packages/helloworld/tsconfig.json b/packages/helloworld/tsconfig.json deleted file mode 100644 index ea3ea6b9595..00000000000 --- a/packages/helloworld/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../typescript-config/tsconfig.json" -} diff --git a/yarn.lock b/yarn.lock index a1f3c822bd2..3dc0fb0e1dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3853,6 +3853,14 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +chalk@4, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -3873,14 +3881,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"