@whatwg-node/server
Advanced tools
Comparing version 0.4.6-alpha-20220922203506-26c69f1 to 0.4.6-alpha-20220923142202-8e122e5
@@ -33,3 +33,3 @@ /// <reference types="node" /> | ||
**/ | ||
handleNodeRequest(nodeRequest: NodeRequest, ctx: TServerContext): Promise<Response> | Response; | ||
handleNodeRequest(nodeRequest: NodeRequest, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response; | ||
/** | ||
@@ -39,8 +39,10 @@ * A request listener function that can be used with any Node server variation. | ||
requestListener: RequestListener; | ||
/** | ||
* Proxy to requestListener to mimic Node middlewares | ||
*/ | ||
handle: ServerAdapterObject<TServerContext, TBaseObject>['requestListener'] & ServerAdapterObject<TServerContext, TBaseObject>['fetch']; | ||
handle(req: NodeRequest, res: ServerResponse, ...ctx: Partial<TServerContext>[]): Promise<void>; | ||
handle(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response; | ||
handle(fetchEvent: FetchEvent & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): void; | ||
handle(container: { | ||
request: Request; | ||
} & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response; | ||
} | ||
export declare type ServerAdapter<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext>> = TBaseObject & ServerAdapterObject<TServerContext, TBaseObject>['requestListener'] & ServerAdapterObject<TServerContext, TBaseObject>['fetch'] & ServerAdapterObject<TServerContext, TBaseObject>; | ||
export declare type ServerAdapter<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext>> = TBaseObject & ServerAdapterObject<TServerContext, TBaseObject>['handle'] & ServerAdapterObject<TServerContext, TBaseObject>; | ||
export declare type ServerAdapterRequestHandler<TServerContext> = (request: Request, ctx: TServerContext) => Promise<Response> | Response; | ||
@@ -47,0 +49,0 @@ export declare type DefaultServerAdapterContext = { |
76
index.js
@@ -122,2 +122,5 @@ 'use strict'; | ||
} | ||
function isNodeRequest(request) { | ||
return isReadable(request); | ||
} | ||
function isServerResponse(stream) { | ||
@@ -127,2 +130,5 @@ // Check all used functions are defined | ||
} | ||
function isFetchEvent(event) { | ||
return event != null && event.request != null && event.respondWith != null; | ||
} | ||
async function sendNodeResponse({ headers, status, statusText, body }, serverResponse) { | ||
@@ -192,9 +198,10 @@ headers.forEach((value, name) => { | ||
const handleRequest = typeof serverAdapterBaseObject === 'function' ? serverAdapterBaseObject : serverAdapterBaseObject.handle; | ||
function handleNodeRequest(nodeRequest, ctx) { | ||
function handleNodeRequest(nodeRequest, ...ctx) { | ||
const serverContext = Object.assign({}, ...ctx); | ||
const request = normalizeNodeRequest(nodeRequest, RequestCtor); | ||
return handleRequest(request, ctx); | ||
return handleRequest(request, serverContext); | ||
} | ||
async function requestListener(nodeRequest, serverResponse) { | ||
async function requestListener(nodeRequest, serverResponse, ...ctx) { | ||
const waitUntilPromises = []; | ||
const response = await handleNodeRequest(nodeRequest, { | ||
const defaultServerContext = { | ||
req: nodeRequest, | ||
@@ -205,3 +212,4 @@ res: serverResponse, | ||
}, | ||
}); | ||
}; | ||
const response = await handleNodeRequest(nodeRequest, defaultServerContext, ...ctx); | ||
if (response) { | ||
@@ -219,3 +227,2 @@ await sendNodeResponse(response, serverResponse); | ||
} | ||
return response; | ||
} | ||
@@ -226,13 +233,9 @@ function handleEvent(event, ...ctx) { | ||
} | ||
let serverContext = {}; | ||
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) { | ||
serverContext = Object.assign({}, serverContext, ...ctx); | ||
} | ||
const serverContext = Object.assign({}, event, ...ctx); | ||
const response$ = handleRequest(event.request, serverContext); | ||
event.respondWith(response$); | ||
return response$; | ||
} | ||
function handleRequestWithWaitUntil(request, ctx) { | ||
function handleRequestWithWaitUntil(request, ...ctx) { | ||
var _a; | ||
const extendedCtx = ctx; | ||
const serverContext = Object.assign({}, ...ctx); | ||
if ('process' in globalThis && ((_a = process.versions) === null || _a === void 0 ? void 0 : _a['bun']) != null) { | ||
@@ -242,9 +245,6 @@ // This is required for bun | ||
} | ||
if (!extendedCtx.waitUntil) { | ||
if (!('waitUntil' in serverContext)) { | ||
const waitUntilPromises = []; | ||
extendedCtx.waitUntil = (p) => { | ||
waitUntilPromises.push(p); | ||
}; | ||
const response$ = handleRequest(request, { | ||
...extendedCtx, | ||
...serverContext, | ||
waitUntil(p) { | ||
@@ -259,26 +259,20 @@ waitUntilPromises.push(p); | ||
} | ||
return handleRequest(request, extendedCtx); | ||
return handleRequest(request, serverContext); | ||
} | ||
const fetchFn = (input, initOrCtx, ...ctx) => { | ||
let init; | ||
let serverContext = {}; | ||
if (isRequestInit(initOrCtx)) { | ||
init = initOrCtx; | ||
} | ||
else { | ||
init = {}; | ||
serverContext = Object.assign({}, serverContext, initOrCtx); | ||
} | ||
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) { | ||
serverContext = Object.assign({}, serverContext, ...ctx); | ||
} | ||
if (typeof input === 'string' || input instanceof URL) { | ||
return handleRequestWithWaitUntil(new RequestCtor(input, init), serverContext); | ||
if (isRequestInit(initOrCtx)) { | ||
return handleRequestWithWaitUntil(new RequestCtor(input, initOrCtx), ...ctx); | ||
} | ||
return handleRequestWithWaitUntil(new RequestCtor(input), initOrCtx, ...ctx); | ||
} | ||
return handleRequestWithWaitUntil(input, serverContext); | ||
return handleRequestWithWaitUntil(input, initOrCtx, ...ctx); | ||
}; | ||
const genericRequestHandler = (input, initOrCtxOrRes, ...ctx) => { | ||
// If it is a Node request | ||
if (isReadable(input) && isServerResponse(initOrCtxOrRes)) { | ||
return requestListener(input, initOrCtxOrRes); | ||
if (isNodeRequest(input)) { | ||
if (!isServerResponse(initOrCtxOrRes)) { | ||
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`); | ||
} | ||
return requestListener(input, initOrCtxOrRes, ...ctx); | ||
} | ||
@@ -291,15 +285,11 @@ if (isServerResponse(initOrCtxOrRes)) { | ||
// Is it FetchEvent? | ||
if ('respondWith' in input) { | ||
return handleEvent(input, isRequestInit(initOrCtxOrRes) ? {} : initOrCtxOrRes, ...ctx); | ||
if (isFetchEvent(input)) { | ||
return handleEvent(input, initOrCtxOrRes, ...ctx); | ||
} | ||
// In this input is also the context | ||
return fetchFn( | ||
// @ts-expect-error input can indeed be a Request | ||
input.request, initOrCtxOrRes, ...ctx); | ||
return handleRequestWithWaitUntil(input.request, input, initOrCtxOrRes, ...ctx); | ||
} | ||
// Or is it Request itself? | ||
// Then ctx is present and it is the context | ||
return fetchFn( | ||
// @ts-expect-error input can indeed string | Request | URL | ||
input, initOrCtxOrRes, ...ctx); | ||
return fetchFn(input, initOrCtxOrRes, ...ctx); | ||
}; | ||
@@ -306,0 +296,0 @@ const adapterObj = { |
{ | ||
"name": "@whatwg-node/server", | ||
"version": "0.4.6-alpha-20220922203506-26c69f1", | ||
"version": "0.4.6-alpha-20220923142202-8e122e5", | ||
"description": "Fetch API compliant HTTP Server adapter", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
@@ -7,3 +7,3 @@ /// <reference types="node" /> | ||
import type { Readable } from 'node:stream'; | ||
export interface NodeRequest { | ||
export interface NodeRequest extends Readable { | ||
protocol?: string; | ||
@@ -15,3 +15,3 @@ hostname?: string; | ||
method?: string; | ||
headers: any; | ||
headers?: any; | ||
req?: IncomingMessage; | ||
@@ -24,4 +24,6 @@ raw?: IncomingMessage; | ||
export declare function isReadable(stream: any): stream is Readable; | ||
export declare function isNodeRequest(request: any): request is NodeRequest; | ||
export declare function isServerResponse(stream: any): stream is ServerResponse; | ||
export declare function isFetchEvent(event: any): event is FetchEvent; | ||
export declare function sendNodeResponse({ headers, status, statusText, body }: Response, serverResponse: ServerResponse): Promise<void>; | ||
export declare function isRequestInit(val: unknown): val is RequestInit; |
Sorry, the diff of this file is not supported yet
41653
735