@creator.co/wapi 1.2.7 → 1.2.8
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/package.json +1 -1
- package/dist/src/API/Request.d.ts +15 -1
- package/dist/src/API/Request.js +23 -1
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/Server/RouteResolver.d.ts +2 -1
- package/dist/src/Server/RouteResolver.js +2 -4
- package/dist/src/Server/RouteResolver.js.map +1 -1
- package/dist/src/Server/Router.d.ts +2 -1
- package/dist/src/Server/Router.js.map +1 -1
- package/package.json +1 -1
- package/src/API/Request.ts +24 -2
- package/src/Server/RouteResolver.ts +5 -6
- package/src/Server/Router.ts +2 -1
- package/tests/API/Request.test.ts +14 -6
- package/tests/Server/RouteResolver.test.ts +42 -43
- package/tests/Server/lib/ContainerServer.test.ts +8 -7
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +2 -1
package/dist/package.json
CHANGED
|
@@ -72,7 +72,7 @@ export default class Request<InputType> {
|
|
|
72
72
|
* Retrieves the HTTP method of the current request.
|
|
73
73
|
* @returns {string} The HTTP method of the request.
|
|
74
74
|
*/
|
|
75
|
-
getMethod():
|
|
75
|
+
getMethod(): HttpMethod;
|
|
76
76
|
/**
|
|
77
77
|
* Retrieves the path parameters from the request event.
|
|
78
78
|
* @returns {object | null} - The path parameters object, or null if not found.
|
|
@@ -101,3 +101,17 @@ export default class Request<InputType> {
|
|
|
101
101
|
*/
|
|
102
102
|
setFixedPathParams(keys: any[], result: any[]): void;
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Enum representing the HTTP methods.
|
|
106
|
+
*/
|
|
107
|
+
export declare enum HttpMethod {
|
|
108
|
+
GET = "GET",
|
|
109
|
+
HEAD = "HEAD",
|
|
110
|
+
POST = "POST",
|
|
111
|
+
PUT = "PUT",
|
|
112
|
+
DELETE = "DELETE",
|
|
113
|
+
CONNECT = "CONNECT",
|
|
114
|
+
OPTIONS = "OPTIONS",
|
|
115
|
+
TRACE = "TRACE",
|
|
116
|
+
PATCH = "PATCH"
|
|
117
|
+
}
|
package/dist/src/API/Request.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpMethod = void 0;
|
|
3
4
|
var Utils_1 = require("./Utils");
|
|
4
5
|
/**
|
|
5
6
|
* Represents a request object with utility methods for accessing request information.
|
|
@@ -97,7 +98,13 @@ var Request = /** @class */ (function () {
|
|
|
97
98
|
* @returns {string} The HTTP method of the request.
|
|
98
99
|
*/
|
|
99
100
|
Request.prototype.getMethod = function () {
|
|
100
|
-
|
|
101
|
+
if (this.requestEvent.httpMethod) {
|
|
102
|
+
var httpMethod = this.requestEvent.httpMethod.toUpperCase();
|
|
103
|
+
if (httpMethod in HttpMethod) {
|
|
104
|
+
return HttpMethod[httpMethod];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error("Invalid HTTP method: ".concat(this.requestEvent.httpMethod));
|
|
101
108
|
};
|
|
102
109
|
/**
|
|
103
110
|
* Retrieves the path parameters from the request event.
|
|
@@ -151,4 +158,19 @@ var Request = /** @class */ (function () {
|
|
|
151
158
|
return Request;
|
|
152
159
|
}());
|
|
153
160
|
exports.default = Request;
|
|
161
|
+
/**
|
|
162
|
+
* Enum representing the HTTP methods.
|
|
163
|
+
*/
|
|
164
|
+
var HttpMethod;
|
|
165
|
+
(function (HttpMethod) {
|
|
166
|
+
HttpMethod["GET"] = "GET";
|
|
167
|
+
HttpMethod["HEAD"] = "HEAD";
|
|
168
|
+
HttpMethod["POST"] = "POST";
|
|
169
|
+
HttpMethod["PUT"] = "PUT";
|
|
170
|
+
HttpMethod["DELETE"] = "DELETE";
|
|
171
|
+
HttpMethod["CONNECT"] = "CONNECT";
|
|
172
|
+
HttpMethod["OPTIONS"] = "OPTIONS";
|
|
173
|
+
HttpMethod["TRACE"] = "TRACE";
|
|
174
|
+
HttpMethod["PATCH"] = "PATCH";
|
|
175
|
+
})(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
|
|
154
176
|
//# sourceMappingURL=Request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/API/Request.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/API/Request.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Route, RouterConfig } from './Router';
|
|
2
|
+
import { HttpMethod } from '../API/Request';
|
|
2
3
|
/**
|
|
3
4
|
* A class that resolves routes based on the provided configuration.
|
|
4
5
|
* @class RouteResolver
|
|
@@ -23,7 +24,7 @@ export default class RouteResolver {
|
|
|
23
24
|
* @param {string} path - The path of the request.
|
|
24
25
|
* @returns {Route | undefined} - The resolved route or undefined if no route is found.
|
|
25
26
|
*/
|
|
26
|
-
resolveRoute(method:
|
|
27
|
+
resolveRoute(method: HttpMethod, path: string): Route | undefined;
|
|
27
28
|
/**
|
|
28
29
|
* Builds the routes for the router based on the given configuration.
|
|
29
30
|
* @param {RouterConfig} config - The router configuration object.
|
|
@@ -88,7 +88,6 @@ var RouteResolver = /** @class */ (function () {
|
|
|
88
88
|
*/
|
|
89
89
|
RouteResolver.prototype.resolveRoute = function (method, path) {
|
|
90
90
|
var _a;
|
|
91
|
-
method = method.toLowerCase();
|
|
92
91
|
var parts = path.split('/').filter(function (p) { return p.length; });
|
|
93
92
|
return (_a = this.routes[method]) === null || _a === void 0 ? void 0 : _a.resolveRoute(parts);
|
|
94
93
|
};
|
|
@@ -102,10 +101,9 @@ var RouteResolver = /** @class */ (function () {
|
|
|
102
101
|
try {
|
|
103
102
|
for (var _b = __values(config.routes), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
104
103
|
var route = _c.value;
|
|
105
|
-
var method = route.method.toLowerCase();
|
|
106
104
|
var parts = route.path.split('/').filter(function (p) { return p.length; });
|
|
107
|
-
this.routes[method] = this.routes[method] || new Routes();
|
|
108
|
-
this.routes[method].addRoute(route, parts);
|
|
105
|
+
this.routes[route.method] = this.routes[route.method] || new Routes();
|
|
106
|
+
this.routes[route.method].addRoute(route, parts);
|
|
109
107
|
}
|
|
110
108
|
}
|
|
111
109
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteResolver.js","sourceRoot":"","sources":["../../../src/Server/RouteResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"RouteResolver.js","sourceRoot":"","sources":["../../../src/Server/RouteResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Server as HTTPServer } from 'http';
|
|
3
3
|
import * as express from 'express';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import { HttpMethod } from '../API/Request';
|
|
5
6
|
import { ResponseErrorType } from '../API/Response';
|
|
6
7
|
import Transaction, { TransactionConfig, TransactionExecution } from '../BaseEvent/Transaction';
|
|
7
8
|
/**
|
|
@@ -24,7 +25,7 @@ export interface Route<InputType = any, OutputType = any> {
|
|
|
24
25
|
* Represents the method used in an API request.
|
|
25
26
|
* @type {string}
|
|
26
27
|
*/
|
|
27
|
-
method:
|
|
28
|
+
method: HttpMethod;
|
|
28
29
|
/**
|
|
29
30
|
* Represents a handler for executing a transaction with the given input type and output type.
|
|
30
31
|
* @param {Transaction<InputType, OutputType | ResponseErrorType>} transaction - The transaction to execute.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../src/Server/Router.ts"],"names":[],"mappings":";;AAKA,yDAAmD;AACnD,uCAAiC;
|
|
1
|
+
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../src/Server/Router.ts"],"names":[],"mappings":";;AAKA,yDAAmD;AACnD,uCAAiC;AAGjC,sCAAgC;AAwGhC;;GAEG;AACH;IAUE;;;;OAIG;IACH,gBAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,yBAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,gBAAM,CAAC,MAAM,CAAC,CAAA;IACrF,CAAC;IAED;;;OAGG;IACI,0BAAS,GAAhB;QACE,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAA;IAChC,CAAC;IAED;;;OAGG;IACK,4BAAW,GAAnB;QACE,OAAO,eAAK,CAAC,qBAAqB,EAAE,CAAA;IACtC,CAAC;IACH,aAAC;AAAD,CAAC,AAnCD,IAmCC"}
|
package/package.json
CHANGED
package/src/API/Request.ts
CHANGED
|
@@ -115,8 +115,15 @@ export default class Request<InputType> {
|
|
|
115
115
|
* Retrieves the HTTP method of the current request.
|
|
116
116
|
* @returns {string} The HTTP method of the request.
|
|
117
117
|
*/
|
|
118
|
-
public getMethod():
|
|
119
|
-
|
|
118
|
+
public getMethod(): HttpMethod {
|
|
119
|
+
if (this.requestEvent.httpMethod) {
|
|
120
|
+
const httpMethod = this.requestEvent.httpMethod.toUpperCase()
|
|
121
|
+
if (httpMethod in HttpMethod) {
|
|
122
|
+
return HttpMethod[httpMethod]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
throw new Error(`Invalid HTTP method: ${this.requestEvent.httpMethod}`)
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
/**
|
|
@@ -169,3 +176,18 @@ export default class Request<InputType> {
|
|
|
169
176
|
})
|
|
170
177
|
}
|
|
171
178
|
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Enum representing the HTTP methods.
|
|
182
|
+
*/
|
|
183
|
+
export enum HttpMethod {
|
|
184
|
+
GET = 'GET',
|
|
185
|
+
HEAD = 'HEAD',
|
|
186
|
+
POST = 'POST',
|
|
187
|
+
PUT = 'PUT',
|
|
188
|
+
DELETE = 'DELETE',
|
|
189
|
+
CONNECT = 'CONNECT',
|
|
190
|
+
OPTIONS = 'OPTIONS',
|
|
191
|
+
TRACE = 'TRACE',
|
|
192
|
+
PATCH = 'PATCH',
|
|
193
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Route, RouterConfig } from './Router'
|
|
2
|
+
import { HttpMethod } from '../API/Request'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Represents a collection of routes that can be added and resolved.
|
|
@@ -80,7 +81,7 @@ export default class RouteResolver {
|
|
|
80
81
|
* @property {object} routes - The routes object.
|
|
81
82
|
* @property {Routes} routes.method - The routes for the specified HTTP method.
|
|
82
83
|
*/
|
|
83
|
-
private routes: { [method
|
|
84
|
+
private routes: { [method in HttpMethod]?: Routes }
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
87
|
* Constructs a new instance of the Router class with the given configuration.
|
|
@@ -98,8 +99,7 @@ export default class RouteResolver {
|
|
|
98
99
|
* @param {string} path - The path of the request.
|
|
99
100
|
* @returns {Route | undefined} - The resolved route or undefined if no route is found.
|
|
100
101
|
*/
|
|
101
|
-
public resolveRoute(method:
|
|
102
|
-
method = method.toLowerCase()
|
|
102
|
+
public resolveRoute(method: HttpMethod, path: string): Route | undefined {
|
|
103
103
|
const parts = path.split('/').filter(p => p.length)
|
|
104
104
|
return this.routes[method]?.resolveRoute(parts)
|
|
105
105
|
}
|
|
@@ -111,10 +111,9 @@ export default class RouteResolver {
|
|
|
111
111
|
*/
|
|
112
112
|
private buildRoutes(config: RouterConfig): void {
|
|
113
113
|
for (const route of config.routes) {
|
|
114
|
-
const method = route.method.toLowerCase()
|
|
115
114
|
const parts = route.path.split('/').filter(p => p.length)
|
|
116
|
-
this.routes[method] = this.routes[method] || new Routes()
|
|
117
|
-
this.routes[method].addRoute(route, parts)
|
|
115
|
+
this.routes[route.method] = this.routes[route.method] || new Routes()
|
|
116
|
+
this.routes[route.method].addRoute(route, parts)
|
|
118
117
|
}
|
|
119
118
|
}
|
|
120
119
|
}
|
package/src/Server/Router.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { z } from 'zod'
|
|
|
5
5
|
|
|
6
6
|
import ContainerServer from './lib/ContainerServer'
|
|
7
7
|
import Server from './lib/Server'
|
|
8
|
+
import { HttpMethod } from '../API/Request'
|
|
8
9
|
import { ResponseErrorType } from '../API/Response'
|
|
9
10
|
import Utils from '../API/Utils'
|
|
10
11
|
import Transaction, { TransactionConfig, TransactionExecution } from '../BaseEvent/Transaction'
|
|
@@ -29,7 +30,7 @@ export interface Route<InputType = any, OutputType = any> {
|
|
|
29
30
|
* Represents the method used in an API request.
|
|
30
31
|
* @type {string}
|
|
31
32
|
*/
|
|
32
|
-
method:
|
|
33
|
+
method: HttpMethod
|
|
33
34
|
/* If you are here to know why implementing this method
|
|
34
35
|
does not auto infer the param type, check long discussion on TS
|
|
35
36
|
- https://github.com/Microsoft/TypeScript/issues/1373
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { APIGatewayEvent, Context } from 'aws-lambda'
|
|
2
2
|
import { expect } from 'chai'
|
|
3
3
|
|
|
4
|
-
import Request from '../../src/API/Request'
|
|
4
|
+
import Request, { HttpMethod } from '../../src/API/Request'
|
|
5
5
|
import Logger from '../../src/Logger/Logger'
|
|
6
6
|
|
|
7
7
|
function newReq(event: any, context?: any) {
|
|
@@ -180,7 +180,7 @@ describe('Request path/method', () => {
|
|
|
180
180
|
httpMethod: null,
|
|
181
181
|
})
|
|
182
182
|
expect(r.getPath()).to.be.null
|
|
183
|
-
expect(r.getMethod()).to.
|
|
183
|
+
expect(r.getMethod.bind(r)).to.throw('Invalid HTTP method: null')
|
|
184
184
|
})
|
|
185
185
|
|
|
186
186
|
test('Empty path/method', () => {
|
|
@@ -190,19 +190,27 @@ describe('Request path/method', () => {
|
|
|
190
190
|
})
|
|
191
191
|
expect(r.getPath()).to.be.a('string')
|
|
192
192
|
expect(r.getPath()).to.be.equals('')
|
|
193
|
-
expect(r.getMethod()).to.
|
|
194
|
-
expect(r.getMethod()).to.be.equals('')
|
|
193
|
+
expect(r.getMethod.bind(r)).to.throw('Invalid HTTP method: ')
|
|
195
194
|
})
|
|
196
195
|
|
|
197
196
|
test('Valid method/path', () => {
|
|
198
197
|
const r = newReq({
|
|
199
198
|
path: '/root',
|
|
200
|
-
httpMethod:
|
|
199
|
+
httpMethod: HttpMethod.GET,
|
|
201
200
|
})
|
|
202
201
|
expect(r.getPath()).to.be.a('string')
|
|
203
202
|
expect(r.getPath()).to.be.equals('/root')
|
|
204
203
|
expect(r.getMethod()).to.be.a('string')
|
|
205
|
-
expect(r.getMethod()).to.be.equals(
|
|
204
|
+
expect(r.getMethod()).to.be.equals(HttpMethod.GET)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('Case insensitive method', () => {
|
|
208
|
+
const r = newReq({
|
|
209
|
+
path: '/root',
|
|
210
|
+
httpMethod: 'poST',
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
expect(r.getMethod()).to.be.equals(HttpMethod.POST)
|
|
206
214
|
})
|
|
207
215
|
})
|
|
208
216
|
|
|
@@ -1,37 +1,33 @@
|
|
|
1
|
+
import { HttpMethod } from '../../src/API/Request'
|
|
1
2
|
import { Route } from '../../src/Server/Router'
|
|
2
3
|
import RouteResolver from '../../src/Server/RouteResolver'
|
|
3
4
|
|
|
4
|
-
const mockRoute = (method:
|
|
5
|
+
const mockRoute = (method: HttpMethod, path: string) =>
|
|
5
6
|
({
|
|
6
7
|
method: method,
|
|
7
8
|
path: path,
|
|
8
9
|
}) as any as Route
|
|
9
10
|
|
|
10
|
-
type Method =
|
|
11
|
-
| Lowercase<'GET' | 'POST' | 'PUT' | 'DELETE'>
|
|
12
|
-
| Uppercase<'GET' | 'POST' | 'PUT' | 'DELETE'>
|
|
13
|
-
|
|
14
11
|
describe('RouteResolver', () => {
|
|
15
12
|
test('no routes configured', () => {
|
|
16
13
|
parameterizedTest({}, () => [
|
|
17
|
-
[
|
|
18
|
-
[
|
|
19
|
-
[
|
|
14
|
+
[HttpMethod.GET, '/', undefined],
|
|
15
|
+
[HttpMethod.GET, '', undefined],
|
|
16
|
+
[HttpMethod.GET, 'hjdah', undefined],
|
|
20
17
|
])
|
|
21
18
|
})
|
|
22
19
|
|
|
23
|
-
test('one route
|
|
20
|
+
test('one route', () => {
|
|
24
21
|
parameterizedTest(
|
|
25
22
|
{
|
|
26
|
-
route: mockRoute(
|
|
23
|
+
route: mockRoute(HttpMethod.GET, '/'),
|
|
27
24
|
},
|
|
28
25
|
routes => [
|
|
29
|
-
[
|
|
30
|
-
[
|
|
31
|
-
[
|
|
32
|
-
[
|
|
33
|
-
[
|
|
34
|
-
['DELETE', '/', undefined],
|
|
26
|
+
[HttpMethod.GET, '/', routes.route],
|
|
27
|
+
[HttpMethod.GET, '', routes.route],
|
|
28
|
+
[HttpMethod.GET, 'hjdah', undefined],
|
|
29
|
+
[HttpMethod.POST, '/', undefined],
|
|
30
|
+
[HttpMethod.DELETE, '/', undefined],
|
|
35
31
|
]
|
|
36
32
|
)
|
|
37
33
|
})
|
|
@@ -39,22 +35,22 @@ describe('RouteResolver', () => {
|
|
|
39
35
|
test('basic matching', () => {
|
|
40
36
|
parameterizedTest(
|
|
41
37
|
{
|
|
42
|
-
getBase: mockRoute(
|
|
43
|
-
getA: mockRoute(
|
|
44
|
-
getB: mockRoute(
|
|
45
|
-
postBase: mockRoute(
|
|
46
|
-
postA: mockRoute(
|
|
47
|
-
variable: mockRoute(
|
|
48
|
-
getAb: mockRoute(
|
|
38
|
+
getBase: mockRoute(HttpMethod.GET, '/'),
|
|
39
|
+
getA: mockRoute(HttpMethod.GET, '/a'),
|
|
40
|
+
getB: mockRoute(HttpMethod.GET, '/b'),
|
|
41
|
+
postBase: mockRoute(HttpMethod.POST, '/'),
|
|
42
|
+
postA: mockRoute(HttpMethod.POST, '/a'),
|
|
43
|
+
variable: mockRoute(HttpMethod.GET, '/:a'),
|
|
44
|
+
getAb: mockRoute(HttpMethod.GET, '/a/b'),
|
|
49
45
|
},
|
|
50
46
|
routes => [
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[
|
|
54
|
-
[
|
|
55
|
-
[
|
|
56
|
-
[
|
|
57
|
-
[
|
|
47
|
+
[HttpMethod.GET, '/', routes.getBase],
|
|
48
|
+
[HttpMethod.GET, '/a', routes.getA],
|
|
49
|
+
[HttpMethod.GET, '/b', routes.getB],
|
|
50
|
+
[HttpMethod.POST, '/', routes.postBase],
|
|
51
|
+
[HttpMethod.POST, '/a', routes.postA],
|
|
52
|
+
[HttpMethod.GET, '/c', routes.variable],
|
|
53
|
+
[HttpMethod.GET, '/a/b', routes.getAb],
|
|
58
54
|
]
|
|
59
55
|
)
|
|
60
56
|
})
|
|
@@ -62,19 +58,19 @@ describe('RouteResolver', () => {
|
|
|
62
58
|
test('path variables', () => {
|
|
63
59
|
parameterizedTest(
|
|
64
60
|
{
|
|
65
|
-
path_vars: mockRoute(
|
|
66
|
-
abc: mockRoute(
|
|
67
|
-
abcd: mockRoute(
|
|
68
|
-
abc_path: mockRoute(
|
|
61
|
+
path_vars: mockRoute(HttpMethod.GET, '/base/:a/:b/:c'),
|
|
62
|
+
abc: mockRoute(HttpMethod.GET, '/base/a/b/c'),
|
|
63
|
+
abcd: mockRoute(HttpMethod.GET, '/base/a/b/c/d'),
|
|
64
|
+
abc_path: mockRoute(HttpMethod.GET, '/base/a/b/c/:d'),
|
|
69
65
|
},
|
|
70
66
|
routes => [
|
|
71
|
-
[
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
76
|
-
[
|
|
77
|
-
[
|
|
67
|
+
[HttpMethod.GET, '/base/1/2/3', routes.path_vars],
|
|
68
|
+
[HttpMethod.GET, '/base/a/b/c', routes.abc],
|
|
69
|
+
[HttpMethod.GET, '/base/a/b/c/d', routes.abcd],
|
|
70
|
+
[HttpMethod.GET, '/base/a/b/c/u', routes.abc_path],
|
|
71
|
+
[HttpMethod.GET, '/base/a/b', undefined],
|
|
72
|
+
[HttpMethod.GET, '/base/a/b/c/d/e', undefined],
|
|
73
|
+
[HttpMethod.GET, '/base/a/b/c/d/e/f', undefined],
|
|
78
74
|
]
|
|
79
75
|
)
|
|
80
76
|
})
|
|
@@ -83,7 +79,10 @@ describe('RouteResolver', () => {
|
|
|
83
79
|
expect(
|
|
84
80
|
() =>
|
|
85
81
|
new RouteResolver({
|
|
86
|
-
routes: [
|
|
82
|
+
routes: [
|
|
83
|
+
mockRoute(HttpMethod.GET, '/a/b/c/:d/:e/b'),
|
|
84
|
+
mockRoute(HttpMethod.GET, '/a/b/c/:jshj/:e/b'),
|
|
85
|
+
],
|
|
87
86
|
})
|
|
88
87
|
).toThrowError('Duplicate route: GET: /a/b/c/:jshj/:e/b')
|
|
89
88
|
})
|
|
@@ -91,7 +90,7 @@ describe('RouteResolver', () => {
|
|
|
91
90
|
|
|
92
91
|
const parameterizedTest = <T extends { [k: string]: Route }>(
|
|
93
92
|
routes: T,
|
|
94
|
-
tests: (routes: T) => [
|
|
93
|
+
tests: (routes: T) => [HttpMethod, string, Route?][]
|
|
95
94
|
) => {
|
|
96
95
|
const underTest = new RouteResolver({
|
|
97
96
|
routes: Object.values(routes),
|
|
@@ -2,6 +2,7 @@ import { expect as c_expect } from 'chai'
|
|
|
2
2
|
import * as request from 'supertest'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
5
|
+
import { HttpMethod } from '../../../src/API/Request'
|
|
5
6
|
import Response from '../../../src/API/Response'
|
|
6
7
|
import Globals from '../../../src/Globals'
|
|
7
8
|
import ContainerServer from '../../../src/Server/lib/ContainerServer'
|
|
@@ -54,7 +55,7 @@ describe('Container server routing', () => {
|
|
|
54
55
|
routes: [
|
|
55
56
|
{
|
|
56
57
|
path: '/abc',
|
|
57
|
-
method:
|
|
58
|
+
method: HttpMethod.GET,
|
|
58
59
|
handler: async () => {
|
|
59
60
|
return Response.SimpleResponse({ name: 'abc' })
|
|
60
61
|
},
|
|
@@ -181,7 +182,7 @@ describe('Container server validation', () => {
|
|
|
181
182
|
routes: [
|
|
182
183
|
{
|
|
183
184
|
path: '/abc',
|
|
184
|
-
method:
|
|
185
|
+
method: HttpMethod.POST,
|
|
185
186
|
inputSchema: ViewSchema,
|
|
186
187
|
handler: async () => {
|
|
187
188
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -204,7 +205,7 @@ describe('Container server validation', () => {
|
|
|
204
205
|
routes: [
|
|
205
206
|
{
|
|
206
207
|
path: '/abc',
|
|
207
|
-
method:
|
|
208
|
+
method: HttpMethod.POST,
|
|
208
209
|
inputSchema: ViewSchema,
|
|
209
210
|
handler: async () => {
|
|
210
211
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -228,7 +229,7 @@ describe('Container server validation', () => {
|
|
|
228
229
|
routes: [
|
|
229
230
|
{
|
|
230
231
|
path: '/abc',
|
|
231
|
-
method:
|
|
232
|
+
method: HttpMethod.POST,
|
|
232
233
|
inputSchema: ViewSchema,
|
|
233
234
|
handler: async () => {
|
|
234
235
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -252,7 +253,7 @@ describe('Container server validation', () => {
|
|
|
252
253
|
routes: [
|
|
253
254
|
{
|
|
254
255
|
path: '/abc',
|
|
255
|
-
method:
|
|
256
|
+
method: HttpMethod.POST,
|
|
256
257
|
inputSchema: ViewSchema,
|
|
257
258
|
handler: async () => {
|
|
258
259
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -276,7 +277,7 @@ describe('Container server validation', () => {
|
|
|
276
277
|
routes: [
|
|
277
278
|
{
|
|
278
279
|
path: '/abc',
|
|
279
|
-
method:
|
|
280
|
+
method: HttpMethod.POST,
|
|
280
281
|
inputSchema: ViewSchema,
|
|
281
282
|
handler: async () => {
|
|
282
283
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -300,7 +301,7 @@ describe('Container server validation', () => {
|
|
|
300
301
|
routes: [
|
|
301
302
|
{
|
|
302
303
|
path: '/abc',
|
|
303
|
-
method:
|
|
304
|
+
method: HttpMethod.POST,
|
|
304
305
|
inputSchema: ViewSchema,
|
|
305
306
|
handler: async () => {
|
|
306
307
|
return Response.SimpleResponse({ name: 'abc' })
|
|
@@ -2,6 +2,7 @@ import { APIGatewayProxyEvent, Context } from 'aws-lambda'
|
|
|
2
2
|
import { expect } from 'chai'
|
|
3
3
|
import { Request } from 'express'
|
|
4
4
|
|
|
5
|
+
import { HttpMethod } from '../../../../src/API/Request'
|
|
5
6
|
import GenericHandlerEvent from '../../../../src/Server/lib/container/GenericHandlerEvent'
|
|
6
7
|
|
|
7
8
|
describe('GenericHandlerEvent invocation paths', () => {
|
|
@@ -84,7 +85,7 @@ describe('GenericHandlerEvent event test', () => {
|
|
|
84
85
|
const event = new GenericHandlerEvent(
|
|
85
86
|
<Request>(<unknown>{
|
|
86
87
|
headers: { Authorization: '123', 'x-forwarded-for': '127.0.0.1' },
|
|
87
|
-
method:
|
|
88
|
+
method: HttpMethod.GET,
|
|
88
89
|
query: '/status?name=ryan',
|
|
89
90
|
}),
|
|
90
91
|
async (event: APIGatewayProxyEvent, context: Context) => {
|