@react-router/express 0.0.0-experimental-8cee090e4 → 0.0.0-experimental-63fd291ad

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ import * as express from 'express';
2
+ import { UNSAFE_MiddlewareEnabled, RouterContextProvider, AppLoadContext, ServerBuild } from 'react-router';
3
+
4
+ /// <reference lib="dom.iterable" />
5
+
6
+ type MaybePromise<T> = T | Promise<T>;
7
+ /**
8
+ * A function that returns the value to use as `context` in route `loader` and
9
+ * `action` functions.
10
+ *
11
+ * You can think of this as an escape hatch that allows you to pass
12
+ * environment/platform-specific values through to your loader/action, such as
13
+ * values that are generated by Express middleware like `req.session`.
14
+ */
15
+ type GetLoadContextFunction = (req: express.Request, res: express.Response) => UNSAFE_MiddlewareEnabled extends true ? MaybePromise<RouterContextProvider> : MaybePromise<AppLoadContext>;
16
+ type RequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>;
17
+ /**
18
+ * Returns a request handler for Express that serves the response using Remix.
19
+ */
20
+ declare function createRequestHandler({ build, getLoadContext, mode, }: {
21
+ build: ServerBuild | (() => Promise<ServerBuild>);
22
+ getLoadContext?: GetLoadContextFunction;
23
+ mode?: string;
24
+ }): RequestHandler;
25
+
26
+ export { type GetLoadContextFunction, type RequestHandler, createRequestHandler };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
+ import * as express from 'express';
2
+ import { UNSAFE_MiddlewareEnabled, RouterContextProvider, AppLoadContext, ServerBuild } from 'react-router';
1
3
 
2
- import { RouterContextProvider, ServerBuild } from "react-router";
3
- import * as express from "express";
4
+ /// <reference lib="dom.iterable" />
4
5
 
5
- //#region server.d.ts
6
6
  type MaybePromise<T> = T | Promise<T>;
7
7
  /**
8
8
  * A function that returns the value to use as `context` in route `loader` and
@@ -12,19 +12,15 @@ type MaybePromise<T> = T | Promise<T>;
12
12
  * environment/platform-specific values through to your loader/action, such as
13
13
  * values that are generated by Express middleware like `req.session`.
14
14
  */
15
- type GetLoadContextFunction = (req: express.Request, res: express.Response) => MaybePromise<RouterContextProvider>;
15
+ type GetLoadContextFunction = (req: express.Request, res: express.Response) => UNSAFE_MiddlewareEnabled extends true ? MaybePromise<RouterContextProvider> : MaybePromise<AppLoadContext>;
16
16
  type RequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>;
17
17
  /**
18
18
  * Returns a request handler for Express that serves the response using Remix.
19
19
  */
