Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hono

Package Overview
Dependencies
Maintainers
1
Versions
343
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hono - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

dist/middleware/jwt/index.d.ts

6

dist/context.d.ts

@@ -8,2 +8,3 @@ /// <reference types="@cloudflare/workers-types" />

export declare class Context<RequestParamKeyType = string> {
#private;
req: Request<RequestParamKeyType>;

@@ -13,7 +14,2 @@ res: Response;

event: FetchEvent;
private _headers;
private _status;
private _statusText;
private _pretty;
private _prettySpace;
render: (template: string, params?: object, options?: object) => Promise<Response>;

@@ -20,0 +16,0 @@ notFound: () => Response | Promise<Response>;

"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Context_headers, _Context_status, _Context_statusText, _Context_pretty, _Context_prettySpace;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -8,6 +20,10 @@ exports.Context = void 0;

constructor(req, opts) {
this._prettySpace = 2;
_Context_headers.set(this, void 0);
_Context_status.set(this, void 0);
_Context_statusText.set(this, void 0);
_Context_pretty.set(this, void 0);
_Context_prettySpace.set(this, 2);
this.req = this.initRequest(req);
Object.assign(this, opts);
this._headers = {};
__classPrivateFieldSet(this, _Context_headers, {}, "f");
}

@@ -28,3 +44,3 @@ initRequest(req) {

}
this._headers[name] = value;
__classPrivateFieldGet(this, _Context_headers, "f")[name] = value;
}

