Skip to content

Commit

Permalink
Create dev-middleware package (facebook#38194)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#38194

## Context

RFC: Decoupling Flipper from React Native core: react-native-community/discussions-and-proposals#641

## Changes

Inits the `react-native/dev-middleware` package. Contains an initial implementation of `/open-debugger`, migrated from react-native-community/cli@2535dbe.

## Attribution

This implementation is greatly inspired by `expo/dev-server`: https://github.com/expo/expo/blob/1120c716f35cb28d88800e8f5d963d2b2ac94705/packages/%40expo/dev-server/src/JsInspector.ts#L18

Changelog: [Internal]

Reviewed By: motiz88

Differential Revision: D46283818

fbshipit-source-id: 7b38ad2f6d7346366a7c599d16e289e04b7bd88d
  • Loading branch information
huntie authored and facebook-github-bot committed Jul 7, 2023
1 parent 8431509 commit a991ff3
Show file tree
Hide file tree
Showing 18 changed files with 740 additions and 1 deletion.
49 changes: 49 additions & 0 deletions flow-typed/npm/chrome-launcher_v0.15.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* 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 'chrome-launcher' {
import typeof fs from 'fs';
import typeof childProcess from 'child_process';
import type {ChildProcess} from 'child_process';

declare export type Options = {
startingUrl?: string,
chromeFlags?: Array<string>,
prefs?: mixed,
port?: number,
handleSIGINT?: boolean,
chromePath?: string,
userDataDir?: string | boolean,
logLevel?: 'verbose' | 'info' | 'error' | 'warn' | 'silent',
ignoreDefaultFlags?: boolean,
connectionPollInterval?: number,
maxConnectionRetries?: number,
envVars?: {[key: string]: ?string},
};

declare export type LaunchedChrome = {
pid: number,
port: number,
process: ChildProcess,
kill: () => void,
};

declare export type ModuleOverrides = {
fs?: fs,
spawn?: childProcess['spawn'],
};

declare class Launcher {
launch(options: Options): Promise<LaunchedChrome>;
}

declare module.exports: Launcher;
}
50 changes: 50 additions & 0 deletions flow-typed/npm/connect_v3.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* 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 'connect' {
import type http from 'http';

declare export type ServerHandle = HandleFunction | http.Server;

declare type NextFunction = (err?: mixed) => void;

declare export type NextHandleFunction = (
req: IncomingMessage,
res: http.ServerResponse,
next: NextFunction,
) => void | Promise<void>;
declare export type HandleFunction = NextHandleFunction;

declare export interface IncomingMessage extends http.IncomingMessage {
originalUrl?: http.IncomingMessage['url'];
}

declare export interface Server extends events$EventEmitter {
(req: IncomingMessage, res: http.ServerResponse): void;

use(fn: HandleFunction): Server;
use(route: string, fn: HandleFunction): Server;

listen(
port: number,
hostname?: string,
backlog?: number,
callback?: Function,
): http.Server;
listen(port: number, hostname?: string, callback?: Function): http.Server;
listen(path: string, callback?: Function): http.Server;
listen(handle: any, listeningListener?: Function): http.Server;
}

declare type createServer = () => Server;

declare module.exports: createServer;
}
189 changes: 189 additions & 0 deletions flow-typed/npm/node-fetch_v2.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/**
* 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
*/

// Modified from flow-typed repo:
// https://github.com/flow-typed/flow-typed/blob/master/definitions/npm/node-fetch_v2.x.x/flow_v0.104.x-/node-fetch_v2.x.x.js

declare module 'node-fetch' {
import type http from 'http';
import type https from 'https';
import type {Readable} from 'stream';

declare type AbortSignal = {
+aborted: boolean,
+onabort: (event?: {...}) => void,

+addEventListener: (name: string, cb: () => mixed) => void,
+removeEventListener: (name: string, cb: () => mixed) => void,
+dispatchEvent: (event: {...}) => void,
...
};

declare class Request mixins Body {
constructor(
input: string | {href: string, ...} | Request,
init?: RequestInit,
): this;
context: RequestContext;
headers: Headers;
method: string;
redirect: RequestRedirect;
referrer: string;
url: string;

// node-fetch extensions
agent: http.Agent | https.Agent;
compress: boolean;
counter: number;
follow: number;
hostname: string;
port: number;
protocol: string;
size: number;
timeout: number;
}

declare type HeaderObject = {[index: string]: string | number, ...};

declare type RequestInit = {|
body?: BodyInit,
headers?: HeaderObject | null,
method?: string,
redirect?: RequestRedirect,
signal?: AbortSignal | null,

// node-fetch extensions
agent?: (URL => http.Agent | https.Agent) | http.Agent | https.Agent | null,
compress?: boolean,
follow?: number,
size?: number,
timeout?: number,
|};

declare interface FetchError extends Error {
// cannot set name due to incompatible extend error
// name: 'FetchError';
type: string;
code: ?number;
errno: ?number;
}

declare interface AbortError extends Error {
// cannot set name due to incompatible extend error
// name: 'AbortError';
type: 'aborted';
}

declare type RequestContext =
| 'audio'
| 'beacon'
| 'cspreport'
| 'download'
| 'embed'
| 'eventsource'
| 'favicon'
| 'fetch'
| 'font'
| 'form'
| 'frame'
| 'hyperlink'
| 'iframe'
| 'image'
| 'imageset'
| 'import'
| 'internal'
| 'location'
| 'manifest'
| 'object'
| 'ping'
| 'plugin'
| 'prefetch'
| 'script'
| 'serviceworker'
| 'sharedworker'
| 'subresource'
| 'style'
| 'track'
| 'video'
| 'worker'
| 'xmlhttprequest'
| 'xslt';
declare type RequestRedirect = 'error' | 'follow' | 'manual';

declare class Headers {
append(name: string, value: string): void;
delete(name: string): void;
forEach(callback: (value: string, name: string) => void): void;
get(name: string): string;
getAll(name: string): Array<string>;
has(name: string): boolean;
raw(): {[k: string]: string[], ...};
set(name: string, value: string): void;
entries(): Iterator<[string, string]>;
keys(): Iterator<string>;
values(): Iterator<string>;
@@iterator(): Iterator<[string, string]>;
}

declare class Body {
buffer(): Promise<Buffer>;
json(): Promise<any>;
json<T>(): Promise<T>;
text(): Promise<string>;
body: stream$Readable;
bodyUsed: boolean;
}

declare class Response mixins Body {
constructor(body?: BodyInit, init?: ResponseInit): this;
clone(): Response;
error(): Response;
redirect(url: string, status: number): Response;
headers: Headers;
ok: boolean;
status: number;
statusText: string;
size: number;
timeout: number;
type: ResponseType;
url: string;
}

declare type ResponseType =
| 'basic'
| 'cors'
| 'default'
| 'error'
| 'opaque'
| 'opaqueredirect';

declare interface ResponseInit {
headers?: HeaderInit;
status: number;
statusText?: string;
}

declare type HeaderInit = Headers | Array<string>;
declare type BodyInit =
| string
| null
| Buffer
| Blob
| Readable
| URLSearchParams;

declare function fetch(
url: string | URL | Request,
init?: RequestInit,
): Promise<Response>;

declare module.exports: typeof fetch;
}
14 changes: 14 additions & 0 deletions flow-typed/npm/temp-dir_2.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* 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 'temp-dir' {
declare module.exports: string;
}
13 changes: 13 additions & 0 deletions packages/dev-middleware/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"presets": [
"@babel/preset-flow",
[
"@babel/preset-env",
{
"targets": {
"node": "16"
}
}
]
]
}
5 changes: 5 additions & 0 deletions packages/dev-middleware/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Dependencies
/node_modules

# Build output
/dist
11 changes: 11 additions & 0 deletions packages/dev-middleware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# @react-native/dev-middleware

![https://img.shields.io/npm/v/@react-native/dev-middleware?color=brightgreen&label=npm%20package](https://www.npmjs.com/package/@react-native/dev-middleware)

Dev server middleware supporting core React Native development features. This package is preconfigured in all React Native projects.

## Endpoints

### `/open-debugger`

Open the JavaScript debugger for a given CDP target (direct Hermes debugging).
12 changes: 12 additions & 0 deletions packages/dev-middleware/index.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* 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
*/

export * from './src';
43 changes: 43 additions & 0 deletions packages/dev-middleware/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@react-native/dev-middleware",
"version": "0.73.0",
"description": "Dev server middleware for React Native",
"keywords": [
"react-native",
"tools"
],
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/dev-middleware#readme",
"bugs": "https://github.com/facebook/react-native/issues",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react-native.git",
"directory": "packages/dev-middleware"
},
"license": "MIT",
"exports": "./dist/index.js",
"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"
}
}
Loading

0 comments on commit a991ff3

Please sign in to comment.