hono 0.3.8 → 0.4.2

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.
@@ -1,15 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Node = exports.Result = void 0;
4
- const url_1 = require("./utils/url");
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;
3
+ exports.Node = void 0;
4
+ const url_1 = require("../../utils/url");
5
+ const router_1 = require("../../router");
13
6
  const noRoute = () => {
14
7
  return null;
15
8
  };
@@ -21,6 +14,7 @@ class Node {
21
14
  this.method[method] = handler;
22
15
  }
23
16
  this.middlewares = [];
17
+ this.patterns = [];
24
18
  }
25
19
  insert(method, path, handler) {
26
20
  // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -33,6 +27,10 @@ class Node {
33
27
  continue;
34
28
  }
35
29
  curNode.children[p] = new Node();
30
+ const pattern = (0, url_1.getPattern)(p);
31
+ if (pattern) {
32
+ curNode.patterns.push(pattern);
33
+ }
36
34
  curNode = curNode.children[p];
37
35
  }
38
36
  curNode.method[method] = handler;
@@ -64,29 +62,24 @@ class Node {
64
62
  }
65
63
  let isWildcard = false;
66
64
  let isParamMatch = false;
67
- const keys = Object.keys(curNode.children);
68
- for (let j = 0, len = keys.length; j < len; j++) {
69
- const key = keys[j];
65
+ for (let j = 0, len = curNode.patterns.length; j < len; j++) {
66
+ const pattern = curNode.patterns[j];
70
67
  // Wildcard
71
68
  // '/hello/*/foo' => match /hello/bar/foo
72
- if (key === '*') {
69
+ if (pattern === '*') {
73
70
  curNode = curNode.children['*'];
74
71
  isWildcard = true;
75
72
  break;
76
73
  }
77
- const pattern = (0, url_1.getPattern)(key);
78
74
  // Named match
79
- if (pattern) {
80
- const match = p.match(new RegExp(pattern[1]));
81
- if (match) {
82
- const k = pattern[0];
83
- params[k] = match[1];
84
- curNode = curNode.children[key];
85
- isParamMatch = true;
86
- break;
87
- }
88
- return noRoute();
75
+ const [key, name, matcher] = pattern;
76
+ if (p !== '' && (matcher === true || matcher.test(p))) {
77
+ params[name] = p;
78
+ curNode = curNode.children[key];
79
+ isParamMatch = true;
80
+ break;
89
81
  }
82
+ return noRoute();
90
83
  }
91
84
  if (isWildcard && i === len - 1) {
92
85
  break;
@@ -95,11 +88,11 @@ class Node {
95
88
  return noRoute();
96
89
  }
97
90
  }
98
- const handler = curNode.method[METHOD_NAME_OF_ALL] || curNode.method[method];
91
+ const handler = curNode.method[router_1.METHOD_NAME_OF_ALL] || curNode.method[method];
99
92
  if (!handler) {
100
93
  return noRoute();
101
94
  }
102
- return new Result(handler, params);
95
+ return new router_1.Result(handler, params);
103
96
  }
104
97
  }
105
98
  exports.Node = Node;
@@ -0,0 +1,9 @@
1
+ import { Router } from '../../router';
2
+ import type { Result } from '../../router';
3
+ import { Node } from './node';
4
+ export declare class TrieRouter<T> extends Router<T> {
5
+ node: Node<T>;
6
+ constructor();
7
+ add(method: string, path: string, handler: T): void;
8
+ match(method: string, path: string): Result<T> | null;
9
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrieRouter = void 0;
4
+ const router_1 = require("../../router");
5
+ const node_1 = require("./node");
6
+ class TrieRouter extends router_1.Router {
7
+ constructor() {
8
+ super();
9
+ this.node = new node_1.Node();
10
+ }
11
+ add(method, path, handler) {
12
+ this.node.insert(method, path, handler);
13
+ }
14
+ match(method, path) {
15
+ return this.node.search(method, path);
16
+ }
17
+ }
18
+ exports.TrieRouter = TrieRouter;
@@ -0,0 +1,10 @@
1
+ export declare const METHOD_NAME_OF_ALL = "ALL";
2
+ export declare abstract class Router<T> {
3
+ abstract add(method: string, path: string, handler: T): void;
4
+ abstract match(method: string, path: string): Result<T> | null;
5
+ }
6
+ export declare class Result<T> {
7
+ handler: T;
8
+ params: Record<string, string>;
9
+ constructor(handler: T, params: Record<string, string>);
10
+ }
package/dist/router.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Result = exports.Router = exports.METHOD_NAME_OF_ALL = void 0;
4
+ exports.METHOD_NAME_OF_ALL = 'ALL';
5
+ class Router {
6
+ }
7
+ exports.Router = Router;
8
+ class Result {
9
+ constructor(handler, params) {
10
+ this.handler = handler;
11
+ this.params = params;
12
+ }
13
+ }
14
+ exports.Result = Result;
@@ -46,7 +46,9 @@ const sha256 = async (a) => {
46
46
  const buffer = await crypto.subtle.digest({
47
47
  name: 'SHA-256',
48
48
  }, new TextEncoder().encode(String(a)));
49
- const hash = Array.prototype.map.call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2)).join('');
49
+ const hash = Array.prototype.map
50
+ .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
51
+ .join('');
50
52
  return hash;
51
53
  }
