@modern-js/bff-core 1.0.1-beta.0 → 1.0.1-beta.3

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.
@@ -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 = '';
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { HttpMetadata, OperatorType, HttpMethod, TriggerType } from "../types";
2
+ import { HttpMetadata, OperatorType, HttpMethod, TriggerType, ResponseMetaType } from "../types";
3
3
  import { ValidationError } from "../errors/http";
4
4
 
5
5
  const validateInput = async (schema, input) => {
@@ -133,14 +133,21 @@ export const Headers = schema => {
133
133
 
134
134
  };
135
135
  };
136
+
137
+ const setResponseMeta = (helper, type, value) => {
138
+ const responseMetaData = helper.getMetadata(HttpMetadata.Response) || [];
139
+ helper.setMetadata(HttpMetadata.Response, [...responseMetaData, {
140
+ type,
141
+ value
142
+ }]);
143
+ };
144
+
136
145
  export const HttpCode = statusCode => {
137
146
  return {
138
147
  name: 'HttpCode',
139
148
 
140
- metadata({
141
- setMetadata
142
- }) {
143
- setMetadata(HttpMetadata.StatusCode, statusCode);
149
+ metadata(helper) {
150
+ setResponseMeta(helper, ResponseMetaType.StatusCode, statusCode);
144
151
  }
145
152
 
146
153
  };
@@ -149,10 +156,8 @@ export const SetHeaders = headers => {
149
156
  return {
150
157
  name: 'SetHeaders',
151
158
 
152
- metadata({
153
- setMetadata
154
- }) {
155
- setMetadata(HttpMetadata.ResponseHeaders, headers);
159
+ metadata(helper) {
160
+ setResponseMeta(helper, ResponseMetaType.Headers, headers);
156
161
  }
157
162
 
158
163
  };
@@ -161,10 +166,8 @@ export const Redirect = url => {
161
166
  return {
162
167
  name: 'Redirect',
163
168
 
164
- metadata({
165
- setMetadata
166
- }) {
167
- setMetadata(HttpMetadata.Redirect, url);
169
+ metadata(helper) {
170
+ setResponseMeta(helper, ResponseMetaType.Redirect, url);
168
171
  }
169
172
 
170
173
  };
@@ -5,8 +5,9 @@ import { fs, logger } from '@modern-js/utils';
5
5
  import 'reflect-metadata';
6
6
  import 'esbuild-register';
7
7
  import { HttpMethod, httpMethods, OperatorType, TriggerType } from "../types";
8
+ import { debug } from "../utils";
8
9
  import { APIMode, FRAMEWORK_MODE_LAMBDA_DIR, API_FILE_RULES } from "./constants";
9
- import { getFiles, getPathFromFilename, requireHandlerModule } from "./utils";
10
+ import { getFiles, getPathFromFilename, requireHandlerModule, sortRoutes } from "./utils";
10
11
  export * from "./types";
11
12
  export * from "./constants";
12
13
  export class ApiRouter {
@@ -59,86 +60,6 @@ export class ApiRouter {
59
60
  this.apiDir = _apiDir;
60
61
  this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
61
62
  }
62
- /**
63
- * 如果用户未传入或传入空串,默认为 /api
64
- * 如果传入 /,则 prefix 为 /
65
- */
66
-
67
-
68
- initPrefix(prefix) {
69
- if (prefix === '/') {
70
- return '';
71
- }
72
-
73
- return prefix || '/api';
74
- }
75
-
76
- validateAbsolute(filename, paramsName) {
77
- if (!path.isAbsolute(filename)) {
78
- throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
79
- }
80
- }
81
-
82
- getModuleInfos(filenames) {
83
- return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
84
- }
85
-
86
- getModuleInfo(filename) {
87
- try {
88
- const module = requireHandlerModule(filename);
89
- return {
90
- filename,
91
- module
92
- };
93
- } catch (err) {
94
- if (process.env.NODE_ENV === 'production') {
95
- throw err;
96
- } else {
97
- console.error(err);
98
- return null;
99
- }
100
- }
101
- }
102
-
103
- getHandlerInfos(moduleInfos) {
104
- let apiHandlers = [];
105
- moduleInfos.forEach(moduleInfo => {
106
- const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
107
-
108
- if (handlerInfos) {
109
- apiHandlers = apiHandlers.concat(handlerInfos);
110
- }
111
- });
112
- return apiHandlers;
113
- }
114
-
115
- getModuleHandlerInfos(moduleInfo) {
116
- const {
117
- module,
118
- filename
119
- } = moduleInfo;
120
- return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
121
- const handler = module[key];
122
- const handlerInfo = this.getHandlerInfo(filename, key, handler);
123
- return handlerInfo;
124
- }).filter(handlerInfo => Boolean(handlerInfo));
125
- }
126
-
127
- validateValidApifile(filename) {
128
- if (!this.apiFiles.includes(filename)) {
129
- throw new Error(`The ${filename} is not a valid api file.`);
130
- }
131
- }
132
-
133
- getRoutePath(prefix, routeName) {
134
- const finalRouteName = routeName === '/' ? '' : routeName;
135
-
136
- if (prefix === '' && finalRouteName === '') {
137
- return '/';
138
- }
139
-
140
- return `${prefix}${finalRouteName}`;
141
- }
142
63
 
143
64
  isApiFile(filename) {
144
65
  if (!this.apiFiles.includes(filename)) {
@@ -265,7 +186,90 @@ export class ApiRouter {
265
186
  getApiHandlers() {
266
187
  const filenames = this.getApiFiles();
267
188
  const moduleInfos = this.getModuleInfos(filenames);
268
- return this.getHandlerInfos(moduleInfos);
189
+ const apiHandlers = this.getHandlerInfos(moduleInfos);
190
+ debug('apiHandlers', apiHandlers);
191
+ return apiHandlers;
192
+ }
193
+ /**
194
+ * 如果用户未传入或传入空串,默认为 /api
195
+ * 如果传入 /,则 prefix 为 /
196
+ */
197
+
198
+
199
+ initPrefix(prefix) {
200
+ if (prefix === '/') {
201
+ return '';
202
+ }
203
+
204
+ return prefix || '/api';
205
+ }
206
+
207
+ validateAbsolute(filename, paramsName) {
208
+ if (!path.isAbsolute(filename)) {
209
+ throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
210
+ }
211
+ }
212
+
213
+ getModuleInfos(filenames) {
214
+ return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
215
+ }
216
+
217
+ getModuleInfo(filename) {
218
+ try {
219
+ const module = requireHandlerModule(filename);
220
+ return {
221
+ filename,
222
+ module
223
+ };
224
+ } catch (err) {
225
+ if (process.env.NODE_ENV === 'production') {
226
+ throw err;
227
+ } else {
228
+ console.error(err);
229
+ return null;
230
+ }
231
+ }
232
+ }
233
+
234
+ getHandlerInfos(moduleInfos) {
235
+ let apiHandlers = [];
236
+ moduleInfos.forEach(moduleInfo => {
237
+ const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
238
+
239
+ if (handlerInfos) {
240
+ apiHandlers = apiHandlers.concat(handlerInfos);
241
+ }
242
+ });
243
+ const sortedHandlers = sortRoutes(apiHandlers);
244
+ return sortedHandlers;
245
+ }
246
+
247
+ getModuleHandlerInfos(moduleInfo) {
248
+ const {
249
+ module,
250
+ filename
251
+ } = moduleInfo;
252
+ return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
253
+ const handler = module[key];
254
+ const handlerInfo = this.getHandlerInfo(filename, key, handler);
255
+ return handlerInfo;
256
+ }).filter(handlerInfo => Boolean(handlerInfo));
257
+ }
258
+
259
+ validateValidApifile(filename) {
260
+ if (!this.apiFiles.includes(filename)) {
261
+ throw new Error(`The ${filename} is not a valid api file.`);
262
+ }
263
+ }
264
+
265
+ getRoutePath(prefix, routeName) {
266
+ const finalRouteName = routeName === '/' ? '' : routeName;
267
+
268
+ if (prefix === '' && finalRouteName === '') {
269
+ return '/';
270
+ }
271
+
272
+ return `${prefix}${finalRouteName}`;
269
273
  }
270
274
 
271
275
  }
@@ -50,4 +50,14 @@ export const requireHandlerModule = modulePath => {
50
50
  }
51
51
 
52
52
  return module;
53
+ };
54
+ export const sortRoutes = apiHandlers => {
55
+ const sortedHandlers = apiHandlers.slice();
56
+ sortedHandlers.forEach((apiHandler, handlerIndex) => {
57
+ if (apiHandler.routeName.includes(':')) {
58
+ sortedHandlers.splice(handlerIndex, 1);
59
+ sortedHandlers.push(apiHandler);
60
+ }
61
+ });
62
+ return sortedHandlers;
53
63
  };
@@ -20,11 +20,16 @@ export let HttpMetadata;
20
20
  HttpMetadata["Params"] = "PARAMS";
21
21
  HttpMetadata["Headers"] = "HEADERS";
22
22
  HttpMetadata["Response"] = "RESPONSE";
23
- HttpMetadata["StatusCode"] = "STATUS_CODE";
24
- HttpMetadata["Redirect"] = "REDIRECT";
25
- HttpMetadata["ResponseHeaders"] = "RESPONSE_HEADERS";
26
23
  })(HttpMetadata || (HttpMetadata = {}));
27
24
 
25
+ export let ResponseMetaType;
26
+
27
+ (function (ResponseMetaType) {
28
+ ResponseMetaType[ResponseMetaType["StatusCode"] = 0] = "StatusCode";
29
+ ResponseMetaType[ResponseMetaType["Redirect"] = 1] = "Redirect";
30
+ ResponseMetaType[ResponseMetaType["Headers"] = 2] = "Headers";
31
+ })(ResponseMetaType || (ResponseMetaType = {}));
32
+
28
33
  export let HttpMethod;
29
34
 
30
35
  (function (HttpMethod) {
@@ -1,5 +1,7 @@
1
1
  import util from 'util';
2
- export const HANDLER_WITH_META = 'HANDLER_WITH_SCHEMA'; // export const pick = <T extends Record<string, unknown>, K extends keyof T>(
2
+ import { createDebugger } from '@modern-js/utils';
3
+ export const HANDLER_WITH_META = 'HANDLER_WITH_META';
4
+ export const debug = createDebugger('bff'); // export const pick = <T extends Record<string, unknown>, K extends keyof T>(
3
5
  // obj: T,
4
6
  // keys: readonly K[],
5
7
  // ) => {
@@ -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 = '';
@@ -166,14 +166,20 @@ const Headers = schema => {
166
166
 
167
167
  exports.Headers = Headers;
168
168
 
169
+ const setResponseMeta = (helper, type, value) => {
170
+ const responseMetaData = helper.getMetadata(_types.HttpMetadata.Response) || [];
171
+ helper.setMetadata(_types.HttpMetadata.Response, [...responseMetaData, {
172
+ type,
173
+ value
174
+ }]);
175
+ };
176
+
169
177
  const HttpCode = statusCode => {
170
178
  return {
171
179
  name: 'HttpCode',
172
180
 
173
- metadata({
174
- setMetadata
175
- }) {
176
- setMetadata(_types.HttpMetadata.StatusCode, statusCode);
181
+ metadata(helper) {
182
+ setResponseMeta(helper, _types.ResponseMetaType.StatusCode, statusCode);
177
183
  }
178
184
 
179
185
  };
@@ -185,10 +191,8 @@ const SetHeaders = headers => {
185
191
  return {
186
192
  name: 'SetHeaders',
187
193
 
188
- metadata({
189
- setMetadata
190
- }) {
191
- setMetadata(_types.HttpMetadata.ResponseHeaders, headers);
194
+ metadata(helper) {
195
+ setResponseMeta(helper, _types.ResponseMetaType.Headers, headers);
192
196
  }
193
197
 
194
198
  };
@@ -200,10 +204,8 @@ const Redirect = url => {
200
204
  return {
201
205
  name: 'Redirect',
202
206
 
203
- metadata({
204
- setMetadata
205
- }) {
206
- setMetadata(_types.HttpMetadata.Redirect, url);
207
+ metadata(helper) {
208
+ setResponseMeta(helper, _types.ResponseMetaType.Redirect, url);
207
209
  }
208
210
 
209
211
  };
@@ -18,6 +18,8 @@ require("esbuild-register");
18
18
 
19
19
  var _types = require("../types");
20
20
 
21
+ var _utils2 = require("../utils");
22
+
21
23
  var _constants = require("./constants");
22
24
 
23
25
  Object.keys(_constants).forEach(function (key) {
@@ -32,7 +34,7 @@ Object.keys(_constants).forEach(function (key) {
32
34
  });
33
35
  });
34
36
 
35
- var _utils2 = require("./utils");
37
+ var _utils3 = require("./utils");
36
38
 
37
39
  var _types2 = require("./types");
38
40
 
@@ -102,86 +104,6 @@ class ApiRouter {
102
104
  this.apiDir = _apiDir;
103
105
  this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
104
106
  }
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
107
 
186
108
  isApiFile(filename) {
187
109
  if (!this.apiFiles.includes(filename)) {
@@ -239,7 +161,7 @@ class ApiRouter {
239
161
  }
240
162
  }
241
163
 
242
- const routePath = (0, _utils2.getPathFromFilename)(this.lambdaDir, filename);
164
+ const routePath = (0, _utils3.getPathFromFilename)(this.lambdaDir, filename);
243
165
  return routePath;
244
166
  }
245
167
 
@@ -294,7 +216,7 @@ class ApiRouter {
294
216
 
295
217
  loadApiFiles() {
296
218
  // eslint-disable-next-line no-multi-assign
297
- const apiFiles = this.apiFiles = (0, _utils2.getFiles)(this.lambdaDir, _constants.API_FILE_RULES);
219
+ const apiFiles = this.apiFiles = (0, _utils3.getFiles)(this.lambdaDir, _constants.API_FILE_RULES);
298
220
  return apiFiles;
299
221
  }
300
222
 
@@ -309,7 +231,90 @@ class ApiRouter {
309
231
  getApiHandlers() {
310
232
  const filenames = this.getApiFiles();
311
233
  const moduleInfos = this.getModuleInfos(filenames);
312
- return this.getHandlerInfos(moduleInfos);
234
+ const apiHandlers = this.getHandlerInfos(moduleInfos);
235
+ (0, _utils2.debug)('apiHandlers', apiHandlers);
236
+ return apiHandlers;
237
+ }
238
+ /**
239
+ * 如果用户未传入或传入空串,默认为 /api
240
+ * 如果传入 /,则 prefix 为 /
241
+ */
242
+
243
+
244
+ initPrefix(prefix) {
245
+ if (prefix === '/') {
246
+ return '';
247
+ }
248
+
249
+ return prefix || '/api';
250
+ }
251
+
252
+ validateAbsolute(filename, paramsName) {
253
+ if (!_path.default.isAbsolute(filename)) {
254
+ throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
255
+ }
256
+ }
257
+
258
+ getModuleInfos(filenames) {
259
+ return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
260
+ }
261
+
262
+ getModuleInfo(filename) {
263
+ try {
264
+ const module = (0, _utils3.requireHandlerModule)(filename);
265
+ return {
266
+ filename,
267
+ module
268
+ };
269
+ } catch (err) {
270
+ if (process.env.NODE_ENV === 'production') {
271
+ throw err;
272
+ } else {
273
+ console.error(err);
274
+ return null;
275
+ }
276
+ }
277
+ }
278
+
279
+ getHandlerInfos(moduleInfos) {
280
+ let apiHandlers = [];
281
+ moduleInfos.forEach(moduleInfo => {
282
+ const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
283
+
284
+ if (handlerInfos) {
285
+ apiHandlers = apiHandlers.concat(handlerInfos);
286
+ }
287
+ });
288
+ const sortedHandlers = (0, _utils3.sortRoutes)(apiHandlers);
289
+ return sortedHandlers;
290
+ }
291
+
292
+ getModuleHandlerInfos(moduleInfo) {
293
+ const {
294
+ module,
295
+ filename
296
+ } = moduleInfo;
297
+ return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
298
+ const handler = module[key];
299
+ const handlerInfo = this.getHandlerInfo(filename, key, handler);
300
+ return handlerInfo;
301
+ }).filter(handlerInfo => Boolean(handlerInfo));
302
+ }
303
+
304
+ validateValidApifile(filename) {
305
+ if (!this.apiFiles.includes(filename)) {
306
+ throw new Error(`The ${filename} is not a valid api file.`);
307
+ }
308
+ }
309
+
310
+ getRoutePath(prefix, routeName) {
311
+ const finalRouteName = routeName === '/' ? '' : routeName;
312
+
313
+ if (prefix === '' && finalRouteName === '') {
314
+ return '/';
315
+ }
316
+
317
+ return `${prefix}${finalRouteName}`;
313
318
  }
314
319
 
315
320
  }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.requireHandlerModule = exports.isHandler = exports.getPathFromFilename = exports.getFiles = void 0;
6
+ exports.sortRoutes = exports.requireHandlerModule = exports.isHandler = exports.getPathFromFilename = exports.getFiles = void 0;
7
7
 
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
 
@@ -71,4 +71,17 @@ const requireHandlerModule = modulePath => {
71
71
  return module;
72
72
  };
73
73
 
74
- exports.requireHandlerModule = requireHandlerModule;
74
+ exports.requireHandlerModule = requireHandlerModule;
75
+
76
+ const sortRoutes = apiHandlers => {
77
+ const sortedHandlers = apiHandlers.slice();
78
+ sortedHandlers.forEach((apiHandler, handlerIndex) => {
79
+ if (apiHandler.routeName.includes(':')) {
80
+ sortedHandlers.splice(handlerIndex, 1);
81
+ sortedHandlers.push(apiHandler);
82
+ }
83
+ });
84
+ return sortedHandlers;
85
+ };
86
+
87
+ exports.sortRoutes = sortRoutes;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.httpMethods = exports.TriggerType = exports.OperatorType = exports.HttpMethod = exports.HttpMetadata = void 0;
6
+ exports.httpMethods = exports.TriggerType = exports.ResponseMetaType = exports.OperatorType = exports.HttpMethod = exports.HttpMetadata = void 0;
7
7
  let OperatorType;
8
8
  exports.OperatorType = OperatorType;
9
9
 
@@ -29,11 +29,17 @@ exports.HttpMetadata = HttpMetadata;
29
29
  HttpMetadata["Params"] = "PARAMS";
30
30
  HttpMetadata["Headers"] = "HEADERS";
31
31
  HttpMetadata["Response"] = "RESPONSE";
32
- HttpMetadata["StatusCode"] = "STATUS_CODE";
33
- HttpMetadata["Redirect"] = "REDIRECT";
34
- HttpMetadata["ResponseHeaders"] = "RESPONSE_HEADERS";
35
32
  })(HttpMetadata || (exports.HttpMetadata = HttpMetadata = {}));
36
33
 
34
+ let ResponseMetaType;
35
+ exports.ResponseMetaType = ResponseMetaType;
36
+
37
+ (function (ResponseMetaType) {
38
+ ResponseMetaType[ResponseMetaType["StatusCode"] = 0] = "StatusCode";
39
+ ResponseMetaType[ResponseMetaType["Redirect"] = 1] = "Redirect";
40
+ ResponseMetaType[ResponseMetaType["Headers"] = 2] = "Headers";
41
+ })(ResponseMetaType || (exports.ResponseMetaType = ResponseMetaType = {}));
42
+
37
43
  let HttpMethod;
38
44
  exports.HttpMethod = HttpMethod;
39
45
 
@@ -3,13 +3,17 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.validateFunction = exports.isWithMetaHandler = exports.getTypeErrorMessage = exports.HANDLER_WITH_META = exports.ERR_INVALID_ARG_TYPE = void 0;
6
+ exports.validateFunction = exports.isWithMetaHandler = exports.getTypeErrorMessage = exports.debug = exports.HANDLER_WITH_META = exports.ERR_INVALID_ARG_TYPE = void 0;
7
7
 
8
8
  var _util = _interopRequireDefault(require("util"));
9
9
 
10
+ var _utils = require("@modern-js/utils");
11
+
10
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
13
 
12
- const HANDLER_WITH_META = 'HANDLER_WITH_SCHEMA'; // export const pick = <T extends Record<string, unknown>, K extends keyof T>(
14
+ const HANDLER_WITH_META = 'HANDLER_WITH_META';
15
+ exports.HANDLER_WITH_META = HANDLER_WITH_META;
16
+ const debug = (0, _utils.createDebugger)('bff'); // export const pick = <T extends Record<string, unknown>, K extends keyof T>(
13
17
  // obj: T,
14
18
  // keys: readonly K[],
15
19
  // ) => {
@@ -19,7 +23,7 @@ const HANDLER_WITH_META = 'HANDLER_WITH_SCHEMA'; // export const pick = <T exten
19
23
  // };
20
24
  // fork from https://github.com/nodejs/node/blob/master/lib/internal/errors.js
21
25
 
22
- exports.HANDLER_WITH_META = HANDLER_WITH_META;
26
+ exports.debug = debug;
23
27
 
24
28
  const getTypeErrorMessage = actual => {
25
29
  let msg = '';
@@ -1,5 +1,9 @@
1
1
  import { z } from 'zod';
2
- import { Operator, HttpMethod, ApiMiddleware } from '../types';
2
+ import { Operator, HttpMethod, ApiMiddleware, ResponseMetaType } from '../types';
3
+ export interface ResponseMeta {
4
+ type: ResponseMetaType;
5
+ value: unknown;
6
+ }
3
7
  export declare const createHttpOperator: (method: HttpMethod) => (urlPath: string) => Operator<void>;
4
8
  export declare const Get: (urlPath: string) => Operator<void>;
5
9
  export declare const Post: (urlPath: string) => Operator<void>;
@@ -18,6 +18,15 @@ export declare class ApiRouter {
18
18
  lambdaDir?: string;
19
19
  prefix?: string;
20
20
  });
21
+ isApiFile(filename: string): boolean;
22
+ getSingleModuleHandlers(filename: string): APIHandlerInfo[] | null;
23
+ getHandlerInfo(filename: string, originFuncName: string, handler: ApiHandler): APIHandlerInfo | null;
24
+ getSafeRoutePath(filename: string, handler?: ApiHandler): string;
25
+ getRouteName(filename: string, handler?: ApiHandler): string;
26
+ getHttpMethod(originHandlerName: string, handler?: ApiHandler): HttpMethod | null;
27
+ loadApiFiles(): string[];
28
+ getApiFiles(): string[];
29
+ getApiHandlers(): APIHandlerInfo[];
21
30
  /**
22
31
  * 如果用户未传入或传入空串,默认为 /api
23
32
  * 如果传入 /,则 prefix 为 /
@@ -34,13 +43,4 @@ export declare class ApiRouter {
34
43
  private getModuleHandlerInfos;
35
44
  private validateValidApifile;
36
45
  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
46
  }
@@ -1,7 +1,9 @@
1
1
  import { MaybeAsync } from '@modern-js/bff-runtime';
2
+ import { APIHandlerInfo } from './types';
2
3
  export declare type NormalHandler = (...args: any[]) => any;
3
4
  export declare type Handler<I, O> = (input: I) => MaybeAsync<O>;
4
5
  export declare const getFiles: (lambdaDir: string, rules: string | string[]) => string[];
5
6
  export declare const getPathFromFilename: (baseDir: string, filename: string) => string;
6
7
  export declare const isHandler: (input: any) => input is Handler<any, any>;
7
- export declare const requireHandlerModule: (modulePath: string) => any;
8
+ export declare const requireHandlerModule: (modulePath: string) => any;
9
+ export declare const sortRoutes: (apiHandlers: APIHandlerInfo[]) => APIHandlerInfo[];
@@ -13,9 +13,11 @@ export declare enum HttpMetadata {
13
13
  Params = "PARAMS",
14
14
  Headers = "HEADERS",
15
15
  Response = "RESPONSE",
16
- StatusCode = "STATUS_CODE",
17
- Redirect = "REDIRECT",
18
- ResponseHeaders = "RESPONSE_HEADERS",
16
+ }
17
+ export declare enum ResponseMetaType {
18
+ StatusCode = 0,
19
+ Redirect = 1,
20
+ Headers = 2,
19
21
  }
20
22
  export declare enum HttpMethod {
21
23
  Get = "GET",
@@ -1,4 +1,5 @@
1
- export declare const HANDLER_WITH_META = "HANDLER_WITH_SCHEMA";
1
+ export declare const HANDLER_WITH_META = "HANDLER_WITH_META";
2
+ export declare const debug: import("@modern-js/utils/compiled/debug").Debugger;
2
3
  export declare const getTypeErrorMessage: (actual: unknown) => string;
3
4
  export declare class ERR_INVALID_ARG_TYPE extends Error {
4
5
  constructor(funcName: string, expectedType: string, actual: unknown);
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.0.1-beta.0",
14
+ "version": "1.0.1-beta.3",
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"