@@ -36,29 +52,17 @@ status(status) {

}
this._status = status;
this._statusText = (0, http_status_1.getStatusText)(status);
__classPrivateFieldSet(this, _Context_status, status, "f");
__classPrivateFieldSet(this, _Context_statusText, (0, http_status_1.getStatusText)(status), "f");
}
pretty(prettyJSON, space = 2) {
this._pretty = prettyJSON;
this._prettySpace = space;
__classPrivateFieldSet(this, _Context_pretty, prettyJSON, "f");
__classPrivateFieldSet(this, _Context_prettySpace, space, "f");
}
newResponse(data, init = {}) {
init.status = init.status || this._status || 200;
init.status = init.status || __classPrivateFieldGet(this, _Context_status, "f") || 200;
init.statusText =
init.statusText || this._statusText || (0, http_status_1.getStatusText)(init.status);
init.headers = Object.assign(Object.assign({}, this._headers), init.headers);
// Content-Length
let length = 0;
if (data) {
if (data instanceof ArrayBuffer) {
length = data.byteLength;
}
else if (typeof data == 'string') {
const Encoder = new TextEncoder();
length = Encoder.encode(data).byteLength || 0;
}
}
init.headers = Object.assign(Object.assign({}, init.headers), { 'Content-Length': length.toString() });
init.statusText || __classPrivateFieldGet(this, _Context_statusText, "f") || (0, http_status_1.getStatusText)(init.status);
init.headers = Object.assign(Object.assign({}, __classPrivateFieldGet(this, _Context_headers, "f")), init.headers);
return new Response(data, init);
}
body(data, status = this._status, headers = this._headers) {
body(data, status = __classPrivateFieldGet(this, _Context_status, "f"), headers = __classPrivateFieldGet(this, _Context_headers, "f")) {
return this.newResponse(data, {

@@ -69,3 +73,3 @@ status: status,

}
text(text, status = this._status, headers = {}) {
text(text, status = __classPrivateFieldGet(this, _Context_status, "f"), headers = {}) {
if (typeof text !== 'string') {

@@ -77,8 +81,8 @@ throw new TypeError('text method arg must be a string!');

}
json(object, status = this._status, headers = {}) {
json(object, status = __classPrivateFieldGet(this, _Context_status, "f"), headers = {}) {
if (typeof object !== 'object') {
throw new TypeError('json method arg must be an object!');
}
const body = this._pretty
? JSON.stringify(object, null, this._prettySpace)
const body = __classPrivateFieldGet(this, _Context_pretty, "f")
? JSON.stringify(object, null, __classPrivateFieldGet(this, _Context_prettySpace, "f"))
: JSON.stringify(object);

@@ -88,3 +92,3 @@ headers['Content-Type'] || (headers['Content-Type'] = 'application/json; charset=UTF-8');

}
html(html, status = this._status, headers = {}) {
html(html, status = __classPrivateFieldGet(this, _Context_status, "f"), headers = {}) {
if (typeof html !== 'string') {

@@ -114,1 +118,2 @@ throw new TypeError('html method arg must be a string!');

exports.Context = Context;
_Context_headers = new WeakMap(), _Context_status = new WeakMap(), _Context_statusText = new WeakMap(), _Context_pretty = new WeakMap(), _Context_prettySpace = new WeakMap();

@@ -10,6 +10,5 @@ /// <reference types="@cloudflare/workers-types" />

header: (name: string) => string;
parsedBody: any;
}
}
export declare type Handler<RequestParamKeyType = string> = (c: Context<RequestParamKeyType | string>, next?: Next) => Response | Promise<Response>;
export declare type Handler<RequestParamKeyType = string> = (c: Context<RequestParamKeyType>, next?: Next) => Response | Promise<Response>;
export declare type MiddlewareHandler = (c: Context, next: Next) => Promise<void>;

@@ -22,15 +21,18 @@ export declare type NotFoundHandler = (c: Context) => Response | Promise<Response>;

declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
declare const Hono_base: new () => {
delete: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
get: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
post: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
put: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
head: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
options: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
patch: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
all: <Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>) => Hono;
} & {
methods: ["get", "post", "put", "delete", "head", "options", "patch", "all"];
interface HandlerInterface<T extends string> {
<Path extends string>(path: Path, handler: Handler<ParamKeys<Path>>): Hono<Path>;
<Path extends T>(handler: Handler<ParamKeys<T>>): Hono<Path>;
}
declare const Hono_base: new <T extends string>() => {
delete: HandlerInterface<T>;
get: HandlerInterface<T>;
post: HandlerInterface<T>;
put: HandlerInterface<T>;
head: HandlerInterface<T>;
options: HandlerInterface<T>;
patch: HandlerInterface<T>;
all: HandlerInterface<T>;
};
export declare class Hono extends Hono_base {
export declare class Hono<P extends string> extends Hono_base<P> {
#private;
readonly routerClass: {

@@ -40,12 +42,11 @@ new (): Router<any>;

readonly strict: boolean;
private router;
private middlewareRouters;
private tempPath;
constructor(init?: Partial<Pick<Hono, 'routerClass' | 'strict'>>);
private path;
constructor(init?: Partial<Pick<Hono<P>, 'routerClass' | 'strict'>>);
private notFoundHandler;
private errorHandler;
route(path: string): Hono;
use(path: string, middleware: MiddlewareHandler): void;
onError(handler: ErrorHandler): Hono;
notFound(handler: NotFoundHandler): Hono;
route(path: string): Hono<P>;
use(path: string, middleware: MiddlewareHandler): Hono<P>;
use(middleware: MiddlewareHandler): Hono<P>;
onError(handler: ErrorHandler): Hono<P>;
notFound(handler: NotFoundHandler): Hono<P>;
private addRoute;

@@ -52,0 +53,0 @@ private matchRoute;

"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Hono_router, _Hono_middlewareRouters, _Hono_tempPath;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -9,10 +21,8 @@ exports.Hono = void 0;

const url_1 = require("./utils/url");
function defineDynamicClass(...methods) {
const methods = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch', 'all'];
function defineDynamicClass() {
return class {
get methods() {
return methods;
}
};
}
class Hono extends defineDynamicClass('get', 'post', 'put', 'delete', 'head', 'options', 'patch', 'all') {
class Hono extends defineDynamicClass() {
constructor(init = {}) {

@@ -22,2 +32,5 @@ super();

this.strict = true; // strict routing - default is true
_Hono_router.set(this, void 0);
_Hono_middlewareRouters.set(this, void 0);
_Hono_tempPath.set(this, void 0);
this.notFoundHandler = (c) => {

@@ -32,25 +45,38 @@ const message = '404 Not Found';

};
this.methods.map((method) => {
this[method] = (path, handler) => {
return this.addRoute(method, path, handler);
methods.map((method) => {
this[method] = (arg1, arg2) => {
if (typeof arg1 === 'string') {
this.path = arg1;
return this.addRoute(method, this.path, arg2);
}
return this.addRoute(method, this.path, arg1);
};
});
Object.assign(this, init);
this.router = new this.routerClass();
this.middlewareRouters = [];
this.tempPath = null;
__classPrivateFieldSet(this, _Hono_router, new this.routerClass(), "f");
__classPrivateFieldSet(this, _Hono_middlewareRouters, [], "f");
__classPrivateFieldSet(this, _Hono_tempPath, null, "f");
}
route(path) {
const newHono = new Hono();
newHono.tempPath = path;
newHono.router = this.router;
__classPrivateFieldSet(newHono, _Hono_tempPath, path, "f");
__classPrivateFieldSet(newHono, _Hono_router, __classPrivateFieldGet(this, _Hono_router, "f"), "f");
return newHono;
}
use(path, middleware) {
if (middleware.constructor.name !== 'AsyncFunction') {
use(arg1, arg2) {
let handler;
if (typeof arg1 === 'string') {
this.path = arg1;
handler = arg2;
}
else {
handler = arg1;
}
if (handler.constructor.name !== 'AsyncFunction') {
throw new TypeError('middleware must be a async function!');
}
const router = new this.routerClass();
router.add(router_1.METHOD_NAME_OF_ALL, path, middleware);
this.middlewareRouters.push(router);
router.add(router_1.METHOD_NAME_OF_ALL, this.path, handler);
__classPrivateFieldGet(this, _Hono_middlewareRouters, "f").push(router);
return this;
}

@@ -65,13 +91,12 @@ onError(handler) {

}
// addRoute('get', '/', handler)
addRoute(method, path, handler) {
method = method.toUpperCase();
if (this.tempPath) {
path = (0, url_1.mergePath)(this.tempPath, path);
if (__classPrivateFieldGet(this, _Hono_tempPath, "f")) {
path = (0, url_1.mergePath)(__classPrivateFieldGet(this, _Hono_tempPath, "f"), path);
}
this.router.add(method, path, handler);
__classPrivateFieldGet(this, _Hono_router, "f").add(method, path, handler);
return this;
}
async matchRoute(method, path) {
return this.router.match(method, path);
return __classPrivateFieldGet(this, _Hono_router, "f").match(method, path);
}

@@ -89,3 +114,3 @@ async dispatch(request, env, event) {

const middleware = [];
for (const mr of this.middlewareRouters) {
for (const mr of __classPrivateFieldGet(this, _Hono_middlewareRouters, "f")) {
const mwResult = mr.match(router_1.METHOD_NAME_OF_ALL, path);

@@ -127,1 +152,2 @@ if (mwResult)

exports.Hono = Hono;
_Hono_router = new WeakMap(), _Hono_middlewareRouters = new WeakMap(), _Hono_tempPath = new WeakMap();

@@ -5,3 +5,3 @@ "use strict";

const buffer_1 = require("../../utils/buffer");
const crypto_1 = require("../../utils/crypto");
const encode_1 = require("../../utils/encode");
const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;

@@ -23,3 +23,3 @@ const USER_PASS_REGEXP = /^([^:]*):(.*)$/;

}
const userPass = USER_PASS_REGEXP.exec((0, crypto_1.decodeBase64)(match[1]));
const userPass = USER_PASS_REGEXP.exec((0, encode_1.decodeBase64)(match[1]));
if (!userPass) {

@@ -26,0 +26,0 @@ return undefined;

import type { Context } from '../../context';
import type { Next } from '../../hono';
declare global {
interface Request {
parsedBody: any;
}
}
export declare const bodyParse: () => (ctx: Context, next: Next) => Promise<void>;

@@ -13,5 +13,3 @@ import type { Context } from '../../context';

}
export declare type Cookie = {
[key: string]: string;
};
export declare type Cookie = Record<string, string>;
export declare type CookieOptions = {

@@ -18,0 +16,0 @@ domain?: string;

@@ -1,3 +0,1 @@

export declare function parseBody(req: Request): Promise<{
[param: string]: unknown;
}>;
export declare function parseBody(req: Request): Promise<Record<string, unknown>>;

@@ -34,6 +34,6 @@ "use strict";

};
function log(fn, prefix, method, path, status, elapsed, contentLength) {
function log(fn, prefix, method, path, status, elapsed) {
const out = prefix === LogPrefix.Incoming
? ` ${prefix} ${method} ${path}`
: ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed} ${contentLength}`;
: ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
fn(out);

@@ -48,7 +48,5 @@ }

await next();
const len = parseFloat(c.res.headers.get('Content-Length'));
const contentLength = isNaN(len) ? '0' : len < 1024 ? `${len}b` : `${len / 1024}kB`;
log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start), contentLength);
log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start));
};
};
exports.logger = logger;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mustache = void 0;
const buffer_1 = require("../../utils/buffer");
const cloudflare_1 = require("../../utils/cloudflare");

@@ -27,3 +28,3 @@ const EXTENSION = '.mustache';

}
const content = bufferToString(buffer);
const content = (0, buffer_1.bufferToString)(buffer);
const partialArgs = {};

@@ -42,3 +43,3 @@ if (options) {

}
partialArgs[key] = bufferToString(partialBuffer);
partialArgs[key] = (0, buffer_1.bufferToString)(partialBuffer);
}

@@ -53,8 +54,1 @@ }

exports.mustache = mustache;
const bufferToString = (buffer) => {
if (buffer instanceof ArrayBuffer) {
const enc = new TextDecoder('utf-8');
return enc.decode(buffer);
}
return buffer;
};
export declare const equal: (a: ArrayBuffer, b: ArrayBuffer) => boolean;
export declare const timingSafeEqual: (a: string | object | boolean, b: string | object | boolean, hashFunction?: Function) => Promise<boolean>;
export declare const bufferToString: (buffer: ArrayBuffer) => string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.timingSafeEqual = exports.equal = void 0;
exports.bufferToString = exports.timingSafeEqual = exports.equal = void 0;
const crypto_1 = require("../utils/crypto");

@@ -32,1 +32,9 @@ const equal = (a, b) => {

exports.timingSafeEqual = timingSafeEqual;
const bufferToString = (buffer) => {
if (buffer instanceof ArrayBuffer) {
const enc = new TextDecoder('utf-8');
return enc.decode(buffer);
}
return buffer;
};
exports.bufferToString = bufferToString;

@@ -9,4 +9,2 @@ declare type Algorithm = {

export declare const createHash: (data: Data, algorithm: Algorithm) => Promise<string>;
export declare const encodeBase64: (str: string) => string;
export declare const decodeBase64: (str: string) => string;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeBase64 = exports.encodeBase64 = exports.createHash = exports.sha1 = exports.sha256 = void 0;
exports.createHash = exports.sha1 = exports.sha256 = void 0;
const sha256 = async (data) => {

@@ -37,51 +37,1 @@ const algorithm = { name: 'SHA-256', alias: 'sha256' };

exports.createHash = createHash;
const encodeBase64 = (str) => {
if (str === null) {
throw new TypeError('1st argument of "encodeBase64" should not be null.');
}
try {
const encoder = new TextEncoder();
const bytes = encoder.encode(str);
const length = bytes.byteLength;
let binary = '';
for (let i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
catch (_a) { }
try {
const { Buffer } = require('buffer');
return Buffer.from(str).toString('base64');
}
catch (e) {
console.error('If you want to do "encodeBase64", polyfill "buffer" module.');
throw e;
}
};
exports.encodeBase64 = encodeBase64;
const decodeBase64 = (str) => {
if (str === null) {
throw new TypeError('1st argument of "decodeBase64" should not be null.');
}
try {
const text = atob(str);
const length = text.length;
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = text.charCodeAt(i);
}
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
catch (_a) { }
try {
const { Buffer } = require('buffer');
return Buffer.from(str, 'base64').toString();
}
catch (e) {
console.error('If you want to do "decodeBase64", polyfill "buffer" module.');
throw e;
}
};
exports.decodeBase64 = decodeBase64;
{
"name": "hono",
"version": "1.0.0",
"version": "1.1.0",
"description": "Ultrafast web framework for Cloudflare Workers.",

@@ -26,2 +26,3 @@ "main": "dist/index.js",

"./graphql-server": "./dist/middleware/graphql-server/index.js",
"./jwt": "./dist/middleware/jwt/index.js",
"./logger": "./dist/middleware/logger/index.js",

@@ -56,2 +57,5 @@ "./mustache": "./dist/middleware/mustache/index.js",

],
"jwt": [
"./dist/middleware/jwt"
],
"logger": [

@@ -87,5 +91,5 @@ "./dist/middleware/logger"

"type": "git",
"url": "https://github.com/yusukebe/hono.git"
"url": "https://github.com/honojs/hono.git"
},
"homepage": "https://github.com/yusukebe/hono",
"homepage": "https://github.com/honojs/hono",
"keywords": [

@@ -104,29 +108,29 @@ "web",

"devDependencies": {
"@cloudflare/workers-types": "^3.3.0",
"@cloudflare/workers-types": "^3.7.1",
"@types/crypto-js": "^4.1.1",
"@types/jest": "^27.4.0",
"@types/jest": "^27.4.1",
"@types/mustache": "^4.1.2",
"@types/node": "^17.0.8",
"@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.9.0",
"@types/node": "^17.0.29",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"crypto-js": "^4.1.1",
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"eslint-define-config": "^1.2.1",
"eslint-import-resolver-typescript": "^2.0.0",
"eslint": "^8.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-define-config": "^1.4.0",
"eslint-import-resolver-typescript": "^2.7.1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-flowtype": "^5.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"form-data": "^4.0.0",
"graphql": "^16.3.0",
"jest": "^27.4.5",
"jest-environment-miniflare": "^2.0.0",
"graphql": "^16.4.0",
"jest": "27.5.1",
"jest-environment-miniflare": "^2.4.0",
"mustache": "^4.2.0",
"prettier": "^2.5.1",
"prettier": "^2.6.2",
"prettier-plugin-md-nocjsp": "^1.2.0",
"rimraf": "^3.0.2",
"ts-jest": "^27.1.2",
"tsc-alias": "^1.6.6",
"typescript": "^4.5.5"
"ts-jest": "^27.1.4",
"tsc-alias": "^1.6.7",
"typescript": "^4.6.3"
},

@@ -133,0 +137,0 @@ "engines": {

<div align="center">
<a href="https://github.com/yusukebe/hono">
<img src="https://raw.githubusercontent.com/yusukebe/hono/master/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
<a href="https://github.com/honojs/hono">
<img src="https://raw.githubusercontent.com/honojs/hono/master/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
</a>

@@ -10,16 +10,16 @@ </div>

<p>
<a href="https://github.com/yusukebe/hono/blob/master/README.md">English</a>
<a href="https://github.com/honojs/hono/blob/master/README.md">English</a>
&#x000B7;
<a href="https://github.com/yusukebe/hono/blob/master/docs/README.ja.md">日本語</a>
<a href="https://github.com/honojs/hono/blob/master/docs/README.ja.md">日本語</a>
</p>
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/yusukebe/hono/ci)](https://github.com/yusukebe/hono/actions)
[![GitHub](https://img.shields.io/github/license/yusukebe/hono)](https://github.com/yusukebe/hono/blob/master/LICENSE)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/honojs/hono/ci)](https://github.com/honojs/hono/actions)
[![GitHub](https://img.shields.io/github/license/honojs/hono)](https://github.com/honojs/hono/blob/master/LICENSE)
[![npm](https://img.shields.io/npm/v/hono)](https://www.npmjs.com/package/hono)
[![npm](https://img.shields.io/npm/dm/hono)](https://www.npmjs.com/package/hono)
[![npm type definitions](https://img.shields.io/npm/types/hono)](https://www.npmjs.com/package/hono)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/yusukebe/hono)](https://github.com/yusukebe/hono/pulse)
[![GitHub last commit](https://img.shields.io/github/last-commit/yusukebe/hono)](https://github.com/yusukebe/hono/commits/master)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
[![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/master)
Hono - _**[炎] means flame🔥 in Japanese**_ - is small, simple, and ultrafast web framework for Cloudflare Workers and Fastly Compute@Edge.
Hono - _**[炎] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for Cloudflare Workers and Service Worker based serverless such as Fastly Compute@Edge.

@@ -41,3 +41,3 @@ ```js

- **TypeScript** - first-class TypeScript support.
- **Optimized** - for Cloudflare Workers.
- **Optimized** - for Cloudflare Workers and Fastly Compute@Edge.

@@ -63,4 +63,39 @@ ## Benchmark

Now, the named path parameter has types.
## Not only fast
Hono is fast. But not only fast.
### Write Less, do more
Built-in middleware make _"**Write Less, do more**"_ in reality. You can use a lot of middleware without writing code from scratch. Below are examples.
- [Basic Authentication](https://github.com/honojs/hono/tree/master/src/middleware/basic-auth/)
- [Cookie parsing / serializing](https://github.com/honojs/hono/tree/master/src/middleware/cookie/)
- [CORS](https://github.com/honojs/hono/tree/master/src/middleware/cors/)
- [ETag](https://github.com/honojs/hono/tree/master/src/middleware/etag/)
- [GraphQL Server](https://github.com/honojs/hono/tree/master/src/middleware/graphql-server/)
- [JWT Authentication](https://github.com/honojs/hono/tree/master/src/middleware/jwt/)
- [Logger](https://github.com/honojs/hono/tree/master/src/middleware/logger/)
- [Mustache template engine](https://github.com/honojs/hono/tree/master/src/middleware/mustache/) (Only for Cloudflare Workers)
- [JSON pretty printing](https://github.com/honojs/hono/tree/master/src/middleware/pretty-json/)
- [Serving static files](https://github.com/honojs/hono/tree/master/src/middleware/serve-static/) (Only for Cloudflare Workers)
You can enable logger and CORS middleware with just this code.
```js
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
const app = new Hono()
app.use('*', cors()).use(logger())
```
### Developer Experience
And Hono provides fine _"**Developer Experience**"_. Easy access to Request/Response thanks to the `Context` object.
Above all, Hono is written in TypeScript. So, Hono has _"**Types**"_!
For example, the named path parameters will be literal types.
![Demo](https://user-images.githubusercontent.com/10682/154179671-9e491597-6778-44ac-a8e6-4483d7ad5393.png)

@@ -86,6 +121,6 @@

- app.**HTTP_METHOD**(path, handler)
- app.**all**(path, handler)
- app.**HTTP_METHOD**(\[path,\] handler)
- app.**all**(\[path,\] handler)
- app.**route**(path)
- app.**use**(path, middleware)
- app.**use**(\[path,\] middleware)
- app.**notFound**(handler)

@@ -134,2 +169,17 @@ - app.**onError**(err, handler)

### Chained route
```js
app
.get('/endpoint', (c) => {
return c.text('GET /endpoint')
})
.post((c) => {
return c.text('POST /endpoint')
})
.delete((c) => {
return c.text('DELETE /endpoint')
})
```
### Nested route

@@ -183,2 +233,5 @@

app.use('*', logger())
// Or you can write:
// app.use('*', poweredBy()).use(logger())
app.use(

@@ -193,3 +246,3 @@ '/auth/*',

Available built-in middleware is listed on [src/middleware](https://github.com/yusukebe/hono/tree/master/src/middleware).
Available built-in middleware is listed on [src/middleware](https://github.com/honojs/hono/tree/master/src/middleware).

@@ -429,3 +482,3 @@ ### Custom Middleware

1. Use [Wragler 2.0 Beta](https://github.com/cloudflare/wrangler2).
2. Build without webpack 4.x. For example, you can use esbuild. See [the starter template](https://github.com/yusukebe/hono-minimal).
2. Build without webpack 4.x. For example, you can use esbuild. See [the starter template](https://github.com/honojs/hono-minimal).

@@ -500,3 +553,3 @@ ---

You can start making your Cloudflare Workers application with [the starter template](https://github.com/yusukebe/hono-minimal). It is really minimal using TypeScript, esbuild, and Miniflare.
You can start making your Cloudflare Workers application with [the starter template](https://github.com/honojs/hono-minimal). It is really minimal using TypeScript, esbuild, Miniflare, and Jest.

@@ -506,5 +559,9 @@ To generate a project skelton, run this command.

```sh
wrangler generate my-app https://github.com/yusukebe/hono-minimal
wrangler generate my-app https://github.com/honojs/hono-minimal
```
## Examples
- Hono Examples - <https://github.com/honojs/examples>
## Related projects

@@ -514,13 +571,13 @@

- express <https://github.com/expressjs/express>
- koa <https://github.com/koajs/koa>
- itty-router <https://github.com/kwhitley/itty-router>
- Sunder <https://github.com/SunderJS/sunder>
- goblin <https://github.com/bmf-san/goblin>
- worktop <https://github.com/lukeed/worktop>
- Router::Boom <https://github.com/tokuhirom/Router-Boom>
- express - <https://github.com/expressjs/express>
- koa - <https://github.com/koajs/koa>
- itty-router - <https://github.com/kwhitley/itty-router>
- Sunder - <https://github.com/SunderJS/sunder>
- goblin - <https://github.com/bmf-san/goblin>
- worktop - <https://github.com/lukeed/worktop>
- Router::Boom - <https://github.com/tokuhirom/Router-Boom>
## Contributing
Contributions Welcome! You can contribute by the following way.
Contributions Welcome! You can contribute in the following ways.

@@ -533,7 +590,5 @@ - Write or fix documents

Let's make Hono together!
## Contributors
Thanks to [all contributors](https://github.com/yusukebe/hono/graphs/contributors)!
Thanks to [all contributors](https://github.com/honojs/hono/graphs/contributors)!

@@ -540,0 +595,0 @@ ## Author

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc