Comparing version 1.4.2 to 1.4.3
@@ -19,9 +19,8 @@ "use strict"; | ||
if (!handler) { | ||
if (context instanceof context_1.Context && context.res._finalized === false && onNotFound) { | ||
if (context instanceof context_1.Context && context.finalized === false && onNotFound) { | ||
context.res = onNotFound(context); | ||
context.res._finalized = true; | ||
} | ||
return Promise.resolve(context); | ||
} | ||
return Promise.resolve(handler(context, dispatch.bind(null, i + 1))) | ||
return Promise.resolve(handler(context, () => dispatch(i + 1))) | ||
.then(async (res) => { | ||
@@ -31,3 +30,2 @@ // If handler return Response like `return c.text('foo')` | ||
context.res = res; | ||
context.res._finalized = true; | ||
} | ||
@@ -40,3 +38,2 @@ return context; | ||
context.res = onError(err, context); | ||
context.res._finalized = true; | ||
} | ||
@@ -43,0 +40,0 @@ return context; |
/// <reference types="@cloudflare/workers-types" /> | ||
import { HonoResponse } from './response'; | ||
import type { StatusCode } from './utils/http-status'; | ||
@@ -9,5 +8,5 @@ declare type Headers = Record<string, string>; | ||
req: Request<RequestParamKeyType>; | ||
res: Response; | ||
env: E; | ||
event: FetchEvent | undefined; | ||
finalized: boolean; | ||
private _status; | ||
@@ -17,10 +16,9 @@ private _pretty; | ||
private _map; | ||
private _headers; | ||
private _res; | ||
private notFoundHandler; | ||
render: (template: string, params?: object, options?: object) => Promise<Response>; | ||
notFound: () => Response | Promise<Response>; | ||
constructor(req: Request<RequestParamKeyType>, opts?: { | ||
env?: Env; | ||
event?: FetchEvent; | ||
res?: Response | HonoResponse; | ||
}); | ||
private initRequest; | ||
constructor(req: Request<RequestParamKeyType>, env?: E | undefined, event?: FetchEvent | undefined, notFoundHandler?: (c: Context<string, E>) => Response); | ||
get res(): Response; | ||
set res(_res: Response); | ||
header(name: string, value: string): void; | ||
@@ -31,3 +29,3 @@ status(status: StatusCode): void; | ||
pretty(prettyJSON: boolean, space?: number): void; | ||
newResponse(data: Data | null, init?: ResponseInit): Response; | ||
newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response; | ||
body(data: Data | null, status?: StatusCode, headers?: Headers): Response; | ||
@@ -38,3 +36,4 @@ text(text: string, status?: StatusCode, headers?: Headers): Response; | ||
redirect(location: string, status?: StatusCode): Response; | ||
notFound(): Response | Promise<Response>; | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Context = void 0; | ||
const response_1 = require("./response"); | ||
const url_1 = require("./utils/url"); | ||
class Context { | ||
constructor(req, opts = { | ||
env: {}, | ||
event: undefined, | ||
res: undefined, | ||
}) { | ||
constructor(req, env = undefined, event = undefined, notFoundHandler = () => new Response()) { | ||
this._status = 200; | ||
this._pretty = false; | ||
this._prettySpace = 2; | ||
this.req = this.initRequest(req); | ||
this._map = {}; | ||
Object.assign(this, opts); | ||
if (!this.res) { | ||
const res = new response_1.HonoResponse(null, { status: 404 }); | ||
res._finalized = false; | ||
this.res = res; | ||
this.req = req; | ||
if (env) { | ||
this.env = env; | ||
} | ||
this.event = event; | ||
this.notFoundHandler = notFoundHandler; | ||
this.finalized = false; | ||
} | ||
initRequest(req) { | ||
req.header = ((name) => { | ||
if (name) { | ||
return req.headers.get(name); | ||
} | ||
else { | ||
const result = {}; | ||
for (const [key, value] of req.headers) { | ||
result[key] = value; | ||
} | ||
return result; | ||
} | ||
}); | ||
req.query = ((key) => { | ||
const url = new URL(req.url); | ||
if (key) { | ||
return url.searchParams.get(key); | ||
} | ||
else { | ||
const result = {}; | ||
for (const key of url.searchParams.keys()) { | ||
result[key] = url.searchParams.get(key) || ''; | ||
} | ||
return result; | ||
} | ||
}); | ||
req.queries = ((key) => { | ||
const url = new URL(req.url); | ||
if (key) { | ||
return url.searchParams.getAll(key); | ||
} | ||
else { | ||
const result = {}; | ||
for (const key of url.searchParams.keys()) { | ||
result[key] = url.searchParams.getAll(key); | ||
} | ||
return result; | ||
} | ||
}); | ||
return req; | ||
get res() { | ||
return (this._res || (this._res = new Response())); | ||
} | ||
set res(_res) { | ||
this._res = _res; | ||
this.finalized = true; | ||
} | ||
header(name, value) { | ||
this.res.headers.set(name, value); | ||
this._headers || (this._headers = {}); | ||
this._headers[name] = value; | ||
if (this.finalized) { | ||
this.res.headers.set(name, value); | ||
} | ||
} | ||
@@ -72,5 +36,9 @@ status(status) { | ||
set(key, value) { | ||
this._map || (this._map = {}); | ||
this._map[key] = value; | ||
} | ||
get(key) { | ||
if (!this._map) { | ||
return undefined; | ||
} | ||
return this._map[key]; | ||
@@ -82,21 +50,18 @@ } | ||
} | ||
newResponse(data, init = {}) { | ||
init.status = init.status || this._status || 200; | ||
const headers = {}; | ||
this.res.headers.forEach((v, k) => { | ||
headers[k] = v; | ||
newResponse(data, status, headers = {}) { | ||
const _headers = { ...this._headers, ...headers }; | ||
if (this._res) { | ||
this._res.headers.forEach((v, k) => { | ||
_headers[k] = v; | ||
}); | ||
} | ||
return new Response(data, { | ||
status: status || this._status || 200, | ||
headers: _headers, | ||
}); | ||
init.headers = Object.assign(headers, init.headers); | ||
return new Response(data, init); | ||
} | ||
body(data, status = this._status, headers = {}) { | ||
return this.newResponse(data, { | ||
status: status, | ||
headers: headers, | ||
}); | ||
return this.newResponse(data, status, headers); | ||
} | ||
text(text, status = this._status, headers = {}) { | ||
if (typeof text !== 'string') { | ||
throw new TypeError('text method arg must be a string!'); | ||
} | ||
headers['Content-Type'] || (headers['Content-Type'] = 'text/plain; charset=UTF-8'); | ||
@@ -106,5 +71,2 @@ return this.body(text, status, headers); | ||
json(object, status = this._status, headers = {}) { | ||
if (typeof object !== 'object') { | ||
throw new TypeError('json method arg must be an object!'); | ||
} | ||
const body = this._pretty | ||
@@ -117,5 +79,2 @@ ? JSON.stringify(object, null, this._prettySpace) | ||
html(html, status = this._status, headers = {}) { | ||
if (typeof html !== 'string') { | ||
throw new TypeError('html method arg must be a string!'); | ||
} | ||
headers['Content-Type'] || (headers['Content-Type'] = 'text/html; charset=UTF-8'); | ||
@@ -125,5 +84,2 @@ return this.body(html, status, headers); | ||
redirect(location, status = 302) { | ||
if (typeof location !== 'string') { | ||
throw new TypeError('location must be a string!'); | ||
} | ||
if (!(0, url_1.isAbsoluteURL)(location)) { | ||
@@ -134,10 +90,10 @@ const url = new URL(this.req.url); | ||
} | ||
return this.newResponse(null, { | ||
status: status, | ||
headers: { | ||
Location: location, | ||
}, | ||
return this.newResponse(null, status, { | ||
Location: location, | ||
}); | ||
} | ||
notFound() { | ||
return this.notFoundHandler(this); | ||
} | ||
} | ||
exports.Context = Context; |
@@ -5,25 +5,2 @@ /// <reference types="@cloudflare/workers-types" /> | ||
import type { Router } from './router'; | ||
declare global { | ||
interface Request<ParamKeyType extends string = string> { | ||
param: { | ||
(key: ParamKeyType): string; | ||
(): Record<ParamKeyType, string>; | ||
}; | ||
query: { | ||
(key: string): string; | ||
(): Record<string, string>; | ||
}; | ||
queries: { | ||
(key: string): string[]; | ||
(): Record<string, string[]>; | ||
}; | ||
header: { | ||
(name: string): string; | ||
(): Record<string, string>; | ||
}; | ||
} | ||
interface Response { | ||
_finalized: boolean; | ||
} | ||
} | ||
export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>; | ||
@@ -36,3 +13,3 @@ export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response; | ||
declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>; | ||
interface HandlerInterface<T extends string, E = Env, U = Hono<E, T>> { | ||
interface HandlerInterface<T extends string, E extends Env = Env, U = Hono<E, T>> { | ||
<Path extends string>(path: Path, ...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U; | ||
@@ -58,3 +35,3 @@ (path: string, ...handlers: Handler<string, E>[]): U; | ||
}; | ||
export declare class Hono<E = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> { | ||
export declare class Hono<E extends Env = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> { | ||
readonly router: Router<Handler<string, E>>; | ||
@@ -61,0 +38,0 @@ readonly strict: boolean; |
@@ -6,2 +6,3 @@ "use strict"; | ||
const context_1 = require("./context"); | ||
const request_1 = require("./request"); | ||
const router_1 = require("./router"); | ||
@@ -32,2 +33,3 @@ const trie_router_1 = require("./router/trie-router"); // Default Router | ||
}; | ||
(0, request_1.extendRequestPrototype)(); // FIXME: should be executed at a better timing | ||
const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE]; | ||
@@ -91,26 +93,12 @@ allMethods.map((method) => { | ||
} | ||
async matchRoute(method, path) { | ||
matchRoute(method, path) { | ||
return this.router.match(method, path); | ||
} | ||
async dispatch(request, event, env) { | ||
const path = (0, url_1.getPathFromURL)(request.url, { strict: this.strict }); | ||
const path = (0, url_1.getPathFromURL)(request.url, this.strict); | ||
const method = request.method; | ||
const result = await this.matchRoute(method, path); | ||
request.param = ((key) => { | ||
if (result) { | ||
if (key) { | ||
return result.params[key]; | ||
} | ||
else { | ||
return result.params; | ||
} | ||
} | ||
return null; | ||
}); | ||
const result = this.matchRoute(method, path); | ||
request.paramData = result?.params; | ||
const handlers = result ? result.handlers : [this.notFoundHandler]; | ||
const c = new context_1.Context(request, { | ||
env: env, | ||
event: event, | ||
}); | ||
c.notFound = () => this.notFoundHandler(c); | ||
const c = new context_1.Context(request, env, event, this.notFoundHandler); | ||
const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler); | ||
@@ -127,4 +115,2 @@ let context; | ||
} | ||
if (!context.res) | ||
return context.notFound(); | ||
return context.res; | ||
@@ -131,0 +117,0 @@ } |
@@ -37,3 +37,2 @@ "use strict"; | ||
return async (ctx, next) => { | ||
var _a; | ||
const requestUser = auth(ctx.req); | ||
@@ -54,3 +53,3 @@ if (requestUser) { | ||
headers: { | ||
'WWW-Authenticate': 'Basic realm="' + ((_a = options.realm) === null || _a === void 0 ? void 0 : _a.replace(/"/g, '\\"')) + '"', | ||
'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"', | ||
}, | ||
@@ -57,0 +56,0 @@ }); |
@@ -11,5 +11,7 @@ "use strict"; | ||
}; | ||
const opts = Object.assign(Object.assign({}, defaults), options); | ||
const opts = { | ||
...defaults, | ||
...options, | ||
}; | ||
return async (c, next) => { | ||
var _a, _b; | ||
await next(); | ||
@@ -28,3 +30,3 @@ function set(key, value) { | ||
} | ||
if ((_a = opts.exposeHeaders) === null || _a === void 0 ? void 0 : _a.length) { | ||
if (opts.exposeHeaders?.length) { | ||
set('Access-Control-Expose-Headers', opts.exposeHeaders.join(',')); | ||
@@ -37,7 +39,7 @@ } | ||
} | ||
if ((_b = opts.allowMethods) === null || _b === void 0 ? void 0 : _b.length) { | ||
if (opts.allowMethods?.length) { | ||
set('Access-Control-Allow-Methods', opts.allowMethods.join(',')); | ||
} | ||
let headers = opts.allowHeaders; | ||
if (!(headers === null || headers === void 0 ? void 0 : headers.length)) { | ||
if (!headers?.length) { | ||
const requestHeaders = c.req.headers.get('Access-Control-Request-Headers'); | ||
@@ -48,3 +50,3 @@ if (requestHeaders) { | ||
} | ||
if (headers === null || headers === void 0 ? void 0 : headers.length) { | ||
if (headers?.length) { | ||
set('Access-Control-Allow-Headers', headers.join(',')); | ||
@@ -51,0 +53,0 @@ set('Vary', 'Access-Control-Request-Headers'); |
@@ -9,7 +9,6 @@ "use strict"; | ||
const graphqlServer = (options) => { | ||
var _a, _b; | ||
const schema = options.schema; | ||
const rootValue = options.rootValue; | ||
const pretty = (_a = options.pretty) !== null && _a !== void 0 ? _a : false; | ||
const validationRules = (_b = options.validationRules) !== null && _b !== void 0 ? _b : []; | ||
const pretty = options.pretty ?? false; | ||
const validationRules = options.validationRules ?? []; | ||
// const showGraphiQL = options.graphiql ?? false | ||
@@ -126,7 +125,6 @@ return async (c, next) => { | ||
const getGraphQLParams = async (request) => { | ||
var _a, _b, _c; | ||
const urlData = new URLSearchParams(request.url.split('?')[1]); | ||
const bodyData = await (0, parse_body_1.parseBody)(request); | ||
// GraphQL Query string. | ||
let query = (_a = urlData.get('query')) !== null && _a !== void 0 ? _a : bodyData.query; | ||
let query = urlData.get('query') ?? bodyData.query; | ||
if (typeof query !== 'string') { | ||
@@ -136,3 +134,3 @@ query = null; | ||
// Parse the variables if needed. | ||
let variables = ((_b = urlData.get('variables')) !== null && _b !== void 0 ? _b : bodyData.variables); | ||
let variables = (urlData.get('variables') ?? bodyData.variables); | ||
if (typeof variables === 'string') { | ||
@@ -142,3 +140,3 @@ try { | ||
} | ||
catch (_d) { | ||
catch { | ||
throw Error('Variables are invalid JSON.'); | ||
@@ -151,3 +149,3 @@ } | ||
// Name of GraphQL operation to execute. | ||
let operationName = (_c = urlData.get('operationName')) !== null && _c !== void 0 ? _c : bodyData.operationName; | ||
let operationName = urlData.get('operationName') ?? bodyData.operationName; | ||
if (typeof operationName !== 'string') { | ||
@@ -154,0 +152,0 @@ operationName = null; |
@@ -13,5 +13,5 @@ "use strict"; | ||
ctx.res = new Response('Unauthorized', { | ||
status: 401, | ||
status: 400, | ||
headers: { | ||
'WWW-Authenticate': 'Basic ${options.secret}', | ||
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="no authorization included in request"`, | ||
}, | ||
@@ -24,5 +24,5 @@ }); | ||
ctx.res = new Response('Unauthorized', { | ||
status: 401, | ||
status: 400, | ||
headers: { | ||
'WWW-Authenticate': 'Basic ${options.secret}', | ||
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="no authorization included in request"`, | ||
}, | ||
@@ -45,3 +45,3 @@ }); | ||
headers: { | ||
'WWW-Authenticate': 'Bearer ${options.secret}', | ||
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_token",error_description="token verification failure"`, | ||
}, | ||
@@ -48,0 +48,0 @@ }); |
@@ -11,3 +11,3 @@ "use strict"; | ||
// Do nothing if Response is already set | ||
if (c.res && c.res._finalized) { | ||
if (c.res && c.finalized) { | ||
await next(); | ||
@@ -14,0 +14,0 @@ } |
@@ -14,8 +14,8 @@ import type { Result } from '../../router'; | ||
name: string; | ||
handlerSetCache: Record<string, HandlerSet<T>[]>; | ||
constructor(method?: string, handler?: T, children?: Record<string, Node<T>>); | ||
insert(method: string, path: string, handler: T): Node<T>; | ||
private getHandlerSets; | ||
private next; | ||
search(method: string, path: string): Result<T> | null; | ||
} | ||
export {}; |
@@ -31,2 +31,3 @@ "use strict"; | ||
this.patterns = []; | ||
this.handlerSetCache = {}; | ||
} | ||
@@ -86,69 +87,22 @@ insert(method, path, handler) { | ||
getHandlerSets(node, method, wildcard) { | ||
const handlerSets = []; | ||
node.methods.map((m) => { | ||
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL]; | ||
if (handlerSet !== undefined) { | ||
const hs = Object.assign({}, handlerSet); | ||
if (wildcard) { | ||
hs.score = handlerSet.score - 1; | ||
} | ||
handlerSets.push(hs); | ||
return; | ||
} | ||
}); | ||
return handlerSets; | ||
} | ||
next(node, part, method, isLast) { | ||
const handlerSets = []; | ||
const nextNodes = []; | ||
const params = {}; | ||
for (let j = 0, len = node.patterns.length; j < len; j++) { | ||
const pattern = node.patterns[j]; | ||
// Wildcard | ||
// '/hello/*/foo' => match /hello/bar/foo | ||
if (pattern === '*') { | ||
const astNode = node.children['*']; | ||
if (astNode) { | ||
handlerSets.push(...this.getHandlerSets(astNode, method)); | ||
nextNodes.push(astNode); | ||
} | ||
} | ||
if (part === '') | ||
continue; | ||
// Named match | ||
// `/posts/:id` => match /posts/123 | ||
const [key, name, matcher] = pattern; | ||
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) { | ||
if (typeof key === 'string') { | ||
if (isLast === true) { | ||
handlerSets.push(...this.getHandlerSets(node.children[key], method)); | ||
var _a, _b; | ||
return ((_a = node.handlerSetCache)[_b = `${method}:${wildcard ? '1' : '0'}`] || (_a[_b] = (() => { | ||
const handlerSets = []; | ||
node.methods.map((m) => { | ||
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL]; | ||
if (handlerSet !== undefined) { | ||
const hs = { ...handlerSet }; | ||
if (wildcard) { | ||
hs.score = handlerSet.score - 1; | ||
} | ||
nextNodes.push(node.children[key]); | ||
handlerSets.push(hs); | ||
return; | ||
} | ||
if (typeof name === 'string') { | ||
params[name] = part; | ||
} | ||
} | ||
} | ||
const nextNode = node.children[part]; | ||
if (nextNode) { | ||
if (isLast === true) { | ||
// '/hello/*' => match '/hello' | ||
if (nextNode.children['*']) { | ||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true)); | ||
} | ||
handlerSets.push(...this.getHandlerSets(nextNode, method)); | ||
} | ||
nextNodes.push(nextNode); | ||
} | ||
const next = { | ||
nodes: nextNodes, | ||
handlerSets: handlerSets, | ||
params: params, | ||
}; | ||
return next; | ||
}); | ||
return handlerSets; | ||
})())); | ||
} | ||
search(method, path) { | ||
const handlerSets = []; | ||
let params = {}; | ||
const params = {}; | ||
// eslint-disable-next-line @typescript-eslint/no-this-alias | ||
@@ -159,13 +113,47 @@ const curNode = this; | ||
for (let i = 0, len = parts.length; i < len; i++) { | ||
const p = parts[i]; | ||
const part = parts[i]; | ||
const isLast = i === len - 1; | ||
const tempNodes = []; | ||
for (let j = 0, len2 = curNodes.length; j < len2; j++) { | ||
const res = this.next(curNodes[j], p, method, isLast); | ||
if (res.nodes.length === 0) { | ||
continue; | ||
const node = curNodes[j]; | ||
for (let k = 0, len3 = node.patterns.length; k < len3; k++) { | ||
const pattern = node.patterns[k]; | ||
// Wildcard | ||
// '/hello/*/foo' => match /hello/bar/foo | ||
if (pattern === '*') { | ||
const astNode = node.children['*']; | ||
if (astNode) { | ||
handlerSets.push(...this.getHandlerSets(astNode, method)); | ||
tempNodes.push(astNode); | ||
} | ||
continue; | ||
} | ||
if (part === '') | ||
continue; | ||
// Named match | ||
// `/posts/:id` => match /posts/123 | ||
const [key, name, matcher] = pattern; | ||
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) { | ||
if (typeof key === 'string') { | ||
if (isLast === true) { | ||
handlerSets.push(...this.getHandlerSets(node.children[key], method)); | ||
} | ||
tempNodes.push(node.children[key]); | ||
} | ||
if (typeof name === 'string') { | ||
params[name] = part; | ||
} | ||
} | ||
} | ||
handlerSets.push(...res.handlerSets); | ||
params = Object.assign(params, res.params); | ||
tempNodes.push(...res.nodes); | ||
const nextNode = node.children[part]; | ||
if (nextNode) { | ||
if (isLast === true) { | ||
// '/hello/*' => match '/hello' | ||
if (nextNode.children['*']) { | ||
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true)); | ||
} | ||
handlerSets.push(...this.getHandlerSets(nextNode, method)); | ||
} | ||
tempNodes.push(nextNode); | ||
} | ||
} | ||
@@ -172,0 +160,0 @@ curNodes = tempNodes; |
@@ -13,3 +13,3 @@ "use strict"; | ||
} | ||
catch (_a) { } | ||
catch { } | ||
try { | ||
@@ -34,3 +34,3 @@ return Buffer.from(str).toString('base64'); | ||
} | ||
catch (_a) { } | ||
catch { } | ||
try { | ||
@@ -37,0 +37,0 @@ return Buffer.from(str, 'base64').toString(); |
export declare type Pattern = readonly [string, string, RegExp | true] | '*'; | ||
export declare const splitPath: (path: string) => string[]; | ||
export declare const getPattern: (label: string) => Pattern | null; | ||
declare type Params = { | ||
strict: boolean; | ||
}; | ||
export declare const getPathFromURL: (url: string, params?: Params) => string; | ||
export declare const getPathFromURL: (url: string, strict?: boolean) => string; | ||
export declare const isAbsoluteURL: (url: string) => boolean; | ||
export declare const mergePath: (...paths: string[]) => string; | ||
export {}; |
@@ -37,13 +37,11 @@ "use strict"; | ||
exports.getPattern = getPattern; | ||
const getPathFromURL = (url, params = { strict: true }) => { | ||
const getPathFromURL = (url, strict = true) => { | ||
const queryIndex = url.indexOf('?'); | ||
const result = url.substring(url.indexOf('/', 8), queryIndex === -1 ? url.length : queryIndex); | ||
// if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same | ||
// default is true | ||
if (params.strict === false && url.endsWith('/')) { | ||
url = url.slice(0, -1); | ||
if (strict === false && result.endsWith('/')) { | ||
return result.slice(0, -1); | ||
} | ||
const match = url.match(URL_REGEXP); | ||
if (match) { | ||
return match[1]; | ||
} | ||
return ''; | ||
return result; | ||
}; | ||
@@ -50,0 +48,0 @@ exports.getPathFromURL = getPathFromURL; |
{ | ||
"name": "hono", | ||
"version": "1.4.2", | ||
"version": "1.4.3", | ||
"description": "Ultrafast web framework for Cloudflare Workers.", | ||
@@ -136,3 +136,3 @@ "main": "dist/index.js", | ||
"jest": "27.5.1", | ||
"jest-environment-miniflare": "^2.4.0", | ||
"jest-environment-miniflare": "^2.5.0", | ||
"mustache": "^4.2.0", | ||
@@ -139,0 +139,0 @@ "prettier": "^2.6.2", |
@@ -41,9 +41,9 @@ <div align="center"> | ||
```plain | ||
hono - trie-router(default) x 724,143 ops/sec ±3.63% (80 runs sampled) | ||
hono - regexp-router x 1,236,810 ops/sec ±6.77% (72 runs sampled) | ||
itty-router x 161,786 ops/sec ±2.28% (97 runs sampled) | ||
sunder x 312,262 ops/sec ±2.59% (85 runs sampled) | ||
worktop x 224,979 ops/sec ±1.13% (96 runs sampled) | ||
hono - trie-router(default) x 389,510 ops/sec ±3.16% (85 runs sampled) | ||
hono - regexp-router x 452,290 ops/sec ±2.64% (84 runs sampled) | ||
itty-router x 206,013 ops/sec ±3.39% (90 runs sampled) | ||
sunder x 323,131 ops/sec ±0.75% (97 runs sampled) | ||
worktop x 191,218 ops/sec ±2.70% (91 runs sampled) | ||
Fastest is hono - regexp-router | ||
✨ Done in 95.05s. | ||
✨ Done in 43.56s. | ||
``` | ||
@@ -102,3 +102,3 @@ | ||
v1.get('/posts', (c) => { | ||
return c.text('list pots') | ||
return c.text('list posts') | ||
}) | ||
@@ -649,3 +649,3 @@ .post(basicAuth({ username, password }), (c) => { | ||
To generate a project skelton, run this command. | ||
To generate a project skeleton, run this command. | ||
@@ -652,0 +652,0 @@ ``` |
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
1
123972
2768