@whatwg-node/server
Advanced tools
Comparing version 0.3.0 to 0.4.0-alpha-20220916163145-ea58ba1
@@ -5,34 +5,26 @@ /// <reference types="node" /> | ||
import { NodeRequest } from './utils'; | ||
export interface CreateServerAdapterOptions<TServerContext, TBaseObject> { | ||
export interface ServerAdapterBaseObject<TServerContext, THandleRequest extends HandleRequestFn<TServerContext>> { | ||
/** | ||
* WHATWG Fetch spec compliant `Request` constructor. | ||
*/ | ||
Request?: typeof Request; | ||
/** | ||
* An async function that takes `Request` and the server context and returns a `Response`. | ||
* If you use `requestListener`, the server context is `{ req: IncomingMessage, res: ServerResponse }`. | ||
*/ | ||
handleRequest: (request: Request, serverContext: TServerContext) => Promise<Response>; | ||
/** | ||
* If you extend a server object with this, you can pass the original object and it will be extended with the required methods and functionalities. | ||
*/ | ||
baseObject?: TBaseObject; | ||
handle: THandleRequest; | ||
} | ||
export interface ServerAdapterObject<TServerContext> extends EventListenerObject { | ||
export interface ServerAdapterObject<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext, HandleRequestFn<TServerContext>>> extends EventListenerObject { | ||
/** | ||
* A basic request listener that takes a `Request` with the server context and returns a `Response`. | ||
*/ | ||
handleRequest: (request: Request, serverContext: TServerContext) => Promise<Response>; | ||
handleRequest: TBaseObject['handle']; | ||
/** | ||
* WHATWG Fetch spec compliant `fetch` function that can be used for testing purposes. | ||
*/ | ||
fetch(request: Request, ...ctx: any[]): Promise<Response>; | ||
fetch(urlStr: string, ...ctx: any[]): Promise<Response>; | ||
fetch(urlStr: string, init: RequestInit, ...ctx: any[]): Promise<Response>; | ||
fetch(url: URL, ...ctx: any[]): Promise<Response>; | ||
fetch(url: URL, init: RequestInit, ...ctx: any[]): Promise<Response>; | ||
fetch(request: Request, ...ctx: any[]): Promise<Response> | Response; | ||
fetch(urlStr: string, ...ctx: any[]): Promise<Response> | Response; | ||
fetch(urlStr: string, init: RequestInit, ...ctx: any[]): Promise<Response> | Response; | ||
fetch(url: URL, ...ctx: any[]): Promise<Response> | Response; | ||
fetch(url: URL, init: RequestInit, ...ctx: any[]): Promise<Response> | Response; | ||
/** | ||
* This function takes Node's request object and returns a WHATWG Fetch spec compliant `Response` object. | ||
**/ | ||
handleNodeRequest(nodeRequest: NodeRequest, serverContext: TServerContext): Promise<Response>; | ||
handleNodeRequest(nodeRequest: NodeRequest, serverContext: TServerContext): Promise<Response> | Response; | ||
/** | ||
@@ -45,9 +37,13 @@ * A request listener function that can be used with any Node server variation. | ||
*/ | ||
handle: RequestListener; | ||
handle: RequestListener & ServerAdapterObject<TServerContext, TBaseObject>['fetch']; | ||
} | ||
export declare type ServerAdapter<TServerContext, TBaseObject> = TBaseObject & RequestListener & ServerAdapterObject<TServerContext>['fetch'] & ServerAdapterObject<TServerContext>; | ||
export declare function createServerAdapter<TServerContext = { | ||
export declare type ServerAdapter<TServerContext, THandleRequest extends HandleRequestFn<TServerContext>, TBaseObject extends ServerAdapterBaseObject<TServerContext, THandleRequest>> = Omit<TBaseObject, 'handle'> & RequestListener & ServerAdapterObject<TServerContext, TBaseObject>['fetch'] & ServerAdapterObject<TServerContext, TBaseObject>; | ||
declare type HandleRequestFn<TServerContext> = (request: Request, serverContext: TServerContext) => Promise<Response> | Response; | ||
declare type DefaultServerContext = { | ||
req: NodeRequest; | ||
res: ServerResponse; | ||
waitUntil(promise: Promise<unknown>): void; | ||
}, TBaseObject = unknown>({ Request: RequestCtor, handleRequest, baseObject, }: CreateServerAdapterOptions<TServerContext, TBaseObject>): ServerAdapter<TServerContext, TBaseObject>; | ||
}; | ||
declare function createServerAdapter<TServerContext = DefaultServerContext, THandleRequest extends HandleRequestFn<TServerContext> = HandleRequestFn<TServerContext>>(serverAdapterBaseObject: THandleRequest): ServerAdapter<TServerContext, THandleRequest, ServerAdapterBaseObject<TServerContext, THandleRequest>>; | ||
declare function createServerAdapter<TServerContext = DefaultServerContext, THandleRequest extends HandleRequestFn<TServerContext> = HandleRequestFn<TServerContext>, TBaseObject extends ServerAdapterBaseObject<TServerContext, THandleRequest> = ServerAdapterBaseObject<TServerContext, THandleRequest>>(serverAdapterBaseObject: TBaseObject): ServerAdapter<TServerContext, THandleRequest, TBaseObject>; | ||
export { createServerAdapter }; |
50
index.js
@@ -159,10 +159,16 @@ 'use strict'; | ||
/// <reference lib="webworker" /> | ||
function handleWaitUntils(waitUntilPromises) { | ||
return Promise.allSettled(waitUntilPromises).then(waitUntils => waitUntils.forEach(waitUntil => { | ||
async function handleWaitUntils(waitUntilPromises) { | ||
const waitUntils = await Promise.allSettled(waitUntilPromises); | ||
waitUntils.forEach(waitUntil => { | ||
if (waitUntil.status === 'rejected') { | ||
console.error(waitUntil.reason); | ||
} | ||
})); | ||
}); | ||
} | ||
function createServerAdapter({ Request: RequestCtor = fetch.Request, handleRequest, baseObject, }) { | ||
function createServerAdapter(serverAdapterBaseObject, | ||
/** | ||
* WHATWG Fetch spec compliant `Request` constructor. | ||
*/ | ||
RequestCtor = fetch.Request) { | ||
const handleRequest = typeof serverAdapterBaseObject === 'function' ? serverAdapterBaseObject : serverAdapterBaseObject.handle; | ||
function fetchFn(input, init, ...ctx) { | ||
@@ -196,3 +202,5 @@ if (typeof input === 'string' || input instanceof URL) { | ||
} | ||
await handleWaitUntils(waitUntilPromises); | ||
if (waitUntilPromises.length > 0) { | ||
await handleWaitUntils(waitUntilPromises); | ||
} | ||
} | ||
@@ -206,10 +214,2 @@ function handleEvent(event) { | ||
} | ||
const adapterObj = { | ||
handleRequest, | ||
fetch: fetchFn, | ||
handleNodeRequest, | ||
requestListener, | ||
handleEvent, | ||
handle: requestListener, | ||
}; | ||
function genericRequestHandler(input, ctx, ...rest) { | ||
@@ -256,16 +256,16 @@ var _a; | ||
} | ||
const adapterObj = { | ||
handleRequest, | ||
fetch: fetchFn, | ||
handleNodeRequest, | ||
requestListener, | ||
handleEvent, | ||
handle: genericRequestHandler, | ||
}; | ||
return new Proxy(genericRequestHandler, { | ||
// It should have all the attributes of the handler function and the server instance | ||
has: (_, prop) => { | ||
return (baseObject && prop in baseObject) || prop in adapterObj || prop in genericRequestHandler; | ||
return prop in adapterObj || prop in genericRequestHandler || (serverAdapterBaseObject && prop in serverAdapterBaseObject); | ||
}, | ||
get: (_, prop) => { | ||
if (baseObject) { | ||
if (prop in baseObject) { | ||
if (baseObject[prop].bind) { | ||
return baseObject[prop].bind(baseObject); | ||
} | ||
return baseObject[prop]; | ||
} | ||
} | ||
if (adapterObj[prop]) { | ||
@@ -283,2 +283,8 @@ if (adapterObj[prop].bind) { | ||
} | ||
if (prop in serverAdapterBaseObject) { | ||
if (serverAdapterBaseObject[prop].bind) { | ||
return serverAdapterBaseObject[prop].bind(serverAdapterBaseObject); | ||
} | ||
return serverAdapterBaseObject[prop]; | ||
} | ||
}, | ||
@@ -285,0 +291,0 @@ apply(_, __, [input, ctx]) { |
{ | ||
"name": "@whatwg-node/server", | ||
"version": "0.3.0", | ||
"version": "0.4.0-alpha-20220916163145-ea58ba1", | ||
"description": "Fetch API compliant HTTP Server adapter", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
@@ -15,6 +15,4 @@ # WHATWG Node Generic Server Adapter | ||
export default createServerAdapter({ | ||
handleRequest(request: Request) { | ||
export default createServerAdapter((request: Request) => { | ||
return new Response(`Hello World!`, { status: 200 }) | ||
} | ||
}) | ||
@@ -207,5 +205,3 @@ ``` | ||
const myServerAdapter = createServerAdapter({ | ||
// ... | ||
async handleRequest(request) { | ||
const myServerAdapter = createServerAdapter(async request => { | ||
// Parse the request as `FormData` | ||
@@ -226,4 +222,3 @@ const formData = await request.formData() | ||
}) | ||
} | ||
}) | ||
}) | ||
``` | ||
@@ -242,2 +237,3 @@ | ||
import { createServerAdapter } from '@whatwg-node/server' | ||
// now let's create a router (note the lack of "new") | ||
@@ -254,9 +250,12 @@ const router = Router() | ||
}) | ||
// Redirect to a URL | ||
router.get('/google', () => Response.redirect('http://www.google.com')) | ||
// 404 for everything else | ||
router.all('*', () => new Response('Not Found.', { status: 404 })) | ||
// attach the router "handle" to our server adapter | ||
const myServerAdapter = createServerAdapter({ | ||
handleRequest: router.handle | ||
}) | ||
// attach the router to our server adapter | ||
const myServerAdapter = createServerAdapter(router) | ||
// Then use it in any environment | ||
@@ -263,0 +262,0 @@ import { createServer } from 'http' |
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
37031
645
290