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