Skip to content

Commit d20d7c8

Browse files
huntiefacebook-github-bot
authored andcommitted
Update types and improve docs for server.enhanceMiddleware
Summary: Resolves #739. Usage example / types fix is inspired by use in `react-native-community/cli-plugin-metro`: https://github.com/react-native-community/cli/blob/main/packages/cli-plugin-metro/src/commands/start/runServer.ts#L87-L97 Changelog: **[Types]** Update config and `Server` types to use broader types from `connect` package Reviewed By: motiz88 Differential Revision: D46228146 fbshipit-source-id: 63718ae44bed12735bd798a9c819b128aeb5a9d6
1 parent 06682f8 commit d20d7c8

File tree

12 files changed

+168
-25
lines changed

12 files changed

+168
-25
lines changed

docs/Configuration.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,23 @@ Whether we should enable CMD+R hotkey for refreshing the bundle.
607607
608608
#### `enhanceMiddleware`
609609
610-
Type: `(Middleware, Server) => Middleware`
610+
Type: `(Middleware, MetroServer) => Middleware`
611611
612-
The possibility to add custom middleware to the server response chain.
612+
A function that allows attaching custom [`connect`](https://www.npmjs.com/package/connect) middleware to Metro. For example:
613+
614+
:::tip
615+
You can use [`connect()`](https://www.npmjs.com/package/connect#mount-middleware) as a util to extend the base `metroMiddleware` and to mount additional middleware handlers.
616+
:::
617+
618+
```ts
619+
enhanceMiddleware: (metroMiddleware: Middleware, metroServer: MetroServer) => {
620+
return connect()
621+
.use(metroMiddleware)
622+
.use('/custom-endpoint', customEndpointMiddleware());
623+
},
624+
```
625+
626+
The `Middleware` type is an alias for [`connect.HandleFunction`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/876b9ec96ba02d0c84b1e49af5890c8f5aa2dfe3/types/connect/index.d.ts#L29).
613627
614628
#### `rewriteRequestUrl`
615629

flow-typed/Promise.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) Facebook, Inc. and its affiliates.
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
33
*
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.

flow-typed/npm/chalk_v4.x.x.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) Facebook, Inc. and its affiliates.
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
33
*
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.

flow-typed/npm/connect_v3.x.x.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
declare module 'connect' {
13+
import type http from 'http';
14+
15+
declare export type ServerHandle = HandleFunction | http.Server;
16+
17+
declare type NextFunction = (err?: mixed) => void;
18+
19+
declare export type NextHandleFunction = (
20+
req: IncomingMessage,
21+
res: http.ServerResponse,
22+
next: NextFunction,
23+
) => void | Promise<void>;
24+
declare export type HandleFunction =
25+
| NextHandleFunction;
26+
27+
declare export interface IncomingMessage extends http.IncomingMessage {
28+
originalUrl?: http.IncomingMessage['url'];
29+
}
30+
31+
declare export interface Server extends events$EventEmitter {
32+
(req: IncomingMessage, res: http.ServerResponse): void;
33+
34+
use(fn: HandleFunction): Server;
35+
use(route: string, fn: HandleFunction): Server;
36+
37+
listen(
38+
port: number,
39+
hostname?: string,
40+
backlog?: number,
41+
callback?: Function,
42+
): http.Server;
43+
listen(port: number, hostname?: string, callback?: Function): http.Server;
44+
listen(path: string, callback?: Function): http.Server;
45+
listen(handle: any, listeningListener?: Function): http.Server;
46+
}
47+
48+
declare type createServer = () => Server;
49+
50+
declare module.exports: createServer;
51+
}

packages/metro-config/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
},
1414
"license": "MIT",
1515
"dependencies": {
16+
"connect": "^3.6.5",
1617
"cosmiconfig": "^5.0.5",
1718
"jest-validate": "^29.2.1",
1819
"metro": "0.76.5",
@@ -21,6 +22,7 @@
2122
"metro-runtime": "0.76.5"
2223
},
2324
"devDependencies": {
25+
"@types/connect": "^3.4.35",
2426
"pretty-format": "^26.5.2",
2527
"strip-ansi": "^6.0.0"
2628
},

packages/metro-config/src/configTypes.flow.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010

1111
'use strict';
1212

13-
import type {IncomingMessage, ServerResponse} from 'http';
13+
import type {HandleFunction, Server} from 'connect';
1414
import type {CacheStore} from 'metro-cache';
1515
import typeof MetroCache from 'metro-cache';
1616
import type {CacheManagerFactory} from 'metro-file-map';
1717
import type {CustomResolver} from 'metro-resolver';
1818
import type {JsTransformerConfig} from 'metro-transform-worker';
1919
import type {TransformResult} from 'metro/src/DeltaBundler';
20+
import type MetroServer from 'metro/src/Server';
2021

