hono 3.1.3 → 3.1.5
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/dist/cjs/middleware/jwt/index.js +5 -3
- package/dist/cjs/request.js +2 -10
- package/dist/cjs/utils/jwt/jwt.js +1 -1
- package/dist/cjs/utils/url.js +67 -43
- package/dist/middleware/jwt/index.js +5 -3
- package/dist/request.js +3 -11
- package/dist/types/adapter.d.ts +1 -1
- package/dist/types/context.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/middleware/jwt/index.d.ts +6 -0
- package/dist/types/utils/jwt/jwt.d.ts +1 -1
- package/dist/types/utils/url.d.ts +2 -3
- package/dist/utils/jwt/jwt.js +1 -1
- package/dist/utils/url.js +67 -42
- package/package.json +1 -1
|
@@ -23,6 +23,7 @@ __export(jwt_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(jwt_exports);
|
|
24
24
|
var import_http_exception = require("../../http-exception");
|
|
25
25
|
var import_jwt = require("../../utils/jwt");
|
|
26
|
+
var import_context = require("../../context");
|
|
26
27
|
const jwt = (options) => {
|
|
27
28
|
if (!options) {
|
|
28
29
|
throw new Error('JWT auth middleware requires options for "secret');
|
|
@@ -58,14 +59,14 @@ const jwt = (options) => {
|
|
|
58
59
|
});
|
|
59
60
|
throw new import_http_exception.HTTPException(401, { res });
|
|
60
61
|
}
|
|
61
|
-
let
|
|
62
|
+
let payload;
|
|
62
63
|
let msg = "";
|
|
63
64
|
try {
|
|
64
|
-
|
|
65
|
+
payload = await import_jwt.Jwt.verify(token, options.secret, options.alg);
|
|
65
66
|
} catch (e) {
|
|
66
67
|
msg = `${e}`;
|
|
67
68
|
}
|
|
68
|
-
if (!
|
|
69
|
+
if (!payload) {
|
|
69
70
|
const res = new Response("Unauthorized", {
|
|
70
71
|
status: 401,
|
|
71
72
|
statusText: msg,
|
|
@@ -75,6 +76,7 @@ const jwt = (options) => {
|
|
|
75
76
|
});
|
|
76
77
|
throw new import_http_exception.HTTPException(401, { res });
|
|
77
78
|
}
|
|
79
|
+
ctx.set("jwtPayload", payload);
|
|
78
80
|
await next();
|
|
79
81
|
};
|
|
80
82
|
};
|
package/dist/cjs/request.js
CHANGED
|
@@ -49,18 +49,10 @@ class HonoRequest {
|
|
|
49
49
|
return null;
|
|
50
50
|
}
|
|
51
51
|
query(key) {
|
|
52
|
-
|
|
53
|
-
const result = (0, import_url.getQueryParam)(queryString, key);
|
|
54
|
-
if (result === null)
|
|
55
|
-
return void 0;
|
|
56
|
-
return result;
|
|
52
|
+
return (0, import_url.getQueryParam)(this.url, key);
|
|
57
53
|
}
|
|
58
54
|
queries(key) {
|
|
59
|
-
|
|
60
|
-
const result = (0, import_url.getQueryParams)(queryString, key);
|
|
61
|
-
if (result === null)
|
|
62
|
-
return void 0;
|
|
63
|
-
return result;
|
|
55
|
+
return (0, import_url.getQueryParams)(this.url, key);
|
|
64
56
|
}
|
|
65
57
|
header(name) {
|
|
66
58
|
const headerData = {};
|
|
@@ -120,7 +120,7 @@ const verify = async (token, secret, alg = import_types.AlgorithmTypes.HS256) =>
|
|
|
120
120
|
if (encodedSignature !== tokenParts[2]) {
|
|
121
121
|
throw new import_types2.JwtTokenSignatureMismatched(token);
|
|
122
122
|
}
|
|
123
|
-
return
|
|
123
|
+
return payload;
|
|
124
124
|
};
|
|
125
125
|
const decode = (token) => {
|
|
126
126
|
try {
|
package/dist/cjs/utils/url.js
CHANGED
|
@@ -23,7 +23,6 @@ __export(url_exports, {
|
|
|
23
23
|
getPattern: () => getPattern,
|
|
24
24
|
getQueryParam: () => getQueryParam,
|
|
25
25
|
getQueryParams: () => getQueryParams,
|
|
26
|
-
getQueryStringFromURL: () => getQueryStringFromURL,
|
|
27
26
|
mergePath: () => mergePath,
|
|
28
27
|
splitPath: () => splitPath,
|
|
29
28
|
splitRoutingPath: () => splitRoutingPath
|
|
@@ -92,11 +91,6 @@ const getPathFromURL = (url, strict = true) => {
|
|
|
92
91
|
}
|
|
93
92
|
return result;
|
|
94
93
|
};
|
|
95
|
-
const getQueryStringFromURL = (url) => {
|
|
96
|
-
const queryIndex = url.indexOf("?", 8);
|
|
97
|
-
const result = queryIndex !== -1 ? url.slice(queryIndex + 1) : "";
|
|
98
|
-
return result;
|
|
99
|
-
};
|
|
100
94
|
const mergePath = (...paths) => {
|
|
101
95
|
let p = "";
|
|
102
96
|
let endsWithSlash = false;
|
|
@@ -127,48 +121,79 @@ const checkOptionalParameter = (path) => {
|
|
|
127
121
|
const optional = base + match[2];
|
|
128
122
|
return [base === "" ? "/" : base.replace(/\/$/, ""), optional];
|
|
129
123
|
};
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
const _decodeURI = (value) => {
|
|
125
|
+
if (!/[%+]/.test(value)) {
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
if (value.includes("+")) {
|
|
129
|
+
value = value.replace(/\+/g, " ");
|
|
130
|
+
}
|
|
131
|
+
return value.includes("%") ? decodeURIComponent(value) : value;
|
|
132
|
+
};
|
|
133
|
+
const _getQueryParam = (url, key, multiple) => {
|
|
134
|
+
let encoded;
|
|
135
|
+
if (!multiple && key && !/[%+]/.test(key)) {
|
|
136
|
+
let keyIndex2 = url.indexOf(`?${key}`, 8);
|
|
137
|
+
if (keyIndex2 === -1) {
|
|
138
|
+
keyIndex2 = url.indexOf(`&${key}`, 8);
|
|
139
139
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return
|
|
146
|
-
} else {
|
|
147
|
-
|
|
140
|
+
while (keyIndex2 !== -1) {
|
|
141
|
+
const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
|
|
142
|
+
if (trailingKeyCode === 61) {
|
|
143
|
+
const valueIndex = keyIndex2 + key.length + 2;
|
|
144
|
+
const endIndex = url.indexOf("&", valueIndex);
|
|
145
|
+
return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
|
|
146
|
+
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
|
|
147
|
+
return "";
|
|
148
148
|
}
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
keyIndex2 = url.indexOf(`&${key}`, keyIndex2);
|
|
150
|
+
}
|
|
151
|
+
encoded = /[%+]/.test(url);
|
|
152
|
+
if (!encoded) {
|
|
153
|
+
return void 0;
|
|
151
154
|
}
|
|
152
|
-
if (andIndex === -1)
|
|
153
|
-
break;
|
|
154
|
-
queryString = queryString.substring(andIndex + 1, queryString.length);
|
|
155
155
|
}
|
|
156
|
-
if (key)
|
|
157
|
-
return null;
|
|
158
|
-
return results;
|
|
159
|
-
};
|
|
160
|
-
const getQueryParams = (queryString, key) => {
|
|
161
156
|
const results = {};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
157
|
+
encoded ?? (encoded = /[%+]/.test(url));
|
|
158
|
+
let keyIndex = url.indexOf("?", 8);
|
|
159
|
+
while (keyIndex !== -1) {
|
|
160
|
+
const nextKeyIndex = url.indexOf("&", keyIndex + 1);
|
|
161
|
+
let valueIndex = url.indexOf("=", keyIndex);
|
|
162
|
+
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
|
|
163
|
+
valueIndex = -1;
|
|
164
|
+
}
|
|
165
|
+
let name = url.slice(
|
|
166
|
+
keyIndex + 1,
|
|
167
|
+
valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex
|
|
168
|
+
);
|
|
169
|
+
if (encoded) {
|
|
170
|
+
name = _decodeURI(name);
|
|
171
|
+
}
|
|
172
|
+
keyIndex = nextKeyIndex;
|
|
173
|
+
if (name === "") {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
let value;
|
|
177
|
+
if (valueIndex === -1) {
|
|
178
|
+
value = "";
|
|
179
|
+
} else {
|
|
180
|
+
value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
|
|
181
|
+
if (encoded) {
|
|
182
|
+
value = _decodeURI(value);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (multiple) {
|
|
186
|
+
;
|
|
187
|
+
(results[name] ?? (results[name] = [])).push(value);
|
|
188
|
+
} else {
|
|
189
|
+
results[name] ?? (results[name] = value);
|
|
190
|
+
}
|
|
168
191
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
192
|
+
return key ? results[key] : results;
|
|
193
|
+
};
|
|
194
|
+
const getQueryParam = _getQueryParam;
|
|
195
|
+
const getQueryParams = (url, key) => {
|
|
196
|
+
return _getQueryParam(url, key, true);
|
|
172
197
|
};
|
|
173
198
|
// Annotate the CommonJS export names for ESM import in node:
|
|
174
199
|
0 && (module.exports = {
|
|
@@ -177,7 +202,6 @@ const getQueryParams = (queryString, key) => {
|
|
|
177
202
|
getPattern,
|
|
178
203
|
getQueryParam,
|
|
179
204
|
getQueryParams,
|
|
180
|
-
getQueryStringFromURL,
|
|
181
205
|
mergePath,
|
|
182
206
|
splitPath,
|
|
183
207
|
splitRoutingPath
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/middleware/jwt/index.ts
|
|
2
2
|
import { HTTPException } from "../../http-exception.js";
|
|
3
3
|
import { Jwt } from "../../utils/jwt/index.js";
|
|
4
|
+
import "../../context.js";
|
|
4
5
|
var jwt = (options) => {
|
|
5
6
|
if (!options) {
|
|
6
7
|
throw new Error('JWT auth middleware requires options for "secret');
|
|
@@ -36,14 +37,14 @@ var jwt = (options) => {
|
|
|
36
37
|
});
|
|
37
38
|
throw new HTTPException(401, { res });
|
|
38
39
|
}
|
|
39
|
-
let
|
|
40
|
+
let payload;
|
|
40
41
|
let msg = "";
|
|
41
42
|
try {
|
|
42
|
-
|
|
43
|
+
payload = await Jwt.verify(token, options.secret, options.alg);
|
|
43
44
|
} catch (e) {
|
|
44
45
|
msg = `${e}`;
|
|
45
46
|
}
|
|
46
|
-
if (!
|
|
47
|
+
if (!payload) {
|
|
47
48
|
const res = new Response("Unauthorized", {
|
|
48
49
|
status: 401,
|
|
49
50
|
statusText: msg,
|
|
@@ -53,6 +54,7 @@ var jwt = (options) => {
|
|
|
53
54
|
});
|
|
54
55
|
throw new HTTPException(401, { res });
|
|
55
56
|
}
|
|
57
|
+
ctx.set("jwtPayload", payload);
|
|
56
58
|
await next();
|
|
57
59
|
};
|
|
58
60
|
};
|
package/dist/request.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/request.ts
|
|
2
2
|
import { parseBody } from "./utils/body.js";
|
|
3
3
|
import { parse } from "./utils/cookie.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getQueryParam, getQueryParams } from "./utils/url.js";
|
|
5
5
|
var HonoRequest = class {
|
|
6
6
|
constructor(request, path = "/", paramData) {
|
|
7
7
|
this.raw = request;
|
|
@@ -27,18 +27,10 @@ var HonoRequest = class {
|
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
query(key) {
|
|
30
|
-
|
|
31
|
-
const result = getQueryParam(queryString, key);
|
|
32
|
-
if (result === null)
|
|
33
|
-
return void 0;
|
|
34
|
-
return result;
|
|
30
|
+
return getQueryParam(this.url, key);
|
|
35
31
|
}
|
|
36
32
|
queries(key) {
|
|
37
|
-
|
|
38
|
-
const result = getQueryParams(queryString, key);
|
|
39
|
-
if (result === null)
|
|
40
|
-
return void 0;
|
|
41
|
-
return result;
|
|
33
|
+
return getQueryParams(this.url, key);
|
|
42
34
|
}
|
|
43
35
|
header(name) {
|
|
44
36
|
const headerData = {};
|
package/dist/types/adapter.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Context } from './context';
|
|
2
|
-
export declare const env: <T
|
|
2
|
+
export declare const env: <T extends Record<string, string>, C extends Context<any, any, {}> = Context<{}, any, {}>>(c: C) => T & C["env"];
|
package/dist/types/context.d.ts
CHANGED
|
@@ -70,8 +70,8 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
70
70
|
append?: boolean;
|
|
71
71
|
}) => void;
|
|
72
72
|
status: (status: StatusCode) => void;
|
|
73
|
-
set: <Key extends keyof E["Variables"]>(key: Key, value: GetVariable<Key, E>) => void;
|
|
74
|
-
get: <Key extends keyof E["Variables"]>(key: Key) => GetVariable<Key, E>;
|
|
73
|
+
set: <Key extends keyof E["Variables"] | "jwtPayload">(key: Key, value: GetVariable<Key, E>) => void;
|
|
74
|
+
get: <Key extends keyof E["Variables"] | "jwtPayload">(key: Key) => GetVariable<Key, E>;
|
|
75
75
|
pretty: (prettyJSON: boolean, space?: number) => void;
|
|
76
76
|
newResponse: NewResponse;
|
|
77
77
|
body: BodyRespond;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from './hono';
|
|
2
|
-
export type { Env, ErrorHandler, Handler, MiddlewareHandler, Next, NotFoundHandler, ValidationTargets, } from './types';
|
|
2
|
+
export type { Env, ErrorHandler, Handler, MiddlewareHandler, Next, NotFoundHandler, ValidationTargets, Input, } from './types';
|
|
3
3
|
export type { Context, ContextVariableMap } from './context';
|
|
4
4
|
export type { HonoRequest } from './request';
|
|
5
5
|
declare module './hono' {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AlgorithmTypes } from './types';
|
|
2
2
|
export declare const sign: (payload: unknown, secret: string, alg?: AlgorithmTypes) => Promise<string>;
|
|
3
|
-
export declare const verify: (token: string, secret: string, alg?: AlgorithmTypes) => Promise<
|
|
3
|
+
export declare const verify: (token: string, secret: string, alg?: AlgorithmTypes) => Promise<any>;
|
|
4
4
|
export declare const decode: (token: string) => {
|
|
5
5
|
header: any;
|
|
6
6
|
payload: any;
|
|
@@ -3,8 +3,7 @@ export declare const splitPath: (path: string) => string[];
|
|
|
3
3
|
export declare const splitRoutingPath: (path: string) => string[];
|
|
4
4
|
export declare const getPattern: (label: string) => Pattern | null;
|
|
5
5
|
export declare const getPathFromURL: (url: string, strict?: boolean) => string;
|
|
6
|
-
export declare const getQueryStringFromURL: (url: string) => string;
|
|
7
6
|
export declare const mergePath: (...paths: string[]) => string;
|
|
8
7
|
export declare const checkOptionalParameter: (path: string) => string[] | null;
|
|
9
|
-
export declare const getQueryParam: (
|
|
10
|
-
export declare const getQueryParams: (
|
|
8
|
+
export declare const getQueryParam: (url: string, key?: string) => string | undefined | Record<string, string>;
|
|
9
|
+
export declare const getQueryParams: (url: string, key?: string) => string[] | undefined | Record<string, string[]>;
|
package/dist/utils/jwt/jwt.js
CHANGED
package/dist/utils/url.js
CHANGED
|
@@ -62,11 +62,6 @@ var getPathFromURL = (url, strict = true) => {
|
|
|
62
62
|
}
|
|
63
63
|
return result;
|
|
64
64
|
};
|
|
65
|
-
var getQueryStringFromURL = (url) => {
|
|
66
|
-
const queryIndex = url.indexOf("?", 8);
|
|
67
|
-
const result = queryIndex !== -1 ? url.slice(queryIndex + 1) : "";
|
|
68
|
-
return result;
|
|
69
|
-
};
|
|
70
65
|
var mergePath = (...paths) => {
|
|
71
66
|
let p = "";
|
|
72
67
|
let endsWithSlash = false;
|
|
@@ -97,48 +92,79 @@ var checkOptionalParameter = (path) => {
|
|
|
97
92
|
const optional = base + match[2];
|
|
98
93
|
return [base === "" ? "/" : base.replace(/\/$/, ""), optional];
|
|
99
94
|
};
|
|
100
|
-
var
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
var _decodeURI = (value) => {
|
|
96
|
+
if (!/[%+]/.test(value)) {
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
if (value.includes("+")) {
|
|
100
|
+
value = value.replace(/\+/g, " ");
|
|
101
|
+
}
|
|
102
|
+
return value.includes("%") ? decodeURIComponent(value) : value;
|
|
103
|
+
};
|
|
104
|
+
var _getQueryParam = (url, key, multiple) => {
|
|
105
|
+
let encoded;
|
|
106
|
+
if (!multiple && key && !/[%+]/.test(key)) {
|
|
107
|
+
let keyIndex2 = url.indexOf(`?${key}`, 8);
|
|
108
|
+
if (keyIndex2 === -1) {
|
|
109
|
+
keyIndex2 = url.indexOf(`&${key}`, 8);
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return
|
|
116
|
-
} else {
|
|
117
|
-
|
|
111
|
+
while (keyIndex2 !== -1) {
|
|
112
|
+
const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
|
|
113
|
+
if (trailingKeyCode === 61) {
|
|
114
|
+
const valueIndex = keyIndex2 + key.length + 2;
|
|
115
|
+
const endIndex = url.indexOf("&", valueIndex);
|
|
116
|
+
return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
|
|
117
|
+
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
|
|
118
|
+
return "";
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
keyIndex2 = url.indexOf(`&${key}`, keyIndex2);
|
|
121
|
+
}
|
|
122
|
+
encoded = /[%+]/.test(url);
|
|
123
|
+
if (!encoded) {
|
|
124
|
+
return void 0;
|
|
121
125
|
}
|
|
122
|
-
if (andIndex === -1)
|
|
123
|
-
break;
|
|
124
|
-
queryString = queryString.substring(andIndex + 1, queryString.length);
|
|
125
126
|
}
|
|
126
|
-
if (key)
|
|
127
|
-
return null;
|
|
128
|
-
return results;
|
|
129
|
-
};
|
|
130
|
-
var getQueryParams = (queryString, key) => {
|
|
131
127
|
const results = {};
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
128
|
+
encoded ?? (encoded = /[%+]/.test(url));
|
|
129
|
+
let keyIndex = url.indexOf("?", 8);
|
|
130
|
+
while (keyIndex !== -1) {
|
|
131
|
+
const nextKeyIndex = url.indexOf("&", keyIndex + 1);
|
|
132
|
+
let valueIndex = url.indexOf("=", keyIndex);
|
|
133
|
+
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
|
|
134
|
+
valueIndex = -1;
|
|
135
|
+
}
|
|
136
|
+
let name = url.slice(
|
|
137
|
+
keyIndex + 1,
|
|
138
|
+
valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex
|
|
139
|
+
);
|
|
140
|
+
if (encoded) {
|
|
141
|
+
name = _decodeURI(name);
|
|
142
|
+
}
|
|
143
|
+
keyIndex = nextKeyIndex;
|
|
144
|
+
if (name === "") {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
let value;
|
|
148
|
+
if (valueIndex === -1) {
|
|
149
|
+
value = "";
|
|
150
|
+
} else {
|
|
151
|
+
value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
|
|
152
|
+
if (encoded) {
|
|
153
|
+
value = _decodeURI(value);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (multiple) {
|
|
157
|
+
;
|
|
158
|
+
(results[name] ?? (results[name] = [])).push(value);
|
|
159
|
+
} else {
|
|
160
|
+
results[name] ?? (results[name] = value);
|
|
161
|
+
}
|
|
138
162
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
return key ? results[key] : results;
|
|
164
|
+
};
|
|
165
|
+
var getQueryParam = _getQueryParam;
|
|
166
|
+
var getQueryParams = (url, key) => {
|
|
167
|
+
return _getQueryParam(url, key, true);
|
|
142
168
|
};
|
|
143
169
|
export {
|
|
144
170
|
checkOptionalParameter,
|
|
@@ -146,7 +172,6 @@ export {
|
|
|
146
172
|
getPattern,
|
|
147
173
|
getQueryParam,
|
|
148
174
|
getQueryParams,
|
|
149
|
-
getQueryStringFromURL,
|
|
150
175
|
mergePath,
|
|
151
176
|
splitPath,
|
|
152
177
|
splitRoutingPath
|