Skip to content

Instantly share code, notes, and snippets.

@marcus-sa
Last active May 24, 2022 10:28
Show Gist options
  • Save marcus-sa/102bbda4d18bc9614013eb2a88d64f8a to your computer and use it in GitHub Desktop.
Save marcus-sa/102bbda4d18bc9614013eb2a88d64f8a to your computer and use it in GitHub Desktop.
Deepkit HTTP Cloudflare Workers
import { http, JSONResponse, HttpBody, HttpQueries } from '@deepkit/http';
import { entity } from '@deepkit/type';
import { createTestingApp } from '@deepkit/framework';
import { beforeEach, describe } from '@jest/globals';
import { fetchRequestHandler } from '../src';
import { App } from '@deepkit/app';
@entity.name('user')
class User {
constructor(readonly name: string) {}
}
class CreateUserBody {
name!: string;
}
class GetUserQuery {
filter?: string;
}
class UserController {
@http.GET('/user-query/:name')
getUserQuery(name: string, query: HttpQueries<GetUserQuery>) {
expect(name).toEqual('Test');
expect(query).toEqual({ filter: 'Hello' });
return new JSONResponse(new User(name));
}
@http.GET('/user/:name')
getUser(name: string) {
expect(name).toEqual('Test');
return new JSONResponse(new User(name));
}
@http.POST('/user')
createUser(body: HttpBody<CreateUserBody>) {
expect(body).toEqual({ name: 'Test' });
return new JSONResponse(new User(body.name));
}
}
describe('fetchRequestHandler', () => {
let app: App<any>;
beforeEach(() => {
({ app } = createTestingApp({
controllers: [UserController],
}));
});
test('GET query', async () => {
const request = new Request(
'http://localhost/user-query/Test?filter=Hello',
);
const response = await fetchRequestHandler({
app,
request,
});
await expect(response.json()).resolves.toEqual(new User('Test'));
});
test('GET', async () => {
const request = new Request('http://localhost/user/Test');
const response = await fetchRequestHandler({
app,
request,
});
await expect(response.json()).resolves.toEqual(new User('Test'));
});
test('POST', async () => {
const request = new Request('http://localhost/user', {
method: 'POST',
body: JSON.stringify({ name: 'Test' }),
headers: {
'Content-Type': 'application/json',
},
});
const response = await fetchRequestHandler({
app,
request,
});
await expect(response.json()).resolves.toEqual(new User('Test'));
});
});
import type { App } from '@deepkit/app';
import { HttpKernel, RequestBuilder } from '@deepkit/http';
export interface FetchRequestHandlerOptions<M> {
readonly app: App<M>;
readonly request: Request;
}
export async function fetchRequestHandler<M>({
request,
app,
}: FetchRequestHandlerOptions<M>): Promise<Response> {
const url = new URL(request.url);
const builder = new RequestBuilder(url.pathname, request.method).headers(
Object.fromEntries(request.headers),
);
if (url.search !== '') {
(builder as any).queryPath = url.search.substring(1);
}
// TODO: FormData
const contentType = request.headers.get('Content-Type');
if (contentType === 'application/json') {
builder.json(await request.json());
} else if (contentType === 'text/plain') {
builder.body(await request.text());
}
const result = await app.get(HttpKernel).request(builder);
const response = new Response(result.body, {
status: result.statusCode,
statusText: result.statusMessage,
});
for (const [key, value] of Object.entries(result.getHeaders())) {
if (typeof value === 'undefined') continue;
if (typeof value === 'string') {
response.headers.set(key, value);
continue;
}
if (typeof value === 'number') {
response.headers.set(key, value.toString());
continue;
}
for (const v of value) {
response.headers.append(key, v);
}
}
return response;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment