@modern-js/bff-core 1.0.1-beta.0
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/CHANGELOG.md +224 -0
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/js/modern/api.js +59 -0
- package/dist/js/modern/client/generate-client.js +64 -0
- package/dist/js/modern/client/index.js +1 -0
- package/dist/js/modern/client/result.js +20 -0
- package/dist/js/modern/errors/http.js +13 -0
- package/dist/js/modern/index.js +7 -0
- package/dist/js/modern/operators/http.js +183 -0
- package/dist/js/modern/router/constants.js +13 -0
- package/dist/js/modern/router/index.js +271 -0
- package/dist/js/modern/router/types.js +1 -0
- package/dist/js/modern/router/utils.js +53 -0
- package/dist/js/modern/types.js +42 -0
- package/dist/js/modern/utils.js +61 -0
- package/dist/js/node/api.js +71 -0
- package/dist/js/node/client/generate-client.js +82 -0
- package/dist/js/node/client/index.js +18 -0
- package/dist/js/node/client/result.js +32 -0
- package/dist/js/node/errors/http.js +25 -0
- package/dist/js/node/index.js +102 -0
- package/dist/js/node/operators/http.js +227 -0
- package/dist/js/node/router/constants.js +27 -0
- package/dist/js/node/router/index.js +317 -0
- package/dist/js/node/router/types.js +5 -0
- package/dist/js/node/router/utils.js +74 -0
- package/dist/js/node/types.js +53 -0
- package/dist/js/node/utils.js +85 -0
- package/dist/types/api.d.ts +3 -0
- package/dist/types/client/generate-client.d.ts +24 -0
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/client/result.d.ts +15 -0
- package/dist/types/errors/http.d.ts +5 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/operators/http.d.ts +28 -0
- package/dist/types/router/constants.d.ts +16 -0
- package/dist/types/router/index.d.ts +46 -0
- package/dist/types/router/types.d.ts +17 -0
- package/dist/types/router/utils.d.ts +7 -0
- package/dist/types/types.d.ts +54 -0
- package/dist/types/utils.d.ts +7 -0
- package/package.json +89 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
Api: true,
|
|
8
|
+
HttpError: true,
|
|
9
|
+
ValidationError: true
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "Api", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () {
|
|
14
|
+
return _api.Api;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(exports, "HttpError", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () {
|
|
20
|
+
return _http.HttpError;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "ValidationError", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () {
|
|
26
|
+
return _http.ValidationError;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
var _api = require("./api");
|
|
31
|
+
|
|
32
|
+
var _http = require("./errors/http");
|
|
33
|
+
|
|
34
|
+
var _router = require("./router");
|
|
35
|
+
|
|
36
|
+
Object.keys(_router).forEach(function (key) {
|
|
37
|
+
if (key === "default" || key === "__esModule") return;
|
|
38
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
39
|
+
if (key in exports && exports[key] === _router[key]) return;
|
|
40
|
+
Object.defineProperty(exports, key, {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
get: function () {
|
|
43
|
+
return _router[key];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
var _types = require("./types");
|
|
49
|
+
|
|
50
|
+
Object.keys(_types).forEach(function (key) {
|
|
51
|
+
if (key === "default" || key === "__esModule") return;
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
53
|
+
if (key in exports && exports[key] === _types[key]) return;
|
|
54
|
+
Object.defineProperty(exports, key, {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _types[key];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
var _utils = require("./utils");
|
|
63
|
+
|
|
64
|
+
Object.keys(_utils).forEach(function (key) {
|
|
65
|
+
if (key === "default" || key === "__esModule") return;
|
|
66
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
67
|
+
if (key in exports && exports[key] === _utils[key]) return;
|
|
68
|
+
Object.defineProperty(exports, key, {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function () {
|
|
71
|
+
return _utils[key];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
var _client = require("./client");
|
|
77
|
+
|
|
78
|
+
Object.keys(_client).forEach(function (key) {
|
|
79
|
+
if (key === "default" || key === "__esModule") return;
|
|
80
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
81
|
+
if (key in exports && exports[key] === _client[key]) return;
|
|
82
|
+
Object.defineProperty(exports, key, {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function () {
|
|
85
|
+
return _client[key];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
var _http2 = require("./operators/http");
|
|
91
|
+
|
|
92
|
+
Object.keys(_http2).forEach(function (key) {
|
|
93
|
+
if (key === "default" || key === "__esModule") return;
|
|
94
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
95
|
+
if (key in exports && exports[key] === _http2[key]) return;
|
|
96
|
+
Object.defineProperty(exports, key, {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _http2[key];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createHttpOperator = exports.Trace = exports.SetHeaders = exports.Redirect = exports.Query = exports.Put = exports.Post = exports.Patch = exports.Params = exports.Option = exports.Middleware = exports.HttpCode = exports.Headers = exports.Head = exports.Get = exports.Delete = exports.Data = exports.Connect = void 0;
|
|
7
|
+
|
|
8
|
+
var _zod = require("zod");
|
|
9
|
+
|
|
10
|
+
var _types = require("../types");
|
|
11
|
+
|
|
12
|
+
var _http = require("../errors/http");
|
|
13
|
+
|
|
14
|
+
const validateInput = async (schema, input) => {
|
|
15
|
+
try {
|
|
16
|
+
await schema.parseAsync(input);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof _zod.z.ZodError) {
|
|
19
|
+
throw new _http.ValidationError(400, error.message);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const createHttpOperator = method => {
|
|
27
|
+
return urlPath => {
|
|
28
|
+
return {
|
|
29
|
+
name: method,
|
|
30
|
+
|
|
31
|
+
metadata({
|
|
32
|
+
setMetadata
|
|
33
|
+
}) {
|
|
34
|
+
setMetadata(_types.OperatorType.Trigger, {
|
|
35
|
+
type: _types.TriggerType.Http,
|
|
36
|
+
path: urlPath,
|
|
37
|
+
method
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
exports.createHttpOperator = createHttpOperator;
|
|
46
|
+
const Get = createHttpOperator(_types.HttpMethod.Get);
|
|
47
|
+
exports.Get = Get;
|
|
48
|
+
const Post = createHttpOperator(_types.HttpMethod.Post);
|
|
49
|
+
exports.Post = Post;
|
|
50
|
+
const Put = createHttpOperator(_types.HttpMethod.Put);
|
|
51
|
+
exports.Put = Put;
|
|
52
|
+
const Delete = createHttpOperator(_types.HttpMethod.Delete);
|
|
53
|
+
exports.Delete = Delete;
|
|
54
|
+
const Connect = createHttpOperator(_types.HttpMethod.Connect);
|
|
55
|
+
exports.Connect = Connect;
|
|
56
|
+
const Trace = createHttpOperator(_types.HttpMethod.Trace);
|
|
57
|
+
exports.Trace = Trace;
|
|
58
|
+
const Patch = createHttpOperator(_types.HttpMethod.Patch);
|
|
59
|
+
exports.Patch = Patch;
|
|
60
|
+
const Option = createHttpOperator(_types.HttpMethod.Option);
|
|
61
|
+
exports.Option = Option;
|
|
62
|
+
const Head = createHttpOperator(_types.HttpMethod.Head);
|
|
63
|
+
exports.Head = Head;
|
|
64
|
+
|
|
65
|
+
const Data = schema => {
|
|
66
|
+
return {
|
|
67
|
+
name: _types.HttpMetadata.Data,
|
|
68
|
+
|
|
69
|
+
metadata({
|
|
70
|
+
setMetadata
|
|
71
|
+
}) {
|
|
72
|
+
setMetadata(_types.HttpMetadata.Data, schema);
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
async validate(helper, next) {
|
|
76
|
+
const {
|
|
77
|
+
inputs
|
|
78
|
+
} = helper;
|
|
79
|
+
const {
|
|
80
|
+
data
|
|
81
|
+
} = inputs;
|
|
82
|
+
await validateInput(schema, data);
|
|
83
|
+
return next();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
exports.Data = Data;
|
|
90
|
+
|
|
91
|
+
const Query = schema => {
|
|
92
|
+
return {
|
|
93
|
+
name: _types.HttpMetadata.Query,
|
|
94
|
+
|
|
95
|
+
metadata({
|
|
96
|
+
setMetadata
|
|
97
|
+
}) {
|
|
98
|
+
setMetadata(_types.HttpMetadata.Query, schema);
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
async validate(helper, next) {
|
|
102
|
+
const {
|
|
103
|
+
inputs
|
|
104
|
+
} = helper;
|
|
105
|
+
const {
|
|
106
|
+
query
|
|
107
|
+
} = inputs;
|
|
108
|
+
await validateInput(schema, query);
|
|
109
|
+
return next();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
exports.Query = Query;
|
|
116
|
+
|
|
117
|
+
const Params = schema => {
|
|
118
|
+
return {
|
|
119
|
+
name: _types.HttpMetadata.Params,
|
|
120
|
+
|
|
121
|
+
metadata({
|
|
122
|
+
setMetadata
|
|
123
|
+
}) {
|
|
124
|
+
setMetadata(_types.HttpMetadata.Params, schema);
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
async validate(helper, next) {
|
|
128
|
+
const {
|
|
129
|
+
inputs
|
|
130
|
+
} = helper;
|
|
131
|
+
const {
|
|
132
|
+
params
|
|
133
|
+
} = inputs;
|
|
134
|
+
await validateInput(schema, params);
|
|
135
|
+
return next();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
exports.Params = Params;
|
|
142
|
+
|
|
143
|
+
const Headers = schema => {
|
|
144
|
+
return {
|
|
145
|
+
name: _types.HttpMetadata.Headers,
|
|
146
|
+
|
|
147
|
+
metadata({
|
|
148
|
+
setMetadata
|
|
149
|
+
}) {
|
|
150
|
+
setMetadata(_types.HttpMetadata.Headers, schema);
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
async validate(helper, next) {
|
|
154
|
+
const {
|
|
155
|
+
inputs
|
|
156
|
+
} = helper;
|
|
157
|
+
const {
|
|
158
|
+
headers
|
|
159
|
+
} = inputs;
|
|
160
|
+
await validateInput(schema, headers);
|
|
161
|
+
return next();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
exports.Headers = Headers;
|
|
168
|
+
|
|
169
|
+
const HttpCode = statusCode => {
|
|
170
|
+
return {
|
|
171
|
+
name: 'HttpCode',
|
|
172
|
+
|
|
173
|
+
metadata({
|
|
174
|
+
setMetadata
|
|
175
|
+
}) {
|
|
176
|
+
setMetadata(_types.HttpMetadata.StatusCode, statusCode);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
exports.HttpCode = HttpCode;
|
|
183
|
+
|
|
184
|
+
const SetHeaders = headers => {
|
|
185
|
+
return {
|
|
186
|
+
name: 'SetHeaders',
|
|
187
|
+
|
|
188
|
+
metadata({
|
|
189
|
+
setMetadata
|
|
190
|
+
}) {
|
|
191
|
+
setMetadata(_types.HttpMetadata.ResponseHeaders, headers);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
exports.SetHeaders = SetHeaders;
|
|
198
|
+
|
|
199
|
+
const Redirect = url => {
|
|
200
|
+
return {
|
|
201
|
+
name: 'Redirect',
|
|
202
|
+
|
|
203
|
+
metadata({
|
|
204
|
+
setMetadata
|
|
205
|
+
}) {
|
|
206
|
+
setMetadata(_types.HttpMetadata.Redirect, url);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
exports.Redirect = Redirect;
|
|
213
|
+
|
|
214
|
+
const Middleware = middleware => {
|
|
215
|
+
return {
|
|
216
|
+
name: 'Middleware',
|
|
217
|
+
|
|
218
|
+
metadata({
|
|
219
|
+
setMetadata
|
|
220
|
+
}) {
|
|
221
|
+
setMetadata(_types.OperatorType.Middleware, middleware);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
exports.Middleware = Middleware;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.INDEX_SUFFIX = exports.FRAMEWORK_MODE_LAMBDA_DIR = exports.AllHttpMethods = exports.API_FILE_RULES = exports.API_DIR = exports.APIMode = void 0;
|
|
7
|
+
|
|
8
|
+
var _types = require("../types");
|
|
9
|
+
|
|
10
|
+
const AllHttpMethods = Object.values(_types.HttpMethod);
|
|
11
|
+
exports.AllHttpMethods = AllHttpMethods;
|
|
12
|
+
let APIMode;
|
|
13
|
+
exports.APIMode = APIMode;
|
|
14
|
+
|
|
15
|
+
(function (APIMode) {
|
|
16
|
+
APIMode["FARMEWORK"] = "FARMEWORK";
|
|
17
|
+
APIMode["FUNCTION"] = "FUNCTION";
|
|
18
|
+
})(APIMode || (exports.APIMode = APIMode = {}));
|
|
19
|
+
|
|
20
|
+
const FRAMEWORK_MODE_LAMBDA_DIR = 'lambda';
|
|
21
|
+
exports.FRAMEWORK_MODE_LAMBDA_DIR = FRAMEWORK_MODE_LAMBDA_DIR;
|
|
22
|
+
const INDEX_SUFFIX = 'index';
|
|
23
|
+
exports.INDEX_SUFFIX = INDEX_SUFFIX;
|
|
24
|
+
const API_DIR = 'api';
|
|
25
|
+
exports.API_DIR = API_DIR;
|
|
26
|
+
const API_FILE_RULES = ['**/*.[tj]s', '!**/_*', '!**/_*/**/*.[tj]s', '!**/*.test.js', '!**/*.test.ts', '!**/*.d.ts', '!__test__/*.ts', '!__tests__/*.ts', '!node_modules/**', '!bootstrap.js'];
|
|
27
|
+
exports.API_FILE_RULES = API_FILE_RULES;
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
ApiRouter: true
|
|
8
|
+
};
|
|
9
|
+
exports.ApiRouter = void 0;
|
|
10
|
+
|
|
11
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
|
+
|
|
13
|
+
var _utils = require("@modern-js/utils");
|
|
14
|
+
|
|
15
|
+
require("reflect-metadata");
|
|
16
|
+
|
|
17
|
+
require("esbuild-register");
|
|
18
|
+
|
|
19
|
+
var _types = require("../types");
|
|
20
|
+
|
|
21
|
+
var _constants = require("./constants");
|
|
22
|
+
|
|
23
|
+
Object.keys(_constants).forEach(function (key) {
|
|
24
|
+
if (key === "default" || key === "__esModule") return;
|
|
25
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
26
|
+
if (key in exports && exports[key] === _constants[key]) return;
|
|
27
|
+
Object.defineProperty(exports, key, {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () {
|
|
30
|
+
return _constants[key];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
var _utils2 = require("./utils");
|
|
36
|
+
|
|
37
|
+
var _types2 = require("./types");
|
|
38
|
+
|
|
39
|
+
Object.keys(_types2).forEach(function (key) {
|
|
40
|
+
if (key === "default" || key === "__esModule") return;
|
|
41
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
42
|
+
if (key in exports && exports[key] === _types2[key]) return;
|
|
43
|
+
Object.defineProperty(exports, key, {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () {
|
|
46
|
+
return _types2[key];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
52
|
+
|
|
53
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
54
|
+
|
|
55
|
+
class ApiRouter {
|
|
56
|
+
constructor({
|
|
57
|
+
apiDir: _apiDir,
|
|
58
|
+
lambdaDir: _lambdaDir,
|
|
59
|
+
prefix
|
|
60
|
+
}) {
|
|
61
|
+
_defineProperty(this, "apiDir", void 0);
|
|
62
|
+
|
|
63
|
+
_defineProperty(this, "lambdaDir", void 0);
|
|
64
|
+
|
|
65
|
+
_defineProperty(this, "prefix", void 0);
|
|
66
|
+
|
|
67
|
+
_defineProperty(this, "apiFiles", void 0);
|
|
68
|
+
|
|
69
|
+
_defineProperty(this, "getAPIMode", apiDir => {
|
|
70
|
+
const exist = this.createExistChecker(apiDir);
|
|
71
|
+
|
|
72
|
+
if (exist(_constants.FRAMEWORK_MODE_LAMBDA_DIR)) {
|
|
73
|
+
return _constants.APIMode.FARMEWORK;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return _constants.APIMode.FUNCTION;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
_defineProperty(this, "createExistChecker", base => target => _utils.fs.pathExistsSync(_path.default.resolve(base, target)));
|
|
80
|
+
|
|
81
|
+
_defineProperty(this, "getLambdaDir", apiDir => {
|
|
82
|
+
if (this.lambdaDir) {
|
|
83
|
+
return this.lambdaDir;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const mode = this.getAPIMode(apiDir);
|
|
87
|
+
const lambdaDir = mode === _constants.APIMode.FARMEWORK ? _path.default.join(apiDir, _constants.FRAMEWORK_MODE_LAMBDA_DIR) : apiDir;
|
|
88
|
+
return lambdaDir;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
this.apiFiles = [];
|
|
92
|
+
|
|
93
|
+
if (_apiDir) {
|
|
94
|
+
this.validateAbsolute(_apiDir, 'apiDir');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (_lambdaDir) {
|
|
98
|
+
this.validateAbsolute(_lambdaDir, 'lambdaDir');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.prefix = this.initPrefix(prefix);
|
|
102
|
+
this.apiDir = _apiDir;
|
|
103
|
+
this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 如果用户未传入或传入空串,默认为 /api
|
|
107
|
+
* 如果传入 /,则 prefix 为 /
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
initPrefix(prefix) {
|
|
112
|
+
if (prefix === '/') {
|
|
113
|
+
return '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return prefix || '/api';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
validateAbsolute(filename, paramsName) {
|
|
120
|
+
if (!_path.default.isAbsolute(filename)) {
|
|
121
|
+
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getModuleInfos(filenames) {
|
|
126
|
+
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getModuleInfo(filename) {
|
|
130
|
+
try {
|
|
131
|
+
const module = (0, _utils2.requireHandlerModule)(filename);
|
|
132
|
+
return {
|
|
133
|
+
filename,
|
|
134
|
+
module
|
|
135
|
+
};
|
|
136
|
+
} catch (err) {
|
|
137
|
+
if (process.env.NODE_ENV === 'production') {
|
|
138
|
+
throw err;
|
|
139
|
+
} else {
|
|
140
|
+
console.error(err);
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
getHandlerInfos(moduleInfos) {
|
|
147
|
+
let apiHandlers = [];
|
|
148
|
+
moduleInfos.forEach(moduleInfo => {
|
|
149
|
+
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
150
|
+
|
|
151
|
+
if (handlerInfos) {
|
|
152
|
+
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return apiHandlers;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
getModuleHandlerInfos(moduleInfo) {
|
|
159
|
+
const {
|
|
160
|
+
module,
|
|
161
|
+
filename
|
|
162
|
+
} = moduleInfo;
|
|
163
|
+
return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
|
|
164
|
+
const handler = module[key];
|
|
165
|
+
const handlerInfo = this.getHandlerInfo(filename, key, handler);
|
|
166
|
+
return handlerInfo;
|
|
167
|
+
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
validateValidApifile(filename) {
|
|
171
|
+
if (!this.apiFiles.includes(filename)) {
|
|
172
|
+
throw new Error(`The ${filename} is not a valid api file.`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getRoutePath(prefix, routeName) {
|
|
177
|
+
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
178
|
+
|
|
179
|
+
if (prefix === '' && finalRouteName === '') {
|
|
180
|
+
return '/';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return `${prefix}${finalRouteName}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
isApiFile(filename) {
|
|
187
|
+
if (!this.apiFiles.includes(filename)) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
getSingleModuleHandlers(filename) {
|
|
195
|
+
const moduleInfo = this.getModuleInfo(filename);
|
|
196
|
+
|
|
197
|
+
if (moduleInfo) {
|
|
198
|
+
return this.getModuleHandlerInfos(moduleInfo);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
getHandlerInfo(filename, originFuncName, handler) {
|
|
205
|
+
const httpMethod = this.getHttpMethod(originFuncName, handler);
|
|
206
|
+
const routeName = this.getRouteName(filename, handler);
|
|
207
|
+
|
|
208
|
+
if (httpMethod && routeName) {
|
|
209
|
+
return {
|
|
210
|
+
handler,
|
|
211
|
+
name: originFuncName,
|
|
212
|
+
httpMethod,
|
|
213
|
+
routeName,
|
|
214
|
+
filename,
|
|
215
|
+
routePath: this.getRoutePath(this.prefix, routeName)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return null;
|
|
220
|
+
} // TODO: 性能提升,开发环境,判断下 lambda 目录修改时间
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
getSafeRoutePath(filename, handler) {
|
|
224
|
+
this.loadApiFiles();
|
|
225
|
+
this.validateValidApifile(filename);
|
|
226
|
+
return this.getRouteName(filename, handler);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
getRouteName(filename, handler) {
|
|
230
|
+
if (handler) {
|
|
231
|
+
const trigger = Reflect.getMetadata(_types.OperatorType.Trigger, handler);
|
|
232
|
+
|
|
233
|
+
if (trigger && trigger.type === _types.TriggerType.Http) {
|
|
234
|
+
if (!trigger.path) {
|
|
235
|
+
throw new Error(`The http trigger ${trigger.name} needs to specify a path`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return trigger.path;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const routePath = (0, _utils2.getPathFromFilename)(this.lambdaDir, filename);
|
|
243
|
+
return routePath;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getHttpMethod(originHandlerName, handler) {
|
|
247
|
+
if (handler) {
|
|
248
|
+
const trigger = Reflect.getMetadata(_types.OperatorType.Trigger, handler);
|
|
249
|
+
|
|
250
|
+
if (trigger && _types.httpMethods.includes(trigger.method)) {
|
|
251
|
+
return trigger.method;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const upperName = originHandlerName.toUpperCase();
|
|
256
|
+
|
|
257
|
+
switch (upperName) {
|
|
258
|
+
case 'GET':
|
|
259
|
+
return _types.HttpMethod.Get;
|
|
260
|
+
|
|
261
|
+
case 'POST':
|
|
262
|
+
return _types.HttpMethod.Post;
|
|
263
|
+
|
|
264
|
+
case 'PUT':
|
|
265
|
+
return _types.HttpMethod.Put;
|
|
266
|
+
|
|
267
|
+
case 'DELETE':
|
|
268
|
+
case 'DEL':
|
|
269
|
+
return _types.HttpMethod.Delete;
|
|
270
|
+
|
|
271
|
+
case 'CONNECT':
|
|
272
|
+
return _types.HttpMethod.Connect;
|
|
273
|
+
|
|
274
|
+
case 'TRACE':
|
|
275
|
+
return _types.HttpMethod.Trace;
|
|
276
|
+
|
|
277
|
+
case 'PATCH':
|
|
278
|
+
return _types.HttpMethod.Patch;
|
|
279
|
+
|
|
280
|
+
case 'OPTION':
|
|
281
|
+
return _types.HttpMethod.Option;
|
|
282
|
+
|
|
283
|
+
case 'DEFAULT':
|
|
284
|
+
{
|
|
285
|
+
return _types.HttpMethod.Get;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
default:
|
|
289
|
+
_utils.logger.warn(`Only api handlers are allowd to be exported, please remove the function ${originHandlerName} from exports`);
|
|
290
|
+
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
loadApiFiles() {
|
|
296
|
+
// eslint-disable-next-line no-multi-assign
|
|
297
|
+
const apiFiles = this.apiFiles = (0, _utils2.getFiles)(this.lambdaDir, _constants.API_FILE_RULES);
|
|
298
|
+
return apiFiles;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
getApiFiles() {
|
|
302
|
+
if (this.apiFiles.length > 0) {
|
|
303
|
+
return this.apiFiles;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return this.loadApiFiles();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
getApiHandlers() {
|
|
310
|
+
const filenames = this.getApiFiles();
|
|
311
|
+
const moduleInfos = this.getModuleInfos(filenames);
|
|
312
|
+
return this.getHandlerInfos(moduleInfos);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
exports.ApiRouter = ApiRouter;
|