@cfworker/web
Advanced tools
Comparing version 1.14.0 to 2.0.0
@@ -10,8 +10,9 @@ import { preferredCharsets } from 'negotiator/lib/charset.js'; | ||
export class Accepts { | ||
headers; | ||
_type = undefined; | ||
_language = undefined; | ||
_encoding = undefined; | ||
_charset = undefined; | ||
constructor(headers) { | ||
this.headers = headers; | ||
this._type = undefined; | ||
this._language = undefined; | ||
this._encoding = undefined; | ||
this._charset = undefined; | ||
} | ||
@@ -18,0 +19,0 @@ type(...values) { |
@@ -10,4 +10,3 @@ import { Middleware } from './middleware.js'; | ||
}): Promise<Response>; | ||
listen(): void; | ||
private invokeMiddleware; | ||
} |
@@ -7,5 +7,4 @@ import statuses from 'statuses'; | ||
export class Application { | ||
constructor() { | ||
this.middleware = []; | ||
} | ||
middleware = []; | ||
_composedMiddleware; | ||
get composedMiddleware() { | ||
@@ -25,6 +24,2 @@ if (!this._composedMiddleware) { | ||
} | ||
listen() { | ||
const middleware = this.composedMiddleware; | ||
addEventListener('fetch', event => event.respondWith(this.invokeMiddleware(Context.fromFetchEvent(event), middleware))); | ||
} | ||
async invokeMiddleware(context, middleware) { | ||
@@ -31,0 +26,0 @@ try { |
@@ -11,3 +11,2 @@ import { Cookies } from './cookies.js'; | ||
readonly state: any; | ||
static fromFetchEvent(event: FetchEvent): Context; | ||
constructor(request: Request, environmentBindings: any, _context: { | ||
@@ -14,0 +13,0 @@ waitUntil(promise: Promise<any>): void; |
@@ -5,2 +5,8 @@ import { Cookies } from './cookies.js'; | ||
export class Context { | ||
environmentBindings; | ||
_context; | ||
req; | ||
res; | ||
cookies; | ||
state; | ||
constructor(request, environmentBindings, _context) { | ||
@@ -14,7 +20,2 @@ this.environmentBindings = environmentBindings; | ||
} | ||
static fromFetchEvent(event) { | ||
return new Context(event.request, globalThis, { | ||
waitUntil: event.waitUntil.bind(event) | ||
}); | ||
} | ||
waitUntil(promise) { | ||
@@ -21,0 +22,0 @@ this._context.waitUntil(promise); |
import { parse as parseCookie, serialize as serializeCookie } from 'cookie'; | ||
const noCookies = Object.create(null); | ||
export class Cookies { | ||
responseHeaders; | ||
requestCookies; | ||
constructor(requestHeaders, responseHeaders) { | ||
@@ -5,0 +7,0 @@ this.responseHeaders = responseHeaders; |
import statuses from 'statuses'; | ||
export class HttpError extends Error { | ||
status; | ||
statusText; | ||
body; | ||
constructor(status, body) { | ||
@@ -4,0 +7,0 @@ const statusText = statuses.message[status]; |
import { Context } from './context.js'; | ||
export declare type Middleware = (context: Context, next: () => Promise<void>) => Promise<void> | void; | ||
export type Middleware = (context: Context, next: () => Promise<void>) => Promise<void> | void; | ||
export declare function composeMiddleware(middleware: Middleware[]): Middleware; |
import { safeParse } from 'secure-json-parse'; | ||
import { Accepts } from './accepts.js'; | ||
export class Req { | ||
raw; | ||
method; | ||
url; | ||
headers; | ||
params; | ||
accepts; | ||
body; | ||
constructor(request) { | ||
@@ -15,2 +22,7 @@ this.raw = request; | ||
export class ReqBody { | ||
request; | ||
_arrayBuffer; | ||
_formData; | ||
_json; | ||
_text; | ||
constructor(request) { | ||
@@ -17,0 +29,0 @@ this.request = request; |
@@ -1,2 +0,2 @@ | ||
export declare type ExtendedBodyInit = BodyInit | boolean | Date | number | object | null; | ||
export type ExtendedBodyInit = BodyInit | boolean | Date | number | object | null; | ||
export declare class ResponseBuilder { | ||
@@ -3,0 +3,0 @@ readonly headers: Headers; |
import statuses from 'statuses'; | ||
export class ResponseBuilder { | ||
constructor() { | ||
this.headers = new Headers(); | ||
this._status = 404; | ||
this._explicitStatus = false; | ||
this._implicitType = false; | ||
this._body = null; | ||
this._stringifyBody = false; | ||
} | ||
headers = new Headers(); | ||
_status = 404; | ||
_explicitStatus = false; | ||
_implicitType = false; | ||
_body = null; | ||
_stringifyBody = false; | ||
get status() { | ||
@@ -12,0 +10,0 @@ return this._status; |
@@ -1,5 +0,4 @@ | ||
import { ParseOptions, TokensToRegexpOptions } from 'path-to-regexp'; | ||
import { PathToRegexpOptions } from 'path-to-regexp'; | ||
import { Context } from './context.js'; | ||
import { Middleware } from './middleware.js'; | ||
export declare type PathToRegExpOptions = TokensToRegexpOptions & ParseOptions; | ||
export declare const Method: (method: string) => ({ req }: Context) => boolean; | ||
@@ -16,4 +15,4 @@ export declare const Get: ({ req }: Context) => boolean; | ||
export declare const Referer: (host: string) => ({ req }: Context) => boolean; | ||
export declare const Path: (pattern: string, options?: PathToRegExpOptions) => ({ req: { url, params } }: Context) => boolean; | ||
export declare type RouteCondition = (context: Context) => boolean; | ||
export declare const Path: (pattern: string, options?: PathToRegexpOptions) => ({ req: { url, params } }: Context) => boolean; | ||
export type RouteCondition = (context: Context) => boolean; | ||
export interface Route { | ||
@@ -24,3 +23,3 @@ conditions: RouteCondition[]; | ||
export interface RouterOptions { | ||
pathToRegExpOptions?: PathToRegExpOptions; | ||
pathToRegExpOptions?: PathToRegexpOptions; | ||
} | ||
@@ -27,0 +26,0 @@ export declare const defaultRouterOptions: RouterOptions; |
@@ -21,4 +21,3 @@ import { pathToRegexp } from 'path-to-regexp'; | ||
export const Path = (pattern, options) => { | ||
const keys = []; | ||
const regExp = pathToRegexp(pattern, keys, options); | ||
const regExp = pathToRegexp(pattern, options); | ||
return ({ req: { url, params } }) => { | ||
@@ -29,3 +28,3 @@ const match = url.pathname.match(regExp); | ||
} | ||
collectParameters(keys, match, params); | ||
collectParameters(regExp.keys, match, params); | ||
return true; | ||
@@ -38,13 +37,6 @@ }; | ||
export class Router { | ||
options; | ||
routes; | ||
constructor(options = defaultRouterOptions) { | ||
this.options = options; | ||
this.middleware = async (ctx, next) => { | ||
const resolved = this.resolve(ctx); | ||
if (resolved) { | ||
await resolved.middleware(ctx, next); | ||
} | ||
else { | ||
await next(); | ||
} | ||
}; | ||
this.routes = []; | ||
@@ -80,2 +72,11 @@ } | ||
} | ||
middleware = async (ctx, next) => { | ||
const resolved = this.resolve(ctx); | ||
if (resolved) { | ||
await resolved.middleware(ctx, next); | ||
} | ||
else { | ||
await next(); | ||
} | ||
}; | ||
compose(conditions, ...middleware) { | ||
@@ -82,0 +83,0 @@ this.routes.push({ |
@@ -9,4 +9,4 @@ import { OutputUnit, Schema } from '@cfworker/json-schema'; | ||
} | ||
export declare type RequestPart = keyof RequestSchemas; | ||
export declare type RequestParser = (data: URLSearchParams | FormData) => any; | ||
export type RequestPart = keyof RequestSchemas; | ||
export type RequestParser = (data: URLSearchParams | FormData) => any; | ||
declare function middlewareFactory(schemas: RequestSchemas, parser?: RequestParser, lookup?: any): Middleware; | ||
@@ -13,0 +13,0 @@ export declare const messages: Record<RequestPart, string>; |
{ | ||
"name": "@cfworker/web", | ||
"version": "1.14.0", | ||
"version": "2.0.0", | ||
"description": "Web framework for Cloudflare Workers and service workers, inspired by Koa and fastify", | ||
@@ -34,27 +34,27 @@ "keywords": [ | ||
"clean": "tsc --build --clean", | ||
"test": "cfworker test test/**/*.spec.ts --nocheck" | ||
"pretest": "esbuild test/test.ts --target=esnext --bundle --format=esm --conditions=worker,browser --outdir=dist-test --ignore-annotations", | ||
"test": "node ../../test.mjs" | ||
}, | ||
"dependencies": { | ||
"@cfworker/json-schema": "^1.12.6", | ||
"@cfworker/worker-types": "^1.12.3", | ||
"@cloudflare/workers-types": "^2.2.2", | ||
"@types/cookie": "^0.5.1", | ||
"@types/html-escaper": "^3.0.0", | ||
"@types/statuses": "^2.0.0", | ||
"cookie": "^0.5.0", | ||
"@cfworker/json-schema": "^2.0.0", | ||
"@types/cookie": "^0.6.0", | ||
"@types/html-escaper": "^3.0.2", | ||
"@types/statuses": "^2.0.5", | ||
"cookie": "^0.6.0", | ||
"html-escaper": "^3.0.3", | ||
"negotiator": "^0.6.3", | ||
"path-to-regexp": "^6.2.1", | ||
"secure-json-parse": "^2.5.0", | ||
"path-to-regexp": "^7.1.0", | ||
"secure-json-parse": "^2.7.0", | ||
"statuses": "^2.0.1" | ||
}, | ||
"devDependencies": { | ||
"@cfworker/dev": "^1.14.2", | ||
"@types/chai": "^4.3.3", | ||
"@types/mocha": "^10.0.0", | ||
"chai": "^4.3.6", | ||
"@types/chai": "^4.3.17", | ||
"@types/mocha": "^10.0.7", | ||
"chai": "^5.1.1", | ||
"esbuild": "^0.23.1", | ||
"jsonpointer": "^5.0.1", | ||
"mocha": "^10.0.0", | ||
"typescript": "^4.8.4" | ||
"mocha": "^10.7.3", | ||
"typescript": "^5.5.4", | ||
"wrangler": "^3.72.0" | ||
} | ||
} |
@@ -38,11 +38,2 @@ import statuses from 'statuses'; | ||
public listen() { | ||
const middleware = this.composedMiddleware; | ||
addEventListener('fetch', event => | ||
event.respondWith( | ||
this.invokeMiddleware(Context.fromFetchEvent(event), middleware) | ||
) | ||
); | ||
} | ||
private async invokeMiddleware(context: Context, middleware: Middleware) { | ||
@@ -49,0 +40,0 @@ try { |
@@ -11,8 +11,2 @@ import { Cookies } from './cookies.js'; | ||
static fromFetchEvent(event: FetchEvent) { | ||
return new Context(event.request, globalThis as any, { | ||
waitUntil: event.waitUntil.bind(event) | ||
}); | ||
} | ||
constructor( | ||
@@ -19,0 +13,0 @@ request: Request, |
@@ -7,1 +7,5 @@ // secure-json-parse's types rely on node's Buffer | ||
} | ||
interface ErrorConstructor { | ||
captureStackTrace(thisArg: any, func: any): void; | ||
} |
@@ -1,12 +0,5 @@ | ||
import { | ||
Key, | ||
ParseOptions, | ||
pathToRegexp, | ||
TokensToRegexpOptions | ||
} from 'path-to-regexp'; | ||
import { Key, pathToRegexp, PathToRegexpOptions } from 'path-to-regexp'; | ||
import { Context } from './context.js'; | ||
import { composeMiddleware, Middleware } from './middleware.js'; | ||
export type PathToRegExpOptions = TokensToRegexpOptions & ParseOptions; | ||
export const Method = (method: string) => { | ||
@@ -31,5 +24,4 @@ method = method.toUpperCase(); | ||
export const Path = (pattern: string, options?: PathToRegExpOptions) => { | ||
const keys: Key[] = []; | ||
const regExp = pathToRegexp(pattern, keys, options); | ||
export const Path = (pattern: string, options?: PathToRegexpOptions) => { | ||
const regExp = pathToRegexp(pattern, options); | ||
@@ -41,3 +33,3 @@ return ({ req: { url, params } }: Context) => { | ||
} | ||
collectParameters(keys, match, params); | ||
collectParameters(regExp.keys, match, params); | ||
return true; | ||
@@ -55,3 +47,3 @@ }; | ||
export interface RouterOptions { | ||
pathToRegExpOptions?: PathToRegExpOptions; | ||
pathToRegExpOptions?: PathToRegexpOptions; | ||
} | ||
@@ -58,0 +50,0 @@ |
{ | ||
"extends": "../../tsconfig-base", | ||
"compilerOptions": { | ||
"target": "ES2021", | ||
"target": "ESNext", | ||
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"], | ||
"types": [ | ||
"chai", | ||
"mocha", | ||
"@cfworker/worker-types", | ||
"@cloudflare/workers-types" | ||
], | ||
"outDir": "dist", | ||
@@ -13,0 +7,0 @@ "rootDir": "./src" |
10
51297
8
1477
+ Added@cfworker/json-schema@2.0.1(transitive)
+ Added@types/cookie@0.6.0(transitive)
+ Addedcookie@0.6.0(transitive)
+ Addedpath-to-regexp@7.2.0(transitive)
- Removed@cfworker/worker-types@^1.12.3
- Removed@cloudflare/workers-types@^2.2.2
- Removed@cfworker/json-schema@1.12.8(transitive)
- Removed@cfworker/worker-types@1.12.3(transitive)
- Removed@cloudflare/workers-types@2.2.2(transitive)
- Removed@types/cookie@0.5.4(transitive)
- Removedcookie@0.5.0(transitive)
- Removedpath-to-regexp@6.3.0(transitive)
Updated@cfworker/json-schema@^2.0.0
Updated@types/cookie@^0.6.0
Updated@types/html-escaper@^3.0.2
Updated@types/statuses@^2.0.5
Updatedcookie@^0.6.0
Updatedpath-to-regexp@^7.1.0
Updatedsecure-json-parse@^2.7.0