mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add auto-generation of TypeScript definitions on build (#38990)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38990 This PR adds auto-generation of Typescript definitions from Flow source code for packages using the shared monorepo build setup (https://github.com/facebook/react-native/pull/38718). Today, these are the following Node.js packages: - `packages/community-cli-plugin` - `packages/dev-middleware` (⬅️ `emitTypeScriptDefs` enabled) This also improves emitted Flow definitions (`.js.flow`), by using [`flow-api-translator`](https://www.npmjs.com/package/flow-api-translator) to strip implementations. **All changes** - Include `flow-api-translator` and configure this to emit type definitions as part of `yarn build`. - Add translation from Flow source to TypeScript definitions (`.d.ts`) adjacent to each built file. - Improve emitted Flow definitions (`.js.flow`), by using `flow-api-translator` to strip implementations (previously, source files were copied). The Flow and TS defs now mirror each other. - Add `emitFlowDefs` and `emitTypeScriptDefs` options to build config to configure the above. - Integrate TypeScript compiler to perform program validation on emitted `.d.ts` files. - This is based on this guide: https://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md#a-minimal-compiler. - Throw an exception on the `rewritePackageExports` step if a package does not define an `"exports"` field. - Add minimal `flow-typed` definitions for `typescript` 😄. **Notes on [`flow-api-translator`](https://www.npmjs.com/package/flow-api-translator)** This project is experimental but is in a more mature state than when we evaluated it earlier in 2023. - It's now possible to run this tool on our new Node.js packages, since they are exclusively authored using `import`/`export` syntax (a requirement of the tool). - As a safety net, we run the TypeScript compiler against the generated program, which will fail the build. Changelog: [Internal] Reviewed By: robhogan Differential Revision: D48312463 fbshipit-source-id: 817edb35f911f52fa987946f2d8fc1a319078c9d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
e44fdfed60
commit
a978d343a6
+13
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
declare module '@tsconfig/node18/tsconfig.json' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
declare module 'typescript' {
|
||||
declare enum ModuleResolutionKind {
|
||||
Classic = 'Classic',
|
||||
NodeJs = 'NodeJs',
|
||||
Node10 = 'Node10',
|
||||
Node16 = 'Node16',
|
||||
NodeNext = 'NodeNext',
|
||||
Bundler = 'Bundler',
|
||||
}
|
||||
|
||||
declare type SourceFile = $ReadOnly<{
|
||||
fileName: string,
|
||||
text: string,
|
||||
...
|
||||
}>;
|
||||
|
||||
declare type Diagnostic = $ReadOnly<{
|
||||
file?: SourceFile,
|
||||
start?: number,
|
||||
messageText: string,
|
||||
...
|
||||
}>;
|
||||
|
||||
declare type EmitResult = $ReadOnly<{
|
||||
diagnostics: Array<Diagnostic>,
|
||||
...
|
||||
}>;
|
||||
|
||||
declare type Program = $ReadOnly<{
|
||||
emit: () => EmitResult,
|
||||
...
|
||||
}>;
|
||||
|
||||
declare type TypeScriptAPI = {
|
||||
createProgram(files: Array<string>, compilerOptions: Object): Program,
|
||||
flattenDiagnosticMessageText: (...messageText: Array<string>) => string,
|
||||
getLineAndCharacterOfPosition(
|
||||
file: SourceFile,
|
||||
start?: number,
|
||||
): $ReadOnly<{line: number, character: number}>,
|
||||
ModuleResolutionKind: typeof ModuleResolutionKind,
|
||||
...
|
||||
};
|
||||
|
||||
declare module.exports: TypeScriptAPI;
|
||||
}
|
||||
@@ -57,6 +57,7 @@
|
||||
"@pkgjs/parseargs": "^0.11.0",
|
||||
"@react-native/metro-babel-transformer": "^0.73.11",
|
||||
"@react-native/metro-config": "^0.73.0",
|
||||
"@tsconfig/node18": "1.0.1",
|
||||
"@types/react": "^18.0.18",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"async": "^3.2.2",
|
||||
@@ -81,6 +82,7 @@
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"eslint-plugin-redundant-undefined": "^0.4.0",
|
||||
"eslint-plugin-relay": "^1.8.3",
|
||||
"flow-api-translator": "0.15.0",
|
||||
"flow-bin": "^0.214.0",
|
||||
"glob": "^7.1.1",
|
||||
"hermes-eslint": "0.15.0",
|
||||
|
||||
@@ -17,4 +17,4 @@ if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
|
||||
require('../../../scripts/build/babel-register').registerForMonorepo();
|
||||
}
|
||||
|
||||
module.exports = require('./index.flow');
|
||||
export * from './index.flow';
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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';
|
||||
*/
|
||||
|
||||
const TARGET_NODE_VERSION = '18';
|
||||
|
||||
const config /*: BabelCoreOptions */ = {
|
||||
presets: [
|
||||
'@babel/preset-flow',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: TARGET_NODE_VERSION,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
'transform-define',
|
||||
{
|
||||
'process.env.BUILD_EXCLUDE_BABEL_REGISTER': true,
|
||||
},
|
||||
],
|
||||
[
|
||||
'minify-dead-code-elimination',
|
||||
{keepFnName: true, keepFnArgs: true, keepClassName: true},
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
+124
-34
@@ -12,14 +12,22 @@
|
||||
const babel = require('@babel/core');
|
||||
const {parseArgs} = require('@pkgjs/parseargs');
|
||||
const chalk = require('chalk');
|
||||
const translate = require('flow-api-translator');
|
||||
const glob = require('glob');
|
||||
const micromatch = require('micromatch');
|
||||
const fs = require('fs');
|
||||
const {promises: fs} = require('fs');
|
||||
const path = require('path');
|
||||
const prettier = require('prettier');
|
||||
const {buildConfig, getBabelConfig} = require('./config');
|
||||
const ts = require('typescript');
|
||||
const {
|
||||
buildConfig,
|
||||
getBabelConfig,
|
||||
getBuildOptions,
|
||||
getTypeScriptCompilerOptions,
|
||||
} = require('./config');
|
||||
|
||||
const PACKAGES_DIR /*: string */ = path.resolve(__dirname, '../../packages');
|
||||
const REPO_ROOT = path.resolve(__dirname, '../..');
|
||||
const PACKAGES_DIR /*: string */ = path.join(REPO_ROOT, 'packages');
|
||||
const SRC_DIR = 'src';
|
||||
const BUILD_DIR = 'dist';
|
||||
const JS_FILES_PATTERN = '**/*.js';
|
||||
@@ -32,7 +40,7 @@ const config = {
|
||||
},
|
||||
};
|
||||
|
||||
function build() {
|
||||
async function build() {
|
||||
const {
|
||||
positionals: packageNames,
|
||||
values: {help},
|
||||
@@ -53,35 +61,48 @@ function build() {
|
||||
|
||||
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);
|
||||
const packagesToBuild = packageNames.length
|
||||
? packageNames.filter(packageName => packageName in buildConfig.packages)
|
||||
: Object.keys(buildConfig.packages);
|
||||
|
||||
for (const packageName of packagesToBuild) {
|
||||
await buildPackage(packageName);
|
||||
}
|
||||
|
||||
process.exitCode = 0;
|
||||
}
|
||||
|
||||
function buildPackage(packageName /*: string */) {
|
||||
async function buildPackage(packageName /*: string */) {
|
||||
const {emitTypeScriptDefs} = getBuildOptions(packageName);
|
||||
const files = glob.sync(
|
||||
path.resolve(PACKAGES_DIR, packageName, SRC_DIR, '**/*'),
|
||||
{nodir: true},
|
||||
);
|
||||
const packageJsonPath = path.join(PACKAGES_DIR, packageName, 'package.json');
|
||||
|
||||
process.stdout.write(
|
||||
`${packageName} ${chalk.dim('.').repeat(72 - packageName.length)} `,
|
||||
);
|
||||
files.forEach(file => buildFile(path.normalize(file), true));
|
||||
rewritePackageExports(packageJsonPath);
|
||||
|
||||
// Build all files matched for package
|
||||
for (const file of files) {
|
||||
await buildFile(path.normalize(file), true);
|
||||
}
|
||||
|
||||
// Validate program for emitted .d.ts files
|
||||
if (emitTypeScriptDefs) {
|
||||
validateTypeScriptDefs(packageName);
|
||||
}
|
||||
|
||||
// Rewrite package.json "exports" field (src -> dist)
|
||||
await rewritePackageExports(packageName);
|
||||
|
||||
process.stdout.write(chalk.reset.inverse.bold.green(' DONE ') + '\n');
|
||||
}
|
||||
|
||||
function buildFile(file /*: string */, silent /*: boolean */ = false) {
|
||||
async function buildFile(file /*: string */, silent /*: boolean */ = false) {
|
||||
const packageName = getPackageName(file);
|
||||
const buildPath = getBuildPath(file);
|
||||
const {emitFlowDefs, emitTypeScriptDefs} = getBuildOptions(packageName);
|
||||
|
||||
const logResult = ({copied, desc} /*: {copied: boolean, desc?: string} */) =>
|
||||
silent ||
|
||||
@@ -97,24 +118,43 @@ function buildFile(file /*: string */, silent /*: boolean */ = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(buildPath), {recursive: true});
|
||||
await fs.mkdir(path.dirname(buildPath), {recursive: true});
|
||||
|
||||
if (!micromatch.isMatch(file, JS_FILES_PATTERN)) {
|
||||
fs.copyFileSync(file, buildPath);
|
||||
await fs.copyFile(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});
|
||||
return;
|
||||
}
|
||||
|
||||
const source = await fs.readFile(file, 'utf-8');
|
||||
const prettierConfig = {parser: 'babel'};
|
||||
|
||||
// Transform source file using Babel
|
||||
const transformed = prettier.format(
|
||||
(await babel.transformFileAsync(file, getBabelConfig(packageName))).code,
|
||||
prettierConfig,
|
||||
);
|
||||
await fs.writeFile(buildPath, transformed);
|
||||
|
||||
// Translate source Flow types for each type definition target
|
||||
if (/@flow/.test(source)) {
|
||||
await Promise.all([
|
||||
emitFlowDefs
|
||||
? fs.writeFile(
|
||||
buildPath + '.flow',
|
||||
await translate.translateFlowToFlowDef(source, prettierConfig),
|
||||
)
|
||||
: null,
|
||||
emitTypeScriptDefs
|
||||
? fs.writeFile(
|
||||
buildPath.replace(/\.js$/, '') + '.d.ts',
|
||||
await translate.translateFlowToTSDef(source, prettierConfig),
|
||||
)
|
||||
: null,
|
||||
]);
|
||||
}
|
||||
|
||||
logResult({copied: true});
|
||||
}
|
||||
|
||||
function getPackageName(file /*: string */) /*: string */ {
|
||||
@@ -130,16 +170,22 @@ function getBuildPath(file /*: string */) /*: string */ {
|
||||
);
|
||||
}
|
||||
|
||||
function rewritePackageExports(packageJsonPath /*: string */) {
|
||||
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, {encoding: 'utf8'}));
|
||||
async function rewritePackageExports(packageName /*: string */) {
|
||||
const packageJsonPath = path.join(PACKAGES_DIR, packageName, 'package.json');
|
||||
const pkg = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
||||
|
||||
if (pkg.exports == null) {
|
||||
return;
|
||||
throw new Error(
|
||||
packageName +
|
||||
' does not define an "exports" field in its package.json. As part ' +
|
||||
'of the build setup, this field must be used in order to rewrite ' +
|
||||
'paths to built files in production.',
|
||||
);
|
||||
}
|
||||
|
||||
pkg.exports = rewriteExportsField(pkg.exports);
|
||||
|
||||
fs.writeFileSync(
|
||||
await fs.writeFile(
|
||||
packageJsonPath,
|
||||
prettier.format(JSON.stringify(pkg), {parser: 'json'}),
|
||||
);
|
||||
@@ -173,6 +219,49 @@ function rewriteExportsTarget(target /*: string */) /*: string */ {
|
||||
return target.replace('./' + SRC_DIR + '/', './' + BUILD_DIR + '/');
|
||||
}
|
||||
|
||||
function validateTypeScriptDefs(packageName /*: string */) {
|
||||
const files = glob.sync(
|
||||
path.resolve(PACKAGES_DIR, packageName, BUILD_DIR, '**/*.d.ts'),
|
||||
);
|
||||
const compilerOptions = {
|
||||
...getTypeScriptCompilerOptions(packageName),
|
||||
noEmit: true,
|
||||
skipLibCheck: false,
|
||||
};
|
||||
const program = ts.createProgram(files, compilerOptions);
|
||||
const emitResult = program.emit();
|
||||
|
||||
if (emitResult.diagnostics.length) {
|
||||
for (const diagnostic of emitResult.diagnostics) {
|
||||
if (diagnostic.file != null) {
|
||||
let {line, character} = ts.getLineAndCharacterOfPosition(
|
||||
diagnostic.file,
|
||||
diagnostic.start,
|
||||
);
|
||||
let message = ts.flattenDiagnosticMessageText(
|
||||
diagnostic.messageText,
|
||||
'\n',
|
||||
);
|
||||
console.log(
|
||||
// $FlowIssue[incompatible-use] Type refined above
|
||||
`${diagnostic.file.fileName} (${line + 1},${
|
||||
character + 1
|
||||
}): ${message}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'Failing build because TypeScript errors were encountered for ' +
|
||||
'generated type definitions.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildFile,
|
||||
getBuildPath,
|
||||
@@ -182,5 +271,6 @@ module.exports = {
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
build();
|
||||
// eslint-disable-next-line no-void
|
||||
void build();
|
||||
}
|
||||
|
||||
+56
-29
@@ -11,57 +11,82 @@
|
||||
|
||||
/*::
|
||||
import type {BabelCoreOptions} from '@babel/core';
|
||||
*/
|
||||
|
||||
const {ModuleResolutionKind} = require('typescript');
|
||||
|
||||
/*::
|
||||
export type BuildOptions = $ReadOnly<{
|
||||
// The target runtime to compile for.
|
||||
target: 'node',
|
||||
|
||||
// Whether to emit Flow definition files (.js.flow) (default: true).
|
||||
emitFlowDefs?: boolean,
|
||||
|
||||
// Whether to emit TypeScript definition files (.d.ts) (default: false).
|
||||
emitTypeScriptDefs?: boolean,
|
||||
}>;
|
||||
|
||||
export type BuildConfig = $ReadOnly<{
|
||||
// The packages to include for build and their build options.
|
||||
packages: $ReadOnly<{[packageName: string]: BuildOptions}>,
|
||||
}>;
|
||||
*/
|
||||
|
||||
const TARGET_NODE_VERSION = '18';
|
||||
|
||||
/**
|
||||
* - BUILD CONFIG -
|
||||
*
|
||||
* Add packages here to configure them as part of the monorepo `yarn build`
|
||||
* setup. These must use a consistent package structure and (today) target
|
||||
* Node.js packages only.
|
||||
*/
|
||||
const buildConfig /*: BuildConfig */ = {
|
||||
// The packages to include for build and their build options
|
||||
packages: {
|
||||
'community-cli-plugin': {target: 'node'},
|
||||
'dev-middleware': {target: 'node'},
|
||||
'community-cli-plugin': {
|
||||
target: 'node',
|
||||
},
|
||||
'dev-middleware': {
|
||||
target: 'node',
|
||||
emitTypeScriptDefs: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const defaultBuildOptions = {
|
||||
emitFlowDefs: true,
|
||||
emitTypeScriptDefs: false,
|
||||
};
|
||||
|
||||
function getBuildOptions(
|
||||
packageName /*: $Keys<BuildConfig['packages']> */,
|
||||
) /*: Required<BuildOptions> */ {
|
||||
return {
|
||||
...defaultBuildOptions,
|
||||
...buildConfig.packages[packageName],
|
||||
};
|
||||
}
|
||||
|
||||
function getBabelConfig(
|
||||
packageName /*: $Keys<BuildConfig['packages']> */,
|
||||
) /*: BabelCoreOptions */ {
|
||||
const {target} = buildConfig.packages[packageName];
|
||||
const {target} = getBuildOptions(packageName);
|
||||
|
||||
switch (target) {
|
||||
case 'node':
|
||||
return require('./babel/node.config.js');
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeScriptCompilerOptions(
|
||||
packageName /*: $Keys<BuildConfig['packages']> */,
|
||||
) /*: Object */ {
|
||||
const {target} = getBuildOptions(packageName);
|
||||
|
||||
switch (target) {
|
||||
case 'node':
|
||||
return {
|
||||
presets: [
|
||||
'@babel/preset-flow',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: TARGET_NODE_VERSION,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
'transform-define',
|
||||
{
|
||||
'process.env.BUILD_EXCLUDE_BABEL_REGISTER': true,
|
||||
},
|
||||
],
|
||||
[
|
||||
'minify-dead-code-elimination',
|
||||
{keepFnName: true, keepFnArgs: true, keepClassName: true},
|
||||
],
|
||||
],
|
||||
...require('@tsconfig/node18/tsconfig.json').compilerOptions,
|
||||
moduleResolution: ModuleResolutionKind.NodeJs,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -69,4 +94,6 @@ function getBabelConfig(
|
||||
module.exports = {
|
||||
buildConfig,
|
||||
getBabelConfig,
|
||||
getBuildOptions,
|
||||
getTypeScriptCompilerOptions,
|
||||
};
|
||||
|
||||
@@ -2817,6 +2817,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
|
||||
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
|
||||
|
||||
"@tsconfig/node18@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node18/-/node18-1.0.1.tgz#ea5b375a9ead6b09ccbd70c3894ea069829ea1bb"
|
||||
integrity sha512-sNFeK6X2ATlhlvzyH4kKYQlfHXE2f2/wxtB9ClvYXevWpmwkUT7VaSrjIN9E76Qebz8qP5JOJJ9jD3QoD/Z9TA==
|
||||
|
||||
"@types/archiver@5.3.2":
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/archiver/-/archiver-5.3.2.tgz#a9f0bcb0f0b991400e7766d35f6e19d163bdadcc"
|
||||
@@ -3328,6 +3333,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.5.tgz#e63c5952532306d97c6ea432cee0981f6d2258c7"
|
||||
integrity sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==
|
||||
|
||||
"@typescript-eslint/types@5.62.0":
|
||||
version "5.62.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
|
||||
integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.59.5":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz#9b252ce55dd765e972a7a2f99233c439c5101e42"
|
||||
@@ -3363,6 +3373,14 @@
|
||||
"@typescript-eslint/types" "5.59.5"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@^5.42.0":
|
||||
version "5.62.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e"
|
||||
integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.62.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@wdio/config@7.31.1":
|
||||
version "7.31.1"
|
||||
resolved "https://registry.yarnpkg.com/@wdio/config/-/config-7.31.1.tgz#53550a164c970403628525ecdc5e0c3f96a0ff30"
|
||||
@@ -5689,7 +5707,7 @@ esprima@^4.0.0, esprima@~4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esquery@^1.4.2:
|
||||
esquery@^1.4.0, esquery@^1.4.2:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b"
|
||||
integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
|
||||
@@ -6072,6 +6090,19 @@ flatted@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561"
|
||||
integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
|
||||
|
||||
flow-api-translator@0.15.0:
|
||||
version "0.15.0"
|
||||
resolved "https://registry.yarnpkg.com/flow-api-translator/-/flow-api-translator-0.15.0.tgz#3df5af2d45630251f12782679271dc2533bcf094"
|
||||
integrity sha512-cH5Fo08kQO0vucJfcQqMAPc2De8ooVX/9AhBUiRDhe+Ob98HOSBJamaiFLgTmC9UVnSyIFRKgpG+RRopHWtjwg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.0"
|
||||
"@typescript-eslint/visitor-keys" "^5.42.0"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
hermes-eslint "0.15.0"
|
||||
hermes-estree "0.15.0"
|
||||
hermes-parser "0.15.0"
|
||||
hermes-transform "0.15.0"
|
||||
|
||||
flow-bin@^0.214.0:
|
||||
version "0.214.0"
|
||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.214.0.tgz#3ace7984a69309392e056f96cf3bf8623fa93d1c"
|
||||
@@ -6579,6 +6610,18 @@ hermes-profile-transformer@^0.0.6:
|
||||
dependencies:
|
||||
source-map "^0.7.3"
|
||||
|
||||
hermes-transform@0.15.0:
|
||||
version "0.15.0"
|
||||
resolved "https://registry.yarnpkg.com/hermes-transform/-/hermes-transform-0.15.0.tgz#5509cf6993abafbdc32528098d287f5c91eef52c"
|
||||
integrity sha512-ACGdssuE2mcu/qSwSfie1yWQs5IBRYy7yokPbdCkHd4M0jPqCiQbwrlRzQP0+XgyZPooINXWHxkhsI5Iffhppw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.0"
|
||||
esquery "^1.4.0"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
hermes-eslint "0.15.0"
|
||||
hermes-estree "0.15.0"
|
||||
hermes-parser "0.15.0"
|
||||
|
||||
homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
|
||||
|
||||
Reference in New Issue
Block a user