hono 0.0.10 → 0.0.14

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.
Files changed (43) hide show
  1. package/README.md +212 -75
  2. package/dist/compose.d.ts +1 -0
  3. package/dist/compose.js +27 -0
  4. package/dist/context.d.ts +23 -0
  5. package/dist/context.js +65 -0
  6. package/dist/hono.d.ts +44 -0
  7. package/dist/hono.js +147 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.js +9 -0
  10. package/dist/middleware/basic-auth/basic-auth.d.ts +6 -0
  11. package/dist/middleware/basic-auth/basic-auth.js +50 -0
  12. package/dist/middleware/body-parse/body-parse.d.ts +2 -0
  13. package/dist/middleware/body-parse/body-parse.js +27 -0
  14. package/dist/middleware/default.d.ts +2 -0
  15. package/dist/middleware/default.js +16 -0
  16. package/dist/middleware/logger/logger.d.ts +6 -0
  17. package/dist/middleware/logger/logger.js +58 -0
  18. package/dist/middleware/powered-by/powered-by.d.ts +2 -0
  19. package/dist/middleware/powered-by/powered-by.js +11 -0
  20. package/dist/middleware.d.ts +15 -0
  21. package/dist/middleware.js +16 -0
  22. package/dist/node.d.ts +24 -0
  23. package/dist/node.js +104 -0
  24. package/dist/util.d.ts +5 -0
  25. package/dist/util.js +72 -0
  26. package/package.json +34 -5
  27. package/CODE_OF_CONDUCT.md +0 -128
  28. package/src/compose.js +0 -21
  29. package/src/compose.test.js +0 -42
  30. package/src/hono.d.ts +0 -67
  31. package/src/hono.js +0 -141
  32. package/src/hono.test.js +0 -158
  33. package/src/methods.js +0 -30
  34. package/src/middleware/defaultFilter.js +0 -19
  35. package/src/middleware/poweredBy.js +0 -6
  36. package/src/middleware/poweredBy.test.js +0 -17
  37. package/src/middleware.js +0 -9
  38. package/src/middleware.test.js +0 -17
  39. package/src/node.js +0 -97
  40. package/src/node.test.js +0 -135
  41. package/src/router.test.js +0 -88
  42. package/src/util.js +0 -33
  43. package/src/util.test.js +0 -44
