@athenna/http 1.3.2 → 1.3.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/LICENSE.md +3 -15
- package/README.md +8 -5
- package/package.json +95 -106
- package/src/Context/Request.js +168 -137
- package/src/Context/Response.js +102 -94
- package/src/Exceptions/UndefinedMethodException.js +30 -0
- package/src/Facades/Route.js +7 -5
- package/src/Facades/Server.js +7 -5
- package/src/Handlers/FastifyHandler.js +134 -115
- package/src/Handlers/HttpExceptionHandler.js +71 -68
- package/src/Kernels/HttpKernel.js +142 -124
- package/src/Providers/ControllerProvider.js +30 -39
- package/src/Providers/HttpRouteProvider.js +15 -16
- package/src/Providers/HttpServerProvider.js +13 -15
- package/src/Providers/MiddlewareProvider.js +30 -39
- package/src/Router/Route.js +192 -99
- package/src/Router/RouteGroup.js +66 -40
- package/src/Router/RouteResource.js +156 -74
- package/src/Router/Router.js +284 -112
- package/src/Utils/isMiddlewareContract.js +8 -6
- package/src/Utils/removeSlashes.js +21 -0
- package/src/index.d.ts +658 -0
- package/src/index.js +284 -0
- package/index.d.ts +0 -29
- package/index.js +0 -41
- package/src/Context/Request.d.ts +0 -103
- package/src/Context/Response.d.ts +0 -77
- package/src/Contracts/Context/ContextContract.d.ts +0 -17
- package/src/Contracts/Context/ContextContract.js +0 -10
- package/src/Contracts/Context/Error/ErrorContextContract.d.ts +0 -18
- package/src/Contracts/Context/Error/ErrorContextContract.js +0 -10
- package/src/Contracts/Context/Error/ErrorHandlerContract.d.ts +0 -12
- package/src/Contracts/Context/Error/ErrorHandlerContract.js +0 -10
- package/src/Contracts/Context/HandlerContract.d.ts +0 -12
- package/src/Contracts/Context/HandlerContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Handle/HandleContextContract.d.ts +0 -19
- package/src/Contracts/Context/Middlewares/Handle/HandleContextContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Handle/HandleHandlerContract.d.ts +0 -12
- package/src/Contracts/Context/Middlewares/Handle/HandleHandlerContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Intercept/InterceptContextContract.d.ts +0 -19
- package/src/Contracts/Context/Middlewares/Intercept/InterceptContextContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Intercept/InterceptHandlerContract.d.ts +0 -12
- package/src/Contracts/Context/Middlewares/Intercept/InterceptHandlerContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Terminate/TerminateContextContract.d.ts +0 -23
- package/src/Contracts/Context/Middlewares/Terminate/TerminateContextContract.js +0 -10
- package/src/Contracts/Context/Middlewares/Terminate/TerminateHandlerContract.d.ts +0 -12
- package/src/Contracts/Context/Middlewares/Terminate/TerminateHandlerContract.js +0 -10
- package/src/Contracts/Context/NextContract.d.ts +0 -11
- package/src/Contracts/Context/NextContract.js +0 -10
- package/src/Contracts/Context/RequestContract.d.ts +0 -25
- package/src/Contracts/Context/RequestContract.js +0 -10
- package/src/Contracts/Context/ResponseContract.d.ts +0 -20
- package/src/Contracts/Context/ResponseContract.js +0 -2
- package/src/Contracts/FastifyErrorHandlerContract.d.ts +0 -12
- package/src/Contracts/FastifyErrorHandlerContract.js +0 -10
- package/src/Contracts/FastifyHandlerContract.d.ts +0 -12
- package/src/Contracts/FastifyHandlerContract.js +0 -10
- package/src/Contracts/HttpMethodTypes.d.ts +0 -9
- package/src/Contracts/HttpMethodTypes.js +0 -10
- package/src/Contracts/MiddlewareContract.d.ts +0 -16
- package/src/Contracts/MiddlewareContract.js +0 -10
- package/src/Contracts/MiddlewareTypes.d.ts +0 -9
- package/src/Contracts/MiddlewareTypes.js +0 -10
- package/src/Contracts/MiddlewareTypesContract.d.ts +0 -16
- package/src/Contracts/MiddlewareTypesContract.js +0 -10
- package/src/Contracts/RouteContract.d.ts +0 -16
- package/src/Contracts/RouteContract.js +0 -10
- package/src/Exceptions/BadRequestException.d.ts +0 -12
- package/src/Exceptions/BadRequestException.js +0 -18
- package/src/Exceptions/CannotDefineGroupException.d.ts +0 -12
- package/src/Exceptions/CannotDefineGroupException.js +0 -19
- package/src/Exceptions/MiddlewareNotFoundException.d.ts +0 -12
- package/src/Exceptions/MiddlewareNotFoundException.js +0 -19
- package/src/Exceptions/UndefinedControllerMethodException.d.ts +0 -12
- package/src/Exceptions/UndefinedControllerMethodException.js +0 -19
- package/src/Facades/Route.d.ts +0 -10
- package/src/Facades/Server.d.ts +0 -10
- package/src/Handlers/FastifyHandler.d.ts +0 -26
- package/src/Handlers/HttpExceptionHandler.d.ts +0 -27
- package/src/Http.d.ts +0 -167
- package/src/Http.js +0 -223
- package/src/Kernels/HttpKernel.d.ts +0 -54
- package/src/Providers/ControllerProvider.d.ts +0 -17
- package/src/Providers/HttpRouteProvider.d.ts +0 -17
- package/src/Providers/HttpServerProvider.d.ts +0 -17
- package/src/Providers/MiddlewareProvider.d.ts +0 -17
- package/src/Router/Route.d.ts +0 -32
- package/src/Router/RouteGroup.d.ts +0 -24
- package/src/Router/RouteResource.d.ts +0 -29
- package/src/Router/Router.d.ts +0 -39
- package/src/Utils/getAppFiles.d.ts +0 -10
- package/src/Utils/getAppFiles.js +0 -22
- package/src/Utils/isMiddlewareContract.d.ts +0 -10
- package/src/Utils/removeSlash.d.ts +0 -9
- package/src/Utils/removeSlash.js +0 -23
package/src/Router/Router.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @athenna/http
|
|
4
3
|
*
|
|
@@ -7,119 +6,292 @@
|
|
|
7
6
|
* For the full copyright and license information, please view the LICENSE
|
|
8
7
|
* file that was distributed with this source code.
|
|
9
8
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
|
|
10
|
+
import { Is } from '@secjs/utils'
|
|
11
|
+
|
|
12
|
+
import { Route } from '#src/Router/Route'
|
|
13
|
+
import { Server } from '#src/Facades/Server'
|
|
14
|
+
import { RouteGroup } from '#src/Router/RouteGroup'
|
|
15
|
+
import { RouteResource } from '#src/Router/RouteResource'
|
|
16
|
+
|
|
17
|
+
export class Router {
|
|
18
|
+
/**
|
|
19
|
+
* All routes registered.
|
|
20
|
+
*
|
|
21
|
+
* @type {(Route | RouteResource | RouteGroup)[]}
|
|
22
|
+
*/
|
|
23
|
+
routes
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Route groups opened.
|
|
27
|
+
*
|
|
28
|
+
* @type {RouteGroup[]}
|
|
29
|
+
*/
|
|
30
|
+
#openedGroups
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The controller instance.
|
|
34
|
+
*
|
|
35
|
+
* @type {any}
|
|
36
|
+
*/
|
|
37
|
+
#controllerInstance
|
|
38
|
+
|
|
39
|
+
constructor() {
|
|
40
|
+
this.routes = []
|
|
41
|
+
this.#openedGroups = []
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* List the routes registered.
|
|
46
|
+
*
|
|
47
|
+
* @return {any}
|
|
48
|
+
*/
|
|
49
|
+
listRoutes() {
|
|
50
|
+
return this.toRoutesJSON(this.routes)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Set the controller instance.
|
|
55
|
+
*
|
|
56
|
+
* @param {any} controller
|
|
57
|
+
* @return {Router}
|
|
58
|
+
*/
|
|
59
|
+
controller(controller) {
|
|
60
|
+
this.#controllerInstance = controller
|
|
61
|
+
|
|
62
|
+
return this
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Register a new route.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} url
|
|
69
|
+
* @param {string[]} methods
|
|
70
|
+
* @param {string|any} handler
|
|
71
|
+
* @return {Route}
|
|
72
|
+
*/
|
|
73
|
+
route(url, methods, handler) {
|
|
74
|
+
if (
|
|
75
|
+
this.#controllerInstance &&
|
|
76
|
+
Is.String(handler) &&
|
|
77
|
+
!handler.includes('.')
|
|
78
|
+
) {
|
|
79
|
+
handler = this.#controllerInstance[handler]
|
|
22
80
|
}
|
|
23
|
-
|
|
24
|
-
|
|
81
|
+
|
|
82
|
+
const route = new Route(url, methods, handler)
|
|
83
|
+
const openedGroup = this.#getRecentGroup()
|
|
84
|
+
|
|
85
|
+
if (openedGroup) {
|
|
86
|
+
openedGroup.routes.push(route)
|
|
87
|
+
} else {
|
|
88
|
+
this.routes.push(route)
|
|
25
89
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
90
|
+
|
|
91
|
+
return route
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new route group.
|
|
96
|
+
*
|
|
97
|
+
* @param {() => void} callback
|
|
98
|
+
* @return {RouteGroup}
|
|
99
|
+
*/
|
|
100
|
+
group(callback) {
|
|
101
|
+
const group = new RouteGroup([])
|
|
102
|
+
|
|
103
|
+
const openedGroup = this.#getRecentGroup()
|
|
104
|
+
|
|
105
|
+
if (openedGroup) {
|
|
106
|
+
openedGroup.routes.push(group)
|
|
107
|
+
} else {
|
|
108
|
+
this.routes.push(group)
|
|
29
109
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
this.openedGroups.push(group);
|
|
56
|
-
callback();
|
|
57
|
-
this.openedGroups.pop();
|
|
58
|
-
return group;
|
|
59
|
-
}
|
|
60
|
-
resource(resource, controller) {
|
|
61
|
-
const resourceInstance = new RouteResource_1.RouteResource(resource, controller);
|
|
62
|
-
const openedGroup = this.getRecentGroup();
|
|
63
|
-
if (openedGroup) {
|
|
64
|
-
openedGroup.routes.push(resourceInstance);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
this.routes.push(resourceInstance);
|
|
68
|
-
}
|
|
69
|
-
return resourceInstance;
|
|
70
|
-
}
|
|
71
|
-
redirect(url, redirectTo, status = 302) {
|
|
72
|
-
return this.any(url, ({ response }) => response.redirectTo(redirectTo, status));
|
|
73
|
-
}
|
|
74
|
-
get(url, handler) {
|
|
75
|
-
return this.route(url, ['GET', 'HEAD'], handler);
|
|
76
|
-
}
|
|
77
|
-
head(url, handler) {
|
|
78
|
-
return this.route(url, ['HEAD'], handler);
|
|
79
|
-
}
|
|
80
|
-
post(url, handler) {
|
|
81
|
-
return this.route(url, ['POST'], handler);
|
|
82
|
-
}
|
|
83
|
-
put(url, handler) {
|
|
84
|
-
return this.route(url, ['PUT'], handler);
|
|
85
|
-
}
|
|
86
|
-
patch(url, handler) {
|
|
87
|
-
return this.route(url, ['PATCH'], handler);
|
|
88
|
-
}
|
|
89
|
-
delete(url, handler) {
|
|
90
|
-
return this.route(url, ['DELETE'], handler);
|
|
91
|
-
}
|
|
92
|
-
options(url, handler) {
|
|
93
|
-
return this.route(url, ['OPTIONS'], handler);
|
|
94
|
-
}
|
|
95
|
-
any(url, handler) {
|
|
96
|
-
return this.route(url, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], handler);
|
|
97
|
-
}
|
|
98
|
-
register() {
|
|
99
|
-
this.toRoutesJSON(this.routes).forEach(route => {
|
|
100
|
-
route.methods.forEach(method => {
|
|
101
|
-
this.http[method.toLowerCase()](route.url, route.handler, route.middlewares);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
toRoutesJSON(routes) {
|
|
106
|
-
return routes.reduce((list, route) => {
|
|
107
|
-
if (route instanceof RouteGroup_1.RouteGroup) {
|
|
108
|
-
list = list.concat(this.toRoutesJSON(route.routes));
|
|
109
|
-
return list;
|
|
110
|
-
}
|
|
111
|
-
if (route instanceof RouteResource_1.RouteResource) {
|
|
112
|
-
list = list.concat(this.toRoutesJSON(route.routes));
|
|
113
|
-
return list;
|
|
114
|
-
}
|
|
115
|
-
if (!route.deleted) {
|
|
116
|
-
list.push(route.toJSON());
|
|
117
|
-
}
|
|
118
|
-
return list;
|
|
119
|
-
}, []);
|
|
120
|
-
}
|
|
121
|
-
getRecentGroup() {
|
|
122
|
-
return this.openedGroups[this.openedGroups.length - 1];
|
|
110
|
+
|
|
111
|
+
this.#openedGroups.push(group)
|
|
112
|
+
callback()
|
|
113
|
+
|
|
114
|
+
this.#openedGroups.pop()
|
|
115
|
+
|
|
116
|
+
return group
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Creates a new route resource.
|
|
121
|
+
*
|
|
122
|
+
* @param {string} resource
|
|
123
|
+
* @param {any} controller
|
|
124
|
+
* @return {RouteResource}
|
|
125
|
+
*/
|
|
126
|
+
resource(resource, controller) {
|
|
127
|
+
const resourceInstance = new RouteResource(resource, controller)
|
|
128
|
+
const openedGroup = this.#getRecentGroup()
|
|
129
|
+
|
|
130
|
+
if (openedGroup) {
|
|
131
|
+
openedGroup.routes.push(resourceInstance)
|
|
132
|
+
} else {
|
|
133
|
+
this.routes.push(resourceInstance)
|
|
123
134
|
}
|
|
135
|
+
|
|
136
|
+
return resourceInstance
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Creates a new redirect route.
|
|
141
|
+
*
|
|
142
|
+
* @param {string} url
|
|
143
|
+
* @param {string} redirectTo
|
|
144
|
+
* @param {number} [status]
|
|
145
|
+
* @return {Route}
|
|
146
|
+
*/
|
|
147
|
+
redirect(url, redirectTo, status = 302) {
|
|
148
|
+
return this.any(url, ({ response }) =>
|
|
149
|
+
response.redirectTo(redirectTo, status),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Register a new get method route.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} url
|
|
157
|
+
* @param {string|any} handler
|
|
158
|
+
* @return {Route}
|
|
159
|
+
*/
|
|
160
|
+
get(url, handler) {
|
|
161
|
+
return this.route(url, ['GET', 'HEAD'], handler)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Register a new head method route.
|
|
166
|
+
*
|
|
167
|
+
* @param {string} url
|
|
168
|
+
* @param {string|any} handler
|
|
169
|
+
* @return {Route}
|
|
170
|
+
*/
|
|
171
|
+
head(url, handler) {
|
|
172
|
+
return this.route(url, ['HEAD'], handler)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Register a new post method route.
|
|
177
|
+
*
|
|
178
|
+
* @param {string} url
|
|
179
|
+
* @param {string|any} handler
|
|
180
|
+
* @return {Route}
|
|
181
|
+
*/
|
|
182
|
+
post(url, handler) {
|
|
183
|
+
return this.route(url, ['POST'], handler)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Register a new put method route.
|
|
188
|
+
*
|
|
189
|
+
* @param {string} url
|
|
190
|
+
* @param {string|any} handler
|
|
191
|
+
* @return {Route}
|
|
192
|
+
*/
|
|
193
|
+
put(url, handler) {
|
|
194
|
+
return this.route(url, ['PUT'], handler)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Register a new patch method route.
|
|
199
|
+
*
|
|
200
|
+
* @param {string} url
|
|
201
|
+
* @param {string|any} handler
|
|
202
|
+
* @return {Route}
|
|
203
|
+
*/
|
|
204
|
+
patch(url, handler) {
|
|
205
|
+
return this.route(url, ['PATCH'], handler)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Register a new delete method route.
|
|
210
|
+
*
|
|
211
|
+
* @param {string} url
|
|
212
|
+
* @param {string|any} handler
|
|
213
|
+
* @return {Route}
|
|
214
|
+
*/
|
|
215
|
+
delete(url, handler) {
|
|
216
|
+
return this.route(url, ['HEAD'], handler)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Register a new options method route.
|
|
221
|
+
*
|
|
222
|
+
* @param {string} url
|
|
223
|
+
* @param {string|any} handler
|
|
224
|
+
* @return {Route}
|
|
225
|
+
*/
|
|
226
|
+
options(url, handler) {
|
|
227
|
+
return this.route(url, ['OPTIONS'], handler)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Register a new route with all methods.
|
|
232
|
+
*
|
|
233
|
+
* @param {string} url
|
|
234
|
+
* @param {string|any} handler
|
|
235
|
+
* @return {Route}
|
|
236
|
+
*/
|
|
237
|
+
any(url, handler) {
|
|
238
|
+
return this.route(
|
|
239
|
+
url,
|
|
240
|
+
['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
|
|
241
|
+
handler,
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Register all the routes inside the Server.
|
|
247
|
+
*
|
|
248
|
+
* @param {string} url
|
|
249
|
+
* @param {string|any} handler
|
|
250
|
+
* @return {Route}
|
|
251
|
+
*/
|
|
252
|
+
register() {
|
|
253
|
+
this.toRoutesJSON(this.routes).forEach(route => {
|
|
254
|
+
route.methods.forEach(method => {
|
|
255
|
+
Server[method.toLowerCase()](
|
|
256
|
+
route.url,
|
|
257
|
+
route.handler,
|
|
258
|
+
route.middlewares,
|
|
259
|
+
)
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Transform the routes to JSON Object.
|
|
266
|
+
*
|
|
267
|
+
* @param {any[]} [routes]
|
|
268
|
+
*/
|
|
269
|
+
toRoutesJSON(routes) {
|
|
270
|
+
return routes.reduce((list, route) => {
|
|
271
|
+
if (route instanceof RouteGroup) {
|
|
272
|
+
list = list.concat(this.toRoutesJSON(route.routes))
|
|
273
|
+
return list
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (route instanceof RouteResource) {
|
|
277
|
+
list = list.concat(this.toRoutesJSON(route.routes))
|
|
278
|
+
return list
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (!route.deleted) {
|
|
282
|
+
list.push(route.toJSON())
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return list
|
|
286
|
+
}, [])
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Returns the recent group.
|
|
291
|
+
*
|
|
292
|
+
* @return {RouteGroup}
|
|
293
|
+
*/
|
|
294
|
+
#getRecentGroup() {
|
|
295
|
+
return this.#openedGroups[this.#openedGroups.length - 1]
|
|
296
|
+
}
|
|
124
297
|
}
|
|
125
|
-
exports.Router = Router;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @athenna/http
|
|
4
3
|
*
|
|
@@ -7,9 +6,12 @@
|
|
|
7
6
|
* For the full copyright and license information, please view the LICENSE
|
|
8
7
|
* file that was distributed with this source code.
|
|
9
8
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Verify if the middleware implements the middleware contract.
|
|
12
|
+
*
|
|
13
|
+
* @param {any} object
|
|
14
|
+
*/
|
|
15
|
+
export function isMiddlewareContract(object) {
|
|
16
|
+
return 'handle' in object || 'intercept' in object || 'terminate' in object
|
|
14
17
|
}
|
|
15
|
-
exports.isMiddlewareContract = isMiddlewareContract;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Is } from '@secjs/utils'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Remove additional slashes from url.
|
|
5
|
+
*
|
|
6
|
+
* @param {string|string[]} url
|
|
7
|
+
* @return {string|string[]}
|
|
8
|
+
*/
|
|
9
|
+
export function removeSlashes(url) {
|
|
10
|
+
if (url === '/') {
|
|
11
|
+
return url
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const matcher = url => `/${url.replace(/^\//, '').replace(/\/$/, '')}`
|
|
15
|
+
|
|
16
|
+
if (Is.Array(url)) {
|
|
17
|
+
return url.map(u => matcher(u))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return matcher(url)
|
|
21
|
+
}
|