hono 1.3.5 → 1.4.1

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
@@ -38,13 +38,13 @@ app.fire()
38
38
  **Hono is fastest**, compared to other routers for Cloudflare Workers.
39
39
 
40
40
  ```plain
41
- hono - trie-router(default) x 737,602 ops/sec ±3.65% (67 runs sampled)
42
- hono - regexp-router x 1,188,203 ops/sec ±6.42% (60 runs sampled)
43
- itty-router x 163,970 ops/sec ±3.05% (91 runs sampled)
44
- sunder x 344,468 ops/sec ±0.87% (97 runs sampled)
45
- worktop x 222,044 ops/sec ±2.13% (85 runs sampled)
46
- Fastest is hono - regexp-router
47
- ✨ Done in 84.04s.
41
+ hono - trie-router(default) x 725,892 ops/sec ±4.02% (74 runs sampled)
42
+ hono - regexp-router x 733,494 ops/sec ±3.00% (67 runs sampled)
43
+ itty-router x 167,167 ops/sec ±1.25% (91 runs sampled)
44
+ sunder x 327,697 ops/sec ±2.45% (92 runs sampled)
45
+ worktop x 216,468 ops/sec ±3.01% (85 runs sampled)
46
+ Fastest is hono - regexp-router,hono - trie-router(default)
47
+ ✨ Done in 69.57s.
48
48
  ```
49
49
 
50
50
  ## Why so fast?
@@ -137,10 +137,10 @@ npm install hono
137
137
 
138
138
  An instance of `Hono` has these methods.
139
139
 
140
- - app.**HTTP_METHOD**(\[path,\] handler|middleware...)
141
- - app.**all**(\[path,\] handler|middleware...)
140
+ - app.**HTTP_METHOD**(\[path,\]handler|middleware...)
141
+ - app.**all**(\[path,\]handler|middleware...)
142
142
  - app.**route**(path, \[app\])
143
- - app.**use**(\[path,\] middleware)
143
+ - app.**use**(\[path,\]middleware)
144
144
  - app.**notFound**(handler)
145
145
  - app.**onError**(err, handler)
146
146
  - app.**fire**()
@@ -249,12 +249,37 @@ app.route('/book', book)
249
249
 
250
250
  ## Middleware
251
251
 
252
- Middleware operate after/before executing Handler. We can get `Response` before dispatching or manipulate `Response` after dispatching.
252
+ Middleware works after/before Handler. We can get `Request` before dispatching or manipulate `Response` after dispatching.
253
253
 
254
254
  ### Definition of Middleware
255
255
 
256
- - Handler - should return `Response` object.
257
- - Middleware - should return nothing, do `await next()`
256
+ - Handler - should return `Response` object. Only one handler will be called.
257
+ - Middleware - should return nothing, will be proceeded to next middleware with `await next()`
258
+
259
+ The user can register middleware using `c.use` or using `c.HTTP_METHOD` as well as the handlers. For this feature, it's easy to specify the path and the method.
260
+
261
+ ```ts
262
+ // match any method, all routes
263
+ app.use('*', logger())
264
+
265
+ // specify path
266
+ app.use('/posts/*', cors())
267
+
268
+ // specify method and path
269
+ app.post('/posts/*', basicAuth(), bodyParse())
270
+ ```
271
+
272
+ If the handler returns `Response`, it will be used for the end-user, and stopping the processing.
273
+
274
+ ```ts
275
+ app.post('/posts', (c) => c.text('Created!', 201))
276
+ ```
277
+
278
+ In this case, four middleware are processed before dispatching like this:
279
+
280
+ ```ts
281
+ logger() -> cors() -> basicAuth() -> bodyParse() -> *handler*
282
+ ```
258
283
 
259
284
  ### Built-in Middleware
260
285
 
@@ -354,6 +379,14 @@ app.get('/search', (c) => {
354
379
  ...
355
380
  })
356
381
 
382
+ // Multiple query values
383
+ app.get('/search', (c) => {
384
+ const queries = c.req.queries('q')
385
+ // ---> GET search?q=foo&q=bar
386
+ // queries[0] => foo, queries[1] => bar
387
+ ...
388
+ })
389
+
357
390
  // Captured params
