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

hono

Package Overview
Dependencies
Maintainers
1
Versions
340
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 0.0.12 to 0.0.13

dist/middleware/body-parse/body-parse.d.ts

22

dist/context.d.ts

@@ -0,9 +1,23 @@

/// <reference types="@cloudflare/workers-types" />
declare type Headers = {
[key: string]: string;
};
export interface Env {
}
export declare class Context {
req: Request;
res: Response;
constructor(req: Request, res: Response);
env: Env;
event: FetchEvent;
constructor(req: Request, opts?: {
res: Response;
env: Env;
event: FetchEvent;
});
newResponse(body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
text(body: string): Response;
json(object: object, replacer?: (string | number)[], space?: string | number): Response;
html(body: string): Response;
text(text: string, status?: number, headers?: Headers): Response;
json(object: object, status?: number, headers?: Headers): Response;
html(html: string, status?: number, headers?: Headers): Response;
redirect(location: string, status?: number): Response;
}
export {};

58

dist/context.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Context = void 0;
const util_1 = require("./util");
class Context {
constructor(req, res) {
constructor(req, opts) {
this.req = req;
this.res = res;
if (opts) {
this.res = opts.res;
this.env = opts.env;
this.event = opts.event;
}
}

@@ -12,33 +17,46 @@ newResponse(body, init) {

}
text(body) {
if (typeof body !== 'string') {
text(text, status = 200, headers = {}) {
if (typeof text !== 'string') {
throw new TypeError('text method arg must be a string!');
}
return this.newResponse(body, {
status: 200,
headers: {
'Content-Type': 'text/plain',
},
headers['Content-Type'] = 'text/plain';
return this.newResponse(text, {
status: status,
headers: headers,
});
}
json(object, replacer, space) {
json(object, status = 200, headers = {}) {
if (typeof object !== 'object') {
throw new TypeError('json method arg must be a object!');
}
const body = JSON.stringify(object, replacer, space);
const body = JSON.stringify(object);
headers['Content-Type'] = 'application/json; charset=UTF-8';
return this.newResponse(body, {
status: 200,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
status: status,
headers: headers,
});
}
html(body) {
if (typeof body !== 'string') {
html(html, status = 200, headers = {}) {
if (typeof html !== 'string') {
throw new TypeError('html method arg must be a string!');
}
return this.newResponse(body, {
status: 200,
headers['Content-Type'] = 'text/html; charset=UTF-8';
return this.newResponse(html, {
status: status,
headers: headers,
});
}
redirect(location, status = 302) {
if (typeof location !== 'string') {
throw new TypeError('location must be a string!');
}
if (!(0, util_1.isAbsoluteURL)(location)) {
const url = new URL(this.req.url);
url.pathname = location;
location = url.toString();
}
return this.newResponse(null, {
status: status,
headers: {
'Content-Type': 'text/html; charset=UTF-8',
Location: location,
},

@@ -45,0 +63,0 @@ });

/// <reference types="@cloudflare/workers-types" />
import type { Result } from './node';
import { Node } from './node';
import { Middleware } from './middleware';
import { Context } from './context';
export { Middleware };
import type { Env } from './context';
declare global {
interface Request {
params: (key: string) => any;
params: (key: string) => string;
query: (key: string) => string | null;
parsedBody: any;
}
}
declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
declare type MiddlwareHandler = (c: Context, next: Function) => Promise<void>;
export declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
export declare type MiddlewareHandler = (c: Context, next: Function) => Promise<void>;
export declare class Router<T> {

@@ -23,3 +23,3 @@ node: Node<T>;

router: Router<Handler[]>;
middlewareRouters: Router<MiddlwareHandler>[];
middlewareRouters: Router<MiddlewareHandler>[];
tempPath: string;

@@ -36,9 +36,10 @@ constructor();

route(path: string): Hono;
use(path: string, middleware: MiddlwareHandler): void;
use(path: string, middleware: MiddlewareHandler): void;
addRoute(method: string, arg: string | Handler, ...args: Handler[]): Hono;
matchRoute(method: string, path: string): Promise<Result<Handler[]>>;
dispatch(request: Request, response?: Response): Promise<Response>;
dispatch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
handleEvent(event: FetchEvent): Promise<Response>;
fetch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
fire(): void;
notFound(): Response;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hono = exports.Router = exports.Middleware = void 0;
exports.Hono = exports.Router = void 0;
const node_1 = require("./node");

@@ -8,3 +8,2 @@ const compose_1 = require("./compose");

const middleware_1 = require("./middleware");
Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
const context_1 = require("./context");

@@ -98,3 +97,3 @@ const METHOD_NAME_OF_ALL = 'ALL';

}
async dispatch(request, response) {
async dispatch(request, env, event) {
const [method, path] = [request.method, (0, util_1.getPathFromURL)(request.url)];

@@ -120,6 +119,6 @@ const result = await this.matchRoute(method, path);

};
middleware.push(middleware_1.Middleware.defaultFilter);
middleware.push(middleware_1.Middleware.default);
middleware.push(wrappedHandler);
const composed = (0, compose_1.compose)(middleware);
const c = new context_1.Context(request, response);
const c = new context_1.Context(request, { env: env, event: event, res: null });
await composed(c);

@@ -129,4 +128,7 @@ return c.res;

async handleEvent(event) {
return this.dispatch(event.request);
return this.dispatch(event.request, {}, event);
}
async fetch(request, env, event) {
return this.dispatch(request, env, event);
}
fire() {

@@ -133,0 +135,0 @@ addEventListener('fetch', (event) => {

@@ -1,2 +0,5 @@

export { Hono, Middleware } from './hono';
export { Hono } from './hono';
export type { Handler, MiddlewareHandler } from './hono';
export { Middleware } from './middleware';
export { Context } from './context';
export type { Env } from './context';

@@ -6,4 +6,5 @@ "use strict";

Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return hono_1.Middleware; } });
var middleware_1 = require("./middleware");
Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
var context_1 = require("./context");
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
export declare class Middleware {
static defaultFilter: (c: import("./context").Context, next: Function) => Promise<void>;
static default: (c: import("./context").Context, next: Function) => Promise<void>;
static poweredBy: () => (c: import("./context").Context, next: Function) => Promise<void>;

@@ -14,2 +14,3 @@ static logger: (fn?: {

}) => (ctx: import("./context").Context, next: Function) => Promise<any>;
static bodyParse: () => (ctx: import("./context").Context, next: Function) => Promise<void>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Middleware = void 0;
const defaultFilter_1 = require("./middleware/defaultFilter");
const poweredBy_1 = require("./middleware/poweredBy/poweredBy");
const default_1 = require("./middleware/default");
const powered_by_1 = require("./middleware/powered-by/powered-by");
const logger_1 = require("./middleware/logger/logger");
const basic_auth_1 = require("./middleware/basic-auth/basic-auth");
const body_parse_1 = require("./middleware/body-parse/body-parse");
class Middleware {
}
exports.Middleware = Middleware;
Middleware.defaultFilter = defaultFilter_1.defaultFilter;
Middleware.poweredBy = poweredBy_1.poweredBy;
Middleware.default = default_1.defaultMiddleware;
Middleware.poweredBy = powered_by_1.poweredBy;
Middleware.logger = logger_1.logger;
Middleware.basicAuth = basic_auth_1.basicAuth;
Middleware.bodyParse = body_parse_1.bodyParse;
export declare const splitPath: (path: string) => string[];
export declare const getPattern: (label: string) => string[] | null;
export declare const getPathFromURL: (url: string) => string;
export declare const isAbsoluteURL: (url: string) => boolean;
export declare const timingSafeEqual: (a: any, b: any) => Promise<boolean>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.timingSafeEqual = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
exports.timingSafeEqual = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
const URL_REGEXP = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
const splitPath = (path) => {

@@ -30,3 +31,3 @@ const paths = path.split(/\//); // faster than path.split('/')

// XXX
const match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
const match = url.match(URL_REGEXP);
if (match) {

@@ -38,2 +39,10 @@ return match[5];

exports.getPathFromURL = getPathFromURL;
const isAbsoluteURL = (url) => {
const match = url.match(URL_REGEXP);
if (match && match[1]) {
return true;
}
return false;
};
exports.isAbsoluteURL = isAbsoluteURL;
const bufferEqual = (a, b) => {

@@ -40,0 +49,0 @@ if (a === b) {

{
"name": "hono",
"version": "0.0.12",
"description": "Tiny web framework for Cloudflare Workers and others.",
"version": "0.0.13",
"description": "Ultrafast web framework for Cloudflare Workers.",
"main": "dist/index.js",

@@ -40,4 +40,4 @@ "types": "dist/index.d.ts",

"@types/node": "^17.0.8",
"@types/service-worker-mock": "^2.0.1",
"@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.9.0",
"eslint": "^7.26.0",

@@ -52,7 +52,7 @@ "eslint-config-prettier": "^8.1.0",

"eslint-plugin-prettier": "^4.0.0",
"form-data": "^4.0.0",
"jest": "^27.4.5",
"jest-environment-miniflare": "^2.0.0",
"rimraf": "^3.0.2",
"service-worker-mock": "^2.0.5",
"ts-jest": "^27.1.2",
"@typescript-eslint/parser": "^5.9.0",
"typescript": "^4.5.4"

@@ -59,0 +59,0 @@ },

# Hono
Hono [炎] - Tiny web framework for Cloudflare Workers and others.
Hono[炎] - _**means flame🔥 in Japanese**_ - is small, simple, and ultrafast web flamework for a Service Workers API based serverless such as Cloudflare Workers and Fastly Compute@Edge.
```js
const { Hono } = require('hono')
import { Hono } from 'hono'
const app = new Hono()

@@ -14,11 +14,8 @@

Hono[炎] - _**means flame🔥 in Japanese**_ - is small, fast and simple web flamework for a Service Workers API based serverless such as **Cloudflare Workers** and **Fastly Compute@Edge**. Hono does not depend on any npm packages. However, Hono has a router, context object, and middleware including the builtins. It's easy to make a web application.
## Features
- **Fast** - the router is implemented with Trie-Tree structure.
- **Tiny** - zero dependencies, using Web standard API.
- **Flexible** - you can make your own middleware.
- **Easy** - simple API, builtin middleware, and written in TypeScript.
- **Optimized** - for Cloudflare Workers or Fastly Compute@Edge.
- **Ultra Fast** - the router is implemented with Trie-Tree structure.
- **Zero dependencies** - using only Web standard API.
- **Middleware** - builtin middleware, and you can make your own middleware.
- **Optimized** - for Cloudflare Workers.

@@ -29,8 +26,9 @@ ## Benchmark

```
hono x 758,264 ops/sec ±5.41% (75 runs sampled)
itty-router x 158,359 ops/sec ±3.21% (89 runs sampled)
sunder x 297,581 ops/sec ±4.74% (83 runs sampled)
```plain
hono x 748,188 ops/sec ±5.40% (77 runs sampled)
itty-router x 158,817 ops/sec ±3.62% (87 runs sampled)
sunder x 332,339 ops/sec ±1.11% (95 runs sampled)
worktop x 205,906 ops/sec ±4.43% (83 runs sampled)
Fastest is hono
✨ Done in 42.84s.
✨ Done in 52.79s.
```

@@ -48,5 +46,5 @@

```sh
yarn add hono
```
$ yarn add hono
```

@@ -56,3 +54,3 @@ or

```sh
$ npm install hono
npm install hono
```

@@ -69,2 +67,3 @@

- app.**fire**()
- app.**fetch**(request, env, event)

@@ -137,6 +136,8 @@ ## Routing

```js
const { Hono, Middleware } = require('hono')
import { Hono, Middleware } from 'hono'
...
app.use('*', Middleware.poweredBy())
app.use('*', Middleware.logger())
app.use(

@@ -244,2 +245,24 @@ '/auth/*',

### c.event
```js
// FetchEvent objest
app.use('*', async (c, next) => {
c.event.waitUntil(
...
)
await next()
})
```
### c.env
```js
// Environment object for Cloudflare Workers
app.get('*', async c => {
const counter = c.env.COUNTER
...
})
```
### c.text()

@@ -270,3 +293,3 @@

```js
app.get('/api', (c) => {
app.get('/', (c) => {
return c.html('<h1>Hello! Hono!</h1>')

@@ -276,2 +299,11 @@ })

### c.redirect()
Redirect, default status code is `302`:
```js
app.get('/redirect', (c) => c.redirect('/'))
app.get('/redirect-permanently', (c) => c.redirect('/', 301))
```
## fire

@@ -287,2 +319,14 @@

## fetch
`app.fetch()` is for Cloudflare Module Worker syntax.
```js
export default {
fetch(request: Request, env: Env, event: FetchEvent) {
return app.fetch(request, env, event)
},
}
```
## Cloudflare Workers with Hono

@@ -299,3 +343,3 @@

```sh
$ npm i @cloudflare/wrangler -g
npm i @cloudflare/wrangler -g
```

@@ -308,5 +352,5 @@

```sh
$ mkdir hono-example
$ ch hono-example
$ npm init -y
mkdir hono-example
ch hono-example
npm init -y
```

@@ -319,3 +363,3 @@

```sh
$ wrangler init
wrangler init
```

@@ -327,5 +371,5 @@

```sh
npm i hono
```
$ npm i hono
```

@@ -337,3 +381,3 @@ ### 5. Write your app

```js
const { Hono } = require('hono')
import { Hono } from 'hono'
const app = new Hono()

@@ -351,3 +395,3 @@

```sh
$ wrangler dev
wrangler dev
```

@@ -360,3 +404,3 @@

```sh
$ wrangler publish
wrangler publish
```

@@ -366,3 +410,3 @@

Implementation of the router is inspired by [goblin](https://github.com/bmf-san/goblin). API design is inspired by [express](https://github.com/expressjs/express) and [koa](https://github.com/koajs/koa). [itty-router](https://github.com/kwhitley/itty-router) and [Sunder](https://github.com/SunderJS/sunder) are the other routers or frameworks for Cloudflare Workers.
Implementation of the router is inspired by [goblin](https://github.com/bmf-san/goblin). API design is inspired by [express](https://github.com/expressjs/express) and [koa](https://github.com/koajs/koa). [itty-router](https://github.com/kwhitley/itty-router), [Sunder](https://github.com/SunderJS/sunder), and [worktop](https://github.com/lukeed/worktop) are the other routers or frameworks for Cloudflare Workers.

@@ -374,2 +418,3 @@ - express <https://github.com/expressjs/express>

- goblin <https://github.com/bmf-san/goblin>
- worktop <https://github.com/lukeed/worktop>

@@ -376,0 +421,0 @@ ## Contributing

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