@whatwg-node/server
Advanced tools
Comparing version 0.4.6-alpha-20220923235827-6722c6b to 0.4.6-alpha-20220924014209-92abf34
@@ -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 = { |
89
index.js
@@ -122,6 +122,12 @@ 'use strict'; | ||
} | ||
function isNodeRequest(request) { | ||
return isReadable(request); | ||
} | ||
function isServerResponse(stream) { | ||
// Check all used functions are defined | ||
return stream.setHeader != null && stream.end != null && stream.once != null && stream.write != null; | ||
return stream != null && stream.setHeader != null && stream.end != null && stream.once != null && stream.write != null; | ||
} | ||
function isFetchEvent(event) { | ||
return event != null && event.request != null && event.respondWith != null; | ||
} | ||
async function sendNodeResponse({ headers, status, statusText, body }, serverResponse) { | ||
@@ -144,2 +150,3 @@ headers.forEach((value, name) => { | ||
body.destroy(); | ||
resolve(); | ||
}); | ||
@@ -192,9 +199,10 @@ body.pipe(serverResponse); | ||
const handleRequest = typeof serverAdapterBaseObject === 'function' ? serverAdapterBaseObject : serverAdapterBaseObject.handle; | ||
function handleNodeRequest(nodeRequest, ctx) { | ||
function handleNodeRequest(nodeRequest, ...ctx) { | ||
const serverContext = ctx.length > 1 ? Object.assign({}, ...ctx) : ctx[0]; | ||
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 +213,4 @@ res: serverResponse, | ||
}, | ||
}); | ||
}; | ||
const response = await handleNodeRequest(nodeRequest, defaultServerContext, ...ctx); | ||
if (response) { | ||
@@ -219,3 +228,2 @@ await sendNodeResponse(response, serverResponse); | ||
} | ||
return response; | ||
} | ||
@@ -226,13 +234,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 = ctx.length > 0 ? Object.assign({}, event, ...ctx) : event; | ||
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 = ctx.length > 1 ? Object.assign({}, ...ctx) : (ctx[0] || {}); | ||
if ('process' in globalThis && ((_a = process.versions) === null || _a === void 0 ? void 0 : _a['bun']) != null) { | ||
@@ -242,9 +246,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 +260,22 @@ 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); | ||
} | ||
const fetchFn = (input, ...maybeCtx) => { | ||
if (typeof input === 'string' || input instanceof URL) { | ||
return handleRequestWithWaitUntil(new RequestCtor(input, init), serverContext); | ||
const [initOrCtx, ...restOfCtx] = maybeCtx; | ||
if (isRequestInit(initOrCtx)) { | ||
return handleRequestWithWaitUntil(new RequestCtor(input.toString(), initOrCtx), ...restOfCtx); | ||
} | ||
return handleRequestWithWaitUntil(new RequestCtor(input.toString()), ...maybeCtx); | ||
} | ||
return handleRequestWithWaitUntil(input, serverContext); | ||
return handleRequestWithWaitUntil(input, ...maybeCtx); | ||
}; | ||
const genericRequestHandler = (input, initOrCtxOrRes, ...ctx) => { | ||
const genericRequestHandler = (input, ...maybeCtx) => { | ||
// If it is a Node request | ||
if (isReadable(input) && isServerResponse(initOrCtxOrRes)) { | ||
return requestListener(input, initOrCtxOrRes); | ||
const [initOrCtxOrRes, ...restOfCtx] = maybeCtx; | ||
if (isNodeRequest(input)) { | ||
if (!isServerResponse(initOrCtxOrRes)) { | ||
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`); | ||
} | ||
return requestListener(input, initOrCtxOrRes, ...restOfCtx); | ||
} | ||
@@ -291,15 +288,11 @@ if (isServerResponse(initOrCtxOrRes)) { | ||
// Is it FetchEvent? | ||
if ('respondWith' in input) { | ||
return handleEvent(input, isRequestInit(initOrCtxOrRes) ? {} : initOrCtxOrRes, ...ctx); | ||
if (isFetchEvent(input)) { | ||
return handleEvent(input, ...maybeCtx); | ||
} | ||
// 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, ...maybeCtx); | ||
} | ||
// 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, ...maybeCtx); | ||
}; | ||
@@ -346,4 +339,4 @@ const adapterObj = { | ||
}, | ||
apply(_, __, [input, ctx]) { | ||
return genericRequestHandler(input, ctx); | ||
apply(_, __, args) { | ||
return genericRequestHandler(...args); | ||
}, | ||
@@ -350,0 +343,0 @@ }); // 😡 |
{ | ||
"name": "@whatwg-node/server", | ||
"version": "0.4.6-alpha-20220923235827-6722c6b", | ||
"version": "0.4.6-alpha-20220924014209-92abf34", | ||
"description": "Fetch API compliant HTTP Server adapter", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
@@ -122,3 +122,3 @@ # WHATWG Node Generic Server Adapter | ||
req, | ||
reply, | ||
reply | ||
}) | ||
@@ -125,0 +125,0 @@ response.headers.forEach((value, key) => { |
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42060
741