@react-router/architect 7.15.1 → 8.0.0-pre.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # `@react-router/architect`
2
2
 
3
+ ## v7.16.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies:
8
+ - [`react-router@7.16.0`](https://github.com/remix-run/react-router/releases/tag/react-router@7.16.0)
9
+ - [`@react-router/node@7.16.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@7.16.0)
10
+
3
11
  ## v7.15.1
4
12
 
5
13
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,28 +1,30 @@
1
- import { SessionData, SessionIdStorageStrategy, SessionStorage, UNSAFE_MiddlewareEnabled, RouterContextProvider, AppLoadContext, ServerBuild } from 'react-router';
2
- import { ArcTable } from '@architect/functions/types/tables';
3
- import { APIGatewayProxyEventV2, APIGatewayProxyHandlerV2 } from 'aws-lambda';
4
1
 
2
+ import { RouterContextProvider, ServerBuild, SessionData, SessionIdStorageStrategy, SessionStorage } from "react-router";
3
+ import { ArcTable } from "@architect/functions/types/tables";
4
+ import { APIGatewayProxyEventV2, APIGatewayProxyHandlerV2 } from "aws-lambda";
5
+
6
+ //#region sessions/arcTableSessionStorage.d.ts
5
7
  interface ArcTableSessionStorageOptions {
6
- /**
7
- * The Cookie used to store the session id on the client, or options used
8
- * to automatically create one.
9
- */
10
- cookie?: SessionIdStorageStrategy["cookie"];
11
- /**
12
- * The table used to store sessions, or its name as it appears in your
13
- * project's app.arc file.
14
- */
15
- table: ArcTable<SessionData> | string;
16
- /**
17
- * The name of the DynamoDB attribute used to store the session ID.
18
- * This should be the table's partition key.
19
- */
20
- idx: string;
21
- /**
22
- * The name of the DynamoDB attribute used to store the expiration time.
23
- * If absent, then no TTL will be stored and session records will not expire.
24
- */
25
- ttl?: string;
8
+ /**
9
+ * The Cookie used to store the session id on the client, or options used
10
+ * to automatically create one.
11
+ */
12
+ cookie?: SessionIdStorageStrategy["cookie"];
13
+ /**
14
+ * The table used to store sessions, or its name as it appears in your
15
+ * project's app.arc file.
16
+ */
17
+ table: ArcTable<SessionData> | string;
18
+ /**
19
+ * The name of the DynamoDB attribute used to store the session ID.
20
+ * This should be the table's partition key.
21
+ */
22
+ idx: string;
23
+ /**
24
+ * The name of the DynamoDB attribute used to store the expiration time.
25
+ * If absent, then no TTL will be stored and session records will not expire.
26
+ */
27
+ ttl?: string;
26
28
  }
27
29
  /**
28
30
  * Session storage using a DynamoDB table managed by Architect.
@@ -34,8 +36,12 @@ interface ArcTableSessionStorageOptions {
34
36
  * _idx *String
35
37
  * _ttl TTL
36
38
  */
37
- declare function createArcTableSessionStorage<Data = SessionData, FlashData = Data>({ cookie, ...props }: ArcTableSessionStorageOptions): SessionStorage<Data, FlashData>;
38
-
39
+ declare function createArcTableSessionStorage<Data = SessionData, FlashData = Data>({
40
+ cookie,
41
+ ...props
42
+ }: ArcTableSessionStorageOptions): SessionStorage<Data, FlashData>;
43
+ //#endregion
44
+ //#region server.d.ts
39
45
  type MaybePromise<T> = T | Promise<T>;
40
46
  /**
41
47
  * A function that returns the value to use as `context` in route `loader` and
@@ -44,16 +50,20 @@ type MaybePromise<T> = T | Promise<T>;
44
50
  * You can think of this as an escape hatch that allows you to pass
45
51
  * environment/platform-specific values through to your loader/action.
46
52
  */
47
- type GetLoadContextFunction = (event: APIGatewayProxyEventV2) => UNSAFE_MiddlewareEnabled extends true ? MaybePromise<RouterContextProvider> : MaybePromise<AppLoadContext>;
53
+ type GetLoadContextFunction = (event: APIGatewayProxyEventV2) => MaybePromise<RouterContextProvider>;
48
54
  type RequestHandler = APIGatewayProxyHandlerV2;
49
55
  /**
50
56
  * Returns a request handler for Architect that serves the response using
51
57
  * React Router.
52
58
  */
53
- declare function createRequestHandler({ build, getLoadContext, mode, }: {
54
- build: ServerBuild;
55
- getLoadContext?: GetLoadContextFunction;
56
- mode?: string;
59
+ declare function createRequestHandler({
60
+ build,
61
+ getLoadContext,
62
+ mode
63
+ }: {
64
+ build: ServerBuild;
65
+ getLoadContext?: GetLoadContextFunction;
66
+ mode?: string;
57
67
  }): RequestHandler;
58
-
59
- export { type GetLoadContextFunction, type RequestHandler, createArcTableSessionStorage, createRequestHandler };
68
+ //#endregion
69
+ export { type GetLoadContextFunction, type RequestHandler, createArcTableSessionStorage, createRequestHandler };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/architect v7.15.1
2
+ * @react-router/architect v8.0.0-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,248 +8,174 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- "use strict";
12
- var __create = Object.create;
13
- var __defProp = Object.defineProperty;
14
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
- var __getOwnPropNames = Object.getOwnPropertyNames;
16
- var __getProtoOf = Object.getPrototypeOf;
17
- var __hasOwnProp = Object.prototype.hasOwnProperty;
18
- var __export = (target, all) => {
19
- for (var name in all)
20
- __defProp(target, name, { get: all[name], enumerable: true });
21
- };
22
- var __copyProps = (to, from, except, desc) => {
23
- if (from && typeof from === "object" || typeof from === "function") {
24
- for (let key of __getOwnPropNames(from))
25
- if (!__hasOwnProp.call(to, key) && key !== except)
26
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
27
- }
28
- return to;
29
- };
30
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
- // If the importer is in node compatibility mode or this is not an ESM
32
- // file that has been converted to a CommonJS file using a Babel-
33
- // compatible transform (i.e. "__esModule" has not been set), then set
34
- // "default" to the CommonJS "module.exports" for node compatibility.
35
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
- mod
37
- ));
38
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
39
-
40
- // index.ts
41
- var index_exports = {};
42
- __export(index_exports, {
43
- createArcTableSessionStorage: () => createArcTableSessionStorage,
44
- createRequestHandler: () => createRequestHandler
45
- });
46
- module.exports = __toCommonJS(index_exports);
47
-
48
- // sessions/arcTableSessionStorage.ts
49
- var import_react_router = require("react-router");
50
- var import_functions = __toESM(require("@architect/functions"));
51
- function createArcTableSessionStorage({
52
- cookie,
53
- ...props
54
- }) {
55
- async function getTable() {
56
- if (typeof props.table === "string") {
57
- let tables = await import_functions.default.tables();
58
- return tables[props.table];
59
- } else {
60
- return props.table;
61
- }
62
- }
63
- return (0, import_react_router.createSessionStorage)({
64
- cookie,
65
- async createData(data, expires) {
66
- let table = await getTable();
67
- while (true) {
68
- let randomBytes = crypto.getRandomValues(new Uint8Array(8));
69
- let id = [...randomBytes].map((x) => x.toString(16).padStart(2, "0")).join("");
70
- if (await table.get({ [props.idx]: id })) {
71
- continue;
72
- }
73
- let params = {
74
- [props.idx]: id,
75
- ...data
76
- };
77
- if (props.ttl) {
78
- params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
79
- }
80
- await table.put(params);
81
- return id;
82
- }
83
- },
84
- async readData(id) {
85
- let table = await getTable();
86
- let data = await table.get({ [props.idx]: id });
87
- if (data) {
88
- delete data[props.idx];
89
- if (props.ttl) delete data[props.ttl];
90
- }
91
- return data;
92
- },
93
- async updateData(id, data, expires) {
94
- let table = await getTable();
95
- let params = {
96
- [props.idx]: id,
97
- ...data
98
- };
99
- if (props.ttl) {
100
- params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
101
- }
102
- await table.put(params);
103
- },
104
- async deleteData(id) {
105
- let table = await getTable();
106
- await table.delete({ [props.idx]: id });
107
- }
108
- });
11
+ import { createRequestHandler as createRequestHandler$1, createSessionStorage } from "react-router";
12
+ import arc from "@architect/functions";
13
+ import { readableStreamToString } from "@react-router/node";
14
+ //#region sessions/arcTableSessionStorage.ts
15
+ /**
16
+ * Session storage using a DynamoDB table managed by Architect.
17
+ *
18
+ * Add the following lines to your project's `app.arc` file:
19
+ *
20
+ * @tables
21
+ * arc-sessions
22
+ * _idx *String
23
+ * _ttl TTL
24
+ */
25
+ function createArcTableSessionStorage({ cookie, ...props }) {
26
+ async function getTable() {
27
+ if (typeof props.table === "string") return (await arc.tables())[props.table];
28
+ else return props.table;
29
+ }
30
+ return createSessionStorage({
31
+ cookie,
32
+ async createData(data, expires) {
33
+ let table = await getTable();
34
+ while (true) {
35
+ let id = [...crypto.getRandomValues(new Uint8Array(8))].map((x) => x.toString(16).padStart(2, "0")).join("");
36
+ if (await table.get({ [props.idx]: id })) continue;
37
+ let params = {
38
+ [props.idx]: id,
39
+ ...data
40
+ };
41
+ if (props.ttl) params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
42
+ await table.put(params);
43
+ return id;
44
+ }
45
+ },
46
+ async readData(id) {
47
+ let data = await (await getTable()).get({ [props.idx]: id });
48
+ if (data) {
49
+ delete data[props.idx];
50
+ if (props.ttl) delete data[props.ttl];
51
+ }
52
+ return data;
53
+ },
54
+ async updateData(id, data, expires) {
55
+ let table = await getTable();
56
+ let params = {
57
+ [props.idx]: id,
58
+ ...data
59
+ };
60
+ if (props.ttl) params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
61
+ await table.put(params);
62
+ },
63
+ async deleteData(id) {
64
+ await (await getTable()).delete({ [props.idx]: id });
65
+ }
66
+ });
109
67
  }
110
-
111
- // server.ts
112
- var import_react_router2 = require("react-router");
113
- var import_node = require("@react-router/node");
114
-
115
- // binaryTypes.ts
116
- var binaryTypes = [
117
- "application/octet-stream",
118
- // Docs
119
- "application/epub+zip",
120
- "application/msword",
121
- "application/pdf",
122
- "application/rtf",
123
- "application/vnd.amazon.ebook",
124
- "application/vnd.ms-excel",
125
- "application/vnd.ms-powerpoint",
126
- "application/vnd.openxmlformats-officedocument.presentationml.presentation",
127
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
128
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
129
- // Fonts
130
- "font/otf",
131
- "font/woff",
132
- "font/woff2",
133
- // Images
134
- "image/avif",
135
- "image/bmp",
136
- "image/gif",
137
- "image/jpeg",
138
- "image/png",
139
- "image/tiff",
140
- "image/vnd.microsoft.icon",
141
- "image/webp",
142
- // Audio
143
- "audio/3gpp",
144
- "audio/aac",
145
- "audio/basic",
146
- "audio/mpeg",
147
- "audio/ogg",
148
- "audio/wav",
149
- "audio/webm",
150
- "audio/x-aiff",
151
- "audio/x-midi",
152
- "audio/x-wav",
153
- // Video
154
- "video/3gpp",
155
- "video/mp2t",
156
- "video/mpeg",
157
- "video/ogg",
158
- "video/quicktime",
159
- "video/webm",
160
- "video/x-msvideo",
161
- // Archives
162
- "application/java-archive",
163
- "application/vnd.apple.installer+xml",
164
- "application/x-7z-compressed",
165
- "application/x-apple-diskimage",
166
- "application/x-bzip",
167
- "application/x-bzip2",
168
- "application/x-gzip",
169
- "application/x-java-archive",
170
- "application/x-rar-compressed",
171
- "application/x-tar",
172
- "application/x-zip",
173
- "application/zip"
68
+ //#endregion
69
+ //#region binaryTypes.ts
70
+ /**
71
+ * Common binary MIME types
72
+ * @see https://github.com/architect/functions/blob/45254fc1936a1794c185aac07e9889b241a2e5c6/src/http/helpers/binary-types.js
73
+ */
74
+ const binaryTypes = [
75
+ "application/octet-stream",
76
+ "application/epub+zip",
77
+ "application/msword",
78
+ "application/pdf",
79
+ "application/rtf",
80
+ "application/vnd.amazon.ebook",
81
+ "application/vnd.ms-excel",
82
+ "application/vnd.ms-powerpoint",
83
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
84
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
85
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
86
+ "font/otf",
87
+ "font/woff",
88
+ "font/woff2",
89
+ "image/avif",
90
+ "image/bmp",
91
+ "image/gif",
92
+ "image/jpeg",
93
+ "image/png",
94
+ "image/tiff",
95
+ "image/vnd.microsoft.icon",
96
+ "image/webp",
97
+ "audio/3gpp",
98
+ "audio/aac",
99
+ "audio/basic",
100
+ "audio/mpeg",
101
+ "audio/ogg",
102
+ "audio/wav",
103
+ "audio/webm",
104
+ "audio/x-aiff",
105
+ "audio/x-midi",
106
+ "audio/x-wav",
107
+ "video/3gpp",
108
+ "video/mp2t",
109
+ "video/mpeg",
110
+ "video/ogg",
111
+ "video/quicktime",
112
+ "video/webm",
113
+ "video/x-msvideo",
114
+ "application/java-archive",
115
+ "application/vnd.apple.installer+xml",
116
+ "application/x-7z-compressed",
117
+ "application/x-apple-diskimage",
118
+ "application/x-bzip",
119
+ "application/x-bzip2",
120
+ "application/x-gzip",
121
+ "application/x-java-archive",
122
+ "application/x-rar-compressed",
123
+ "application/x-tar",
124
+ "application/x-zip",
125
+ "application/zip"
174
126
  ];
175
127
  function isBinaryType(contentType) {
176
- if (!contentType) return false;
177
- let [test] = contentType.split(";");
178
- return binaryTypes.includes(test);
128
+ if (!contentType) return false;
129
+ let [test] = contentType.split(";");
130
+ return binaryTypes.includes(test);
179
131
  }
180
-
181
- // server.ts
182
- function createRequestHandler({
183
- build,
184
- getLoadContext,
185
- mode = process.env.NODE_ENV
186
- }) {
187
- let handleRequest = (0, import_react_router2.createRequestHandler)(build, mode);
188
- return async (event) => {
189
- let request = createReactRouterRequest(event);
190
- let loadContext = await getLoadContext?.(event);
191
- let response = await handleRequest(request, loadContext);
192
- return sendReactRouterResponse(response);
193
- };
132
+ //#endregion
133
+ //#region server.ts
134
+ /**
135
+ * Returns a request handler for Architect that serves the response using
136
+ * React Router.
137
+ */
138
+ function createRequestHandler({ build, getLoadContext, mode = process.env.NODE_ENV }) {
139
+ let handleRequest = createRequestHandler$1(build, mode);
140
+ return async (event) => {
141
+ return sendReactRouterResponse(await handleRequest(createReactRouterRequest(event), await getLoadContext?.(event)));
142
+ };
194
143
  }
195
144
  function createReactRouterRequest(event) {
196
- let host = event.headers["x-forwarded-host"] || event.headers.host;
197
- let search = event.rawQueryString.length ? `?${event.rawQueryString}` : "";
198
- let scheme = process.env.ARC_SANDBOX ? "http" : "https";
199
- let url = new URL(`${scheme}://${host}${event.rawPath}${search}`);
200
- let isFormData = event.headers["content-type"]?.includes(
201
- "multipart/form-data"
202
- );
203
- let controller = new AbortController();
204
- return new Request(url.href, {
205
- method: event.requestContext.http.method,
206
- headers: createReactRouterHeaders(event.headers, event.cookies),
207
- signal: controller.signal,
208
- body: event.body && event.isBase64Encoded ? isFormData ? Buffer.from(event.body, "base64") : Buffer.from(event.body, "base64").toString() : event.body
209
- });
145
+ let host = event.headers["x-forwarded-host"] || event.headers.host;
146
+ let search = event.rawQueryString.length ? `?${event.rawQueryString}` : "";
147
+ let scheme = process.env.ARC_SANDBOX ? "http" : "https";
148
+ let url = new URL(`${scheme}://${host}${event.rawPath}${search}`);
149
+ let isFormData = event.headers["content-type"]?.includes("multipart/form-data");
150
+ let controller = new AbortController();
151
+ return new Request(url.href, {
152
+ method: event.requestContext.http.method,
153
+ headers: createReactRouterHeaders(event.headers, event.cookies),
154
+ signal: controller.signal,
155
+ body: event.body && event.isBase64Encoded ? isFormData ? Buffer.from(event.body, "base64") : Buffer.from(event.body, "base64").toString() : event.body
156
+ });
210
157
  }
211
158
  function createReactRouterHeaders(requestHeaders, requestCookies) {
212
- let headers = new Headers();
213
- for (let [header, value] of Object.entries(requestHeaders)) {
214
- if (value) {
215
- headers.append(header, value);
216
- }
217
- }
218
- if (requestCookies) {
219
- headers.append("Cookie", requestCookies.join("; "));
220
- }
221
- return headers;
159
+ let headers = new Headers();
160
+ for (let [header, value] of Object.entries(requestHeaders)) if (value) headers.append(header, value);
161
+ if (requestCookies) headers.append("Cookie", requestCookies.join("; "));
162
+ return headers;
222
163
  }
223
164
  async function sendReactRouterResponse(nodeResponse) {
224
- let cookies = [];
225
- for (let [key, value] of nodeResponse.headers.entries()) {
226
- if (key.toLowerCase() === "set-cookie") {
227
- cookies.push(value);
228
- }
229
- }
230
- if (cookies.length) {
231
- nodeResponse.headers.delete("Set-Cookie");
232
- }
233
- let contentType = nodeResponse.headers.get("Content-Type");
234
- let isBase64Encoded = isBinaryType(contentType);
235
- let body;
236
- if (nodeResponse.body) {
237
- if (isBase64Encoded) {
238
- body = await (0, import_node.readableStreamToString)(nodeResponse.body, "base64");
239
- } else {
240
- body = await nodeResponse.text();
241
- }
242
- }
243
- return {
244
- statusCode: nodeResponse.status,
245
- headers: Object.fromEntries(nodeResponse.headers.entries()),
246
- cookies,
247
- body,
248
- isBase64Encoded
249
- };
165
+ let cookies = [];
166
+ for (let [key, value] of nodeResponse.headers.entries()) if (key.toLowerCase() === "set-cookie") cookies.push(value);
167
+ if (cookies.length) nodeResponse.headers.delete("Set-Cookie");
168
+ let isBase64Encoded = isBinaryType(nodeResponse.headers.get("Content-Type"));
169
+ let body;
170
+ if (nodeResponse.body) if (isBase64Encoded) body = await readableStreamToString(nodeResponse.body, "base64");
171
+ else body = await nodeResponse.text();
172
+ return {
173
+ statusCode: nodeResponse.status,
174
+ headers: Object.fromEntries(nodeResponse.headers.entries()),
175
+ cookies,
176
+ body,
177
+ isBase64Encoded
178
+ };
250
179
  }
251
- // Annotate the CommonJS export names for ESM import in node:
252
- 0 && (module.exports = {
253
- createArcTableSessionStorage,
254
- createRequestHandler
255
- });
180
+ //#endregion
181
+ export { createArcTableSessionStorage, createRequestHandler };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@react-router/architect",
3
- "version": "7.15.1",
3
+ "type": "module",
4
+ "version": "8.0.0-pre.0",
4
5
  "description": "Architect server request handler for React Router",
5
6
  "bugs": {
6
7
  "url": "https://github.com/remix-run/react-router/issues"
@@ -15,25 +16,15 @@
15
16
  "typings": "dist/index.d.ts",
16
17
  "exports": {
17
18
  ".": {
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
- }
19
+ "types": "./dist/index.d.ts",
20
+ "module-sync": "./dist/index.js",
21
+ "default": "./dist/index.js"
31
22
  },
32
23
  "./package.json": "./package.json"
33
24
  },
34
25
  "wireit": {
35
26
  "build": {
36
- "command": "tsup",
27
+ "command": "tsdown",
37
28
  "files": [
38
29
  "../../pnpm-workspace.yaml",
39
30
  "sessions/**",
@@ -47,25 +38,26 @@
47
38
  }
48
39
  },
49
40
  "dependencies": {
50
- "@architect/functions": "^7.0.0",
51
- "@types/aws-lambda": "^8.10.82"
41
+ "@architect/functions": "^8.1.9",
42
+ "@types/aws-lambda": "^8.10.161"
52
43
  },
53
44
  "devDependencies": {
54
- "@types/lambda-tester": "^3.6.1",
55
- "@types/node": "^20.0.0",
45
+ "@types/jest": "^30.0.0",
46
+ "@types/lambda-tester": "^4.0.3",
47
+ "@types/node": "^22.19.19",
56
48
  "lambda-tester": "^4.0.1",
57
- "react": "^19.2.3",
58
- "react-dom": "^19.2.3",
59
- "tsup": "^8.3.0",
60
- "typescript": "^5.4.5",
61
- "wireit": "0.14.9",
62
- "@react-router/node": "7.15.1",
63
- "react-router": "7.15.1"
49
+ "react": "^19.2.6",
50
+ "react-dom": "^19.2.6",
51
+ "tsdown": "^0.22.0",
52
+ "typescript": "^6.0.3",
53
+ "wireit": "0.14.12",
54
+ "@react-router/node": "8.0.0-pre.0",
55
+ "react-router": "8.0.0-pre.0"
64
56
  },
65
57
  "peerDependencies": {
66
58
  "typescript": "^5.1.0 || ^6.0.0",
67
- "@react-router/node": "^7.15.1",
68
- "react-router": "^7.15.1"
59
+ "@react-router/node": "^8.0.0-pre.0",
60
+ "react-router": "^8.0.0-pre.0"
69
61
  },
70
62
  "peerDependenciesMeta": {
71
63
  "typescript": {
@@ -73,7 +65,7 @@
73
65
  }
74
66
  },
75
67
  "engines": {
76
- "node": ">=20.0.0"
68
+ "node": ">=22.12.0"
77
69
  },
78
70
  "files": [
79
71
  "dist/",
package/dist/index.d.mts DELETED
@@ -1,59 +0,0 @@
1
- import { SessionData, SessionIdStorageStrategy, SessionStorage, UNSAFE_MiddlewareEnabled, RouterContextProvider, AppLoadContext, ServerBuild } from 'react-router';
2
- import { ArcTable } from '@architect/functions/types/tables';
3
- import { APIGatewayProxyEventV2, APIGatewayProxyHandlerV2 } from 'aws-lambda';
4
-
5
- interface ArcTableSessionStorageOptions {
6
- /**
7
- * The Cookie used to store the session id on the client, or options used
8
- * to automatically create one.
9
- */
10
- cookie?: SessionIdStorageStrategy["cookie"];
11
- /**
12
- * The table used to store sessions, or its name as it appears in your
13
- * project's app.arc file.
14
- */
15
- table: ArcTable<SessionData> | string;
16
- /**
17
- * The name of the DynamoDB attribute used to store the session ID.
18
- * This should be the table's partition key.
19
- */
20
- idx: string;
21
- /**
22
- * The name of the DynamoDB attribute used to store the expiration time.
23
- * If absent, then no TTL will be stored and session records will not expire.
24
- */
25
- ttl?: string;
26
- }
27
- /**
28
- * Session storage using a DynamoDB table managed by Architect.
29
- *
30
- * Add the following lines to your project's `app.arc` file:
31
- *
32
- * @tables
33
- * arc-sessions
34
- * _idx *String
35
- * _ttl TTL
36
- */
37
- declare function createArcTableSessionStorage<Data = SessionData, FlashData = Data>({ cookie, ...props }: ArcTableSessionStorageOptions): SessionStorage<Data, FlashData>;
38
-
39
- type MaybePromise<T> = T | Promise<T>;
40
- /**
41
- * A function that returns the value to use as `context` in route `loader` and
42
- * `action` functions.
43
- *
44
- * You can think of this as an escape hatch that allows you to pass
45
- * environment/platform-specific values through to your loader/action.
46
- */
47
- type GetLoadContextFunction = (event: APIGatewayProxyEventV2) => UNSAFE_MiddlewareEnabled extends true ? MaybePromise<RouterContextProvider> : MaybePromise<AppLoadContext>;
48
- type RequestHandler = APIGatewayProxyHandlerV2;
49
- /**
50
- * Returns a request handler for Architect that serves the response using
51
- * React Router.
52
- */
53
- declare function createRequestHandler({ build, getLoadContext, mode, }: {
54
- build: ServerBuild;
55
- getLoadContext?: GetLoadContextFunction;
56
- mode?: string;
57
- }): RequestHandler;
58
-
59
- export { type GetLoadContextFunction, type RequestHandler, createArcTableSessionStorage, createRequestHandler };
package/dist/index.mjs DELETED
@@ -1,218 +0,0 @@
1
- /**
2
- * @react-router/architect v7.15.1
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
- // sessions/arcTableSessionStorage.ts
13
- import { createSessionStorage } from "react-router";
14
- import arc from "@architect/functions";
15
- function createArcTableSessionStorage({
16
- cookie,
17
- ...props
18
- }) {
19
- async function getTable() {
20
- if (typeof props.table === "string") {
21
- let tables = await arc.tables();
22
- return tables[props.table];
23
- } else {
24
- return props.table;
25
- }
26
- }
27
- return createSessionStorage({
28
- cookie,
29
- async createData(data, expires) {
30
- let table = await getTable();
31
- while (true) {
32
- let randomBytes = crypto.getRandomValues(new Uint8Array(8));
33
- let id = [...randomBytes].map((x) => x.toString(16).padStart(2, "0")).join("");
34
- if (await table.get({ [props.idx]: id })) {
35
- continue;
36
- }
37
- let params = {
38
- [props.idx]: id,
39
- ...data
40
- };
41
- if (props.ttl) {
42
- params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
43
- }
44
- await table.put(params);
45
- return id;
46
- }
47
- },
48
- async readData(id) {
49
- let table = await getTable();
50
- let data = await table.get({ [props.idx]: id });
51
- if (data) {
52
- delete data[props.idx];
53
- if (props.ttl) delete data[props.ttl];
54
- }
55
- return data;
56
- },
57
- async updateData(id, data, expires) {
58
- let table = await getTable();
59
- let params = {
60
- [props.idx]: id,
61
- ...data
62
- };
63
- if (props.ttl) {
64
- params[props.ttl] = expires ? Math.round(expires.getTime() / 1e3) : void 0;
65
- }
66
- await table.put(params);
67
- },
68
- async deleteData(id) {
69
- let table = await getTable();
70
- await table.delete({ [props.idx]: id });
71
- }
72
- });
73
- }
74
-
75
- // server.ts
76
- import { createRequestHandler as createReactRouterRequestHandler } from "react-router";
77
- import { readableStreamToString } from "@react-router/node";
78
-
79
- // binaryTypes.ts
80
- var binaryTypes = [
81
- "application/octet-stream",
82
- // Docs
83
- "application/epub+zip",
84
- "application/msword",
85
- "application/pdf",
86
- "application/rtf",
87
- "application/vnd.amazon.ebook",
88
- "application/vnd.ms-excel",
89
- "application/vnd.ms-powerpoint",
90
- "application/vnd.openxmlformats-officedocument.presentationml.presentation",
91
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
92
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
93
- // Fonts
94
- "font/otf",
95
- "font/woff",
96
- "font/woff2",
97
- // Images
98
- "image/avif",
99
- "image/bmp",
100
- "image/gif",
101
- "image/jpeg",
102
- "image/png",
103
- "image/tiff",
104
- "image/vnd.microsoft.icon",
105
- "image/webp",
106
- // Audio
107
- "audio/3gpp",
108
- "audio/aac",
109
- "audio/basic",
110
- "audio/mpeg",
111
- "audio/ogg",
112
- "audio/wav",
113
- "audio/webm",
114
- "audio/x-aiff",
115
- "audio/x-midi",
116
- "audio/x-wav",
117
- // Video
118
- "video/3gpp",
119
- "video/mp2t",
120
- "video/mpeg",
121
- "video/ogg",
122
- "video/quicktime",
123
- "video/webm",
124
- "video/x-msvideo",
125
- // Archives
126
- "application/java-archive",
127
- "application/vnd.apple.installer+xml",
128
- "application/x-7z-compressed",
129
- "application/x-apple-diskimage",
130
- "application/x-bzip",
131
- "application/x-bzip2",
132
- "application/x-gzip",
133
- "application/x-java-archive",
134
- "application/x-rar-compressed",
135
- "application/x-tar",
136
- "application/x-zip",
137
- "application/zip"
138
- ];
139
- function isBinaryType(contentType) {
140
- if (!contentType) return false;
141
- let [test] = contentType.split(";");
142
- return binaryTypes.includes(test);
143
- }
144
-
145
- // server.ts
146
- function createRequestHandler({
147
- build,
148
- getLoadContext,
149
- mode = process.env.NODE_ENV
150
- }) {
151
- let handleRequest = createReactRouterRequestHandler(build, mode);
152
- return async (event) => {
153
- let request = createReactRouterRequest(event);
154
- let loadContext = await getLoadContext?.(event);
155
- let response = await handleRequest(request, loadContext);
156
- return sendReactRouterResponse(response);
157
- };
158
- }
159
- function createReactRouterRequest(event) {
160
- let host = event.headers["x-forwarded-host"] || event.headers.host;
161
- let search = event.rawQueryString.length ? `?${event.rawQueryString}` : "";
162
- let scheme = process.env.ARC_SANDBOX ? "http" : "https";
163
- let url = new URL(`${scheme}://${host}${event.rawPath}${search}`);
164
- let isFormData = event.headers["content-type"]?.includes(
165
- "multipart/form-data"
166
- );
167
- let controller = new AbortController();
168
- return new Request(url.href, {
169
- method: event.requestContext.http.method,
170
- headers: createReactRouterHeaders(event.headers, event.cookies),
171
- signal: controller.signal,
172
- body: event.body && event.isBase64Encoded ? isFormData ? Buffer.from(event.body, "base64") : Buffer.from(event.body, "base64").toString() : event.body
173
- });
174
- }
175
- function createReactRouterHeaders(requestHeaders, requestCookies) {
176
- let headers = new Headers();
177
- for (let [header, value] of Object.entries(requestHeaders)) {
178
- if (value) {
179
- headers.append(header, value);
180
- }
181
- }
182
- if (requestCookies) {
183
- headers.append("Cookie", requestCookies.join("; "));
184
- }
185
- return headers;
186
- }
187
- async function sendReactRouterResponse(nodeResponse) {
188
- let cookies = [];
189
- for (let [key, value] of nodeResponse.headers.entries()) {
190
- if (key.toLowerCase() === "set-cookie") {
191
- cookies.push(value);
192
- }
193
- }
194
- if (cookies.length) {
195
- nodeResponse.headers.delete("Set-Cookie");
196
- }
197
- let contentType = nodeResponse.headers.get("Content-Type");
198
- let isBase64Encoded = isBinaryType(contentType);
199
- let body;
200
- if (nodeResponse.body) {
201
- if (isBase64Encoded) {
202
- body = await readableStreamToString(nodeResponse.body, "base64");
203
- } else {
204
- body = await nodeResponse.text();
205
- }
206
- }
207
- return {
208
- statusCode: nodeResponse.status,
209
- headers: Object.fromEntries(nodeResponse.headers.entries()),
210
- cookies,
211
- body,
212
- isBase64Encoded
213
- };
214
- }
215
- export {
216
- createArcTableSessionStorage,
217
- createRequestHandler
218
- };