Skip to content

Commit

Permalink
feat: allow returning an object
Browse files Browse the repository at this point in the history
  • Loading branch information
svedova committed Oct 4, 2023
1 parent 1b0bab1 commit 53ac086
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 6 deletions.
7 changes: 4 additions & 3 deletions src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import createStream from "./stream";

export interface ServerlessResponse {
buffer?: string; // Raw http body base64 encoded
status: number;
statusMessage: string;
headers: Record<string, string | string[]>;
body?: string; // Response body returned as string. Either this or `buffer` is used.
status?: number;
statusMessage?: string;
headers?: Record<string, string | string[]>;
}

class Response extends ServerResponse {
Expand Down
90 changes: 90 additions & 0 deletions src/utils/callback.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as http from "node:http";
import { handleApi } from "./callbacks";

jest.mock("./filesys", () => ({
walkTree: () => {
return [];
},
matchPath: () => {
return { path: "/path/to/", name: "api-file.ts" };
},
}));

describe("utils/callback.ts", () => {
describe("handleApi", () => {
const exampleRequest = {
method: "GET",
url: "/",
path: "/",
body: "",
headers: {},
};

afterEach(() => {
jest.resetModules();
});

describe("with returned object", () => {
beforeEach(() => {
jest.mock(
"/path/to/api-file.ts",
() => ({
default: () => {
return {
body: "Hello world",
status: 201,
headers: {
"X-Custom-Header": "Sample Project",
},
};
},
}),
{ virtual: true }
);
});

test("should handle returning a response body", async () => {
const response = await handleApi(exampleRequest, "/");

expect(response).toEqual({
body: "Hello world",
status: 201,
headers: {
"X-Custom-Header": "Sample Project",
},
});
});
});

describe("with response.end", () => {
beforeEach(() => {
jest.mock(
"/path/to/api-file.ts",
() => ({
default: (_: http.IncomingMessage, res: http.ServerResponse) => {
res.setHeader("X-Custom-Header", "Sample Project");
res.write("Hi world");
res.end();
},
}),
{ virtual: true }
);
});

test("should handle returning a response body", async () => {
const response = await handleApi(exampleRequest, "/");

expect(response).toEqual({
buffer: "SGkgd29ybGQ=",
status: 200,
statusMessage: "OK",
headers: {
connection: "close",
date: expect.any(String),
"x-custom-header": "Sample Project",
},
});
});
});
});
});
22 changes: 21 additions & 1 deletion src/utils/callbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export const handleError = (callback: AwsCallback) => (e: Error) => {

let cachedFiles: WalkFile[];

interface AlternativeSyntax {
body?: string;
headers?: Record<string, string>;
statusCode?: number;
status?: number; // Alias for statusCode
}

export const handleApi = (
event: RequestEvent,
apiDir: string
Expand All @@ -54,7 +61,20 @@ export const handleApi = (
if (file) {
try {
const mod = require(path.join(file.path, file.name));
return mod.default ? mod.default(req, res) : mod(req, res);
const ret = mod.default ? mod.default(req, res) : mod(req, res);

// Allow function to return a value instead of using `response.end`
Promise.resolve(ret).then((r: AlternativeSyntax) => {
if (typeof r !== "undefined" && typeof r === "object") {
resolve({
body: r.body,
headers: r.headers,
status: r.statusCode || r.status,
});
}
});

return;
} catch (e) {
console.error(e);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/app-express.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ describe("express", () => {
{},
(e: Error | null, parsed: ServerlessResponse) => {
expect(e).toBe(null);
expect(parsed.headers["x-custom-proxy-header"]).toBe("1");
expect(parsed.headers?.["x-custom-proxy-header"]).toBe("1");
expect(JSON.parse(decodeString(parsed.buffer))).toEqual({
user: "robin",
email: "robin@stormkit.io",
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/handlers/stormkit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe("handlers/stormkit.ts", () => {
expect(decodeString(parsed.buffer)).toEqual(
"Written a text\r\n\r\nWrite something elsemy-data"
);
expect(parsed.headers["transfer-encoding"]).toBeUndefined();
expect(parsed.headers?.["transfer-encoding"]).toBeUndefined();
expect(parsed).toEqual(
expect.objectContaining({
status: 200,
Expand Down

0 comments on commit 53ac086

Please sign in to comment.