@modern-js/bff-core 2.0.0-beta.0 → 2.0.0-beta.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.
- package/CHANGELOG.md +58 -0
- package/dist/js/modern/api.js +0 -9
- package/dist/js/modern/client/generate-client.js +2 -11
- package/dist/js/modern/client/result.js +2 -1
- package/dist/js/modern/errors/http.js +0 -7
- package/dist/js/modern/operators/http.js +0 -29
- package/dist/js/modern/router/constants.js +0 -2
- package/dist/js/modern/router/index.js +6 -66
- package/dist/js/modern/router/utils.js +3 -18
- package/dist/js/modern/types.js +0 -10
- package/dist/js/modern/utils/alias.js +6 -23
- package/dist/js/modern/utils/storage.js +0 -10
- package/dist/js/modern/utils/validate.js +4 -9
- package/dist/js/node/api.js +0 -14
- package/dist/js/node/client/generate-client.js +2 -19
- package/dist/js/node/client/index.js +0 -2
- package/dist/js/node/client/result.js +2 -5
- package/dist/js/node/errors/http.js +0 -11
- package/dist/js/node/index.js +0 -11
- package/dist/js/node/operators/http.js +0 -45
- package/dist/js/node/router/constants.js +0 -4
- package/dist/js/node/router/index.js +6 -80
- package/dist/js/node/router/utils.js +3 -28
- package/dist/js/node/types.js +0 -10
- package/dist/js/node/utils/alias.js +6 -35
- package/dist/js/node/utils/debug.js +0 -2
- package/dist/js/node/utils/index.js +0 -9
- package/dist/js/node/utils/meta.js +0 -2
- package/dist/js/node/utils/storage.js +0 -13
- package/dist/js/node/utils/validate.js +2 -17
- package/dist/types/router/constants.d.ts +0 -1
- package/dist/types/router/index.d.ts +0 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @modern-js/bff-core
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- dda38c9c3e: chore: v2
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 2344eb2: fix: esbuild should not handle js files
|
|
12
|
+
fix: esbuild 不应该处理非 js 文件
|
|
13
|
+
- a2509bfbdb: feat: bump esbuild from 0.14.38 to 0.15.7
|
|
14
|
+
|
|
15
|
+
feat: 将 esbuild 从 0.14.38 版本升级至 0.15.7 版本
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [92f0ead]
|
|
18
|
+
- Updated dependencies [edd1cfb1af]
|
|
19
|
+
- Updated dependencies [cc971eabfc]
|
|
20
|
+
- Updated dependencies [5b9049f2e9]
|
|
21
|
+
- Updated dependencies [92004d1]
|
|
22
|
+
- Updated dependencies [b8bbe036c7]
|
|
23
|
+
- Updated dependencies [d5a31df781]
|
|
24
|
+
- Updated dependencies [dda38c9c3e]
|
|
25
|
+
- Updated dependencies [3bbea92b2a]
|
|
26
|
+
- Updated dependencies [abf3421a75]
|
|
27
|
+
- Updated dependencies [543be9558e]
|
|
28
|
+
- Updated dependencies [14b712da84]
|
|
29
|
+
- @modern-js/utils@2.0.0-beta.2
|
|
30
|
+
- @modern-js/bff-runtime@2.0.0-beta.2
|
|
31
|
+
|
|
32
|
+
## 2.0.0-beta.1
|
|
33
|
+
|
|
34
|
+
### Major Changes
|
|
35
|
+
|
|
36
|
+
- dda38c9: chore: v2
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- 2344eb2: fix: esbuild should not handle js files
|
|
41
|
+
fix: esbuild 不应该处理非 js 文件
|
|
42
|
+
- a2509bfbdb: feat: bump esbuild from 0.14.38 to 0.15.7
|
|
43
|
+
|
|
44
|
+
feat: 将 esbuild 从 0.14.38 版本升级至 0.15.7 版本
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [92f0ead]
|
|
47
|
+
- Updated dependencies [edd1cfb1af]
|
|
48
|
+
- Updated dependencies [cc971eabfc]
|
|
49
|
+
- Updated dependencies [5b9049f]
|
|
50
|
+
- Updated dependencies [92004d1]
|
|
51
|
+
- Updated dependencies [b8bbe036c7]
|
|
52
|
+
- Updated dependencies [d5a31df781]
|
|
53
|
+
- Updated dependencies [dda38c9]
|
|
54
|
+
- Updated dependencies [3bbea92b2a]
|
|
55
|
+
- Updated dependencies [abf3421]
|
|
56
|
+
- Updated dependencies [543be9558e]
|
|
57
|
+
- Updated dependencies [14b712d]
|
|
58
|
+
- @modern-js/utils@2.0.0-beta.1
|
|
59
|
+
- @modern-js/bff-runtime@2.0.0-beta.1
|
|
60
|
+
|
|
3
61
|
## 2.0.0-beta.0
|
|
4
62
|
|
|
5
63
|
### Major Changes
|
package/dist/js/modern/api.js
CHANGED
|
@@ -9,35 +9,27 @@ export function Api(...args) {
|
|
|
9
9
|
getMetadata(key) {
|
|
10
10
|
return Reflect.getMetadata(key, runner);
|
|
11
11
|
},
|
|
12
|
-
|
|
13
12
|
setMetadata(key, value) {
|
|
14
13
|
return Reflect.defineMetadata(key, value, runner);
|
|
15
14
|
}
|
|
16
|
-
|
|
17
15
|
};
|
|
18
|
-
|
|
19
16
|
for (const operator of operators) {
|
|
20
17
|
if (operator.metadata) {
|
|
21
18
|
operator.metadata(metadataHelper);
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
|
-
|
|
25
21
|
const validateHandlers = operators.filter(operator => operator.validate).map(operator => operator.validate);
|
|
26
22
|
const pipeHandlers = operators.filter(operator => operator.execute).map(operator => operator.execute);
|
|
27
|
-
|
|
28
23
|
async function runner(inputs) {
|
|
29
24
|
const executeHelper = {
|
|
30
25
|
result: null,
|
|
31
|
-
|
|
32
26
|
get inputs() {
|
|
33
27
|
return inputs;
|
|
34
28
|
},
|
|
35
|
-
|
|
36
29
|
set inputs(val) {
|
|
37
30
|
// eslint-disable-next-line no-param-reassign
|
|
38
31
|
inputs = val;
|
|
39
32
|
}
|
|
40
|
-
|
|
41
33
|
};
|
|
42
34
|
const stack = [...validateHandlers, ...pipeHandlers];
|
|
43
35
|
stack.push(async (helper, next) => {
|
|
@@ -48,7 +40,6 @@ export function Api(...args) {
|
|
|
48
40
|
await compose(stack)(executeHelper);
|
|
49
41
|
return executeHelper.result;
|
|
50
42
|
}
|
|
51
|
-
|
|
52
43
|
runner[HANDLER_WITH_META] = true;
|
|
53
44
|
return runner;
|
|
54
45
|
}
|
|
@@ -18,27 +18,21 @@ export const generateClient = async ({
|
|
|
18
18
|
} else {
|
|
19
19
|
// 这里约束传入的 requestCreator 包也必须有两个导出 client 和 server,因为目前的机制 client 和 server 要导出不同的 configure 函数;该 api 不对使用者暴露,后续可优化
|
|
20
20
|
let resolvedPath = requestCreator;
|
|
21
|
-
|
|
22
21
|
try {
|
|
23
22
|
resolvedPath = path.dirname(_requireResolve(requestCreator));
|
|
24
|
-
} catch (error) {}
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
} catch (error) {}
|
|
24
|
+
// eslint-disable-next-line no-param-reassign
|
|
27
25
|
requestCreator = `${resolvedPath}${target ? `/${target}` : ''}`.replace(/\\/g, '/');
|
|
28
26
|
}
|
|
29
|
-
|
|
30
27
|
const apiRouter = new ApiRouter({
|
|
31
28
|
apiDir,
|
|
32
29
|
prefix
|
|
33
30
|
});
|
|
34
31
|
const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
|
|
35
|
-
|
|
36
32
|
if (!handlerInfos) {
|
|
37
33
|
return Err(`generate client error: Cannot require module ${resourcePath}`);
|
|
38
34
|
}
|
|
39
|
-
|
|
40
35
|
let handlersCode = '';
|
|
41
|
-
|
|
42
36
|
for (const handlerInfo of handlerInfos) {
|
|
43
37
|
const {
|
|
44
38
|
name,
|
|
@@ -46,17 +40,14 @@ export const generateClient = async ({
|
|
|
46
40
|
routePath
|
|
47
41
|
} = handlerInfo;
|
|
48
42
|
let exportStatement = `const ${name} =`;
|
|
49
|
-
|
|
50
43
|
if (name.toLowerCase() === 'default') {
|
|
51
44
|
exportStatement = 'default';
|
|
52
45
|
}
|
|
53
|
-
|
|
54
46
|
const upperHttpMethod = httpMethod.toUpperCase();
|
|
55
47
|
const routeName = routePath;
|
|
56
48
|
handlersCode += `export ${exportStatement} createRequest('${routeName}', '${upperHttpMethod}', process.env.PORT || ${String(port)}${fetcher ? `, fetch` : ''});
|
|
57
49
|
`;
|
|
58
50
|
}
|
|
59
|
-
|
|
60
51
|
const importCode = `import { createRequest } from '${requestCreator}';
|
|
61
52
|
${fetcher ? `import { fetch } from '${fetcher}';\n` : ''}`;
|
|
62
53
|
return Ok(`${importCode}\n${handlersCode}`);
|
|
@@ -7,8 +7,9 @@ export const Err = value => {
|
|
|
7
7
|
isOk: false
|
|
8
8
|
};
|
|
9
9
|
return err;
|
|
10
|
-
};
|
|
10
|
+
};
|
|
11
11
|
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
12
13
|
export const Ok = value => {
|
|
13
14
|
const ok = {
|
|
14
15
|
kind: 'Ok',
|
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
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; }
|
|
2
|
-
|
|
3
2
|
export class HttpError extends Error {
|
|
4
3
|
constructor(status, message) {
|
|
5
4
|
super(message);
|
|
6
|
-
|
|
7
5
|
_defineProperty(this, "status", void 0);
|
|
8
|
-
|
|
9
6
|
this.status = status;
|
|
10
7
|
}
|
|
11
|
-
|
|
12
8
|
}
|
|
13
9
|
export class ValidationError extends HttpError {
|
|
14
10
|
constructor(status, message) {
|
|
15
11
|
super(status, message);
|
|
16
|
-
|
|
17
12
|
_defineProperty(this, "code", void 0);
|
|
18
|
-
|
|
19
13
|
this.code = 'VALIDATION_ERROR';
|
|
20
14
|
}
|
|
21
|
-
|
|
22
15
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
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; }
|
|
6
|
-
|
|
7
4
|
import { HttpMetadata, OperatorType, HttpMethod, TriggerType, ResponseMetaType } from "../types";
|
|
8
5
|
import { ValidationError } from "../errors/http";
|
|
9
|
-
|
|
10
6
|
const validateInput = async (schema, input) => {
|
|
11
7
|
try {
|
|
12
8
|
return await schema.parseAsync(input);
|
|
@@ -14,20 +10,16 @@ const validateInput = async (schema, input) => {
|
|
|
14
10
|
const {
|
|
15
11
|
z: zod
|
|
16
12
|
} = require('zod');
|
|
17
|
-
|
|
18
13
|
if (error instanceof zod.ZodError) {
|
|
19
14
|
throw new ValidationError(400, error.message);
|
|
20
15
|
}
|
|
21
|
-
|
|
22
16
|
throw error;
|
|
23
17
|
}
|
|
24
18
|
};
|
|
25
|
-
|
|
26
19
|
export const createHttpOperator = method => {
|
|
27
20
|
return urlPath => {
|
|
28
21
|
return {
|
|
29
22
|
name: method,
|
|
30
|
-
|
|
31
23
|
metadata({
|
|
32
24
|
setMetadata
|
|
33
25
|
}) {
|
|
@@ -37,7 +29,6 @@ export const createHttpOperator = method => {
|
|
|
37
29
|
method
|
|
38
30
|
});
|
|
39
31
|
}
|
|
40
|
-
|
|
41
32
|
};
|
|
42
33
|
};
|
|
43
34
|
};
|
|
@@ -53,13 +44,11 @@ export const Head = createHttpOperator(HttpMethod.Head);
|
|
|
53
44
|
export const Data = schema => {
|
|
54
45
|
return {
|
|
55
46
|
name: HttpMetadata.Data,
|
|
56
|
-
|
|
57
47
|
metadata({
|
|
58
48
|
setMetadata
|
|
59
49
|
}) {
|
|
60
50
|
setMetadata(HttpMetadata.Data, schema);
|
|
61
51
|
},
|
|
62
|
-
|
|
63
52
|
async validate(helper, next) {
|
|
64
53
|
const {
|
|
65
54
|
inputs: {
|
|
@@ -71,19 +60,16 @@ export const Data = schema => {
|
|
|
71
60
|
});
|
|
72
61
|
return next();
|
|
73
62
|
}
|
|
74
|
-
|
|
75
63
|
};
|
|
76
64
|
};
|
|
77
65
|
export const Query = schema => {
|
|
78
66
|
return {
|
|
79
67
|
name: HttpMetadata.Query,
|
|
80
|
-
|
|
81
68
|
metadata({
|
|
82
69
|
setMetadata
|
|
83
70
|
}) {
|
|
84
71
|
setMetadata(HttpMetadata.Query, schema);
|
|
85
72
|
},
|
|
86
|
-
|
|
87
73
|
async validate(helper, next) {
|
|
88
74
|
const {
|
|
89
75
|
inputs: {
|
|
@@ -95,19 +81,16 @@ export const Query = schema => {
|
|
|
95
81
|
});
|
|
96
82
|
return next();
|
|
97
83
|
}
|
|
98
|
-
|
|
99
84
|
};
|
|
100
85
|
};
|
|
101
86
|
export const Params = schema => {
|
|
102
87
|
return {
|
|
103
88
|
name: HttpMetadata.Params,
|
|
104
|
-
|
|
105
89
|
metadata({
|
|
106
90
|
setMetadata
|
|
107
91
|
}) {
|
|
108
92
|
setMetadata(HttpMetadata.Params, schema);
|
|
109
93
|
},
|
|
110
|
-
|
|
111
94
|
async validate(helper, next) {
|
|
112
95
|
const {
|
|
113
96
|
inputs: {
|
|
@@ -119,19 +102,16 @@ export const Params = schema => {
|
|
|
119
102
|
});
|
|
120
103
|
return next();
|
|
121
104
|
}
|
|
122
|
-
|
|
123
105
|
};
|
|
124
106
|
};
|
|
125
107
|
export const Headers = schema => {
|
|
126
108
|
return {
|
|
127
109
|
name: HttpMetadata.Headers,
|
|
128
|
-
|
|
129
110
|
metadata({
|
|
130
111
|
setMetadata
|
|
131
112
|
}) {
|
|
132
113
|
setMetadata(HttpMetadata.Headers, schema);
|
|
133
114
|
},
|
|
134
|
-
|
|
135
115
|
async validate(helper, next) {
|
|
136
116
|
const {
|
|
137
117
|
inputs: {
|
|
@@ -143,10 +123,8 @@ export const Headers = schema => {
|
|
|
143
123
|
});
|
|
144
124
|
return next();
|
|
145
125
|
}
|
|
146
|
-
|
|
147
126
|
};
|
|
148
127
|
};
|
|
149
|
-
|
|
150
128
|
const setResponseMeta = (helper, type, value) => {
|
|
151
129
|
const responseMetaData = helper.getMetadata(HttpMetadata.Response) || [];
|
|
152
130
|
helper.setMetadata(HttpMetadata.Response, [...responseMetaData, {
|
|
@@ -154,34 +132,27 @@ const setResponseMeta = (helper, type, value) => {
|
|
|
154
132
|
value
|
|
155
133
|
}]);
|
|
156
134
|
};
|
|
157
|
-
|
|
158
135
|
export const HttpCode = statusCode => {
|
|
159
136
|
return {
|
|
160
137
|
name: 'HttpCode',
|
|
161
|
-
|
|
162
138
|
metadata(helper) {
|
|
163
139
|
setResponseMeta(helper, ResponseMetaType.StatusCode, statusCode);
|
|
164
140
|
}
|
|
165
|
-
|
|
166
141
|
};
|
|
167
142
|
};
|
|
168
143
|
export const SetHeaders = headers => {
|
|
169
144
|
return {
|
|
170
145
|
name: 'SetHeaders',
|
|
171
|
-
|
|
172
146
|
metadata(helper) {
|
|
173
147
|
setResponseMeta(helper, ResponseMetaType.Headers, headers);
|
|
174
148
|
}
|
|
175
|
-
|
|
176
149
|
};
|
|
177
150
|
};
|
|
178
151
|
export const Redirect = url => {
|
|
179
152
|
return {
|
|
180
153
|
name: 'Redirect',
|
|
181
|
-
|
|
182
154
|
metadata(helper) {
|
|
183
155
|
setResponseMeta(helper, ResponseMetaType.Redirect, url);
|
|
184
156
|
}
|
|
185
|
-
|
|
186
157
|
};
|
|
187
158
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { HttpMethod } from "../types";
|
|
2
2
|
export const AllHttpMethods = Object.values(HttpMethod);
|
|
3
3
|
export let APIMode;
|
|
4
|
-
|
|
5
4
|
(function (APIMode) {
|
|
6
5
|
APIMode["FARMEWORK"] = "framework";
|
|
7
6
|
APIMode["FUNCTION"] = "function";
|
|
8
7
|
})(APIMode || (APIMode = {}));
|
|
9
|
-
|
|
10
8
|
export const FRAMEWORK_MODE_LAMBDA_DIR = 'lambda';
|
|
11
9
|
export const FRAMEWORK_MODE_APP_DIR = 'app';
|
|
12
10
|
export const INDEX_SUFFIX = 'index';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
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; }
|
|
2
|
-
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import { fs, logger } from '@modern-js/utils';
|
|
5
4
|
import 'reflect-metadata';
|
|
@@ -11,47 +10,36 @@ export * from "./types";
|
|
|
11
10
|
export * from "./constants";
|
|
12
11
|
export class ApiRouter {
|
|
13
12
|
// lambdaDir is the dir which equal to the apiDir in function mode, and equal to the api/lambda dir in framework mode
|
|
13
|
+
|
|
14
14
|
constructor({
|
|
15
15
|
apiDir: _apiDir,
|
|
16
16
|
lambdaDir: _lambdaDir,
|
|
17
17
|
prefix
|
|
18
18
|
}) {
|
|
19
19
|
_defineProperty(this, "apiMode", void 0);
|
|
20
|
-
|
|
21
20
|
_defineProperty(this, "apiDir", void 0);
|
|
22
|
-
|
|
23
21
|
_defineProperty(this, "existLambdaDir", void 0);
|
|
24
|
-
|
|
25
22
|
_defineProperty(this, "lambdaDir", void 0);
|
|
26
|
-
|
|
27
23
|
_defineProperty(this, "prefix", void 0);
|
|
28
|
-
|
|
29
24
|
_defineProperty(this, "apiFiles", []);
|
|
30
|
-
|
|
31
25
|
_defineProperty(this, "getExactApiMode", apiDir => {
|
|
32
26
|
const exist = this.createExistChecker(apiDir);
|
|
33
27
|
const existLambdaDir = exist(FRAMEWORK_MODE_LAMBDA_DIR);
|
|
34
28
|
const existAppDir = exist(FRAMEWORK_MODE_APP_DIR);
|
|
35
29
|
const existAppFile = exist('app.ts') || exist('app.js');
|
|
36
|
-
|
|
37
30
|
if (existLambdaDir || existAppDir || existAppFile) {
|
|
38
31
|
return APIMode.FARMEWORK;
|
|
39
32
|
}
|
|
40
|
-
|
|
41
33
|
return APIMode.FUNCTION;
|
|
42
34
|
});
|
|
43
|
-
|
|
44
35
|
_defineProperty(this, "createExistChecker", base => target => fs.pathExistsSync(path.resolve(base, target)));
|
|
45
|
-
|
|
46
36
|
_defineProperty(this, "getExactLambdaDir", apiDir => {
|
|
47
37
|
if (this.lambdaDir) {
|
|
48
38
|
return this.lambdaDir;
|
|
49
39
|
}
|
|
50
|
-
|
|
51
40
|
const lambdaDir = this.apiMode === APIMode.FARMEWORK ? path.join(apiDir, FRAMEWORK_MODE_LAMBDA_DIR) : apiDir;
|
|
52
41
|
return lambdaDir;
|
|
53
42
|
});
|
|
54
|
-
|
|
55
43
|
this.validateAbsolute(_apiDir, 'apiDir');
|
|
56
44
|
this.validateAbsolute(_lambdaDir, 'lambdaDir');
|
|
57
45
|
this.prefix = this.initPrefix(prefix);
|
|
@@ -60,45 +48,34 @@ export class ApiRouter {
|
|
|
60
48
|
this.lambdaDir = _lambdaDir || this.getExactLambdaDir(this.apiDir);
|
|
61
49
|
this.existLambdaDir = fs.existsSync(this.lambdaDir);
|
|
62
50
|
}
|
|
63
|
-
|
|
64
51
|
isExistLambda() {
|
|
65
52
|
return this.existLambdaDir;
|
|
66
53
|
}
|
|
67
|
-
|
|
68
54
|
getApiMode() {
|
|
69
55
|
return this.apiMode;
|
|
70
56
|
}
|
|
71
|
-
|
|
72
57
|
getLambdaDir() {
|
|
73
58
|
return this.lambdaDir;
|
|
74
59
|
}
|
|
75
|
-
|
|
76
60
|
isApiFile(filename) {
|
|
77
61
|
if (this.existLambdaDir) {
|
|
78
62
|
return false;
|
|
79
63
|
}
|
|
80
|
-
|
|
81
64
|
if (!this.apiFiles.includes(filename)) {
|
|
82
65
|
return false;
|
|
83
66
|
}
|
|
84
|
-
|
|
85
67
|
return true;
|
|
86
68
|
}
|
|
87
|
-
|
|
88
69
|
getSingleModuleHandlers(filename) {
|
|
89
70
|
const moduleInfo = this.getModuleInfo(filename);
|
|
90
|
-
|
|
91
71
|
if (moduleInfo) {
|
|
92
72
|
return this.getModuleHandlerInfos(moduleInfo);
|
|
93
73
|
}
|
|
94
|
-
|
|
95
74
|
return null;
|
|
96
75
|
}
|
|
97
|
-
|
|
98
76
|
getHandlerInfo(filename, originFuncName, handler) {
|
|
99
77
|
const httpMethod = this.getHttpMethod(originFuncName, handler);
|
|
100
78
|
const routeName = this.getRouteName(filename, handler);
|
|
101
|
-
|
|
102
79
|
if (httpMethod && routeName) {
|
|
103
80
|
return {
|
|
104
81
|
handler,
|
|
@@ -109,104 +86,80 @@ export class ApiRouter {
|
|
|
109
86
|
routePath: this.getRoutePath(this.prefix, routeName)
|
|
110
87
|
};
|
|
111
88
|
}
|
|
112
|
-
|
|
113
89
|
return null;
|
|
114
|
-
}
|
|
115
|
-
|
|
90
|
+
}
|
|
116
91
|
|
|
92
|
+
// TODO: 性能提升,开发环境,判断下 lambda 目录修改时间
|
|
117
93
|
getSafeRoutePath(filename, handler) {
|
|
118
94
|
this.loadApiFiles();
|
|
119
95
|
this.validateValidApifile(filename);
|
|
120
96
|
return this.getRouteName(filename, handler);
|
|
121
97
|
}
|
|
122
|
-
|
|
123
98
|
getRouteName(filename, handler) {
|
|
124
99
|
if (handler) {
|
|
125
100
|
const trigger = Reflect.getMetadata(OperatorType.Trigger, handler);
|
|
126
|
-
|
|
127
101
|
if (trigger && trigger.type === TriggerType.Http) {
|
|
128
102
|
if (!trigger.path) {
|
|
129
103
|
throw new Error(`The http trigger ${trigger.name} needs to specify a path`);
|
|
130
104
|
}
|
|
131
|
-
|
|
132
105
|
return trigger.path;
|
|
133
106
|
}
|
|
134
107
|
}
|
|
135
|
-
|
|
136
108
|
const routePath = getPathFromFilename(this.lambdaDir, filename);
|
|
137
109
|
return routePath;
|
|
138
110
|
}
|
|
139
|
-
|
|
140
111
|
getHttpMethod(originHandlerName, handler) {
|
|
141
112
|
if (handler) {
|
|
142
113
|
const trigger = Reflect.getMetadata(OperatorType.Trigger, handler);
|
|
143
|
-
|
|
144
114
|
if (trigger && httpMethods.includes(trigger.method)) {
|
|
145
115
|
return trigger.method;
|
|
146
116
|
}
|
|
147
117
|
}
|
|
148
|
-
|
|
149
118
|
const upperName = originHandlerName.toUpperCase();
|
|
150
|
-
|
|
151
119
|
switch (upperName) {
|
|
152
120
|
case 'GET':
|
|
153
121
|
return HttpMethod.Get;
|
|
154
|
-
|
|
155
122
|
case 'POST':
|
|
156
123
|
return HttpMethod.Post;
|
|
157
|
-
|
|
158
124
|
case 'PUT':
|
|
159
125
|
return HttpMethod.Put;
|
|
160
|
-
|
|
161
126
|
case 'DELETE':
|
|
162
127
|
case 'DEL':
|
|
163
128
|
return HttpMethod.Delete;
|
|
164
|
-
|
|
165
129
|
case 'CONNECT':
|
|
166
130
|
return HttpMethod.Connect;
|
|
167
|
-
|
|
168
131
|
case 'TRACE':
|
|
169
132
|
return HttpMethod.Trace;
|
|
170
|
-
|
|
171
133
|
case 'PATCH':
|
|
172
134
|
return HttpMethod.Patch;
|
|
173
|
-
|
|
174
135
|
case 'OPTION':
|
|
175
136
|
return HttpMethod.Option;
|
|
176
|
-
|
|
177
137
|
case 'DEFAULT':
|
|
178
138
|
{
|
|
179
139
|
return HttpMethod.Get;
|
|
180
140
|
}
|
|
181
|
-
|
|
182
141
|
default:
|
|
183
142
|
logger.warn(`Only api handlers are allowd to be exported, please remove the function ${originHandlerName} from exports`);
|
|
184
143
|
return null;
|
|
185
144
|
}
|
|
186
145
|
}
|
|
187
|
-
|
|
188
146
|
loadApiFiles() {
|
|
189
147
|
if (!this.existLambdaDir) {
|
|
190
148
|
return [];
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
149
|
+
}
|
|
150
|
+
// eslint-disable-next-line no-multi-assign
|
|
194
151
|
const apiFiles = this.apiFiles = getFiles(this.lambdaDir, API_FILE_RULES);
|
|
195
152
|
return apiFiles;
|
|
196
153
|
}
|
|
197
|
-
|
|
198
154
|
getApiFiles() {
|
|
199
155
|
if (!this.existLambdaDir) {
|
|
200
156
|
return [];
|
|
201
157
|
}
|
|
202
|
-
|
|
203
158
|
if (this.apiFiles.length > 0) {
|
|
204
159
|
return this.apiFiles;
|
|
205
160
|
}
|
|
206
|
-
|
|
207
161
|
return this.loadApiFiles();
|
|
208
162
|
}
|
|
209
|
-
|
|
210
163
|
getApiHandlers() {
|
|
211
164
|
const filenames = this.getApiFiles();
|
|
212
165
|
const moduleInfos = this.getModuleInfos(filenames);
|
|
@@ -214,30 +167,25 @@ export class ApiRouter {
|
|
|
214
167
|
debug('apiHandlers', apiHandlers.length, apiHandlers);
|
|
215
168
|
return apiHandlers;
|
|
216
169
|
}
|
|
170
|
+
|
|
217
171
|
/**
|
|
218
172
|
* 如果用户未传入或传入空串,默认为 /api
|
|
219
173
|
* 如果传入 /,则 prefix 为 /
|
|
220
174
|
*/
|
|
221
|
-
|
|
222
|
-
|
|
223
175
|
initPrefix(prefix) {
|
|
224
176
|
if (prefix === '/') {
|
|
225
177
|
return '';
|
|
226
178
|
}
|
|
227
|
-
|
|
228
179
|
return prefix || '/api';
|
|
229
180
|
}
|
|
230
|
-
|
|
231
181
|
validateAbsolute(filename, paramsName) {
|
|
232
182
|
if (typeof filename === 'string' && !path.isAbsolute(filename)) {
|
|
233
183
|
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
234
184
|
}
|
|
235
185
|
}
|
|
236
|
-
|
|
237
186
|
getModuleInfos(filenames) {
|
|
238
187
|
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
239
188
|
}
|
|
240
|
-
|
|
241
189
|
getModuleInfo(filename) {
|
|
242
190
|
try {
|
|
243
191
|
const module = requireHandlerModule(filename);
|
|
@@ -254,12 +202,10 @@ export class ApiRouter {
|
|
|
254
202
|
}
|
|
255
203
|
}
|
|
256
204
|
}
|
|
257
|
-
|
|
258
205
|
getHandlerInfos(moduleInfos) {
|
|
259
206
|
let apiHandlers = [];
|
|
260
207
|
moduleInfos.forEach(moduleInfo => {
|
|
261
208
|
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
262
|
-
|
|
263
209
|
if (handlerInfos) {
|
|
264
210
|
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
265
211
|
}
|
|
@@ -267,7 +213,6 @@ export class ApiRouter {
|
|
|
267
213
|
const sortedHandlers = sortRoutes(apiHandlers);
|
|
268
214
|
return sortedHandlers;
|
|
269
215
|
}
|
|
270
|
-
|
|
271
216
|
getModuleHandlerInfos(moduleInfo) {
|
|
272
217
|
const {
|
|
273
218
|
module,
|
|
@@ -279,21 +224,16 @@ export class ApiRouter {
|
|
|
279
224
|
return handlerInfo;
|
|
280
225
|
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
281
226
|
}
|
|
282
|
-
|
|
283
227
|
validateValidApifile(filename) {
|
|
284
228
|
if (!this.apiFiles.includes(filename)) {
|
|
285
229
|
throw new Error(`The ${filename} is not a valid api file.`);
|
|
286
230
|
}
|
|
287
231
|
}
|
|
288
|
-
|
|
289
232
|
getRoutePath(prefix, routeName) {
|
|
290
233
|
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
291
|
-
|
|
292
234
|
if (prefix === '' && finalRouteName === '') {
|
|
293
235
|
return '/';
|
|
294
236
|
}
|
|
295
|
-
|
|
296
237
|
return `${prefix}${finalRouteName}`;
|
|
297
238
|
}
|
|
298
|
-
|
|
299
239
|
}
|