hono 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Hono
2
2
 
3
- Hono [炎] - Tiny web framework for Cloudflare Workers and others.
3
+ 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.
4
4
 
5
5
  ```js
6
- const { Hono } = require('hono')
6
+ import { Hono } from 'hono'
7
7
  const app = new Hono()
8
8
 
9
9
  app.get('/', (c) => c.text('Hono!!'))
@@ -11,26 +11,24 @@ app.get('/', (c) => c.text('Hono!!'))
11
11
  app.fire()
12
12
  ```
13
13
 
14
- 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.
15
-
16
14
  ## Features
17
15
 
18
- - **Fast** - the router is implemented with Trie-Tree structure.
19
- - **Tiny** - zero dependencies, using Web standard API.
20
- - **Flexible** - you can make your own middleware.
21
- - **Easy** - simple API, builtin middleware, and written in TypeScript.
22
- - **Optimized** - for Cloudflare Workers or Fastly Compute@Edge.
16
+ - **Ultra Fast** - the router is implemented with Trie-Tree structure.
17
+ - **Zero dependencies** - using only Web standard API.
18
+ - **Middleware** - builtin middleware, and you can make your own middleware.
19
+ - **Optimized** - for Cloudflare Workers.
23
20
 
24
21
  ## Benchmark
25
22
 
26
23
  **Hono is fastest** compared to other routers for Cloudflare Workers.
27
24
 
28
- ```
29
- hono x 758,264 ops/sec ±5.41% (75 runs sampled)
30
- itty-router x 158,359 ops/sec ±3.21% (89 runs sampled)
31
- sunder x 297,581 ops/sec ±4.74% (83 runs sampled)
25
+ ```plain
26
+ hono x 748,188 ops/sec ±5.40% (77 runs sampled)
27
+ itty-router x 158,817 ops/sec ±3.62% (87 runs sampled)
28
+ sunder x 332,339 ops/sec ±1.11% (95 runs sampled)
29
+ worktop x 205,906 ops/sec ±4.43% (83 runs sampled)
32
30
  Fastest is hono
33
- ✨ Done in 42.84s.
31
+ ✨ Done in 52.79s.
34
32
  ```
35
33
 
36
34
  ## Hono in 1 minute
@@ -43,14 +41,14 @@ Below is a demonstration to create an application of Cloudflare Workers with Hon
43
41
 
44
42
  You can install from npm registry:
45
43
 
46
- ```
47
- $ yarn add hono
44
+ ```sh
45
+ yarn add hono
48
46
  ```
49
47
 
50
48
  or
51
49
 
52
50
  ```sh
53
- $ npm install hono
51
+ npm install hono
54
52
  ```
55
53
 
56
54
  ## Methods
@@ -62,6 +60,7 @@ Instance of `Hono` has these methods:
62
60
  - app.**route**(path)
63
61
  - app.**use**(path, middleware)
64
62
  - app.**fire**()
63
+ - app.**fetch**(request, env, event)
65
64
 
66
65
  ## Routing
67
66
 
