Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"typecheck": "tsc"
},
"dependencies": {
"@google-cloud/functions-framework": "^3.2.0",
"@google-cloud/functions-framework": "^3.4.1",
"@remix-run/node": "*",
"@remix-run/react": "*",
"@remix-run/serve": "*",
"firebase-admin": "^11.7.0",
"firebase-functions": "^4.3.1",
"firebase-admin": "^12.2.0",
"firebase-functions": "^5.0.0",
"isbot": "^3.6.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@
"workspaces": [
"example",
"remix-google-cloud-functions"
]
],
"dependencies": {
"node-gyp": "^10.2.0"
}
}
15 changes: 8 additions & 7 deletions remix-google-cloud-functions/__tests__/server-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import supertest from "supertest";
import { createRequest, createResponse } from "node-mocks-http";
import {
createReadableStreamFromReadable,
createRequestHandler as createRemixRequestHandler,
Response as NodeResponse,
ServerBuild,
} from "@remix-run/node";
import { Readable } from "stream";
Expand Down Expand Up @@ -54,7 +54,7 @@ describe("google-cloud-functions createRequestHandler", () => {

it("handles requests", async () => {
mockedCreateRequestHandler.mockImplementation(() => async (req) => {
return new NodeResponse(`URL: ${new URL(req.url).pathname}`);
return new Response(`URL: ${new URL(req.url).pathname}`);
});

let request = supertest(createApp());
Expand All @@ -67,7 +67,7 @@ describe("google-cloud-functions createRequestHandler", () => {

it("handles null body", async () => {
mockedCreateRequestHandler.mockImplementation(() => async () => {
return new NodeResponse(null, { status: 200 });
return new Response(null, { status: 200 });
});

let request = supertest(createApp());
Expand All @@ -79,8 +79,9 @@ describe("google-cloud-functions createRequestHandler", () => {
// https://github.com/node-fetch/node-fetch/blob/4ae35388b078bddda238277142bf091898ce6fda/test/response.js#L142-L148
it("handles body as stream", async () => {
mockedCreateRequestHandler.mockImplementation(() => async () => {
let stream = Readable.from("hello world");
return new NodeResponse(stream, {
let readable = Readable.from("hello world");
let stream = createReadableStreamFromReadable(readable);
return new Response(stream, {
status: 200,
});
});
Expand All @@ -95,7 +96,7 @@ describe("google-cloud-functions createRequestHandler", () => {

it("handles status codes", async () => {
mockedCreateRequestHandler.mockImplementation(() => async () => {
return new NodeResponse(null, { status: 204 });
return new Response(null, { status: 204 });
});

let request = supertest(createApp());
Expand All @@ -119,7 +120,7 @@ describe("google-cloud-functions createRequestHandler", () => {
"Set-Cookie",
"third=three; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Path=/; HttpOnly; Secure; SameSite=Lax"
);
return new NodeResponse(null, { headers });
return new Response(null, { headers });
});

let request = supertest(createApp());
Expand Down
8 changes: 4 additions & 4 deletions remix-google-cloud-functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"prepare": "cp ../README.md ./README.md"
},
"peerDependencies": {
"@google-cloud/functions-framework": "^3.2.0",
"@remix-run/node": "^1.15.0"
"@google-cloud/functions-framework": "^3.4.1",
"@remix-run/node": "^2.10.2"
},
"devDependencies": {
"@babel/core": "^7.21.5",
Expand All @@ -28,8 +28,8 @@
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.21.5",
"@google-cloud/functions-framework": "^3.2.0",
"@remix-run/node": "^1.15.0",
"@google-cloud/functions-framework": "^3.4.1",
"@remix-run/node": "^2.10.2",
"@types/jest": "^29.5.1",
"@types/supertest": "^2.0.10",
"babel-jest": "^29.5.0",
Expand Down
40 changes: 14 additions & 26 deletions remix-google-cloud-functions/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@ import type {
Request as GcfRequest,
Response as GcfResponse,
} from "@google-cloud/functions-framework";
import type {
AppLoadContext,
ServerBuild,
RequestInit as NodeRequestInit,
} from "@remix-run/node";
import type { AppLoadContext, ServerBuild } from "@remix-run/node";
import {
AbortController,
createRequestHandler as createRemixRequestHandler,
Headers as NodeHeaders,
Request as NodeRequest,
Response as NodeResponse,
createReadableStreamFromReadable,
writeReadableStreamToWritable,
} from "@remix-run/node";

Expand Down Expand Up @@ -54,26 +47,23 @@ export function createRequestHandler({
? getLoadContext(req, res)
: undefined;

let response = (await handleRequest(
request,
loadContext
)) as NodeResponse;
let response = await handleRequest(request, loadContext);

await sendRemixResponse(res, response);
} catch (error) {
console.error(error);
await sendRemixResponse(
res,
new NodeResponse("Internal Error", { status: 500 })
new Response("Internal Error", { status: 500 })
);
}
};
}

export function createRemixHeaders(
requestHeaders: GcfRequest["headers"]
): NodeHeaders {
let headers = new NodeHeaders();
): Headers {
let headers = new Headers();

for (let [key, values] of Object.entries(requestHeaders)) {
if (values) {
Expand All @@ -90,38 +80,36 @@ export function createRemixHeaders(
return headers;
}

export function createRemixRequest(
req: GcfRequest,
res: GcfResponse
): NodeRequest {
export function createRemixRequest(req: GcfRequest, res: GcfResponse): Request {
let origin = `${req.protocol}://${req.get("host")}`;
let url = new URL(req.url, origin);

let controller = new AbortController();

res.on("close", () => controller.abort());

let init: NodeRequestInit = {
let init: RequestInit = {
method: req.method,
headers: createRemixHeaders(req.headers),
signal: controller.signal as NodeRequestInit["signal"],
signal: controller.signal as RequestInit["signal"],
};

if (req.method !== "GET" && req.method !== "HEAD") {
init.body = req.rawBody;
init.body = createReadableStreamFromReadable(req);
(init as { duplex: "half" }).duplex = "half";
}

return new NodeRequest(url.href, init);
return new Request(url.href, init);
}

async function sendRemixResponse(
res: GcfResponse,
nodeResponse: NodeResponse
nodeResponse: Response
): Promise<void> {
res.statusMessage = nodeResponse.statusText;
res.status(nodeResponse.status);

for (let [key, values] of Object.entries(nodeResponse.headers.raw())) {
for (let [key, values] of nodeResponse.headers.entries()) {
for (let value of values) {
res.append(key, value);
}
Expand Down
4 changes: 2 additions & 2 deletions remix-google-cloud-functions/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"exclude": ["__tests__"],
"compilerOptions": {
"lib": ["ES2019", "DOM.Iterable"],
"target": "ES2019",
"lib": ["ES2022", "DOM.Iterable"],
"target": "ES2022",
"module": "CommonJS",
"skipLibCheck": true,

Expand Down
Loading