@midwayjs/faas 3.3.6-beta.5 → 3.4.0-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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2013 - Now midwayjs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  export declare const midwayLogger: {
2
2
  default: {
3
- disableFile: boolean;
4
- disableError: boolean;
3
+ enableFile: boolean;
4
+ enableError: boolean;
5
5
  printFormat: (info: any) => string;
6
6
  };
7
7
  };
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.midwayLogger = void 0;
4
4
  exports.midwayLogger = {
5
5
  default: {
6
- disableFile: true,
7
- disableError: true,
6
+ enableFile: false,
7
+ enableError: false,
8
8
  printFormat: (info) => {
9
9
  var _a, _b, _c, _d, _e, _f;
10
10
  const requestId = (_f = (_c = (_b = (_a = info.ctx) === null || _a === void 0 ? void 0 : _a['originContext']) === null || _b === void 0 ? void 0 : _b['requestId']) !== null && _c !== void 0 ? _c : (_e = (_d = info.ctx) === null || _d === void 0 ? void 0 : _d['originContext']) === null || _e === void 0 ? void 0 : _e['request_id']) !== null && _f !== void 0 ? _f : '';
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { Context, IFaaSConfigurationOptions, Application, NextFunction } from './interface';
2
+ import { Context, IFaaSConfigurationOptions, Application, NextFunction, HandlerOptions } from './interface';
3
3
  import { BaseFramework, CommonMiddlewareUnion, ContextMiddlewareManager, FunctionMiddleware, IMidwayBootstrapOptions, MidwayEnvironmentService, MidwayFrameworkType, MidwayMiddlewareService, RouterInfo } from '@midwayjs/core';
4
4
  import { LoggerOptions } from '@midwayjs/logger';
5
5
  import * as http from 'http';
@@ -15,6 +15,7 @@ export declare class MidwayFaaSFramework extends BaseFramework<Application, Cont
15
15
  private server;
16
16
  private respond;
17
17
  private applicationAdapter;
18
+ private webRouterService;
18
19
  protected httpMiddlewareManager: ContextMiddlewareManager<Context, unknown, unknown>;
19
20
  protected eventMiddlewareManager: ContextMiddlewareManager<Context, unknown, unknown>;
20
21
  environmentService: MidwayEnvironmentService;
@@ -24,15 +25,13 @@ export declare class MidwayFaaSFramework extends BaseFramework<Application, Cont
24
25
  applicationInitialize(options: IMidwayBootstrapOptions): Promise<void>;
25
26
  run(): Promise<void>;
26
27
  getFrameworkType(): MidwayFrameworkType;
27
- handleInvokeWrapper(handlerMapping: string): (...args: any[]) => Promise<{
28
- result: any;
29
- error: Error;
30
- } | {
31
- isBase64Encoded: boolean;
32
- statusCode: any;
33
- headers: any;
34
- body: any;
35
- }>;
28
+ /**
29
+ * @deprecated
30
+ * @param handlerMapping
31
+ */
32
+ handleInvokeWrapper(handlerMapping: string): (...args: any[]) => Promise<any>;
33
+ getTriggerFunction(handlerMapping: string): (context: any, options: HandlerOptions) => Promise<any>;
34
+ wrapHttpRequest(req: http.IncomingMessage, res?: http.ServerResponse): Promise<unknown>;
36
35
  /**
37
36
  * @deprecated
38
37
  * @param middlewareId
@@ -48,6 +47,7 @@ export declare class MidwayFaaSFramework extends BaseFramework<Application, Cont
48
47
  useMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
49
48
  useEventMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
50
49
  getEventMiddleware(): ContextMiddlewareManager<Context, NextFunction, undefined>;
50
+ getAllHandlerNames(): string[];
51
51
  }
52
52
  export declare const createModuleServerlessFramework: (globalOption: Omit<IMidwayBootstrapOptions, 'applicationContext'> & IFaaSConfigurationOptions) => Promise<MidwayFaaSFramework>;
53
53
  //# sourceMappingURL=framework.d.ts.map
package/dist/framework.js CHANGED
@@ -15,7 +15,8 @@ const decorator_1 = require("@midwayjs/decorator");
15
15
  const simple_lock_1 = require("@midwayjs/simple-lock");
16
16
  const logger_1 = require("@midwayjs/logger");
17
17
  const serverless_http_parser_1 = require("@midwayjs/serverless-http-parser");
18
- const http = require("http");
18
+ const util_1 = require("util");
19
+ const { isAnyArrayBuffer, isUint8Array } = util_1.types;
19
20
  const LOCK_KEY = '_faas_starter_start_key';
20
21
  let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework {
21
22
  constructor() {
@@ -48,7 +49,8 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
48
49
  if (!this.logger) {
49
50
  this.logger = options.logger || logger_1.loggers.getLogger('appLogger');
50
51
  }
51
- this.applicationAdapter = this.configurationOptions.applicationAdapter;
52
+ this.applicationAdapter =
53
+ this.configurationOptions.applicationAdapter || {};
52
54
  this.app =
53
55
  ((_b = (_a = this.applicationAdapter).getApplication) === null || _b === void 0 ? void 0 : _b.call(_a)) ||
54
56
  new serverless_http_parser_1.Application();
@@ -68,13 +70,33 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
68
70
  },
69
71
  getFunctionName: () => {
70
72
  var _a;
71
- return (_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getFunctionName();
73
+ return (process.env.MIDWAY_SERVERLESS_FUNCTION_NAME ||
74
+ ((_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getFunctionName()) ||
75
+ '');
72
76
  },
77
+ /**
78
+ * get function service/group in runtime
79
+ */
73
80
  getFunctionServiceName: () => {
74
81
  var _a;
75
- return (_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getFunctionServiceName();
82
+ return (process.env.MIDWAY_SERVERLESS_SERVICE_NAME ||
83
+ ((_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getFunctionServiceName()) ||
84
+ '');
85
+ },
86
+ useEventMiddleware: middleware => {
87
+ return this.useEventMiddleware(middleware);
88
+ },
89
+ getEventMiddleware: () => {
90
+ return this.getEventMiddleware();
91
+ },
92
+ getServerlessInstance: (serviceClass) => {
93
+ return this.app
94
+ .createAnonymousContext()
95
+ .requestContext.getAsync(serviceClass);
96
+ },
97
+ getTriggerFunction: (handlerMapping) => {
98
+ return this.getTriggerFunction(handlerMapping);
76
99
  },
77
- useEventMiddleware: () => { },
78
100
  });
79
101
  // hack use method
80
102
  this.app.originUse = this.app.use;
@@ -85,12 +107,16 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
85
107
  }
86
108
  async run() {
87
109
  return this.lock.sureOnce(async () => {
88
- var _a, _b;
110
+ var _a;
89
111
  // set app keys
90
112
  this.app['keys'] = (_a = this.configService.getConfiguration('keys')) !== null && _a !== void 0 ? _a : '';
91
113
  // store all http function entry
92
- const collector = new core_1.ServerlessTriggerCollector();
93
- const functionList = await collector.getFunctionList();
114
+ this.webRouterService = await this.applicationContext.getAsync(core_1.MidwayWebRouterService, [
115
+ {
116
+ includeFunctionRouter: true,
117
+ },
118
+ ]);
119
+ const functionList = await this.webRouterService.getFlattenRouterTable();
94
120
  for (const funcInfo of functionList) {
95
121
  // store handler
96
122
  this.funMappingStore.set(funcInfo.funcHandlerName, funcInfo);
@@ -103,40 +129,69 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
103
129
  }
104
130
  }
105
131
  this.respond = this.app.callback();
106
- if (this.environmentService.isDevelopmentEnvironment()) {
107
- const faasConfig = (_b = this.configService.getConfiguration('faas')) !== null && _b !== void 0 ? _b : {};
108
- this.server = await new Promise(resolve => {
109
- const server = http.createServer((req, res) => {
110
- const url = new URL(req.url, `http://${req.headers.host}`);
111
- // create event and invoke
112
- this.handleInvokeWrapper(url.pathname)(req, res, {});
113
- });
114
- if (faasConfig['port']) {
115
- server.listen(faasConfig['port']);
116
- }
117
- resolve(server);
118
- });
119
- }
120
132
  }, LOCK_KEY);
121
133
  }
122
134
  getFrameworkType() {
123
135
  return core_1.MidwayFrameworkType.FAAS;
124
136
  }
137
+ /**
138
+ * @deprecated
139
+ * @param handlerMapping
140
+ */
125
141
  handleInvokeWrapper(handlerMapping) {
126
- let funOptions = this.funMappingStore.get(handlerMapping);
142
+ const funOptions = this.funMappingStore.get(handlerMapping);
127
143
  return async (...args) => {
128
- var _a, _b;
129
144
  if (args.length === 0) {
130
145
  throw new Error('first parameter must be function context');
131
146
  }
132
- const event = args[0];
133
- const isLegacyMode = event.originContext && event.originEvent;
134
- const isHttpFunction = event.constructor.name === 'IncomingMessage' ||
135
- event.constructor.name === 'EventEmitter' ||
136
- !!(event.headers && event.get);
147
+ if (!funOptions) {
148
+ throw new Error(`function handler = ${handlerMapping} not found`);
149
+ }
150
+ const context = this.getContext(args.shift());
151
+ const isHttpFunction = !!(context.headers && context.get);
152
+ const globalMiddlewareFn = await this.applyMiddleware();
153
+ const middlewareManager = new core_1.ContextMiddlewareManager();
154
+ middlewareManager.insertLast(globalMiddlewareFn);
155
+ middlewareManager.insertLast(async (ctx, next) => {
156
+ const fn = await this.middlewareService.compose([
157
+ ...(isHttpFunction
158
+ ? this.httpMiddlewareManager
159
+ : this.eventMiddlewareManager),
160
+ ...funOptions.controllerMiddleware,
161
+ ...funOptions.middleware,
162
+ async (ctx, next) => {
163
+ if (isHttpFunction) {
164
+ args = [ctx];
165
+ }
166
+ // invoke handler
167
+ const result = await this.invokeHandler(funOptions, ctx, args, isHttpFunction);
168
+ if (isHttpFunction && result !== undefined) {
169
+ if (result === null) {
170
+ // 这样设置可以绕过 koa 的 _explicitStatus 赋值机制
171
+ ctx.response._body = null;
172
+ }
173
+ else {
174
+ ctx.body = result;
175
+ }
176
+ }
177
+ return result;
178
+ },
179
+ ], this.app);
180
+ return await fn(ctx, next);
181
+ });
182
+ const composeMiddleware = await this.middlewareService.compose(middlewareManager, this.app);
183
+ return await composeMiddleware(context);
184
+ };
185
+ }
186
+ getTriggerFunction(handlerMapping) {
187
+ let funOptions = this.funMappingStore.get(handlerMapping);
188
+ return async (context, options) => {
189
+ var _a;
190
+ const isHttpFunction = options.isHttpFunction;
137
191
  if (!funOptions && isHttpFunction) {
138
192
  for (const item of this.serverlessRoutes) {
139
- if (item.matchPattern.test(event.path)) {
193
+ if (context.method === item.funcInfo['requestMethod'].toUpperCase() &&
194
+ item.matchPattern.test(context.path)) {
140
195
  funOptions = item.funcInfo;
141
196
  break;
142
197
  }
@@ -145,19 +200,7 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
145
200
  if (!funOptions) {
146
201
  throw new Error(`function handler = ${handlerMapping} not found`);
147
202
  }
148
- let context;
149
- if (isLegacyMode) {
150
- context = this.getContext(args.shift());
151
- }
152
- else if (isHttpFunction) {
153
- const newReq = ((_a = this.applicationAdapter) === null || _a === void 0 ? void 0 : _a.runRequestHook(...args)) ||
154
- new serverless_http_parser_1.HTTPRequest(args[0], args[1]);
155
- const newRes = new serverless_http_parser_1.HTTPResponse();
156
- context = this.getContext(await this.createHttpContext(newReq, newRes));
157
- }
158
- else {
159
- context = this.getContext(await ((_b = this.applicationAdapter) === null || _b === void 0 ? void 0 : _b.runEventHook(...args)));
160
- }
203
+ context = this.getContext(context);
161
204
  const result = await (await this.applyMiddleware(async (ctx, next) => {
162
205
  const fn = await this.middlewareService.compose([
163
206
  ...(isHttpFunction
@@ -166,24 +209,34 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
166
209
  ...funOptions.controllerMiddleware,
167
210
  ...funOptions.middleware,
168
211
  async (ctx, next) => {
212
+ let args;
169
213
  if (isHttpFunction) {
170
214
  args = [ctx];
171
215
  }
216
+ else {
217
+ args = [options.originEvent, options.originContext];
218
+ }
172
219
  // invoke handler
173
220
  const result = await this.invokeHandler(funOptions, ctx, args, isHttpFunction);
174
221
  if (isHttpFunction && result !== undefined) {
175
- ctx.body = result;
222
+ if (result === null) {
223
+ // 这样设置可以绕过 koa 的 _explicitStatus 赋值机制
224
+ ctx.response._body = null;
225
+ }
226
+ else {
227
+ ctx.body = result;
228
+ }
229
+ }
230
+ // http 靠 ctx.body,否则会出现状态码不正确的问题
231
+ if (!isHttpFunction) {
232
+ return result;
176
233
  }
177
- return result;
178
234
  },
179
235
  ], this.app);
180
236
  return await fn(ctx, next);
181
237
  }))(context);
182
- if (isLegacyMode) {
183
- return result;
184
- }
185
- else if (isHttpFunction) {
186
- if (!context.response._explicitStatus) {
238
+ if (isHttpFunction) {
239
+ if (!((_a = context.response) === null || _a === void 0 ? void 0 : _a._explicitStatus)) {
187
240
  if (context.body === null || context.body === 'undefined') {
188
241
  context.body = '';
189
242
  context.type = 'text';
@@ -198,13 +251,13 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
198
251
  }
199
252
  context.body = data;
200
253
  }
201
- else if (Buffer.isBuffer(data)) {
254
+ else if (isAnyArrayBuffer(data) || isUint8Array(data)) {
202
255
  encoded = true;
203
256
  if (!context.type) {
204
257
  context.type = 'application/octet-stream';
205
258
  }
206
259
  // data is reserved as buffer
207
- context.body = data.toString('base64');
260
+ context.body = Buffer.from(data).toString('base64');
208
261
  }
209
262
  else if (typeof data === 'object') {
210
263
  if (!context.type) {
@@ -220,6 +273,13 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
220
273
  // set data to string
221
274
  context.body = data = data + '';
222
275
  }
276
+ // middleware return value and will be got 204 status
277
+ if (context.body === undefined &&
278
+ !context.response._explicitStatus &&
279
+ context._matchedRoute) {
280
+ // 如果进了路由,重新赋值,防止 404
281
+ context.body = undefined;
282
+ }
223
283
  return {
224
284
  isBase64Encoded: encoded,
225
285
  statusCode: context.status,
@@ -232,6 +292,11 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
232
292
  }
233
293
  };
234
294
  }
295
+ async wrapHttpRequest(req, res) {
296
+ const newReq = res ? new serverless_http_parser_1.HTTPRequest(req, res) : req;
297
+ const newRes = new serverless_http_parser_1.HTTPResponse();
298
+ return this.createHttpContext(newReq, newRes);
299
+ }
235
300
  /**
236
301
  * @deprecated
237
302
  * @param middlewareId
@@ -325,6 +390,9 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
325
390
  getEventMiddleware() {
326
391
  return this.eventMiddlewareManager;
327
392
  }
393
+ getAllHandlerNames() {
394
+ return Array.from(this.funMappingStore.keys());
395
+ }
328
396
  };
329
397
  __decorate([
330
398
  (0, decorator_1.Inject)(),
@@ -1,4 +1,4 @@
1
- import { MidwayRequestContainer, IMidwayApplication, IConfigurationOptions, IMidwayContext, NextFunction as BaseNextFunction, CommonMiddlewareUnion, ContextMiddlewareManager } from '@midwayjs/core';
1
+ import { MidwayRequestContainer, IMidwayApplication, IConfigurationOptions, IMidwayContext, NextFunction as BaseNextFunction, CommonMiddlewareUnion, ContextMiddlewareManager, IMidwayBootstrapOptions } from '@midwayjs/core';
2
2
  import { FaaSHTTPContext } from '@midwayjs/faas-typings';
3
3
  import { ILogger } from '@midwayjs/logger';
4
4
  import { Application as ServerlessHttpApplication } from '@midwayjs/serverless-http-parser';
@@ -12,6 +12,11 @@ export interface FaaSContext extends IMidwayContext<FaaSHTTPContext> {
12
12
  * @deprecated
13
13
  */
14
14
  export declare type FaaSMiddleware = ((context: Context, next: () => Promise<any>) => any) | string;
15
+ export interface HandlerOptions {
16
+ isHttpFunction: boolean;
17
+ originEvent: any;
18
+ originContext: any;
19
+ }
15
20
  export declare type IMidwayFaaSApplication = IMidwayApplication<Context, {
16
21
  getInitializeContext(): any;
17
22
  use(middleware: FaaSMiddleware): any;
@@ -30,6 +35,8 @@ export declare type IMidwayFaaSApplication = IMidwayApplication<Context, {
30
35
  getFunctionServiceName(): string;
31
36
  useEventMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
32
37
  getEventMiddleware: ContextMiddlewareManager<Context, NextFunction, undefined>;
38
+ getTriggerFunction(handler: string): (context: any, options: HandlerOptions) => Promise<any>;
39
+ getServerlessInstance<T>(serviceClass: T): Promise<T>;
33
40
  }> & ServerlessHttpApplication;
34
41
  export interface Application extends IMidwayFaaSApplication {
35
42
  }
@@ -44,8 +51,6 @@ export interface IFaaSConfigurationOptions extends IConfigurationOptions {
44
51
  getFunctionName(): string;
45
52
  getFunctionServiceName(): string;
46
53
  runAppHook?(app: Application): void;
47
- runEventHook?(...args: any[]): any | void;
48
- runRequestHook?(...args: any[]): any | void;
49
54
  };
50
55
  }
51
56
  /**
@@ -54,4 +59,17 @@ export interface IFaaSConfigurationOptions extends IConfigurationOptions {
54
59
  export interface IWebMiddleware {
55
60
  resolve(): FaaSMiddleware;
56
61
  }
62
+ export interface ServerlessStarterOptions extends IMidwayBootstrapOptions {
63
+ initializeMethodName?: string;
64
+ handlerName?: string;
65
+ createAdapter?: () => Promise<{
66
+ close(): any;
67
+ createAppHook(app?: any): any;
68
+ }>;
69
+ performance?: {
70
+ mark(label: string): any;
71
+ end(): any;
72
+ };
73
+ exportAllHandler?: boolean;
74
+ }
57
75
  //# sourceMappingURL=interface.d.ts.map
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@midwayjs/faas",
3
- "version": "3.3.6-beta.5",
3
+ "version": "3.4.0-beta.3",
4
4
  "main": "dist/index",
5
5
  "typings": "index.d.ts",
6
6
  "dependencies": {
7
- "@midwayjs/core": "^3.3.5",
7
+ "@midwayjs/core": "^3.4.0-beta.3",
8
8
  "@midwayjs/faas-typings": "^3.3.5",
9
9
  "@midwayjs/logger": "^2.15.0",
10
- "@midwayjs/simple-lock": "^1.1.4",
11
- "@midwayjs/serverless-http-parser": "^3.3.5"
10
+ "@midwayjs/serverless-http-parser": "^3.4.0-beta.3",
11
+ "@midwayjs/simple-lock": "^1.1.4"
12
12
  },
13
13
  "devDependencies": {
14
- "@midwayjs/decorator": "^3.3.4",
15
- "@midwayjs/mock": "^3.3.5",
16
- "@midwayjs/serverless-fc-starter": "^3.3.5",
17
- "@midwayjs/serverless-scf-starter": "^3.3.5",
14
+ "@midwayjs/decorator": "^3.4.0-beta.3",
15
+ "@midwayjs/mock": "^3.4.0-beta.3",
16
+ "@midwayjs/serverless-fc-starter": "^3.4.0-beta.3",
17
+ "@midwayjs/serverless-scf-starter": "^3.4.0-beta.3",
18
18
  "mm": "3.2.0"
19
19
  },
20
20
  "engines": {
@@ -46,5 +46,5 @@
46
46
  "url": "git@github.com:midwayjs/midway.git"
47
47
  },
48
48
  "license": "MIT",
49
- "gitHead": "a603d2348d6141f8f723901498f03a162a037708"
49
+ "gitHead": "ddbff5c3da5d908953cc691a8e5de4f0197de365"
50
50
  }