@modern-js/bff-core 1.0.1-beta.1 → 1.0.1-beta.4
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/js/modern/api.js +0 -11
- package/dist/js/modern/client/generate-client.js +2 -3
- package/dist/js/modern/router/index.js +82 -83
- package/dist/js/modern/router/utils.js +9 -0
- package/dist/js/node/api.js +0 -11
- package/dist/js/node/client/generate-client.js +2 -3
- package/dist/js/node/router/index.js +87 -89
- package/dist/js/node/router/utils.js +9 -0
- package/dist/types/router/index.d.ts +9 -10
- package/dist/types/router/utils.d.ts +3 -2
- package/package.json +6 -1
- package/CHANGELOG.md +0 -224
package/dist/js/modern/api.js
CHANGED
|
@@ -25,17 +25,6 @@ export function Api(...args) {
|
|
|
25
25
|
const validateHandlers = operators.filter(operator => operator.validate).map(operator => operator.validate);
|
|
26
26
|
|
|
27
27
|
async function runner(inputs) {
|
|
28
|
-
// 错误组合传给用户哪些信息?
|
|
29
|
-
// 取出来所有的 schema,然后做校验
|
|
30
|
-
// 包裹中间件,怎么根据不同框架去包裹?
|
|
31
|
-
// 需要满足的需求,可以关闭某一样 schema 的校验
|
|
32
|
-
// 可以关闭某一个字段的校验
|
|
33
|
-
// 可以设置校验函数以替换 zod ?类型怎么搞?
|
|
34
|
-
// 全局可配置校验函数
|
|
35
|
-
// middleware 多框架实现要支持在路由上配,但这样 middleware 就要在校验之前先执行了
|
|
36
|
-
// 简易模式适配怎么处理?
|
|
37
|
-
// 不同框架适配,响应怎么处理?都传入 co ntext 给这个函数?
|
|
38
|
-
// 如何不依赖 zod 库?支持用户自定义 schema 库? Query,Data 实现可以统一代码,类型好像无解,除非这些函数是创建出来的,保证只有 http 中依赖 zod 吧
|
|
39
28
|
const executeHelper = {
|
|
40
29
|
result: null,
|
|
41
30
|
|
|
@@ -29,13 +29,12 @@ export const generateClient = async ({
|
|
|
29
29
|
|
|
30
30
|
const apiRouter = new ApiRouter({
|
|
31
31
|
apiDir,
|
|
32
|
-
prefix
|
|
33
|
-
lambdaDir: apiDir
|
|
32
|
+
prefix
|
|
34
33
|
});
|
|
35
34
|
const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
|
|
36
35
|
|
|
37
36
|
if (!handlerInfos) {
|
|
38
|
-
return Err(`Cannot require module ${resourcePath}`);
|
|
37
|
+
return Err(`generate client error: Cannot require module ${resourcePath}`);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
let handlersCode = '';
|
|
@@ -3,11 +3,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { fs, logger } from '@modern-js/utils';
|
|
5
5
|
import 'reflect-metadata';
|
|
6
|
-
import 'esbuild-register';
|
|
7
6
|
import { HttpMethod, httpMethods, OperatorType, TriggerType } from "../types";
|
|
7
|
+
import { debug } from "../utils";
|
|
8
8
|
import { APIMode, FRAMEWORK_MODE_LAMBDA_DIR, API_FILE_RULES } from "./constants";
|
|
9
9
|
import { getFiles, getPathFromFilename, requireHandlerModule, sortRoutes } from "./utils";
|
|
10
|
-
import { debug } from 'console';
|
|
11
10
|
export * from "./types";
|
|
12
11
|
export * from "./constants";
|
|
13
12
|
export class ApiRouter {
|
|
@@ -60,87 +59,6 @@ export class ApiRouter {
|
|
|
60
59
|
this.apiDir = _apiDir;
|
|
61
60
|
this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
|
|
62
61
|
}
|
|
63
|
-
/**
|
|
64
|
-
* 如果用户未传入或传入空串,默认为 /api
|
|
65
|
-
* 如果传入 /,则 prefix 为 /
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
initPrefix(prefix) {
|
|
70
|
-
if (prefix === '/') {
|
|
71
|
-
return '';
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return prefix || '/api';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
validateAbsolute(filename, paramsName) {
|
|
78
|
-
if (!path.isAbsolute(filename)) {
|
|
79
|
-
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
getModuleInfos(filenames) {
|
|
84
|
-
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
getModuleInfo(filename) {
|
|
88
|
-
try {
|
|
89
|
-
const module = requireHandlerModule(filename);
|
|
90
|
-
return {
|
|
91
|
-
filename,
|
|
92
|
-
module
|
|
93
|
-
};
|
|
94
|
-
} catch (err) {
|
|
95
|
-
if (process.env.NODE_ENV === 'production') {
|
|
96
|
-
throw err;
|
|
97
|
-
} else {
|
|
98
|
-
console.error(err);
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
getHandlerInfos(moduleInfos) {
|
|
105
|
-
let apiHandlers = [];
|
|
106
|
-
moduleInfos.forEach(moduleInfo => {
|
|
107
|
-
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
108
|
-
|
|
109
|
-
if (handlerInfos) {
|
|
110
|
-
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
const sortedHandlers = sortRoutes(apiHandlers);
|
|
114
|
-
return sortedHandlers;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
getModuleHandlerInfos(moduleInfo) {
|
|
118
|
-
const {
|
|
119
|
-
module,
|
|
120
|
-
filename
|
|
121
|
-
} = moduleInfo;
|
|
122
|
-
return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
|
|
123
|
-
const handler = module[key];
|
|
124
|
-
const handlerInfo = this.getHandlerInfo(filename, key, handler);
|
|
125
|
-
return handlerInfo;
|
|
126
|
-
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
validateValidApifile(filename) {
|
|
130
|
-
if (!this.apiFiles.includes(filename)) {
|
|
131
|
-
throw new Error(`The ${filename} is not a valid api file.`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
getRoutePath(prefix, routeName) {
|
|
136
|
-
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
137
|
-
|
|
138
|
-
if (prefix === '' && finalRouteName === '') {
|
|
139
|
-
return '/';
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return `${prefix}${finalRouteName}`;
|
|
143
|
-
}
|
|
144
62
|
|
|
145
63
|
isApiFile(filename) {
|
|
146
64
|
if (!this.apiFiles.includes(filename)) {
|
|
@@ -271,5 +189,86 @@ export class ApiRouter {
|
|
|
271
189
|
debug('apiHandlers', apiHandlers);
|
|
272
190
|
return apiHandlers;
|
|
273
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* 如果用户未传入或传入空串,默认为 /api
|
|
194
|
+
* 如果传入 /,则 prefix 为 /
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
initPrefix(prefix) {
|
|
199
|
+
if (prefix === '/') {
|
|
200
|
+
return '';
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return prefix || '/api';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
validateAbsolute(filename, paramsName) {
|
|
207
|
+
if (!path.isAbsolute(filename)) {
|
|
208
|
+
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
getModuleInfos(filenames) {
|
|
213
|
+
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
getModuleInfo(filename) {
|
|
217
|
+
try {
|
|
218
|
+
const module = requireHandlerModule(filename);
|
|
219
|
+
return {
|
|
220
|
+
filename,
|
|
221
|
+
module
|
|
222
|
+
};
|
|
223
|
+
} catch (err) {
|
|
224
|
+
if (process.env.NODE_ENV === 'production') {
|
|
225
|
+
throw err;
|
|
226
|
+
} else {
|
|
227
|
+
console.error(err);
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
getHandlerInfos(moduleInfos) {
|
|
234
|
+
let apiHandlers = [];
|
|
235
|
+
moduleInfos.forEach(moduleInfo => {
|
|
236
|
+
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
237
|
+
|
|
238
|
+
if (handlerInfos) {
|
|
239
|
+
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
const sortedHandlers = sortRoutes(apiHandlers);
|
|
243
|
+
return sortedHandlers;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getModuleHandlerInfos(moduleInfo) {
|
|
247
|
+
const {
|
|
248
|
+
module,
|
|
249
|
+
filename
|
|
250
|
+
} = moduleInfo;
|
|
251
|
+
return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
|
|
252
|
+
const handler = module[key];
|
|
253
|
+
const handlerInfo = this.getHandlerInfo(filename, key, handler);
|
|
254
|
+
return handlerInfo;
|
|
255
|
+
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
validateValidApifile(filename) {
|
|
259
|
+
if (!this.apiFiles.includes(filename)) {
|
|
260
|
+
throw new Error(`The ${filename} is not a valid api file.`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
getRoutePath(prefix, routeName) {
|
|
265
|
+
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
266
|
+
|
|
267
|
+
if (prefix === '' && finalRouteName === '') {
|
|
268
|
+
return '/';
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return `${prefix}${finalRouteName}`;
|
|
272
|
+
}
|
|
274
273
|
|
|
275
274
|
}
|
|
@@ -41,6 +41,14 @@ export const isHandler = input => input && typeof input === 'function';
|
|
|
41
41
|
const isFunction = input => input && {}.toString.call(input) === '[object Function]';
|
|
42
42
|
|
|
43
43
|
export const requireHandlerModule = modulePath => {
|
|
44
|
+
const {
|
|
45
|
+
register
|
|
46
|
+
} = require('esbuild-register/dist/node');
|
|
47
|
+
|
|
48
|
+
const {
|
|
49
|
+
unregister
|
|
50
|
+
} = register({});
|
|
51
|
+
|
|
44
52
|
const module = require(modulePath);
|
|
45
53
|
|
|
46
54
|
if (isFunction(module)) {
|
|
@@ -49,6 +57,7 @@ export const requireHandlerModule = modulePath => {
|
|
|
49
57
|
};
|
|
50
58
|
}
|
|
51
59
|
|
|
60
|
+
unregister();
|
|
52
61
|
return module;
|
|
53
62
|
};
|
|
54
63
|
export const sortRoutes = apiHandlers => {
|
package/dist/js/node/api.js
CHANGED
|
@@ -37,17 +37,6 @@ function Api(...args) {
|
|
|
37
37
|
const validateHandlers = operators.filter(operator => operator.validate).map(operator => operator.validate);
|
|
38
38
|
|
|
39
39
|
async function runner(inputs) {
|
|
40
|
-
// 错误组合传给用户哪些信息?
|
|
41
|
-
// 取出来所有的 schema,然后做校验
|
|
42
|
-
// 包裹中间件,怎么根据不同框架去包裹?
|
|
43
|
-
// 需要满足的需求,可以关闭某一样 schema 的校验
|
|
44
|
-
// 可以关闭某一个字段的校验
|
|
45
|
-
// 可以设置校验函数以替换 zod ?类型怎么搞?
|
|
46
|
-
// 全局可配置校验函数
|
|
47
|
-
// middleware 多框架实现要支持在路由上配,但这样 middleware 就要在校验之前先执行了
|
|
48
|
-
// 简易模式适配怎么处理?
|
|
49
|
-
// 不同框架适配,响应怎么处理?都传入 co ntext 给这个函数?
|
|
50
|
-
// 如何不依赖 zod 库?支持用户自定义 schema 库? Query,Data 实现可以统一代码,类型好像无解,除非这些函数是创建出来的,保证只有 http 中依赖 zod 吧
|
|
51
40
|
const executeHelper = {
|
|
52
41
|
result: null,
|
|
53
42
|
|
|
@@ -45,13 +45,12 @@ const generateClient = async ({
|
|
|
45
45
|
|
|
46
46
|
const apiRouter = new _router.ApiRouter({
|
|
47
47
|
apiDir,
|
|
48
|
-
prefix
|
|
49
|
-
lambdaDir: apiDir
|
|
48
|
+
prefix
|
|
50
49
|
});
|
|
51
50
|
const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
|
|
52
51
|
|
|
53
52
|
if (!handlerInfos) {
|
|
54
|
-
return (0, _result.Err)(`Cannot require module ${resourcePath}`);
|
|
53
|
+
return (0, _result.Err)(`generate client error: Cannot require module ${resourcePath}`);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
let handlersCode = '';
|
|
@@ -14,10 +14,10 @@ var _utils = require("@modern-js/utils");
|
|
|
14
14
|
|
|
15
15
|
require("reflect-metadata");
|
|
16
16
|
|
|
17
|
-
require("esbuild-register");
|
|
18
|
-
|
|
19
17
|
var _types = require("../types");
|
|
20
18
|
|
|
19
|
+
var _utils2 = require("../utils");
|
|
20
|
+
|
|
21
21
|
var _constants = require("./constants");
|
|
22
22
|
|
|
23
23
|
Object.keys(_constants).forEach(function (key) {
|
|
@@ -32,9 +32,7 @@ Object.keys(_constants).forEach(function (key) {
|
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
var _console = require("console");
|
|
35
|
+
var _utils3 = require("./utils");
|
|
38
36
|
|
|
39
37
|
var _types2 = require("./types");
|
|
40
38
|
|
|
@@ -104,87 +102,6 @@ class ApiRouter {
|
|
|
104
102
|
this.apiDir = _apiDir;
|
|
105
103
|
this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
|
|
106
104
|
}
|
|
107
|
-
/**
|
|
108
|
-
* 如果用户未传入或传入空串,默认为 /api
|
|
109
|
-
* 如果传入 /,则 prefix 为 /
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
initPrefix(prefix) {
|
|
114
|
-
if (prefix === '/') {
|
|
115
|
-
return '';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return prefix || '/api';
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
validateAbsolute(filename, paramsName) {
|
|
122
|
-
if (!_path.default.isAbsolute(filename)) {
|
|
123
|
-
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
getModuleInfos(filenames) {
|
|
128
|
-
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
getModuleInfo(filename) {
|
|
132
|
-
try {
|
|
133
|
-
const module = (0, _utils2.requireHandlerModule)(filename);
|
|
134
|
-
return {
|
|
135
|
-
filename,
|
|
136
|
-
module
|
|
137
|
-
};
|
|
138
|
-
} catch (err) {
|
|
139
|
-
if (process.env.NODE_ENV === 'production') {
|
|
140
|
-
throw err;
|
|
141
|
-
} else {
|
|
142
|
-
console.error(err);
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
getHandlerInfos(moduleInfos) {
|
|
149
|
-
let apiHandlers = [];
|
|
150
|
-
moduleInfos.forEach(moduleInfo => {
|
|
151
|
-
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
152
|
-
|
|
153
|
-
if (handlerInfos) {
|
|
154
|
-
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
const sortedHandlers = (0, _utils2.sortRoutes)(apiHandlers);
|
|
158
|
-
return sortedHandlers;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
getModuleHandlerInfos(moduleInfo) {
|
|
162
|
-
const {
|
|
163
|
-
module,
|
|
164
|
-
filename
|
|
165
|
-
} = moduleInfo;
|
|
166
|
-
return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
|
|
167
|
-
const handler = module[key];
|
|
168
|
-
const handlerInfo = this.getHandlerInfo(filename, key, handler);
|
|
169
|
-
return handlerInfo;
|
|
170
|
-
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
validateValidApifile(filename) {
|
|
174
|
-
if (!this.apiFiles.includes(filename)) {
|
|
175
|
-
throw new Error(`The ${filename} is not a valid api file.`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
getRoutePath(prefix, routeName) {
|
|
180
|
-
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
181
|
-
|
|
182
|
-
if (prefix === '' && finalRouteName === '') {
|
|
183
|
-
return '/';
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return `${prefix}${finalRouteName}`;
|
|
187
|
-
}
|
|
188
105
|
|
|
189
106
|
isApiFile(filename) {
|
|
190
107
|
if (!this.apiFiles.includes(filename)) {
|
|
@@ -242,7 +159,7 @@ class ApiRouter {
|
|
|
242
159
|
}
|
|
243
160
|
}
|
|
244
161
|
|
|
245
|
-
const routePath = (0,
|
|
162
|
+
const routePath = (0, _utils3.getPathFromFilename)(this.lambdaDir, filename);
|
|
246
163
|
return routePath;
|
|
247
164
|
}
|
|
248
165
|
|
|
@@ -297,7 +214,7 @@ class ApiRouter {
|
|
|
297
214
|
|
|
298
215
|
loadApiFiles() {
|
|
299
216
|
// eslint-disable-next-line no-multi-assign
|
|
300
|
-
const apiFiles = this.apiFiles = (0,
|
|
217
|
+
const apiFiles = this.apiFiles = (0, _utils3.getFiles)(this.lambdaDir, _constants.API_FILE_RULES);
|
|
301
218
|
return apiFiles;
|
|
302
219
|
}
|
|
303
220
|
|
|
@@ -313,9 +230,90 @@ class ApiRouter {
|
|
|
313
230
|
const filenames = this.getApiFiles();
|
|
314
231
|
const moduleInfos = this.getModuleInfos(filenames);
|
|
315
232
|
const apiHandlers = this.getHandlerInfos(moduleInfos);
|
|
316
|
-
(0,
|
|
233
|
+
(0, _utils2.debug)('apiHandlers', apiHandlers);
|
|
317
234
|
return apiHandlers;
|
|
318
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* 如果用户未传入或传入空串,默认为 /api
|
|
238
|
+
* 如果传入 /,则 prefix 为 /
|
|
239
|
+
*/
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
initPrefix(prefix) {
|
|
243
|
+
if (prefix === '/') {
|
|
244
|
+
return '';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return prefix || '/api';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
validateAbsolute(filename, paramsName) {
|
|
251
|
+
if (!_path.default.isAbsolute(filename)) {
|
|
252
|
+
throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
getModuleInfos(filenames) {
|
|
257
|
+
return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
getModuleInfo(filename) {
|
|
261
|
+
try {
|
|
262
|
+
const module = (0, _utils3.requireHandlerModule)(filename);
|
|
263
|
+
return {
|
|
264
|
+
filename,
|
|
265
|
+
module
|
|
266
|
+
};
|
|
267
|
+
} catch (err) {
|
|
268
|
+
if (process.env.NODE_ENV === 'production') {
|
|
269
|
+
throw err;
|
|
270
|
+
} else {
|
|
271
|
+
console.error(err);
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
getHandlerInfos(moduleInfos) {
|
|
278
|
+
let apiHandlers = [];
|
|
279
|
+
moduleInfos.forEach(moduleInfo => {
|
|
280
|
+
const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
|
|
281
|
+
|
|
282
|
+
if (handlerInfos) {
|
|
283
|
+
apiHandlers = apiHandlers.concat(handlerInfos);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const sortedHandlers = (0, _utils3.sortRoutes)(apiHandlers);
|
|
287
|
+
return sortedHandlers;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
getModuleHandlerInfos(moduleInfo) {
|
|
291
|
+
const {
|
|
292
|
+
module,
|
|
293
|
+
filename
|
|
294
|
+
} = moduleInfo;
|
|
295
|
+
return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
|
|
296
|
+
const handler = module[key];
|
|
297
|
+
const handlerInfo = this.getHandlerInfo(filename, key, handler);
|
|
298
|
+
return handlerInfo;
|
|
299
|
+
}).filter(handlerInfo => Boolean(handlerInfo));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
validateValidApifile(filename) {
|
|
303
|
+
if (!this.apiFiles.includes(filename)) {
|
|
304
|
+
throw new Error(`The ${filename} is not a valid api file.`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getRoutePath(prefix, routeName) {
|
|
309
|
+
const finalRouteName = routeName === '/' ? '' : routeName;
|
|
310
|
+
|
|
311
|
+
if (prefix === '' && finalRouteName === '') {
|
|
312
|
+
return '/';
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return `${prefix}${finalRouteName}`;
|
|
316
|
+
}
|
|
319
317
|
|
|
320
318
|
}
|
|
321
319
|
|
|
@@ -60,6 +60,14 @@ exports.isHandler = isHandler;
|
|
|
60
60
|
const isFunction = input => input && {}.toString.call(input) === '[object Function]';
|
|
61
61
|
|
|
62
62
|
const requireHandlerModule = modulePath => {
|
|
63
|
+
const {
|
|
64
|
+
register
|
|
65
|
+
} = require('esbuild-register/dist/node');
|
|
66
|
+
|
|
67
|
+
const {
|
|
68
|
+
unregister
|
|
69
|
+
} = register({});
|
|
70
|
+
|
|
63
71
|
const module = require(modulePath);
|
|
64
72
|
|
|
65
73
|
if (isFunction(module)) {
|
|
@@ -68,6 +76,7 @@ const requireHandlerModule = modulePath => {
|
|
|
68
76
|
};
|
|
69
77
|
}
|
|
70
78
|
|
|
79
|
+
unregister();
|
|
71
80
|
return module;
|
|
72
81
|
};
|
|
73
82
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
-
import 'esbuild-register';
|
|
3
2
|
import { HttpMethod } from '../types';
|
|
4
3
|
import { ApiHandler, APIHandlerInfo } from './types';
|
|
5
4
|
export * from './types';
|
|
@@ -18,6 +17,15 @@ export declare class ApiRouter {
|
|
|
18
17
|
lambdaDir?: string;
|
|
19
18
|
prefix?: string;
|
|
20
19
|
});
|
|
20
|
+
isApiFile(filename: string): boolean;
|
|
21
|
+
getSingleModuleHandlers(filename: string): APIHandlerInfo[] | null;
|
|
22
|
+
getHandlerInfo(filename: string, originFuncName: string, handler: ApiHandler): APIHandlerInfo | null;
|
|
23
|
+
getSafeRoutePath(filename: string, handler?: ApiHandler): string;
|
|
24
|
+
getRouteName(filename: string, handler?: ApiHandler): string;
|
|
25
|
+
getHttpMethod(originHandlerName: string, handler?: ApiHandler): HttpMethod | null;
|
|
26
|
+
loadApiFiles(): string[];
|
|
27
|
+
getApiFiles(): string[];
|
|
28
|
+
getApiHandlers(): APIHandlerInfo[];
|
|
21
29
|
/**
|
|
22
30
|
* 如果用户未传入或传入空串,默认为 /api
|
|
23
31
|
* 如果传入 /,则 prefix 为 /
|
|
@@ -34,13 +42,4 @@ export declare class ApiRouter {
|
|
|
34
42
|
private getModuleHandlerInfos;
|
|
35
43
|
private validateValidApifile;
|
|
36
44
|
private getRoutePath;
|
|
37
|
-
isApiFile(filename: string): boolean;
|
|
38
|
-
getSingleModuleHandlers(filename: string): APIHandlerInfo[] | null;
|
|
39
|
-
getHandlerInfo(filename: string, originFuncName: string, handler: ApiHandler): APIHandlerInfo | null;
|
|
40
|
-
getSafeRoutePath(filename: string, handler?: ApiHandler): string;
|
|
41
|
-
getRouteName(filename: string, handler?: ApiHandler): string;
|
|
42
|
-
getHttpMethod(originHandlerName: string, handler?: ApiHandler): HttpMethod | null;
|
|
43
|
-
loadApiFiles(): string[];
|
|
44
|
-
getApiFiles(): string[];
|
|
45
|
-
getApiHandlers(): APIHandlerInfo[];
|
|
46
45
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { MaybeAsync } from '@modern-js/bff-runtime';
|
|
2
1
|
import { APIHandlerInfo } from './types';
|
|
2
|
+
declare type MaybeAsync<I> = I | Promise<I>;
|
|
3
3
|
export declare type NormalHandler = (...args: any[]) => any;
|
|
4
4
|
export declare type Handler<I, O> = (input: I) => MaybeAsync<O>;
|
|
5
5
|
export declare const getFiles: (lambdaDir: string, rules: string | string[]) => string[];
|
|
6
6
|
export declare const getPathFromFilename: (baseDir: string, filename: string) => string;
|
|
7
7
|
export declare const isHandler: (input: any) => input is Handler<any, any>;
|
|
8
8
|
export declare const requireHandlerModule: (modulePath: string) => any;
|
|
9
|
-
export declare const sortRoutes: (apiHandlers: APIHandlerInfo[]) => APIHandlerInfo[];
|
|
9
|
+
export declare const sortRoutes: (apiHandlers: APIHandlerInfo[]) => APIHandlerInfo[];
|
|
10
|
+
export {};
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.0.1-beta.
|
|
14
|
+
"version": "1.0.1-beta.4",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -47,6 +47,11 @@
|
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"zod": "^3.17.3"
|
|
49
49
|
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"zod": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
50
55
|
"modernConfig": {
|
|
51
56
|
"output": {
|
|
52
57
|
"packageMode": "node-js"
|
package/CHANGELOG.md
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
# @modern-js/adapter-helpers
|
|
2
|
-
|
|
3
|
-
## 1.2.4
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- d32f35134: chore: add modern/jest/eslint/ts config files to .npmignore
|
|
8
|
-
|
|
9
|
-
## 1.2.3
|
|
10
|
-
|
|
11
|
-
### Patch Changes
|
|
12
|
-
|
|
13
|
-
- 6cffe99d: chore:
|
|
14
|
-
remove react eslint rules for `modern-js` rule set.
|
|
15
|
-
add .eslintrc for each package to speed up linting
|
|
16
|
-
- 60f7d8bf: feat: add tests dir to npmignore
|
|
17
|
-
- befd9e5b: fix: compatible with babel-plugin-resolver's handling of relative paths on windows
|
|
18
|
-
- 3bf4f8b0: feat: support start api server only
|
|
19
|
-
|
|
20
|
-
## 1.2.2
|
|
21
|
-
|
|
22
|
-
### Patch Changes
|
|
23
|
-
|
|
24
|
-
- 55e18278: chore: remove unused dependencies and devDependencies
|
|
25
|
-
|
|
26
|
-
## 1.2.1
|
|
27
|
-
|
|
28
|
-
### Patch Changes
|
|
29
|
-
|
|
30
|
-
- 83166714: change .npmignore
|
|
31
|
-
|
|
32
|
-
## 1.2.0
|
|
33
|
-
|
|
34
|
-
### Minor Changes
|
|
35
|
-
|
|
36
|
-
- cfe11628: Make Modern.js self bootstraping
|
|
37
|
-
|
|
38
|
-
## 1.1.1
|
|
39
|
-
|
|
40
|
-
### Patch Changes
|
|
41
|
-
|
|
42
|
-
- 0fa83663: support more .env files
|
|
43
|
-
|
|
44
|
-
## 1.1.0
|
|
45
|
-
|
|
46
|
-
### Minor Changes
|
|
47
|
-
|
|
48
|
-
- 96119db2: Relese v1.1.0
|
|
49
|
-
|
|
50
|
-
## 1.0.0
|
|
51
|
-
|
|
52
|
-
### Patch Changes
|
|
53
|
-
|
|
54
|
-
- 224f7fe: fix server route match
|
|
55
|
-
- 30ac27c: feat: add generator package description
|
|
56
|
-
- 0fd196e: feat: fix bugs
|
|
57
|
-
- 204c626: feat: initial
|
|
58
|
-
- 63be0a5: fix: #118 #104
|
|
59
|
-
|
|
60
|
-
## 1.0.0-rc.23
|
|
61
|
-
|
|
62
|
-
### Patch Changes
|
|
63
|
-
|
|
64
|
-
- 224f7fe: fix server route match
|
|
65
|
-
- 30ac27c: feat: add generator package description
|
|
66
|
-
- 0fd196e: feat: fix bugs
|
|
67
|
-
- 204c626: feat: initial
|
|
68
|
-
- 63be0a5: fix: #118 #104
|
|
69
|
-
|
|
70
|
-
## 1.0.0-rc.22
|
|
71
|
-
|
|
72
|
-
### Patch Changes
|
|
73
|
-
|
|
74
|
-
- 224f7fe: fix server route match
|
|
75
|
-
- 30ac27c: feat: add generator package description
|
|
76
|
-
- 0fd196e: feat: fix bugs
|
|
77
|
-
- 204c626: feat: initial
|
|
78
|
-
- 63be0a5: fix: #118 #104
|
|
79
|
-
|
|
80
|
-
## 1.0.0-rc.21
|
|
81
|
-
|
|
82
|
-
### Patch Changes
|
|
83
|
-
|
|
84
|
-
- 224f7fe: fix server route match
|
|
85
|
-
- 30ac27c: feat: add generator package description
|
|
86
|
-
- 0fd196e: feat: fix bugs
|
|
87
|
-
- 204c626: feat: initial
|
|
88
|
-
- 63be0a5: fix: #118 #104
|
|
89
|
-
|
|
90
|
-
## 1.0.0-rc.20
|
|
91
|
-
|
|
92
|
-
### Patch Changes
|
|
93
|
-
|
|
94
|
-
- 224f7fe: fix server route match
|
|
95
|
-
- 30ac27c: feat: add generator package description
|
|
96
|
-
- feat: fix bugs
|
|
97
|
-
- 204c626: feat: initial
|
|
98
|
-
- 63be0a5: fix: #118 #104
|
|
99
|
-
|
|
100
|
-
## 1.0.0-rc.19
|
|
101
|
-
|
|
102
|
-
### Patch Changes
|
|
103
|
-
|
|
104
|
-
- 224f7fe: fix server route match
|
|
105
|
-
- 30ac27c: feat: add generator package description
|
|
106
|
-
- 204c626: feat: initial
|
|
107
|
-
- 63be0a5: fix: #118 #104
|
|
108
|
-
|
|
109
|
-
## 1.0.0-rc.18
|
|
110
|
-
|
|
111
|
-
### Patch Changes
|
|
112
|
-
|
|
113
|
-
- 224f7fe: fix server route match
|
|
114
|
-
- 30ac27c: feat: add generator package description
|
|
115
|
-
- 204c626: feat: initial
|
|
116
|
-
- 63be0a5: fix: #118 #104
|
|
117
|
-
|
|
118
|
-
## 1.0.0-rc.17
|
|
119
|
-
|
|
120
|
-
### Patch Changes
|
|
121
|
-
|
|
122
|
-
- 224f7fe: fix server route match
|
|
123
|
-
- 30ac27c: feat: add generator package description
|
|
124
|
-
- 204c626: feat: initial
|
|
125
|
-
- fix: #118 #104
|
|
126
|
-
|
|
127
|
-
## 1.0.0-rc.16
|
|
128
|
-
|
|
129
|
-
### Patch Changes
|
|
130
|
-
|
|
131
|
-
- 224f7fe: fix server route match
|
|
132
|
-
- 30ac27c: feat: add generator package description
|
|
133
|
-
- 204c626: feat: initial
|
|
134
|
-
|
|
135
|
-
## 1.0.0-rc.15
|
|
136
|
-
|
|
137
|
-
### Patch Changes
|
|
138
|
-
|
|
139
|
-
- 224f7fe: fix server route match
|
|
140
|
-
- 30ac27c: feat: add generator package description
|
|
141
|
-
- 204c626: feat: initial
|
|
142
|
-
|
|
143
|
-
## 1.0.0-rc.14
|
|
144
|
-
|
|
145
|
-
### Patch Changes
|
|
146
|
-
|
|
147
|
-
- 224f7fe: fix server route match
|
|
148
|
-
- 204c626: feat: initial
|
|
149
|
-
|
|
150
|
-
## 1.0.0-rc.13
|
|
151
|
-
|
|
152
|
-
### Patch Changes
|
|
153
|
-
|
|
154
|
-
- 224f7fe: fix server route match
|
|
155
|
-
- 204c626: feat: initial
|
|
156
|
-
|
|
157
|
-
## 1.0.0-rc.12
|
|
158
|
-
|
|
159
|
-
### Patch Changes
|
|
160
|
-
|
|
161
|
-
- 224f7fe: fix server route match
|
|
162
|
-
- 204c626: feat: initial
|
|
163
|
-
|
|
164
|
-
## 1.0.0-rc.11
|
|
165
|
-
|
|
166
|
-
### Patch Changes
|
|
167
|
-
|
|
168
|
-
- 224f7fe: fix server route match
|
|
169
|
-
- 204c626: feat: initial
|
|
170
|
-
|
|
171
|
-
## 1.0.0-rc.10
|
|
172
|
-
|
|
173
|
-
### Patch Changes
|
|
174
|
-
|
|
175
|
-
- 224f7fe: fix server route match
|
|
176
|
-
- 204c626: feat: initial
|
|
177
|
-
|
|
178
|
-
## 1.0.0-rc.9
|
|
179
|
-
|
|
180
|
-
### Patch Changes
|
|
181
|
-
|
|
182
|
-
- 224f7fe: fix server route match
|
|
183
|
-
- 204c626: feat: initial
|
|
184
|
-
|
|
185
|
-
## 1.0.0-rc.8
|
|
186
|
-
|
|
187
|
-
### Patch Changes
|
|
188
|
-
|
|
189
|
-
- 224f7fe: fix server route match
|
|
190
|
-
- 204c626: feat: initial
|
|
191
|
-
|
|
192
|
-
## 1.0.0-rc.7
|
|
193
|
-
|
|
194
|
-
### Patch Changes
|
|
195
|
-
|
|
196
|
-
- 224f7fe: fix server route match
|
|
197
|
-
- 204c626: feat: initial
|
|
198
|
-
|
|
199
|
-
## 1.0.0-rc.6
|
|
200
|
-
|
|
201
|
-
### Patch Changes
|
|
202
|
-
|
|
203
|
-
- 224f7fe: fix server route match
|
|
204
|
-
- 204c626: feat: initial
|
|
205
|
-
|
|
206
|
-
## 1.0.0-rc.5
|
|
207
|
-
|
|
208
|
-
### Patch Changes
|
|
209
|
-
|
|
210
|
-
- 224f7fe: fix server route match
|
|
211
|
-
- 204c626: feat: initial
|
|
212
|
-
|
|
213
|
-
## 1.0.0-rc.4
|
|
214
|
-
|
|
215
|
-
### Patch Changes
|
|
216
|
-
|
|
217
|
-
- fix server route match
|
|
218
|
-
- 204c626: feat: initial
|
|
219
|
-
|
|
220
|
-
## 1.0.0-rc.3
|
|
221
|
-
|
|
222
|
-
### Patch Changes
|
|
223
|
-
|
|
224
|
-
- feat: initial
|