2122
import type {
2223
DeltaResult,
@@ -25,7 +26,6 @@ import type {
2526
SerializerOptions,
2627
} from 'metro/src/DeltaBundler/types.flow.js';
2728
import type {Reporter} from 'metro/src/lib/reporting';
28-
import type Server from 'metro/src/Server';
2929
import type {IntermediateStackFrame} from '../../metro/src/Server/symbolicate';
3030

3131
export type ExtraTransformOptions = {
@@ -52,11 +52,7 @@ export type GetTransformOptions = (
5252
getDependenciesOf: (string) => Promise<Array<string>>,
5353
) => Promise<Partial<ExtraTransformOptions>>;
5454

55-
export type Middleware = (
56-
IncomingMessage,
57-
ServerResponse,
58-
((e: ?Error) => mixed),
59-
) => mixed;
55+
export type Middleware = HandleFunction;
6056

6157
type PerfAnnotations = Partial<{
6258
string: {[key: string]: string},
@@ -168,7 +164,7 @@ type MetalConfigT = {
168164
};
169165

170166
type ServerConfigT = {
171-
enhanceMiddleware: (Middleware, Server) => Middleware,
167+
enhanceMiddleware: (Middleware, MetroServer) => Middleware | Server,
172168
port: number,
173169
rewriteRequestUrl: string => string,
174170
runInspectorProxy: boolean,

packages/metro-config/src/defaults/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({
7373
},
7474

7575
server: {
76-
enhanceMiddleware: middleware => middleware,
76+
enhanceMiddleware: (middleware, _) => middleware,
7777
port: 8080,
7878
rewriteRequestUrl: url => url,
7979
runInspectorProxy: true,

packages/metro-config/types/configTypes.d.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* @oncall react_native
99
*/
1010

11-
import type {IncomingMessage, ServerResponse} from 'http';
11+
import type {HandleFunction, Server} from 'connect';
1212
import type {CacheStore, MetroCache} from 'metro-cache';
1313
import type {CustomResolver} from 'metro-resolver';
1414
import type {JsTransformerConfig} from 'metro-transform-worker';
@@ -20,7 +20,7 @@ import type {
2020
TransformResult,
2121
} from 'metro/src/DeltaBundler/types';
2222
import type {Reporter} from 'metro/src/lib/reporting';
23-
import type Server from 'metro/src/Server';
23+
import type MetroServer from 'metro/src/Server';
2424

2525
export interface ExtraTransformOptions {
2626
readonly preloadedModules: {[path: string]: true} | false;
@@ -45,11 +45,7 @@ export type GetTransformOptions = (
4545
getDependenciesOf: (filePath: string) => Promise<string[]>,
4646
) => Promise<Partial<ExtraTransformOptions>>;
4747

48-
export type Middleware = (
49-
incomingMessage: IncomingMessage,
50-
serverResponse: ServerResponse,
51-
error: (e?: Error) => unknown,
52-
) => unknown;
48+
export type Middleware = HandleFunction;
5349

5450
export type PerfAnnotations = Partial<{
5551
string: {[key: string]: string};
@@ -163,7 +159,10 @@ export interface MetalConfigT {
163159
}
164160

165161
export interface ServerConfigT {
166-
enhanceMiddleware: (middleware: Middleware, server: Server) => Middleware;
162+
enhanceMiddleware: (
163+
metroMiddleware: Middleware,
164+
metroServer: MetroServer,
165+
) => Middleware | Server;
167166
port: number;
168167
rewriteRequestUrl: (url: string) => string;
169168
runInspectorProxy: boolean;

packages/metro/src/Server.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import type {
3131
ResolverInputOptions,
3232
SplitBundleOptions,
3333
} from './shared/types.flow';
34-
import type {IncomingMessage, ServerResponse} from 'http';
34+
import type {IncomingMessage} from 'connect';
35+
import type {ServerResponse} from 'http';
3536
import type {CacheStore} from 'metro-cache';
3637
import type {ConfigT, RootPerfLogger} from 'metro-config/src/configTypes.flow';
3738
import type {
@@ -478,11 +479,11 @@ class Server {
478479
processRequest: (
479480
IncomingMessage,
480481
ServerResponse,
481-
((e: ?Error) => mixed),
482+
((e: ?Error) => void),
482483
) => void = (
483484
req: IncomingMessage,
484485
res: ServerResponse,
485-
next: (?Error) => mixed,
486+
next: (?Error) => void,
486487
) => {
487488
this._processRequest(req, res, next).catch(next);
488489
};
@@ -500,7 +501,7 @@ class Server {
500501
async _processRequest(
501502
req: IncomingMessage,
502503
res: ServerResponse,
503-
next: (?Error) => mixed,
504+
next: (?Error) => void,
504505
) {
505506
const originalUrl = req.url;
506507
req.url = this._rewriteAndNormalizeUrl(req.url);

packages/metro/src/index.flow.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ exports.runServer = async (
299299
...secureServerOptions,
300300
};
301301
}
302+
// $FlowFixMe[incompatible-call] 'http' and 'https' Flow types do not match
302303
httpServer = https.createServer(options, serverApp);
303304
} else {
304305
httpServer = http.createServer(serverApp);

0 commit comments

Comments
 (0)