20
- declare function createRequestHandler({
21
- build,
22
- getLoadContext,
23
- mode
24
- }: {
25
- build: ServerBuild | (() => Promise<ServerBuild>);
26
- getLoadContext?: GetLoadContextFunction;
27
- mode?: string;
20
+ declare function createRequestHandler({ build, getLoadContext, mode, }: {
21
+ build: ServerBuild | (() => Promise<ServerBuild>);
22
+ getLoadContext?: GetLoadContextFunction;
23
+ mode?: string;
28
24
  }): RequestHandler;
29
- //#endregion
30
- export { type GetLoadContextFunction, type RequestHandler, createRequestHandler };
25
+
26
+ export { type GetLoadContextFunction, type RequestHandler, createRequestHandler };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/express v0.0.0-experimental-8cee090e4
2
+ * @react-router/express v0.0.0-experimental-63fd291ad
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,69 +8,119 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { createRequestHandler as createRequestHandler$1 } from "react-router";
12
- import { createReadableStreamFromReadable, writeReadableStreamToWritable } from "@react-router/node";
13
- //#region server.ts
14
- /**
15
- * Returns a request handler for Express that serves the response using Remix.
16
- */
17
- function createRequestHandler({ build, getLoadContext, mode = process.env.NODE_ENV }) {
18
- let handleRequest = createRequestHandler$1(build, mode);
19
- return async (req, res, next) => {
20
- try {
21
- await sendRemixResponse(res, await handleRequest(createRemixRequest(req, res), await getLoadContext?.(req, res)));
22
- } catch (error) {
23
- next(error);
24
- }
25
- };
11
+ "use strict";
12
+ var __defProp = Object.defineProperty;
13
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
14
+ var __getOwnPropNames = Object.getOwnPropertyNames;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ createRequestHandler: () => createRequestHandler
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // server.ts
38
+ var import_react_router = require("react-router");
39
+ var import_node = require("@react-router/node");
40
+ function createRequestHandler({
41
+ build,
42
+ getLoadContext,
43
+ mode = process.env.NODE_ENV
44
+ }) {
45
+ let handleRequest = (0, import_react_router.createRequestHandler)(build, mode);
46
+ return async (req, res, next) => {
47
+ try {
48
+ let request = createRemixRequest(req, res);
49
+ let loadContext = await getLoadContext?.(req, res);
50
+ let response = await handleRequest(request, loadContext);
51
+ await sendRemixResponse(res, response);
52
+ } catch (error) {
53
+ next(error);
54
+ }
55
+ };
26
56
  }
27
57
  function createRemixHeaders(requestHeaders) {
28
- let headers = new Headers();
29
- for (let [key, values] of Object.entries(requestHeaders)) if (values) if (Array.isArray(values)) for (let value of values) headers.append(key, value);
30
- else headers.set(key, values);
31
- return headers;
58
+ let headers = new Headers();
59
+ for (let [key, values] of Object.entries(requestHeaders)) {
60
+ if (values) {
61
+ if (Array.isArray(values)) {
62
+ for (let value of values) {
63
+ headers.append(key, value);
64
+ }
65
+ } else {
66
+ headers.set(key, values);
67
+ }
68
+ }
69
+ }
70
+ return headers;
32
71
  }
33
72
  function createRemixRequest(req, res) {
34
- let [, hostnamePortStr] = req.get("X-Forwarded-Host")?.split(":") ?? [];
35
- let [, hostPortStr] = req.get("host")?.split(":") ?? [];
36
- let hostnamePort = Number.parseInt(hostnamePortStr, 10);
37
- let hostPort = Number.parseInt(hostPortStr, 10);
38
- let port = Number.isSafeInteger(hostnamePort) ? hostnamePort : Number.isSafeInteger(hostPort) ? hostPort : "";
39
- let resolvedHost = `${req.hostname}${port ? `:${port}` : ""}`;
40
- let url = new URL(`${req.protocol}://${resolvedHost}${req.originalUrl}`);
41
- let controller = new AbortController();
42
- let init = {
43
- method: req.method,
44
- headers: createRemixHeaders(req.headers),
45
- signal: controller.signal
46
- };
47
- res.on("finish", () => controller = null);
48
- res.on("close", () => controller?.abort());
49
- if (req.method !== "GET" && req.method !== "HEAD") {
50
- init.body = createReadableStreamFromReadable(req);
51
- init.duplex = "half";
52
- }
53
- return new Request(url.href, init);
73
+ let [, hostnamePortStr] = req.get("X-Forwarded-Host")?.split(":") ?? [];
74
+ let [, hostPortStr] = req.get("host")?.split(":") ?? [];
75
+ let hostnamePort = Number.parseInt(hostnamePortStr, 10);
76
+ let hostPort = Number.parseInt(hostPortStr, 10);
77
+ let port = Number.isSafeInteger(hostnamePort) ? hostnamePort : Number.isSafeInteger(hostPort) ? hostPort : "";
78
+ let resolvedHost = `${req.hostname}${port ? `:${port}` : ""}`;
79
+ let url = new URL(`${req.protocol}://${resolvedHost}${req.originalUrl}`);
80
+ let controller = new AbortController();
81
+ let init = {
82
+ method: req.method,
83
+ headers: createRemixHeaders(req.headers),
84
+ signal: controller.signal
85
+ };
86
+ res.on("finish", () => controller = null);
87
+ res.on("close", () => controller?.abort());
88
+ if (req.method !== "GET" && req.method !== "HEAD") {
89
+ init.body = (0, import_node.createReadableStreamFromReadable)(req);
90
+ init.duplex = "half";
91
+ }
92
+ return new Request(url.href, init);
54
93
  }
55
94
  async function sendRemixResponse(res, nodeResponse) {
56
- if (isResponseClosed(res)) {
57
- await nodeResponse.body?.cancel();
58
- return;
59
- }
60
- res.statusMessage = nodeResponse.statusText;
61
- res.status(nodeResponse.status);
62
- for (let [key, value] of nodeResponse.headers.entries()) res.append(key, value);
63
- if (nodeResponse.headers.get("Content-Type")?.match(/text\/event-stream/i)) res.flushHeaders();
64
- if (nodeResponse.body) try {
65
- await writeReadableStreamToWritable(nodeResponse.body, res);
66
- } catch (error) {
67
- if (isResponseClosed(res)) return;
68
- throw error;
69
- }
70
- else res.end();
95
+ if (isResponseClosed(res)) {
96
+ await nodeResponse.body?.cancel();
97
+ return;
98
+ }
99
+ res.statusMessage = nodeResponse.statusText;
100
+ res.status(nodeResponse.status);
101
+ for (let [key, value] of nodeResponse.headers.entries()) {
102
+ res.append(key, value);
103
+ }
104
+ if (nodeResponse.headers.get("Content-Type")?.match(/text\/event-stream/i)) {
105
+ res.flushHeaders();
106
+ }
107
+ if (nodeResponse.body) {
108
+ try {
109
+ await (0, import_node.writeReadableStreamToWritable)(nodeResponse.body, res);
110
+ } catch (error) {
111
+ if (isResponseClosed(res)) {
112
+ return;
113
+ }
114
+ throw error;
115
+ }
116
+ } else {
117
+ res.end();
118
+ }
71
119
  }
72
120
  function isResponseClosed(res) {
73
- return res.destroyed || res.writableEnded;
121
+ return res.destroyed || res.writableEnded;
74
122
  }
75
- //#endregion
76
- export { createRequestHandler };
123
+ // Annotate the CommonJS export names for ESM import in node:
124
+ 0 && (module.exports = {
125
+ createRequestHandler
126
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @react-router/express v0.0.0-experimental-63fd291ad
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+
12
+ // server.ts
13
+ import { createRequestHandler as createRemixRequestHandler } from "react-router";
14
+ import {
15
+ createReadableStreamFromReadable,
16
+ writeReadableStreamToWritable
17
+ } from "@react-router/node";
18
+ function createRequestHandler({
19
+ build,
20
+ getLoadContext,
21
+ mode = process.env.NODE_ENV
22
+ }) {
23
+ let handleRequest = createRemixRequestHandler(build, mode);
24
+ return async (req, res, next) => {
25
+ try {
26
+ let request = createRemixRequest(req, res);
27
+ let loadContext = await getLoadContext?.(req, res);
28
+ let response = await handleRequest(request, loadContext);
29
+ await sendRemixResponse(res, response);
30
+ } catch (error) {
31
+ next(error);
32
+ }
33
+ };
34
+ }
35
+ function createRemixHeaders(requestHeaders) {
36
+ let headers = new Headers();
37
+ for (let [key, values] of Object.entries(requestHeaders)) {
38
+ if (values) {
39
+ if (Array.isArray(values)) {
40
+ for (let value of values) {
41
+ headers.append(key, value);
42
+ }
43
+ } else {
44
+ headers.set(key, values);
45
+ }
46
+ }
47
+ }
48
+ return headers;
49
+ }
50
+ function createRemixRequest(req, res) {
51
+ let [, hostnamePortStr] = req.get("X-Forwarded-Host")?.split(":") ?? [];
52
+ let [, hostPortStr] = req.get("host")?.split(":") ?? [];
53
+ let hostnamePort = Number.parseInt(hostnamePortStr, 10);
54
+ let hostPort = Number.parseInt(hostPortStr, 10);
55
+ let port = Number.isSafeInteger(hostnamePort) ? hostnamePort : Number.isSafeInteger(hostPort) ? hostPort : "";
56
+ let resolvedHost = `${req.hostname}${port ? `:${port}` : ""}`;
57
+ let url = new URL(`${req.protocol}://${resolvedHost}${req.originalUrl}`);
58
+ let controller = new AbortController();
59
+ let init = {
60
+ method: req.method,
61
+ headers: createRemixHeaders(req.headers),
62
+ signal: controller.signal
63
+ };
64
+ res.on("finish", () => controller = null);
65
+ res.on("close", () => controller?.abort());
66
+ if (req.method !== "GET" && req.method !== "HEAD") {
67
+ init.body = createReadableStreamFromReadable(req);
68
+ init.duplex = "half";
69
+ }
70
+ return new Request(url.href, init);
71
+ }
72
+ async function sendRemixResponse(res, nodeResponse) {
73
+ if (isResponseClosed(res)) {
74
+ await nodeResponse.body?.cancel();
75
+ return;
76
+ }
77
+ res.statusMessage = nodeResponse.statusText;
78
+ res.status(nodeResponse.status);
79
+ for (let [key, value] of nodeResponse.headers.entries()) {
80
+ res.append(key, value);
81
+ }
82
+ if (nodeResponse.headers.get("Content-Type")?.match(/text\/event-stream/i)) {
83
+ res.flushHeaders();
84
+ }
85
+ if (nodeResponse.body) {
86
+ try {
87
+ await writeReadableStreamToWritable(nodeResponse.body, res);
88
+ } catch (error) {
89
+ if (isResponseClosed(res)) {
90
+ return;
91
+ }
92
+ throw error;
93
+ }
94
+ } else {
95
+ res.end();
96
+ }
97
+ }
98
+ function isResponseClosed(res) {
99
+ return res.destroyed || res.writableEnded;
100
+ }
101
+ export {
102
+ createRequestHandler
103
+ };
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@react-router/express",
3
- "type": "module",
4
- "version": "0.0.0-experimental-8cee090e4",
3
+ "version": "0.0.0-experimental-63fd291ad",
5
4
  "description": "Express server request handler for React Router",
6
5
  "bugs": {
7
6
  "url": "https://github.com/remix-run/react-router/issues"
@@ -16,15 +15,25 @@
16
15
  "typings": "dist/index.d.ts",
17
16
  "exports": {
18
17
  ".": {
19
- "types": "./dist/index.d.ts",
20
- "module-sync": "./dist/index.js",
21
- "default": "./dist/index.js"
18
+ "node": {
19
+ "types": "./dist/index.d.ts",
20
+ "module-sync": "./dist/index.mjs",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "import": {
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
26
+ },
27
+ "default": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ }
22
31
  },
23
32
  "./package.json": "./package.json"
24
33
  },
25
34
  "wireit": {
26
35
  "build": {
27
- "command": "tsdown",
36
+ "command": "tsup",
28
37
  "files": [
29
38
  "../../pnpm-workspace.yaml",
30
39
  "*.ts",
@@ -37,23 +46,23 @@
37
46
  }
38
47
  },
39
48
  "dependencies": {
40
- "@react-router/node": "0.0.0-experimental-8cee090e4"
49
+ "@react-router/node": "0.0.0-experimental-63fd291ad"
41
50
  },
42
51
  "devDependencies": {
43
- "@types/express": "^4.17.25",
44
- "@types/node": "^22.19.19",
45
- "@types/supertest": "^7.2.0",
46
- "express": "^4.22.2",
47
- "node-mocks-http": "^1.17.2",
48
- "supertest": "^7.2.2",
49
- "tsdown": "^0.22.0",
50
- "typescript": "^6.0.3",
51
- "wireit": "0.14.12"
52
+ "@types/express": "^4.17.9",
53
+ "@types/node": "^20.0.0",
54
+ "@types/supertest": "^2.0.10",
55
+ "express": "^4.19.2",
56
+ "node-mocks-http": "^1.10.1",
57
+ "supertest": "^6.3.3",
58
+ "tsup": "^8.3.0",
59
+ "typescript": "^5.4.5",
60
+ "wireit": "0.14.9"
52
61
  },
53
62
  "peerDependencies": {
54
- "express": "^4.22.2 || ^5",
63
+ "express": "^4.17.1 || ^5",
55
64
  "typescript": "^5.1.0 || ^6.0.0",
56
- "react-router": "0.0.0-experimental-8cee090e4"
65
+ "react-router": "0.0.0-experimental-63fd291ad"
57
66
  },
58
67
  "peerDependenciesMeta": {
59
68
  "typescript": {
@@ -61,7 +70,7 @@
61
70
  }
62
71
  },
63
72
  "engines": {
64
- "node": ">=22.12.0"
73
+ "node": ">=20.0.0"
65
74
  },
66
75
  "files": [
67
76
  "dist/",