@@ -129,10 +128,12 @@ app.get('/fetch-url', async () => {
129
128
  ### Builtin Middleware
130
129
 
131
130
  ```js
132
- const { Hono, Middleware } = require('hono')
131
+ import { Hono, Middleware } from 'hono'
133
132
 
134
133
  ...
135
134
 
135
+ app.use('*', Middleware.poweredBy())
136
+ app.use('*', Middleware.logger())
136
137
  app.use(
137
138
  '/auth/*',
138
139
  Middleware.basicAuth({
@@ -235,6 +236,28 @@ app.use('/', (c, next) => {
235
236
  })
236
237
  ```
237
238
 
239
+ ### c.event
240
+
241
+ ```js
242
+ // FetchEvent objest
243
+ app.use('*', async (c, next) => {
244
+ c.event.waitUntil(
245
+ ...
246
+ )
247
+ await next()
248
+ })
249
+ ```
250
+
251
+ ### c.env
252
+
253
+ ```js
254
+ // Environment object for Cloudflare Workers
255
+ app.get('*', async c => {
256
+ const counter = c.env.COUNTER
257
+ ...
258
+ })
259
+ ```
260
+
238
261
  ### c.text()
239
262
 
240
263
  Render text as `Content-Type:text/plain`:
@@ -260,11 +283,20 @@ app.get('/api', (c) => {
260
283
  Render HTML as `Content-Type:text/html`:
261
284
 
262
285
  ```js
263
- app.get('/api', (c) => {
286
+ app.get('/', (c) => {
264
287
  return c.html('<h1>Hello! Hono!</h1>')
265
288
  })
266
289
  ```
267
290
 
291
+ ### c.redirect()
292
+
293
+ Redirect, default status code is `302`:
294
+
295
+ ```js
296
+ app.get('/redirect', (c) => c.redirect('/'))
297
+ app.get('/redirect-permanently', (c) => c.redirect('/', 301))
298
+ ```
299
+
268
300
  ## fire
269
301
 
270
302
  `app.fire()` do:
@@ -275,6 +307,18 @@ addEventListener('fetch', (event) => {
275
307
  })
276
308
  ```
277
309
 
310
+ ## fetch
311
+
312
+ `app.fetch()` is for Cloudflare Module Worker syntax.
313
+
314
+ ```js
315
+ export default {
316
+ fetch(request: Request, env: Env, event: FetchEvent) {
317
+ return app.fetch(request, env, event)
318
+ },
319
+ }
320
+ ```
321
+
278
322
  ## Cloudflare Workers with Hono
279
323
 
280
324
  Using `wrangler` or `miniflare`, you can develop the application locally and publish it with few commands.
@@ -286,7 +330,7 @@ Let's write your first code for Cloudflare Workers with Hono.
286
330
  Install Cloudflare Command Line "[Wrangler](https://github.com/cloudflare/wrangler)"
287
331
 
288
332
  ```sh
289
- $ npm i @cloudflare/wrangler -g
333
+ npm i @cloudflare/wrangler -g
290
334
  ```
291
335
 
292
336
  ### 2. `npm init`
@@ -294,9 +338,9 @@ $ npm i @cloudflare/wrangler -g
294
338
  Make npm skeleton directory.
295
339
 
296
340
  ```sh
297
- $ mkdir hono-example
298
- $ ch hono-example
299
- $ npm init -y
341
+ mkdir hono-example
342
+ ch hono-example
343
+ npm init -y
300
344
  ```
301
345
 
302
346
  ### 3. `wrangler init`
@@ -304,15 +348,15 @@ $ npm init -y
304
348
  Init as a wrangler project.
305
349
 
306
350
  ```sh
307
- $ wrangler init
351
+ wrangler init
308
352
  ```
309
353
 
310
354
  ### 4. `npm install hono`
311
355
 
312
356
  Install `hono` from npm registry.
313
357
 
314
- ```
315
- $ npm i hono
358
+ ```sh
359
+ npm i hono
316
360
  ```
317
361
 
318
362
  ### 5. Write your app
@@ -320,7 +364,7 @@ $ npm i hono
320
364
  Only 4 lines!!
321
365
 
322
366
  ```js
323
- const { Hono } = require('hono')
367
+ import { Hono } from 'hono'
324
368
  const app = new Hono()
325
369
 
326
370
  app.get('/', (c) => c.text('Hello! Hono!'))
@@ -333,7 +377,7 @@ app.fire()
333
377
  Run the development server locally. Then, access like `http://127.0.0.1:8787/` in your Web browser.
334
378
 
335
379
  ```sh
336
- $ wrangler dev
380
+ wrangler dev
337
381
  ```
338
382
 
339
383
  ### Publish
@@ -341,18 +385,19 @@ $ wrangler dev
341
385
  Deploy to Cloudflare. That's all!
342
386
 
343
387
  ```sh
344
- $ wrangler publish
388
+ wrangler publish
345
389
  ```
346
390
 
347
391
  ## Related projects
348
392
 
349
- 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.
393
+ 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.
350
394
 
351
395
  - express <https://github.com/expressjs/express>
352
396
  - koa <https://github.com/koajs/koa>
353
397
  - itty-router <https://github.com/kwhitley/itty-router>
354
398
  - Sunder <https://github.com/SunderJS/sunder>
355
399
  - goblin <https://github.com/bmf-san/goblin>
400
+ - worktop <https://github.com/lukeed/worktop>
356
401
 
357
402
  ## Contributing
358
403
 
package/dist/context.d.ts CHANGED
@@ -1,9 +1,23 @@
1
+ /// <reference types="@cloudflare/workers-types" />
2
+ declare type Headers = {
3
+ [key: string]: string;
4
+ };
5
+ export interface Env {
6
+ }
1
7
  export declare class Context {
2
8
  req: Request;
3
9
  res: Response;
4
- constructor(req: Request, res: Response);
10
+ env: Env;
11
+ event: FetchEvent;
12
+ constructor(req: Request, opts?: {
13
+ res: Response;
14
+ env: Env;
15
+ event: FetchEvent;
16
+ });
5
17
  newResponse(body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
6
- text(body: string): Response;
7
- json(object: object, replacer?: (string | number)[], space?: string | number): Response;
8
- html(body: string): Response;
18
+ text(text: string, status?: number, headers?: Headers): Response;
19
+ json(object: object, status?: number, headers?: Headers): Response;
20
+ html(html: string, status?: number, headers?: Headers): Response;
21
+ redirect(location: string, status?: number): Response;
9
22
  }
23
+ export {};
package/dist/context.js CHANGED
@@ -1,45 +1,63 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Context = void 0;
4
+ const util_1 = require("./util");
4
5
  class Context {
5
- constructor(req, res) {
6
+ constructor(req, opts) {
6
7
  this.req = req;
7
- this.res = res;
8
+ if (opts) {
9
+ this.res = opts.res;
10
+ this.env = opts.env;
11
+ this.event = opts.event;
12
+ }
8
13
  }
9
14
  newResponse(body, init) {
10
15
  return new Response(body, init);
11
16
  }
12
- text(body) {
13
- if (typeof body !== 'string') {
17
+ text(text, status = 200, headers = {}) {
18
+ if (typeof text !== 'string') {
14
19
  throw new TypeError('text method arg must be a string!');
15
20
  }
16
- return this.newResponse(body, {
17
- status: 200,
18
- headers: {
19
- 'Content-Type': 'text/plain',
20
- },
21
+ headers['Content-Type'] = 'text/plain';
22
+ return this.newResponse(text, {
23
+ status: status,
24
+ headers: headers,
21
25
  });
22
26
  }
23
- json(object, replacer, space) {
27
+ json(object, status = 200, headers = {}) {
24
28
  if (typeof object !== 'object') {
25
29
  throw new TypeError('json method arg must be a object!');
26
30
  }
27
- const body = JSON.stringify(object, replacer, space);
31
+ const body = JSON.stringify(object);
32
+ headers['Content-Type'] = 'application/json; charset=UTF-8';
28
33
  return this.newResponse(body, {
29
- status: 200,
30
- headers: {
31
- 'Content-Type': 'application/json; charset=UTF-8',
32
- },
34
+ status: status,
35
+ headers: headers,
33
36
  });
34
37
  }
35
- html(body) {
36
- if (typeof body !== 'string') {
38
+ html(html, status = 200, headers = {}) {
39
+ if (typeof html !== 'string') {
37
40
  throw new TypeError('html method arg must be a string!');
38
41
  }
39
- return this.newResponse(body, {
40
- status: 200,
42
+ headers['Content-Type'] = 'text/html; charset=UTF-8';
43
+ return this.newResponse(html, {
44
+ status: status,
45
+ headers: headers,
46
+ });
47
+ }
48
+ redirect(location, status = 302) {
49
+ if (typeof location !== 'string') {
50
+ throw new TypeError('location must be a string!');
51
+ }
52
+ if (!(0, util_1.isAbsoluteURL)(location)) {
53
+ const url = new URL(this.req.url);
54
+ url.pathname = location;
55
+ location = url.toString();
56
+ }
57
+ return this.newResponse(null, {
58
+ status: status,
41
59
  headers: {
42
- 'Content-Type': 'text/html; charset=UTF-8',
60
+ Location: location,
43
61
  },
44
62
  });
45
63
  }
package/dist/hono.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  /// <reference types="@cloudflare/workers-types" />
2
2
  import type { Result } from './node';
3
3
  import { Node } from './node';
4
- import { Middleware } from './middleware';
5
4
  import { Context } from './context';
6
- export { Middleware };
5
+ import type { Env } from './context';
7
6
  declare global {
8
7
  interface Request {
9
- params: (key: string) => any;
8
+ params: (key: string) => string;
10
9
  query: (key: string) => string | null;
10
+ parsedBody: any;
11
11
  }
12
12
  }
13
- declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
14
- declare type MiddlwareHandler = (c: Context, next: Function) => Promise<void>;
13
+ export declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
14
+ export declare type MiddlewareHandler = (c: Context, next: Function) => Promise<void>;
15
15
  export declare class Router<T> {
16
16
  node: Node<T>;
17
17
  constructor();
@@ -20,7 +20,7 @@ export declare class Router<T> {
20
20
  }
21
21
  export declare class Hono {
22
22
  router: Router<Handler[]>;
23
- middlewareRouters: Router<MiddlwareHandler>[];
23
+ middlewareRouters: Router<MiddlewareHandler>[];
24
24
  tempPath: string;
25
25
  constructor();
26
26
  get(arg: string | Handler, ...args: Handler[]): Hono;
@@ -32,11 +32,12 @@ export declare class Hono {
32
32
  patch(arg: string | Handler, ...args: Handler[]): Hono;
33
33
  all(arg: string | Handler, ...args: Handler[]): Hono;
34
34
  route(path: string): Hono;
35
- use(path: string, middleware: MiddlwareHandler): void;
35
+ use(path: string, middleware: MiddlewareHandler): void;
36
36
  addRoute(method: string, arg: string | Handler, ...args: Handler[]): Hono;
37
37
  matchRoute(method: string, path: string): Promise<Result<Handler[]>>;
38
- dispatch(request: Request, response?: Response): Promise<Response>;
38
+ dispatch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
39
39
  handleEvent(event: FetchEvent): Promise<Response>;
40
+ fetch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
40
41
  fire(): void;
41
42
  notFound(): Response;
42
43
  }
package/dist/hono.js CHANGED
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Hono = exports.Router = exports.Middleware = void 0;
3
+ exports.Hono = exports.Router = void 0;
4
4
  const node_1 = require("./node");
5
5
  const compose_1 = require("./compose");
6
6
  const util_1 = require("./util");
7
7
  const middleware_1 = require("./middleware");
8
- Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
9
8
  const context_1 = require("./context");
10
9
  const METHOD_NAME_OF_ALL = 'ALL';
11
10
  class Router {
@@ -94,7 +93,7 @@ class Hono {
94
93
  async matchRoute(method, path) {
95
94
  return this.router.match(method, path);
96
95
  }
97
- async dispatch(request, response) {
96
+ async dispatch(request, env, event) {
98
97
  const [method, path] = [request.method, (0, util_1.getPathFromURL)(request.url)];
99
98
  const result = await this.matchRoute(method, path);
100
99
  request.params = (key) => {
@@ -115,15 +114,18 @@ class Hono {
115
114
  context.res = await handler(context);
116
115
  await next();
117
116
  };
118
- middleware.push(middleware_1.Middleware.defaultFilter);
117
+ middleware.push(middleware_1.Middleware.default);
119
118
  middleware.push(wrappedHandler);
120
119
  const composed = (0, compose_1.compose)(middleware);
121
- const c = new context_1.Context(request, response);
120
+ const c = new context_1.Context(request, { env: env, event: event, res: null });
122
121
  await composed(c);
123
122
  return c.res;
124
123
  }
125
124
  async handleEvent(event) {
126
- return this.dispatch(event.request);
125
+ return this.dispatch(event.request, {}, event);
126
+ }
127
+ async fetch(request, env, event) {
128
+ return this.dispatch(request, env, event);
127
129
  }
128
130
  fire() {
129
131
  addEventListener('fetch', (event) => {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,5 @@
1
- export { Hono, Middleware } from './hono';
1
+ export { Hono } from './hono';
2
+ export type { Handler, MiddlewareHandler } from './hono';
3
+ export { Middleware } from './middleware';
2
4
  export { Context } from './context';
5
+ export type { Env } from './context';
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Context = exports.Middleware = exports.Hono = void 0;
4
4
  var hono_1 = require("./hono");
5
5
  Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
6
- Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return hono_1.Middleware; } });
6
+ var middleware_1 = require("./middleware");
7
+ Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
7
8
  var context_1 = require("./context");
8
9
  Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
@@ -0,0 +1,2 @@
1
+ import type { Context } from '../../context';
2
+ export declare const bodyParse: () => (ctx: Context, next: Function) => Promise<void>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bodyParse = void 0;
4
+ const bodyParse = () => {
5
+ return async (ctx, next) => {
6
+ const contentType = ctx.req.headers.get('Content-Type') || '';
7
+ if (contentType.includes('application/json')) {
8
+ ctx.req.parsedBody = await ctx.req.json();
9
+ }
10
+ else if (contentType.includes('application/text')) {
11
+ ctx.req.parsedBody = await ctx.req.text();
12
+ }
13
+ else if (contentType.includes('text/html')) {
14
+ ctx.req.parsedBody = await ctx.req.text();
15
+ }
16
+ else if (contentType.includes('form')) {
17
+ const form = {};
18
+ const data = [...(await ctx.req.formData())].reduce((acc, cur) => {
19
+ acc[cur[0]] = cur[1];
20
+ return acc;
21
+ }, form);
22
+ ctx.req.parsedBody = data;
23
+ }
24
+ await next();
25
+ };
26
+ };
27
+ exports.bodyParse = bodyParse;
@@ -0,0 +1,2 @@
1
+ import type { Context } from '../context';
2
+ export declare const defaultMiddleware: (c: Context, next: Function) => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultFilter = void 0;
4
- const defaultFilter = async (c, next) => {
3
+ exports.defaultMiddleware = void 0;
4
+ const defaultMiddleware = async (c, next) => {
5
5
  c.req.query = (key) => {
6
6
  // eslint-disable-next-line
7
7
  const url = new URL(c.req.url);
@@ -9,4 +9,4 @@ const defaultFilter = async (c, next) => {
9
9
  };
10
10
  await next();
11
11
  };
12
- exports.defaultFilter = defaultFilter;
12
+ exports.defaultMiddleware = defaultMiddleware;
@@ -1,5 +1,5 @@
1
1
  export declare class Middleware {
2
- static defaultFilter: (c: import("./context").Context, next: Function) => Promise<void>;
2
+ static default: (c: import("./context").Context, next: Function) => Promise<void>;
3
3
  static poweredBy: () => (c: import("./context").Context, next: Function) => Promise<void>;
4
4
  static logger: (fn?: {
5
5
  (...data: any[]): void;
@@ -11,4 +11,5 @@ export declare class Middleware {
11
11
  password: string;
12
12
  realm?: string;
13
13
  }) => (ctx: import("./context").Context, next: Function) => Promise<any>;
14
+ static bodyParse: () => (ctx: import("./context").Context, next: Function) => Promise<void>;
14
15
  }
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Middleware = void 0;
4
- const defaultFilter_1 = require("./middleware/defaultFilter");
5
- const poweredBy_1 = require("./middleware/poweredBy/poweredBy");
4
+ const default_1 = require("./middleware/default");
5
+ const powered_by_1 = require("./middleware/powered-by/powered-by");
6
6
  const logger_1 = require("./middleware/logger/logger");
7
7
  const basic_auth_1 = require("./middleware/basic-auth/basic-auth");
8
+ const body_parse_1 = require("./middleware/body-parse/body-parse");
8
9
  class Middleware {
9
10
  }
10
11
  exports.Middleware = Middleware;
11
- Middleware.defaultFilter = defaultFilter_1.defaultFilter;
12
- Middleware.poweredBy = poweredBy_1.poweredBy;
12
+ Middleware.default = default_1.defaultMiddleware;
13
+ Middleware.poweredBy = powered_by_1.poweredBy;
13
14
  Middleware.logger = logger_1.logger;
14
15
  Middleware.basicAuth = basic_auth_1.basicAuth;
16
+ Middleware.bodyParse = body_parse_1.bodyParse;
package/dist/util.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare const splitPath: (path: string) => string[];
2
2
  export declare const getPattern: (label: string) => string[] | null;
3
3
  export declare const getPathFromURL: (url: string) => string;
4
+ export declare const isAbsoluteURL: (url: string) => boolean;
4
5
  export declare const timingSafeEqual: (a: any, b: any) => Promise<boolean>;
package/dist/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.timingSafeEqual = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
3
+ exports.timingSafeEqual = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
4
+ const URL_REGEXP = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
4
5
  const splitPath = (path) => {
5
6
  const paths = path.split(/\//); // faster than path.split('/')
6
7
  if (paths[0] === '') {
@@ -27,13 +28,21 @@ const getPattern = (label) => {
27
28
  exports.getPattern = getPattern;
28
29
  const getPathFromURL = (url) => {
29
30
  // XXX
30
- const match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
31
+ const match = url.match(URL_REGEXP);
31
32
  if (match) {
32
33
  return match[5];
33
34
  }
34
35
  return '';
35
36
  };
36
37
  exports.getPathFromURL = getPathFromURL;
38
+ const isAbsoluteURL = (url) => {
39
+ const match = url.match(URL_REGEXP);
40
+ if (match && match[1]) {
41
+ return true;
42
+ }
43
+ return false;
44
+ };
45
+ exports.isAbsoluteURL = isAbsoluteURL;
37
46
  const bufferEqual = (a, b) => {
38
47
  if (a === b) {
39
48
  return true;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "0.0.12",
4
- "description": "Tiny web framework for Cloudflare Workers and others.",
3
+ "version": "0.0.13",
4
+ "description": "Ultrafast web framework for Cloudflare Workers.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -37,8 +37,8 @@
37
37
  "@cloudflare/workers-types": "^3.3.0",
38
38
  "@types/jest": "^27.4.0",
39
39
  "@types/node": "^17.0.8",
40
- "@types/service-worker-mock": "^2.0.1",
41
40
  "@typescript-eslint/eslint-plugin": "^5.9.0",
41
+ "@typescript-eslint/parser": "^5.9.0",
42
42
  "eslint": "^7.26.0",
43
43
  "eslint-config-prettier": "^8.1.0",
44
44
  "eslint-define-config": "^1.2.1",
@@ -48,11 +48,11 @@
48
48
  "eslint-plugin-import": "^2.20.2",
49
49
  "eslint-plugin-node": "^11.1.0",
50
50
  "eslint-plugin-prettier": "^4.0.0",
51
+ "form-data": "^4.0.0",
51
52
  "jest": "^27.4.5",
53
+ "jest-environment-miniflare": "^2.0.0",
52
54
  "rimraf": "^3.0.2",
53
- "service-worker-mock": "^2.0.5",
54
55
  "ts-jest": "^27.1.2",
55
- "@typescript-eslint/parser": "^5.9.0",
56
56
  "typescript": "^4.5.4"
57
57
  },
58
58
  "engines": {
@@ -1,2 +0,0 @@
1
- import type { Context } from '../context';
2
- export declare const defaultFilter: (c: Context, next: Function) => Promise<void>;