358
391
  app.get('/entry/:id', (c) => {
359
392
  const id = c.req.param('id')
@@ -382,7 +415,6 @@ The Response is the same as below.
382
415
  ```ts
383
416
  new Response('Thank you for comming', {
384
417
  status: 201,
385
- statusText: 'Created',
386
418
  headers: {
387
419
  'X-Message': 'Hello',
388
420
  'Content-Type': 'text/plain',
@@ -510,14 +542,47 @@ test('GET /hello is ok', async () => {
510
542
  })
511
543
  ```
512
544
 
513
- ## routerClass
545
+ ## router
514
546
 
515
- The `routerClass` option specify which router is used inside. The default router is `TrieRouter`. If you want to use `RexExpRouter`, write like this:
547
+ The `router` option specify which router is used inside. The default router is `TrieRouter`. If you want to use `RexExpRouter`, write like this:
516
548
 
517
549
  ```ts
518
550
  import { RegExpRouter } from 'hono/router/reg-exp-router'
519
551
 
520
- const app = new Hono({ routerClass: RegExpRouter })
552
+ const app = new Hono({ router: new RegExpRouter() })
553
+ ```
554
+
555
+ ## Routing Ordering
556
+
557
+ The routing priority is decided by the order of registration. Only one handler will be dispatched.
558
+
559
+ ```ts
560
+ app.get('/book/a', (c) => c.text('a')) // a
561
+ app.get('/book/:slug', (c) => c.text('common')) // common
562
+ ```
563
+
564
+ ```http
565
+ GET /book/a ---> `a` // common will not be dispatched
566
+ GET /book/b ---> `common` // a will not be dispatched
567
+ ```
568
+
569
+ All scoring rules:
570
+
571
+ ```ts
572
+ app.get('/api/*', 'c') // score 1.1 <--- `/*` is special wildcard
573
+ app.get('/api/:type/:id', 'd') // score 3.2
574
+ app.get('/api/posts/:id', 'e') // score 3.3
575
+ app.get('/api/posts/123', 'f') // score 3.4
576
+ app.get('/*/*/:id', 'g') // score 3.5
577
+ app.get('/api/posts/*/comment', 'h') // score 4.6 - not match
578
+ app.get('*', 'a') // score 0.7
579
+ app.get('*', 'b') // score 0.8
580
+ ```
581
+
582
+ ```plain
583
+ GET /api/posts/123
584
+ ---> will match => c, d, e, f, b, a, b
585
+ ---> sort by score => a, b, c, d, e, f, g
521
586
  ```
522
587
 
523
588
  ## Cloudflare Workers with Hono
@@ -607,6 +672,7 @@ export interface Bindings {
607
672
  }
608
673
 
609
674
  const api = new Hono<Bindings>()
675
+ api.use('/posts/*', cors())
610
676
 
611
677
  api.get('/posts', (c) => {
612
678
  const { limit, offset } = c.req.query()
@@ -633,8 +699,6 @@ api.post(
633
699
  }
634
700
  )
635
701
 
636
- app.use('/posts/*', cors())
637
-
638
702
  app.route('/api', api)
639
703
 
640
704
  export default app
package/dist/compose.js CHANGED
@@ -1,6 +1,9 @@
1
- import { Context } from './context';
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = void 0;
4
+ const context_1 = require("./context");
2
5
  // Based on the code in the MIT licensed `koa-compose` package.
3
- export const compose = (middleware, onError, onNotFound) => {
6
+ const compose = (middleware, onError, onNotFound) => {
4
7
  return async (context, next) => {
5
8
  let index = -1;
6
9
  return dispatch(0);
@@ -13,24 +16,26 @@ export const compose = (middleware, onError, onNotFound) => {
13
16
  if (i === middleware.length)
14
17
  handler = next;
15
18
  if (handler === undefined) {
16
- if (context instanceof Context && context.res === undefined) {
19
+ if (context instanceof context_1.Context && context.res.finalized === false) {
17
20
  context.res = onNotFound(context);
21
+ context.res.finalized = true;
18
22
  }
19
23
  return Promise.resolve(context);
20
24
  }
21
25
  return Promise.resolve(handler(context, dispatch.bind(null, i + 1)))
22
26
  .then(async (res) => {
23
27
  // If handler return Response like `return c.text('foo')`
24
- if (res && context instanceof Context) {
28
+ if (res && context instanceof context_1.Context) {
25
29
  context.res = res;
26
- dispatch(i + 1); // <--- Call next()
30
+ context.res.finalized = true;
27
31
  }
28
32
  return context;
29
33
  })
30
34
  .catch((err) => {
31
- if (onError && context instanceof Context) {
35
+ if (onError && context instanceof context_1.Context) {
32
36
  if (err instanceof Error) {
33
37
  context.res = onError(err, context);
38
+ context.res.finalized = true;
34
39
  }
35
40
  return context;
36
41
  }
@@ -41,3 +46,4 @@ export const compose = (middleware, onError, onNotFound) => {
41
46
  }
42
47
  };
43
48
  };
49
+ exports.compose = compose;
package/dist/context.d.ts CHANGED
@@ -8,18 +8,16 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
8
8
  res: Response;
9
9
  env: E;
10
10
  event: FetchEvent;
11
- private _headers;
12
11
  private _status;
13
- private _statusText;
14
12
  private _pretty;
15
13
  private _prettySpace;
16
14
  private _map;
17
15
  render: (template: string, params?: object, options?: object) => Promise<Response>;
18
16
  notFound: () => Response | Promise<Response>;
19
17
  constructor(req: Request<RequestParamKeyType>, opts?: {
20
- res: Response;
21
18
  env: E;
22
19
  event: FetchEvent;
20
+ res?: Response;
23
21
  });
24
22
  private initRequest;
25
23
  header(name: string, value: string): void;
package/dist/context.js CHANGED
@@ -1,16 +1,20 @@
1
- import { getStatusText } from './utils/http-status';
2
- import { isAbsoluteURL } from './utils/url';
3
- export class Context {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Context = void 0;
4
+ const url_1 = require("./utils/url");
5
+ class Context {
4
6
  constructor(req, opts) {
5
- this.res = undefined;
6
- this._headers = {};
7
7
  this._status = 200;
8
- this._statusText = '';
9
8
  this._pretty = false;
10
9
  this._prettySpace = 2;
11
10
  this.req = this.initRequest(req);
12
11
  this._map = {};
13
12
  Object.assign(this, opts);
13
+ if (!this.res) {
14
+ const res = new Response(null, { status: 404 });
15
+ res.finalized = false;
16
+ this.res = res;
17
+ }
14
18
  }
15
19
  initRequest(req) {
16
20
  req.header = ((name) => {
@@ -32,8 +36,21 @@ export class Context {
32
36
  }
33
37
  else {
34
38
  const result = {};
35
- for (const [key, value] of url.searchParams) {
36
- result[key] = value;
39
+ for (const key of url.searchParams.keys()) {
40
+ result[key] = url.searchParams.get(key);
41
+ }
42
+ return result;
43
+ }
44
+ });
45
+ req.queries = ((key) => {
46
+ const url = new URL(req.url);
47
+ if (key) {
48
+ return url.searchParams.getAll(key);
49
+ }
50
+ else {
51
+ const result = {};
52
+ for (const key of url.searchParams.keys()) {
53
+ result[key] = url.searchParams.getAll(key);
37
54
  }
38
55
  return result;
39
56
  }
@@ -41,14 +58,10 @@ export class Context {
41
58
  return req;
42
59
  }
43
60
  header(name, value) {
44
- if (this.res) {
45
- this.res.headers.set(name, value);
46
- }
47
- this._headers[name] = value;
61
+ this.res.headers.set(name, value);
48
62
  }
49
63
  status(status) {
50
64
  this._status = status;
51
- this._statusText = getStatusText(status);
52
65
  }
53
66
  set(key, value) {
54
67
  this._map[key] = value;
@@ -62,12 +75,15 @@ export class Context {
62
75
  }
63
76
  newResponse(data, init = {}) {
64
77
  init.status = init.status || this._status || 200;
65
- init.statusText =
66
- init.statusText || this._statusText || getStatusText(init.status);
67
- init.headers = { ...this._headers, ...init.headers };
78
+ let headers = {};
79
+ this.res.headers.forEach((v, k) => {
80
+ headers[k] = v;
81
+ });
82
+ init.headers = Object.assign(headers, init.headers);
83
+ headers = {};
68
84
  return new Response(data, init);
69
85
  }
70
- body(data, status = this._status, headers = this._headers) {
86
+ body(data, status = this._status, headers = {}) {
71
87
  return this.newResponse(data, {
72
88
  status: status,
73
89
  headers: headers,
@@ -101,7 +117,7 @@ export class Context {
101
117
  if (typeof location !== 'string') {
102
118
  throw new TypeError('location must be a string!');
103
119
  }
104
- if (!isAbsoluteURL(location)) {
120
+ if (!(0, url_1.isAbsoluteURL)(location)) {
105
121
  const url = new URL(this.req.url);
106
122
  url.pathname = location;
107
123
  location = url.toString();
@@ -114,3 +130,4 @@ export class Context {
114
130
  });
115
131
  }
116
132
  }
133
+ exports.Context = Context;
package/dist/hono.d.ts CHANGED
@@ -12,11 +12,18 @@ declare global {
12
12
  (key: string): string;
13
13
  (): Record<string, string>;
14
14
  };
15
+ queries: {
16
+ (key: string): string[];
17
+ (): Record<string, string[]>;
18
+ };
15
19
  header: {
16
20
  (name: string): string;
17
21
  (): Record<string, string>;
18
22
  };
19
23
  }
24
+ interface Response {
25
+ finalized: boolean;
26
+ }
20
27
  }
21
28
  export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | void | Promise<void>;
22
29
  export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response;
@@ -47,15 +54,13 @@ declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
47
54
  patch: HandlerInterface<T, E_1, U>;
48
55
  };
49
56
  export declare class Hono<E = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
50
- readonly routerClass: {
51
- new (): Router<any>;
52
- };
57
+ readonly router: Router<Handler<string, E>>;
53
58
  readonly strict: boolean;
54
- private _router;
55
59
  private _tempPath;
56
60
  private path;
61
+ private _cachedResponse;
57
62
  routes: Route<E>[];
58
- constructor(init?: Partial<Pick<Hono, 'routerClass' | 'strict'>>);
63
+ constructor(init?: Partial<Pick<Hono, 'router' | 'strict'>>);
59
64
  private notFoundHandler;
60
65
  private errorHandler;
61
66
  route(path: string, app?: Hono<any>): Hono<E, P>;
package/dist/hono.js CHANGED
@@ -1,18 +1,21 @@
1
- import { compose } from './compose';
2
- import { Context } from './context';
3
- import { METHOD_NAME_ALL } from './router';
4
- import { METHOD_NAME_ALL_LOWERCASE } from './router';
5
- import { TrieRouter } from './router/trie-router'; // Default Router
6
- import { getPathFromURL, mergePath } from './utils/url';
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Hono = void 0;
4
+ const compose_1 = require("./compose");
5
+ const context_1 = require("./context");
6
+ const router_1 = require("./router");
7
+ const router_2 = require("./router");
8
+ const trie_router_1 = require("./router/trie-router"); // Default Router
9
+ const url_1 = require("./utils/url");
7
10
  const methods = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch'];
8
11
  function defineDynamicClass() {
9
12
  return class {
10
13
  };
11
14
  }
12
- export class Hono extends defineDynamicClass() {
15
+ class Hono extends defineDynamicClass() {
13
16
  constructor(init = {}) {
14
17
  super();
15
- this.routerClass = TrieRouter;
18
+ this.router = new trie_router_1.TrieRouter();
16
19
  this.strict = true; // strict routing - default is true
17
20
  this.path = '/';
18
21
  this.routes = [];
@@ -25,7 +28,7 @@ export class Hono extends defineDynamicClass() {
25
28
  const message = 'Internal Server Error';
26
29
  return c.text(message, 500);
27
30
  };
28
- const allMethods = [...methods, METHOD_NAME_ALL_LOWERCASE];
31
+ const allMethods = [...methods, router_2.METHOD_NAME_ALL_LOWERCASE];
29
32
  allMethods.map((method) => {
30
33
  this[method] = (args1, ...args) => {
31
34
  if (typeof args1 === 'string') {
@@ -43,8 +46,9 @@ export class Hono extends defineDynamicClass() {
43
46
  };
44
47
  });
45
48
  Object.assign(this, init);
46
- this._router = new this.routerClass();
47
49
  this._tempPath = null;
50
+ this._cachedResponse = new Response(null, { status: 404 });
51
+ this._cachedResponse.finalized = false;
48
52
  }
49
53
  route(path, app) {
50
54
  this._tempPath = path;
@@ -64,7 +68,7 @@ export class Hono extends defineDynamicClass() {
64
68
  handlers.unshift(arg1);
65
69
  }
66
70
  handlers.map((handler) => {
67
- this.addRoute(METHOD_NAME_ALL, this.path, handler);
71
+ this.addRoute(router_1.METHOD_NAME_ALL, this.path, handler);
68
72
  });
69
73
  return this;
70
74
  }
@@ -79,17 +83,17 @@ export class Hono extends defineDynamicClass() {
79
83
  addRoute(method, path, handler) {
80
84
  method = method.toUpperCase();
81
85
  if (this._tempPath) {
82
- path = mergePath(this._tempPath, path);
86
+ path = (0, url_1.mergePath)(this._tempPath, path);
83
87
  }
84
- this._router.add(method, path, handler);
88
+ this.router.add(method, path, handler);
85
89
  const r = { path: path, method: method, handler: handler };
86
90
  this.routes.push(r);
87
91
  }
88
92
  async matchRoute(method, path) {
89
- return this._router.match(method, path);
93
+ return this.router.match(method, path);
90
94
  }
91
95
  async dispatch(request, event, env) {
92
- const path = getPathFromURL(request.url, { strict: this.strict });
96
+ const path = (0, url_1.getPathFromURL)(request.url, { strict: this.strict });
93
97
  const method = request.method;
94
98
  const result = await this.matchRoute(method, path);
95
99
  request.param = ((key) => {
@@ -103,9 +107,13 @@ export class Hono extends defineDynamicClass() {
103
107
  }
104
108
  });
105
109
  const handlers = result ? result.handlers : [this.notFoundHandler];
106
- const c = new Context(request, { env: env, event: event, res: undefined });
110
+ const c = new context_1.Context(request, {
111
+ env: env,
112
+ event: event,
113
+ res: this._cachedResponse,
114
+ });
107
115
  c.notFound = () => this.notFoundHandler(c);
108
- const composed = compose(handlers, this.errorHandler, this.notFoundHandler);
116
+ const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
109
117
  let context;
110
118
  try {
111
119
  context = await composed(c);
@@ -135,3 +143,4 @@ export class Hono extends defineDynamicClass() {
135
143
  });
136
144
  }
137
145
  }
146
+ exports.Hono = Hono;
@@ -8,7 +8,7 @@ declare type Options = {
8
8
  pretty?: boolean;
9
9
  validationRules?: ReadonlyArray<ValidationRule>;
10
10
  };
11
- export declare const graphqlServer: (options: Options) => (c: Context, next: Next) => Promise<void>;
11
+ export declare const graphqlServer: (options: Options) => (c: Context, next: Next) => Promise<Response>;
12
12
  export interface GraphQLParams {
13
13
  query: string | null;
14
14
  variables: {
@@ -13,13 +13,11 @@ const graphqlServer = (options) => {
13
13
  const validationRules = (_b = options.validationRules) !== null && _b !== void 0 ? _b : [];
14
14
  // const showGraphiQL = options.graphiql ?? false
15
15
  return async (c, next) => {
16
- await next();
17
16
  // GraphQL HTTP only supports GET and POST methods.
18
17
  if (c.req.method !== 'GET' && c.req.method !== 'POST') {
19
- c.res = c.json((0, exports.errorMessages)(['GraphQL only supports GET and POST requests.']), 405, {
18
+ return c.json((0, exports.errorMessages)(['GraphQL only supports GET and POST requests.']), 405, {
20
19
  Allow: 'GET, POST',
21
20
  });
22
- return;
23
21
  }
24
22
  let params;
25
23
  try {
@@ -28,20 +26,17 @@ const graphqlServer = (options) => {
28
26
  catch (e) {
29
27
  if (e instanceof Error) {
30
28
  console.error(`${e.stack || e.message}`);
31
- c.res = c.json((0, exports.errorMessages)([e.message], [e]), 400);
29
+ return c.json((0, exports.errorMessages)([e.message], [e]), 400);
32
30
  }
33
- return;
34
31
  }
35
32
  const { query, variables, operationName } = params;
36
33
  if (query == null) {
37
- c.res = c.json((0, exports.errorMessages)(['Must provide query string.']), 400);
38
- return;
34
+ return c.json((0, exports.errorMessages)(['Must provide query string.']), 400);
39
35
  }
40
36
  const schemaValidationErrors = (0, graphql_1.validateSchema)(schema);
41
37
  if (schemaValidationErrors.length > 0) {
42
38
  // Return 500: Internal Server Error if invalid schema.
43
- c.res = c.json((0, exports.errorMessages)(['GraphQL schema validation error.'], schemaValidationErrors), 500);
44
- return;
39
+ return c.json((0, exports.errorMessages)(['GraphQL schema validation error.'], schemaValidationErrors), 500);
45
40
  }
46
41
  let documentAST;
47
42
  try {
@@ -54,16 +49,14 @@ const graphqlServer = (options) => {
54
49
  const e = new graphql_1.GraphQLError(syntaxError.message, {
55
50
  originalError: syntaxError,
56
51
  });
57
- c.res = c.json((0, exports.errorMessages)(['GraphQL syntax error.'], [e]), 400);
52
+ return c.json((0, exports.errorMessages)(['GraphQL syntax error.'], [e]), 400);
58
53
  }
59
- return;
60
54
  }
61
55
  // Validate AST, reporting any errors.
62
56
  const validationErrors = (0, graphql_1.validate)(schema, documentAST, [...graphql_1.specifiedRules, ...validationRules]);
63
57
  if (validationErrors.length > 0) {
64
58
  // Return 400: Bad Request if any validation errors exist.
65
- c.res = c.json((0, exports.errorMessages)(['GraphQL validation error.'], validationErrors), 400);
66
- return;
59
+ return c.json((0, exports.errorMessages)(['GraphQL validation error.'], validationErrors), 400);
67
60
  }
68
61
  if (c.req.method === 'GET') {
69
62
  // Determine if this GET request will perform a non-query.
@@ -76,10 +69,9 @@ const graphqlServer = (options) => {
76
69
  }
77
70
  */
78
71
  // Otherwise, report a 405: Method Not Allowed error.
79
- c.res = c.json((0, exports.errorMessages)([
72
+ return c.json((0, exports.errorMessages)([
80
73
  `Can only perform a ${operationAST.operation} operation from a POST request.`,
81
74
  ]), 405, { Allow: 'POST' });
82
- return;
83
75
  }
84
76
  }
85
77
  let result;
@@ -100,13 +92,11 @@ const graphqlServer = (options) => {
100
92
  nodes: documentAST,
101
93
  });
102
94
  // Return 400: Bad Request if any execution context errors exist.
103
- c.res = c.json((0, exports.errorMessages)(['GraphQL execution context error.'], [e]), 400);
95
+ return c.json((0, exports.errorMessages)(['GraphQL execution context error.'], [e]), 400);
104
96
  }
105
- return;
106
97
  }
107
98
  if (result.data == null) {
108
- c.res = c.json((0, exports.errorMessages)([result.errors.toString()], result.errors), 500);
109
- return;
99
+ return c.json((0, exports.errorMessages)([result.errors.toString()], result.errors), 500);
110
100
  }
111
101
  /*
112
102
  Now, does not support GraphiQL
@@ -115,14 +105,14 @@ const graphqlServer = (options) => {
115
105
  */
116
106
  if (pretty) {
117
107
  const payload = JSON.stringify(result, null, pretty ? 2 : 0);
118
- c.res = c.text(payload, 200, {
108
+ return c.text(payload, 200, {
119
109
  'Content-Type': 'application/json',
120
110
  });
121
111
  }
122
112
  else {
123
- c.res = c.json(result);
113
+ return c.json(result);
124
114
  }
125
- return;
115
+ await next(); // XXX
126
116
  };
127
117
  };
128
118
  exports.graphqlServer = graphqlServer;
@@ -8,7 +8,6 @@ const jwt = (options) => {
8
8
  }
9
9
  return async (ctx, next) => {
10
10
  const credentials = ctx.req.headers.get('Authorization');
11
- await next();
12
11
  if (!credentials) {
13
12
  ctx.res = new Response('Unauthorized', {
14
13
  status: 401,
@@ -26,6 +25,7 @@ const jwt = (options) => {
26
25
  'WWW-Authenticate': 'Basic ${options.secret}',
27
26
  },
28
27
  });
28
+ return;
29
29
  }
30
30
  let authorized = false;
31
31
  let msg = '';
@@ -43,7 +43,9 @@ const jwt = (options) => {
43
43
  'WWW-Authenticate': 'Bearer ${options.secret}',
44
44
  },
45
45
  });
46
+ return;
46
47
  }
48
+ await next();
47
49
  };
48
50
  };
49
51
  exports.jwt = jwt;
@@ -1,13 +1,19 @@
1
- import Mustache from 'mustache';
2
- import { bufferToString } from '../../utils/buffer';
3
- import { getContentFromKVAsset, getKVFilePath } from '../../utils/cloudflare';
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mustache = void 0;
7
+ const mustache_1 = __importDefault(require("mustache"));
8
+ const buffer_1 = require("../../utils/buffer");
9
+ const cloudflare_1 = require("../../utils/cloudflare");
4
10
  const EXTENSION = '.mustache';
5
11
  const DEFAULT_DOCUMENT = 'index.mustache';
6
- export const mustache = (init = { root: '' }) => {
12
+ const mustache = (init = { root: '' }) => {
7
13
  const { root } = init;
8
14
  return async (c, next) => {
9
15
  c.render = async (filename, params = {}, options) => {
10
- const path = getKVFilePath({
16
+ const path = (0, cloudflare_1.getKVFilePath)({
11
17
  filename: `${filename}${EXTENSION}`,
12
18
  root: root,
13
19
  defaultDocument: DEFAULT_DOCUMENT,
@@ -16,30 +22,31 @@ export const mustache = (init = { root: '' }) => {
16
22
  manifest: init.manifest,
17
23
  namespace: init.namespace ? init.namespace : c.env ? c.env.__STATIC_CONTENT : undefined,
18
24
  };
19
- const buffer = await getContentFromKVAsset(path, kvAssetOptions);
25
+ const buffer = await (0, cloudflare_1.getContentFromKVAsset)(path, kvAssetOptions);
20
26
  if (!buffer) {
21
27
  throw new Error(`Template "${path}" is not found or blank.`);
22
28
  }
23
- const content = bufferToString(buffer);
29
+ const content = (0, buffer_1.bufferToString)(buffer);
24
30
  const partialArgs = {};
25
31
  if (options) {
26
32
  const partials = options;
27
33
  for (const key of Object.keys(partials)) {
28
- const partialPath = getKVFilePath({
34
+ const partialPath = (0, cloudflare_1.getKVFilePath)({
29
35
  filename: `${partials[key]}${EXTENSION}`,
30
36
  root: root,
31
37
  defaultDocument: DEFAULT_DOCUMENT,
32
38
  });
33
- const partialBuffer = await getContentFromKVAsset(partialPath, kvAssetOptions);
39
+ const partialBuffer = await (0, cloudflare_1.getContentFromKVAsset)(partialPath, kvAssetOptions);
34
40
  if (!partialBuffer) {
35
41
  throw new Error(`Partial Template "${partialPath}" is not found or blank.`);
36
42
  }
37
- partialArgs[key] = bufferToString(partialBuffer);
43
+ partialArgs[key] = (0, buffer_1.bufferToString)(partialBuffer);
38
44
  }
39
45
  }
40
- const output = Mustache.render(content, params, partialArgs);
46
+ const output = mustache_1.default.render(content, params, partialArgs);
41
47
  return c.html(output);
42
48
  };
43
49
  await next();
44
50
  };
45
51
  };
52
+ exports.mustache = mustache;