52
54
  try {
@@ -1,4 +1,10 @@
1
+ export declare type Pattern = readonly [string, string, RegExp | true] | '*';
1
2
  export declare const splitPath: (path: string) => string[];
2
- export declare const getPattern: (label: string) => string[] | null;
3
- export declare const getPathFromURL: (url: string) => string;
3
+ export declare const getPattern: (label: string) => Pattern | null;
4
+ declare type Params = {
5
+ strict: boolean;
6
+ };
7
+ export declare const getPathFromURL: (url: string, params?: Params) => string;
4
8
  export declare const isAbsoluteURL: (url: string) => boolean;
9
+ export declare const mergePath: (...paths: string[]) => string;
10
+ export {};
package/dist/utils/url.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
3
+ exports.mergePath = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
4
4
  const URL_REGEXP = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
5
5
  const splitPath = (path) => {
6
6
  const paths = path.split(/\//); // faster than path.split('/')
@@ -10,23 +10,36 @@ const splitPath = (path) => {
10
10
  return paths;
11
11
  };
12
12
  exports.splitPath = splitPath;
13
+ const patternCache = {};
13
14
  const getPattern = (label) => {
15
+ // * => wildcard
14
16
  // :id{[0-9]+} => ([0-9]+)
15
17
  // :id => (.+)
16
18
  //const name = ''
19
+ if (label === '*') {
20
+ return '*';
21
+ }
17
22
  const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
18
23
  if (match) {
19
- if (match[2]) {
20
- return [match[1], '(' + match[2] + ')'];
21
- }
22
- else {
23
- return [match[1], '(.+)'];
24
+ if (!patternCache[label]) {
25
+ if (match[2]) {
26
+ patternCache[label] = [label, match[1], new RegExp('^' + match[2] + '$')];
27
+ }
28
+ else {
29
+ patternCache[label] = [label, match[1], true];
30
+ }
24
31
  }
32
+ return patternCache[label];
25
33
  }
26
34
  return null;
27
35
  };
28
36
  exports.getPattern = getPattern;
29
- const getPathFromURL = (url) => {
37
+ const getPathFromURL = (url, params = { strict: true }) => {
38
+ // if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
39
+ // default is true
40
+ if (!params.strict && url.endsWith('/')) {
41
+ url = url.slice(0, -1);
42
+ }
30
43
  const match = url.match(URL_REGEXP);
31
44
  if (match) {
32
45
  return match[5];
@@ -42,3 +55,27 @@ const isAbsoluteURL = (url) => {
42
55
  return false;
43
56
  };
44
57
  exports.isAbsoluteURL = isAbsoluteURL;
58
+ const mergePath = (...paths) => {
59
+ let p = '';
60
+ let endsWithSlash = false;
61
+ for (let path of paths) {
62
+ /* ['/hey/','/say'] => ['/hey', '/say'] */
63
+ if (p.endsWith('/')) {
64
+ p = p.slice(0, -1);
65
+ endsWithSlash = true;
66
+ }
67
+ /* ['/hey','say'] => ['/hey', '/say'] */
68
+ if (!path.startsWith('/')) {
69
+ path = `/${path}`;
70
+ }
71
+ /* ['/hey/', '/'] => `/hey/` */
72
+ if (path === '/' && endsWithSlash) {
73
+ p = `${p}/`;
74
+ }
75
+ else if (path !== '/') {
76
+ p = `${p}${path}`;
77
+ }
78
+ }
79
+ return p;
80
+ };
81
+ exports.mergePath = mergePath;
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "0.3.8",
3
+ "version": "0.4.2",
4
4
  "description": "[炎] Ultrafast web framework for Cloudflare Workers.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist"
9
9
  ],
10
+ "scripts": {
11
+ "test": "jest",
12
+ "lint": "eslint --ext js,ts src .eslintrc.js && prettier --check src",
13
+ "build": "rimraf dist && tsc",
14
+ "watch": "tsc -w",
15
+ "prepublishOnly": "yarn build"
16
+ },
10
17
  "exports": {
11
18
  ".": "./dist/index.js",
12
19
  "./basic-auth": "./dist/middleware/basic-auth/basic-auth.js",
@@ -17,8 +24,7 @@
17
24
  "./mustache": "./dist/middleware/mustache/mustache.js",
18
25
  "./powered-by": "./dist/middleware/powered-by/powered-by.js",
19
26
  "./serve-static": "./dist/middleware/serve-static/serve-static.js",
20
- "./utils/buffer": "./dist/utils/buffer.js",
21
- "./package.json": "./package.json"
27
+ "./router/reg-exp-router": "./dist/router/reg-exp-router/index.js"
22
28
  },
23
29
  "typesVersions": {
24
30
  "*": {
@@ -45,16 +51,12 @@
45
51
  ],
46
52
  "serve-static": [
47
53
  "./dist/middleware/serve-static/serve-static.d.ts"
54
+ ],
55
+ "router/reg-exp-router": [
56
+ "./dist/router/reg-exp-router/router.d.ts"
48
57
  ]
49
58
  }
50
59
  },
51
- "scripts": {
52
- "test": "jest",
53
- "lint": "eslint --ext js,ts src .eslintrc.js test",
54
- "build": "rimraf dist && tsc",
55
- "watch": "tsc -w",
56
- "prepublishOnly": "yarn build"
57
- },
58
60
  "author": "Yusuke Wada <yusuke@kamawada.com> (https://github.com/yusukebe)",
59
61
  "license": "MIT",
60
62
  "repository": {
@@ -82,18 +84,18 @@
82
84
  "@typescript-eslint/eslint-plugin": "^5.9.0",
83
85
  "@typescript-eslint/parser": "^5.9.0",
84
86
  "eslint": "^7.26.0",
85
- "eslint-config-prettier": "^8.1.0",
87
+ "eslint-config-prettier": "^8.3.0",
86
88
  "eslint-define-config": "^1.2.1",
87
89
  "eslint-import-resolver-typescript": "^2.0.0",
88
90
  "eslint-plugin-eslint-comments": "^3.2.0",
89
91
  "eslint-plugin-flowtype": "^5.7.2",
90
92
  "eslint-plugin-import": "^2.20.2",
91
93
  "eslint-plugin-node": "^11.1.0",
92
- "eslint-plugin-prettier": "^4.0.0",
93
94
  "form-data": "^4.0.0",
94
95
  "jest": "^27.4.5",
95
96
  "jest-environment-miniflare": "^2.0.0",
96
97
  "mustache": "^4.2.0",
98
+ "prettier": "^2.5.1",
97
99
  "rimraf": "^3.0.2",
98
100
  "ts-jest": "^27.1.2",
99
101
  "typescript": "^4.5.5"
package/dist/node.d.ts DELETED
@@ -1,24 +0,0 @@
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?: T, 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
- }