package/dist/hono.js ADDED
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Hono = exports.Router = void 0;
4
+ const node_1 = require("./node");
5
+ const compose_1 = require("./compose");
6
+ const util_1 = require("./util");
7
+ const middleware_1 = require("./middleware");
8
+ const context_1 = require("./context");
9
+ const METHOD_NAME_OF_ALL = 'ALL';
10
+ class Router {
11
+ constructor() {
12
+ this.node = new node_1.Node();
13
+ }
14
+ add(method, path, handler) {
15
+ this.node.insert(method, path, handler);
16
+ }
17
+ match(method, path) {
18
+ return this.node.search(method, path);
19
+ }
20
+ }
21
+ exports.Router = Router;
22
+ class Hono {
23
+ constructor() {
24
+ this.router = new Router();
25
+ this.middlewareRouters = [];
26
+ this.tempPath = '/';
27
+ }
28
+ /* HTTP METHODS */
29
+ get(arg, ...args) {
30
+ return this.addRoute('get', arg, ...args);
31
+ }
32
+ post(arg, ...args) {
33
+ return this.addRoute('post', arg, ...args);
34
+ }
35
+ put(arg, ...args) {
36
+ return this.addRoute('put', arg, ...args);
37
+ }
38
+ head(arg, ...args) {
39
+ return this.addRoute('head', arg, ...args);
40
+ }
41
+ delete(arg, ...args) {
42
+ return this.addRoute('delete', arg, ...args);
43
+ }
44
+ options(arg, ...args) {
45
+ return this.addRoute('options', arg, ...args);
46
+ }
47
+ patch(arg, ...args) {
48
+ return this.addRoute('patch', arg, ...args);
49
+ }
50
+ /*
51
+ trace
52
+ copy
53
+ lock
54
+ purge
55
+ unlock
56
+ report
57
+ checkout
58
+ merge
59
+ notify
60
+ subscribe
61
+ unsubscribe
62
+ search
63
+ connect
64
+ */
65
+ all(arg, ...args) {
66
+ return this.addRoute('all', arg, ...args);
67
+ }
68
+ route(path) {
69
+ this.tempPath = path;
70
+ return this;
71
+ }
72
+ use(path, middleware) {
73
+ if (middleware.constructor.name !== 'AsyncFunction') {
74
+ throw new TypeError('middleware must be a async function!');
75
+ }
76
+ const router = new Router();
77
+ router.add(METHOD_NAME_OF_ALL, path, middleware);
78
+ this.middlewareRouters.push(router);
79
+ }
80
+ // addRoute('get', '/', handler)
81
+ addRoute(method, arg, ...args) {
82
+ method = method.toUpperCase();
83
+ if (typeof arg === 'string') {
84
+ this.tempPath = arg;
85
+ this.router.add(method, arg, args);
86
+ }
87
+ else {
88
+ args.unshift(arg);
89
+ this.router.add(method, this.tempPath, args);
90
+ }
91
+ return this;
92
+ }
93
+ async matchRoute(method, path) {
94
+ return this.router.match(method, path);
95
+ }
96
+ async dispatch(request, env, event) {
97
+ const [method, path] = [request.method, (0, util_1.getPathFromURL)(request.url)];
98
+ const result = await this.matchRoute(method, path);
99
+ request.params = (key) => {
100
+ if (result) {
101
+ return result.params[key];
102
+ }
103
+ return '';
104
+ };
105
+ const handler = result ? result.handler[0] : this.notFound; // XXX
106
+ const middleware = [];
107
+ for (const mr of this.middlewareRouters) {
108
+ const mwResult = mr.match(METHOD_NAME_OF_ALL, path);
109
+ if (mwResult) {
110
+ middleware.push(mwResult.handler);
111
+ }
112
+ }
113
+ const wrappedHandler = async (context, next) => {
114
+ context.res = await handler(context);
115
+ await next();
116
+ };
117
+ middleware.push(middleware_1.Middleware.default);
118
+ middleware.push(wrappedHandler);
119
+ const composed = (0, compose_1.compose)(middleware);
120
+ const c = new context_1.Context(request, { env: env, event: event, res: null });
121
+ await composed(c);
122
+ return c.res;
123
+ }
124
+ async handleEvent(event) {
125
+ return this.dispatch(event.request, {}, event).catch((err) => {
126
+ return this.onError(err);
127
+ });
128
+ }
129
+ async fetch(request, env, event) {
130
+ return this.dispatch(request, env, event).catch((err) => {
131
+ return this.onError(err);
132
+ });
133
+ }
134
+ fire() {
135
+ addEventListener('fetch', (event) => {
136
+ event.respondWith(this.handleEvent(event));
137
+ });
138
+ }
139
+ onError(err) {
140
+ console.error(err);
141
+ return new Response('Internal Server Error', { status: 500 });
142
+ }
143
+ notFound() {
144
+ return new Response('Not Found', { status: 404 });
145
+ }
146
+ }
147
+ exports.Hono = Hono;
@@ -0,0 +1,5 @@
1
+ export { Hono } from './hono';
2
+ export type { Handler, MiddlewareHandler } from './hono';
3
+ export { Middleware } from './middleware';
4
+ export { Context } from './context';
5
+ export type { Env } from './context';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Context = exports.Middleware = exports.Hono = void 0;
4
+ var hono_1 = require("./hono");
5
+ Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
6
+ var middleware_1 = require("./middleware");
7
+ Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
8
+ var context_1 = require("./context");
9
+ Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
@@ -0,0 +1,6 @@
1
+ import type { Context } from '../../context';
2
+ export declare const basicAuth: (options: {
3
+ username: string;
4
+ password: string;
5
+ realm?: string;
6
+ }) => (ctx: Context, next: Function) => Promise<any>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.basicAuth = void 0;
4
+ const util_1 = require("../../util");
5
+ const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
6
+ const USER_PASS_REGEXP = /^([^:]*):(.*)$/;
7
+ const auth = (req) => {
8
+ if (!req) {
9
+ throw new TypeError('argument req is required');
10
+ }
11
+ if (typeof req !== 'object') {
12
+ throw new TypeError('argument req is required to be an object');
13
+ }
14
+ if (!req.headers || typeof req.headers !== 'object') {
15
+ throw new TypeError('argument req is required to have headers property');
16
+ }
17
+ const match = CREDENTIALS_REGEXP.exec(req.headers.get('Authorization'));
18
+ if (!match) {
19
+ return undefined;
20
+ }
21
+ const userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]));
22
+ if (!userPass) {
23
+ return undefined;
24
+ }
25
+ return { username: userPass[1], password: userPass[2] };
26
+ };
27
+ function decodeBase64(str) {
28
+ return Buffer.from(str, 'base64').toString();
29
+ }
30
+ const basicAuth = (options) => {
31
+ if (!options.realm) {
32
+ options.realm = 'Secure Area';
33
+ }
34
+ return async (ctx, next) => {
35
+ const user = auth(ctx.req);
36
+ const usernameEqual = user && await (0, util_1.timingSafeEqual)(options.username, user.username);
37
+ const passwordEqual = user && await (0, util_1.timingSafeEqual)(options.password, user.password);
38
+ if (!user || !usernameEqual || !passwordEqual) {
39
+ ctx.res = new Response('Unauthorized', {
40
+ status: 401,
41
+ headers: {
42
+ 'WWW-Authenticate': 'Basic realm="' + options.realm.replace(/"/g, '\\"') + '"',
43
+ },
44
+ });
45
+ return;
46
+ }
47
+ return next();
48
+ };
49
+ };
50
+ exports.basicAuth = basicAuth;
@@ -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>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultMiddleware = void 0;
4
+ const defaultMiddleware = async (c, next) => {
5
+ c.req.query = (key) => {
6
+ // eslint-disable-next-line
7
+ const url = new URL(c.req.url);
8
+ return url.searchParams.get(key);
9
+ };
10
+ await next();
11
+ if (c.res.body) {
12
+ const buff = await c.res.clone().arrayBuffer();
13
+ c.res.headers.append('Content-Length', buff.byteLength.toString());
14
+ }
15
+ };
16
+ exports.defaultMiddleware = defaultMiddleware;
@@ -0,0 +1,6 @@
1
+ import type { Context } from '../../context';
2
+ export declare const logger: (fn?: {
3
+ (...data: any[]): void;
4
+ (...data: any[]): void;
5
+ (message?: any, ...optionalParams: any[]): void;
6
+ }) => (c: Context, next: Function) => Promise<void>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ const util_1 = require("../../util");
5
+ const humanize = (n, opts) => {
6
+ const options = opts || {};
7
+ const d = options.delimiter || ',';
8
+ const s = options.separator || '.';
9
+ n = n.toString().split('.');
10
+ n[0] = n[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + d);
11
+ return n.join(s);
12
+ };
13
+ const time = (start) => {
14
+ const delta = Date.now() - start;
15
+ return humanize([
16
+ delta < 10000 ? delta + 'ms' : Math.round(delta / 1000) + 's',
17
+ ]);
18
+ };
19
+ const LogPrefix = {
20
+ Outgoing: '-->',
21
+ Incoming: '<--',
22
+ Error: 'xxx',
23
+ };
24
+ const colorStatus = (status = 0) => {
25
+ const out = {
26
+ 7: `\x1b[35m${status}\x1b[0m`,
27
+ 5: `\x1b[31m${status}\x1b[0m`,
28
+ 4: `\x1b[33m${status}\x1b[0m`,
29
+ 3: `\x1b[36m${status}\x1b[0m`,
30
+ 2: `\x1b[32m${status}\x1b[0m`,
31
+ 1: `\x1b[32m${status}\x1b[0m`,
32
+ 0: `\x1b[33m${status}\x1b[0m`,
33
+ };
34
+ return out[(status / 100) | 0];
35
+ };
36
+ function log(fn, prefix, method, path, status, elasped) {
37
+ const out = prefix === LogPrefix.Incoming
38
+ ? ` ${prefix} ${method} ${path}`
39
+ : ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elasped}`;
40
+ fn(out);
41
+ }
42
+ const logger = (fn = console.log) => {
43
+ return async (c, next) => {
44
+ const { method } = c.req;
45
+ const path = (0, util_1.getPathFromURL)(c.req.url);
46
+ log(fn, LogPrefix.Incoming, method, path);
47
+ const start = Date.now();
48
+ try {
49
+ await next();
50
+ }
51
+ catch (e) {
52
+ log(fn, LogPrefix.Error, method, path, c.res.status || 500, time(start));
53
+ throw e;
54
+ }
55
+ log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start));
56
+ };
57
+ };
58
+ exports.logger = logger;
@@ -0,0 +1,2 @@
1
+ import type { Context } from '../../context';
2
+ export declare const poweredBy: () => (c: Context, next: Function) => Promise<void>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.poweredBy = void 0;
4
+ const poweredBy = () => {
5
+ return async (c, next) => {
6
+ await next();
7
+ // await c.res.headers.append('X-Powered-By', 'Hono')
8
+ c.res.headers.append('X-Powered-By', 'Hono');
9
+ };
10
+ };
11
+ exports.poweredBy = poweredBy;
@@ -0,0 +1,15 @@
1
+ export declare class Middleware {
2
+ static default: (c: import("./context").Context, next: Function) => Promise<void>;
3
+ static poweredBy: () => (c: import("./context").Context, next: Function) => Promise<void>;
4
+ static logger: (fn?: {
5
+ (...data: any[]): void;
6
+ (...data: any[]): void;
7
+ (message?: any, ...optionalParams: any[]): void;
8
+ }) => (c: import("./context").Context, next: Function) => Promise<void>;
9
+ static basicAuth: (options: {
10
+ username: string;
11
+ password: string;
12
+ realm?: string;
13
+ }) => (ctx: import("./context").Context, next: Function) => Promise<any>;
14
+ static bodyParse: () => (ctx: import("./context").Context, next: Function) => Promise<void>;
15
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Middleware = void 0;
4
+ const default_1 = require("./middleware/default");
5
+ const powered_by_1 = require("./middleware/powered-by/powered-by");
6
+ const logger_1 = require("./middleware/logger/logger");
7
+ const basic_auth_1 = require("./middleware/basic-auth/basic-auth");
8
+ const body_parse_1 = require("./middleware/body-parse/body-parse");
9
+ class Middleware {
10
+ }
11
+ exports.Middleware = Middleware;
12
+ Middleware.default = default_1.defaultMiddleware;
13
+ Middleware.poweredBy = powered_by_1.poweredBy;
14
+ Middleware.logger = logger_1.logger;
15
+ Middleware.basicAuth = basic_auth_1.basicAuth;
16
+ Middleware.bodyParse = body_parse_1.bodyParse;
package/dist/node.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ export declare class Result<T> {
2
+ handler: T;
3
+ params: {
4
+ [key: string]: string;
5
+ };
6
+ constructor(handler: T, params: {
7
+ [key: string]: string;
8
+ });
9
+ }
10
+ export declare class Node<T> {
11
+ method: {
12
+ [key: string]: T;
13
+ };
14
+ handler: T;
15
+ children: {
16
+ [key: string]: Node<T>;
17
+ };
18
+ middlewares: [];
19
+ constructor(method?: string, handler?: any, children?: {
20
+ [key: string]: Node<T>;
21
+ });
22
+ insert(method: string, path: string, handler: T): Node<T>;
23
+ search(method: string, path: string): Result<T>;
24
+ }
package/dist/node.js ADDED
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Node = exports.Result = void 0;
4
+ const util_1 = require("./util");
5
+ const METHOD_NAME_OF_ALL = 'ALL';
6
+ class Result {
7
+ constructor(handler, params) {
8
+ this.handler = handler;
9
+ this.params = params;
10
+ }
11
+ }
12
+ exports.Result = Result;
13
+ const noRoute = () => {
14
+ return null;
15
+ };
16
+ class Node {
17
+ constructor(method, handler, children) {
18
+ this.children = children || {};
19
+ this.method = {};
20
+ if (method && handler) {
21
+ this.method[method] = handler;
22
+ }
23
+ this.middlewares = [];
24
+ }
25
+ insert(method, path, handler) {
26
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
27
+ let curNode = this;
28
+ const parts = (0, util_1.splitPath)(path);
29
+ for (let i = 0, len = parts.length; i < len; i++) {
30
+ const p = parts[i];
31
+ if (Object.keys(curNode.children).includes(p)) {
32
+ curNode = curNode.children[p];
33
+ continue;
34
+ }
35
+ curNode.children[p] = new Node();
36
+ curNode = curNode.children[p];
37
+ }
38
+ curNode.method[method] = handler;
39
+ return curNode;
40
+ }
41
+ search(method, path) {
42
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
43
+ let curNode = this;
44
+ const params = {};
45
+ const parts = (0, util_1.splitPath)(path);
46
+ for (let i = 0, len = parts.length; i < len; i++) {
47
+ const p = parts[i];
48
+ // '*' => match any path
49
+ if (curNode.children['*']) {
50
+ const astNode = curNode.children['*'];
51
+ if (Object.keys(astNode.children).length === 0) {
52
+ curNode = astNode;
53
+ break;
54
+ }
55
+ }
56
+ const nextNode = curNode.children[p];
57
+ if (nextNode) {
58
+ curNode = nextNode;
59
+ // '/hello/*' => match '/hello'
60
+ if (!(i == len - 1 && nextNode.children['*'])) {
61
+ continue;
62
+ }
63
+ }
64
+ let isWildcard = false;
65
+ let isParamMatch = false;
66
+ const keys = Object.keys(curNode.children);
67
+ for (let j = 0, len = keys.length; j < len; j++) {
68
+ const key = keys[j];
69
+ // Wildcard
70
+ // '/hello/*/foo' => match /hello/bar/foo
71
+ if (key === '*') {
72
+ curNode = curNode.children['*'];
73
+ isWildcard = true;
74
+ break;
75
+ }
76
+ const pattern = (0, util_1.getPattern)(key);
77
+ // Named match
78
+ if (pattern) {
79
+ const match = p.match(new RegExp(pattern[1]));
80
+ if (match) {
81
+ const k = pattern[0];
82
+ params[k] = match[1];
83
+ curNode = curNode.children[key];
84
+ isParamMatch = true;
85
+ break;
86
+ }
87
+ return noRoute();
88
+ }
89
+ }
90
+ if (isWildcard && i === len - 1) {
91
+ break;
92
+ }
93
+ if (isWildcard === false && isParamMatch === false) {
94
+ return noRoute();
95
+ }
96
+ }
97
+ const handler = curNode.method[METHOD_NAME_OF_ALL] || curNode.method[method];
98
+ if (!handler) {
99
+ return noRoute();
100
+ }
101
+ return new Result(handler, params);
102
+ }
103
+ }
104
+ exports.Node = Node;
package/dist/util.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare const splitPath: (path: string) => string[];
2
+ export declare const getPattern: (label: string) => string[] | null;
3
+ export declare const getPathFromURL: (url: string) => string;
4
+ export declare const isAbsoluteURL: (url: string) => boolean;
5
+ export declare const timingSafeEqual: (a: any, b: any) => Promise<boolean>;
package/dist/util.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timingSafeEqual = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
4
+ const URL_REGEXP = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
5
+ const splitPath = (path) => {
6
+ const paths = path.split(/\//); // faster than path.split('/')
7
+ if (paths[0] === '') {
8
+ paths.shift();
9
+ }
10
+ return paths;
11
+ };
12
+ exports.splitPath = splitPath;
13
+ const getPattern = (label) => {
14
+ // :id{[0-9]+} => ([0-9]+)
15
+ // :id => (.+)
16
+ //const name = ''
17
+ const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
18
+ if (match) {
19
+ if (match[2]) {
20
+ return [match[1], '(' + match[2] + ')'];
21
+ }
22
+ else {
23
+ return [match[1], '(.+)'];
24
+ }
25
+ }
26
+ return null;
27
+ };
28
+ exports.getPattern = getPattern;
29
+ const getPathFromURL = (url) => {
30
+ // XXX
31
+ const match = url.match(URL_REGEXP);
32
+ if (match) {
33
+ return match[5];
34
+ }
35
+ return '';
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;
46
+ const bufferEqual = (a, b) => {
47
+ if (a === b) {
48
+ return true;
49
+ }
50
+ if (a.byteLength !== b.byteLength) {
51
+ return false;
52
+ }
53
+ const va = new DataView(a);
54
+ const vb = new DataView(b);
55
+ let i = va.byteLength;
56
+ while (i--) {
57
+ if (va.getUint8(i) !== vb.getUint8(i)) {
58
+ return false;
59
+ }
60
+ }
61
+ return true;
62
+ };
63
+ const timingSafeEqual = async (a, b) => {
64
+ const sa = await crypto.subtle.digest({
65
+ name: 'SHA-256',
66
+ }, new TextEncoder().encode(String(a)));
67
+ const sb = await crypto.subtle.digest({
68
+ name: 'SHA-256',
69
+ }, new TextEncoder().encode(String(b)));
70
+ return bufferEqual(sa, sb) && a === b;
71
+ };
72
+ exports.timingSafeEqual = timingSafeEqual;
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "0.0.10",
4
- "description": "Minimal web framework for Cloudflare Workers and Fastly Compute@Edge",
5
- "main": "src/hono.js",
3
+ "version": "0.0.14",
4
+ "description": "[炎] Ultrafast web framework for Cloudflare Workers.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
6
10
  "scripts": {
7
- "test": "jest"
11
+ "test": "jest",
12
+ "lint": "eslint --ext js,ts src .eslintrc.js test",
13
+ "build": "rimraf dist && tsc",
14
+ "watch": "tsc -w",
15
+ "prepublishOnly": "yarn build"
8
16
  },
9
17
  "author": "Yusuke Wada <yusuke@kamawada.com> (https://github.com/yusukebe)",
10
18
  "license": "MIT",
@@ -26,7 +34,28 @@
26
34
  "compute@edge"
27
35
  ],
28
36
  "devDependencies": {
37
+ "@cloudflare/workers-types": "^3.3.0",
38
+ "@types/jest": "^27.4.0",
39
+ "@types/node": "^17.0.8",
40
+ "@typescript-eslint/eslint-plugin": "^5.9.0",
41
+ "@typescript-eslint/parser": "^5.9.0",
42
+ "eslint": "^7.26.0",
43
+ "eslint-config-prettier": "^8.1.0",
44
+ "eslint-define-config": "^1.2.1",
45
+ "eslint-import-resolver-typescript": "^2.0.0",
46
+ "eslint-plugin-eslint-comments": "^3.2.0",
47
+ "eslint-plugin-flowtype": "^5.7.2",
48
+ "eslint-plugin-import": "^2.20.2",
49
+ "eslint-plugin-node": "^11.1.0",
50
+ "eslint-plugin-prettier": "^4.0.0",
51
+ "form-data": "^4.0.0",
29
52
  "jest": "^27.4.5",
30
- "node-fetch": "^2.6.6"
53
+ "jest-environment-miniflare": "^2.0.0",
54
+ "rimraf": "^3.0.2",
55
+ "ts-jest": "^27.1.2",
56
+ "typescript": "^4.5.4"
57
+ },
58
+ "engines": {
59
+ "node": ">=11.0.0"
31
60
  }
32
61
  }