@midwayjs/faas 3.3.6-beta.1 → 3.3.6-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.
@@ -1,33 +1,53 @@
1
- import { FaaSContext, IFaaSConfigurationOptions, IMidwayFaaSApplication } from './interface';
2
- import { BaseFramework, FunctionMiddleware, IMidwayBootstrapOptions, MidwayEnvironmentService, MidwayFrameworkType, MidwayMiddlewareService, RouterInfo } from '@midwayjs/core';
1
+ /// <reference types="node" />
2
+ import { Context, IFaaSConfigurationOptions, Application, NextFunction } from './interface';
3
+ import { BaseFramework, CommonMiddlewareUnion, ContextMiddlewareManager, FunctionMiddleware, IMidwayBootstrapOptions, MidwayEnvironmentService, MidwayFrameworkType, MidwayMiddlewareService, RouterInfo } from '@midwayjs/core';
3
4
  import { LoggerOptions } from '@midwayjs/logger';
4
- export declare class MidwayFaaSFramework extends BaseFramework<IMidwayFaaSApplication, FaaSContext, IFaaSConfigurationOptions> {
5
+ import * as http from 'http';
6
+ export declare class MidwayFaaSFramework extends BaseFramework<Application, Context, IFaaSConfigurationOptions> {
5
7
  protected defaultHandlerMethod: string;
6
8
  protected funMappingStore: Map<string, RouterInfo>;
7
9
  protected logger: any;
8
10
  private lock;
9
- app: IMidwayFaaSApplication;
11
+ app: Application;
10
12
  private isReplaceLogger;
11
13
  private developmentRun;
12
14
  private serverlessRoutes;
15
+ private server;
16
+ private respond;
17
+ private applicationAdapter;
18
+ protected httpMiddlewareManager: ContextMiddlewareManager<Context, unknown, unknown>;
19
+ protected eventMiddlewareManager: ContextMiddlewareManager<Context, unknown, unknown>;
13
20
  environmentService: MidwayEnvironmentService;
14
- middlewareService: MidwayMiddlewareService<FaaSContext, any>;
21
+ middlewareService: MidwayMiddlewareService<Context, any>;
15
22
  configure(options: IFaaSConfigurationOptions): any;
16
23
  isEnable(): boolean;
17
24
  applicationInitialize(options: IMidwayBootstrapOptions): Promise<void>;
18
25
  run(): Promise<void>;
19
26
  getFrameworkType(): MidwayFrameworkType;
20
- handleInvokeWrapper(handlerMapping: string): (...args: any[]) => Promise<any>;
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
+ }>;
21
36
  /**
22
37
  * @deprecated
23
38
  * @param middlewareId
24
39
  */
25
- generateMiddleware(middlewareId: string): Promise<FunctionMiddleware<FaaSContext, any>>;
26
- getContext(context: any): any;
40
+ generateMiddleware(middlewareId: string): Promise<FunctionMiddleware<Context, any>>;
41
+ getContext(context?: any): any;
27
42
  private invokeHandler;
28
43
  protected getFunctionHandler(ctx: any, args: any, target: any, method: any): string;
29
44
  createLogger(name: string, option?: LoggerOptions): import("@midwayjs/core").ILogger;
30
45
  getFrameworkName(): string;
46
+ getServer(): http.Server;
47
+ protected createHttpContext(req: any, res: any): Promise<unknown>;
48
+ useMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
49
+ useEventMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
50
+ getEventMiddleware(): ContextMiddlewareManager<Context, NextFunction, undefined>;
31
51
  }
32
52
  export declare const createModuleServerlessFramework: (globalOption: Omit<IMidwayBootstrapOptions, 'applicationContext'> & IFaaSConfigurationOptions) => Promise<MidwayFaaSFramework>;
33
53
  //# sourceMappingURL=framework.d.ts.map
package/dist/framework.js CHANGED
@@ -14,6 +14,8 @@ const core_1 = require("@midwayjs/core");
14
14
  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
+ const serverless_http_parser_1 = require("@midwayjs/serverless-http-parser");
18
+ const http = require("http");
17
19
  const LOCK_KEY = '_faas_starter_start_key';
18
20
  let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework {
19
21
  constructor() {
@@ -24,6 +26,8 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
24
26
  this.isReplaceLogger = process.env['MIDWAY_SERVERLESS_REPLACE_LOGGER'] === 'true';
25
27
  this.developmentRun = false;
26
28
  this.serverlessRoutes = [];
29
+ this.httpMiddlewareManager = this.createMiddlewareManager();
30
+ this.eventMiddlewareManager = this.createMiddlewareManager();
27
31
  }
28
32
  configure(options) {
29
33
  var _a;
@@ -40,13 +44,14 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
40
44
  return !this.developmentRun;
41
45
  }
42
46
  async applicationInitialize(options) {
43
- var _a;
47
+ var _a, _b;
44
48
  if (!this.logger) {
45
49
  this.logger = options.logger || logger_1.loggers.getLogger('appLogger');
46
50
  }
51
+ this.applicationAdapter = this.configurationOptions.applicationAdapter;
47
52
  this.app =
48
- ((_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getApplication()) ||
49
- {};
53
+ ((_a = this.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getApplication()) ||
54
+ new serverless_http_parser_1.Application();
50
55
  this.defineApplicationProperties({
51
56
  /**
52
57
  * return init context value such as aliyun fc
@@ -69,14 +74,18 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
69
74
  var _a;
70
75
  return (_a = this.configurationOptions.applicationAdapter) === null || _a === void 0 ? void 0 : _a.getFunctionServiceName();
71
76
  },
77
+ useEventMiddleware: () => { },
72
78
  });
73
79
  // hack use method
74
80
  this.app.originUse = this.app.use;
75
81
  this.app.use = this.app.useMiddleware;
82
+ if ((_b = this.configurationOptions.applicationAdapter) === null || _b === void 0 ? void 0 : _b.runAppHook) {
83
+ this.configurationOptions.applicationAdapter.runAppHook(this.app);
84
+ }
76
85
  }
77
86
  async run() {
78
87
  return this.lock.sureOnce(async () => {
79
- var _a;
88
+ var _a, _b;
80
89
  // set app keys
81
90
  this.app['keys'] = (_a = this.configService.getConfiguration('keys')) !== null && _a !== void 0 ? _a : '';
82
91
  // store all http function entry
@@ -93,6 +102,21 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
93
102
  });
94
103
  }
95
104
  }
105
+ 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
+ }
96
120
  }, LOCK_KEY);
97
121
  }
98
122
  getFrameworkType() {
@@ -101,14 +125,18 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
101
125
  handleInvokeWrapper(handlerMapping) {
102
126
  let funOptions = this.funMappingStore.get(handlerMapping);
103
127
  return async (...args) => {
128
+ var _a, _b;
104
129
  if (args.length === 0) {
105
130
  throw new Error('first parameter must be function context');
106
131
  }
107
- const context = this.getContext(args.shift());
108
- const isHttpFunction = !!(context.headers && context.get);
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);
109
137
  if (!funOptions && isHttpFunction) {
110
138
  for (const item of this.serverlessRoutes) {
111
- if (item.matchPattern.test(context.path)) {
139
+ if (item.matchPattern.test(event.path)) {
112
140
  funOptions = item.funcInfo;
113
141
  break;
114
142
  }
@@ -117,11 +145,24 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
117
145
  if (!funOptions) {
118
146
  throw new Error(`function handler = ${handlerMapping} not found`);
119
147
  }
120
- const globalMiddlewareFn = await this.applyMiddleware();
121
- const middlewareManager = new core_1.ContextMiddlewareManager();
122
- middlewareManager.insertLast(globalMiddlewareFn);
123
- middlewareManager.insertLast(async (ctx, next) => {
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
+ }
161
+ const result = await (await this.applyMiddleware(async (ctx, next) => {
124
162
  const fn = await this.middlewareService.compose([
163
+ ...(isHttpFunction
164
+ ? this.httpMiddlewareManager
165
+ : this.eventMiddlewareManager),
125
166
  ...funOptions.controllerMiddleware,
126
167
  ...funOptions.middleware,
127
168
  async (ctx, next) => {
@@ -137,9 +178,58 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
137
178
  },
138
179
  ], this.app);
139
180
  return await fn(ctx, next);
140
- });
141
- const composeMiddleware = await this.middlewareService.compose(middlewareManager, this.app);
142
- return await composeMiddleware(context);
181
+ }))(context);
182
+ if (isLegacyMode) {
183
+ return result;
184
+ }
185
+ else if (isHttpFunction) {
186
+ if (!context.response._explicitStatus) {
187
+ if (context.body === null || context.body === 'undefined') {
188
+ context.body = '';
189
+ context.type = 'text';
190
+ context.status = 204;
191
+ }
192
+ }
193
+ let encoded = false;
194
+ let data = context.body;
195
+ if (typeof data === 'string') {
196
+ if (!context.type) {
197
+ context.type = 'text/plain';
198
+ }
199
+ context.body = data;
200
+ }
201
+ else if (Buffer.isBuffer(data)) {
202
+ encoded = true;
203
+ if (!context.type) {
204
+ context.type = 'application/octet-stream';
205
+ }
206
+ // data is reserved as buffer
207
+ context.body = data.toString('base64');
208
+ }
209
+ else if (typeof data === 'object') {
210
+ if (!context.type) {
211
+ context.type = 'application/json';
212
+ }
213
+ // set data to string
214
+ context.body = data = JSON.stringify(data);
215
+ }
216
+ else {
217
+ if (!context.type) {
218
+ context.type = 'text/plain';
219
+ }
220
+ // set data to string
221
+ context.body = data = data + '';
222
+ }
223
+ return {
224
+ isBase64Encoded: encoded,
225
+ statusCode: context.status,
226
+ headers: context.res.headers,
227
+ body: context.body,
228
+ };
229
+ }
230
+ else {
231
+ return result;
232
+ }
143
233
  };
144
234
  }
145
235
  /**
@@ -150,7 +240,7 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
150
240
  const mwIns = await this.getApplicationContext().getAsync(middlewareId);
151
241
  return mwIns.resolve();
152
242
  }
153
- getContext(context) {
243
+ getContext(context = {}) {
154
244
  if (!context.env) {
155
245
  context.env = this.environmentService.getCurrentEnvironment();
156
246
  }
@@ -218,6 +308,23 @@ let MidwayFaaSFramework = class MidwayFaaSFramework extends core_1.BaseFramework
218
308
  getFrameworkName() {
219
309
  return 'midway:faas';
220
310
  }
311
+ getServer() {
312
+ return this.server;
313
+ }
314
+ async createHttpContext(req, res) {
315
+ return new Promise(resolve => {
316
+ this.respond(req, res, resolve);
317
+ });
318
+ }
319
+ useMiddleware(middleware) {
320
+ this.httpMiddlewareManager.insertLast(middleware);
321
+ }
322
+ useEventMiddleware(middleware) {
323
+ this.eventMiddlewareManager.insertLast(middleware);
324
+ }
325
+ getEventMiddleware() {
326
+ return this.eventMiddlewareManager;
327
+ }
221
328
  };
222
329
  __decorate([
223
330
  (0, decorator_1.Inject)(),
@@ -1,14 +1,18 @@
1
- import { MidwayRequestContainer, IMidwayApplication, IConfigurationOptions, IMidwayContext, NextFunction as BaseNextFunction } from '@midwayjs/core';
1
+ import { MidwayRequestContainer, IMidwayApplication, IConfigurationOptions, IMidwayContext, NextFunction as BaseNextFunction, CommonMiddlewareUnion, ContextMiddlewareManager } from '@midwayjs/core';
2
2
  import { FaaSHTTPContext } from '@midwayjs/faas-typings';
3
3
  import { ILogger } from '@midwayjs/logger';
4
+ import { Application as ServerlessHttpApplication } from '@midwayjs/serverless-http-parser';
4
5
  export interface FaaSContext extends IMidwayContext<FaaSHTTPContext> {
5
6
  logger: ILogger;
6
7
  env: string;
7
8
  requestContext: MidwayRequestContainer;
8
9
  originContext: any;
9
10
  }
10
- export declare type FaaSMiddleware = ((context: FaaSContext, next: () => Promise<any>) => any) | string;
11
- export declare type IMidwayFaaSApplication = IMidwayApplication<FaaSContext, {
11
+ /**
12
+ * @deprecated
13
+ */
14
+ export declare type FaaSMiddleware = ((context: Context, next: () => Promise<any>) => any) | string;
15
+ export declare type IMidwayFaaSApplication = IMidwayApplication<Context, {
12
16
  getInitializeContext(): any;
13
17
  use(middleware: FaaSMiddleware): any;
14
18
  /**
@@ -24,7 +28,9 @@ export declare type IMidwayFaaSApplication = IMidwayApplication<FaaSContext, {
24
28
  * Get function service name in serverless environment
25
29
  */
26
30
  getFunctionServiceName(): string;
27
- }>;
31
+ useEventMiddleware(middleware: CommonMiddlewareUnion<Context, NextFunction, undefined>): void;
32
+ getEventMiddleware: ContextMiddlewareManager<Context, NextFunction, undefined>;
33
+ }> & ServerlessHttpApplication;
28
34
  export interface Application extends IMidwayFaaSApplication {
29
35
  }
30
36
  export interface Context extends FaaSContext {
@@ -34,11 +40,17 @@ export interface IFaaSConfigurationOptions extends IConfigurationOptions {
34
40
  config?: object;
35
41
  initializeContext?: object;
36
42
  applicationAdapter?: {
37
- getApplication(): IMidwayFaaSApplication;
43
+ getApplication(): Application;
38
44
  getFunctionName(): string;
39
45
  getFunctionServiceName(): string;
46
+ runAppHook?(app: Application): void;
47
+ runEventHook?(...args: any[]): any | void;
48
+ runRequestHook?(...args: any[]): any | void;
40
49
  };
41
50
  }
51
+ /**
52
+ * @deprecated
53
+ */
42
54
  export interface IWebMiddleware {
43
55
  resolve(): FaaSMiddleware;
44
56
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@midwayjs/faas",
3
- "version": "3.3.6-beta.1",
3
+ "version": "3.3.6-beta.4",
4
4
  "main": "dist/index",
5
5
  "typings": "index.d.ts",
6
6
  "dependencies": {
7
7
  "@midwayjs/core": "^3.3.5",
8
8
  "@midwayjs/faas-typings": "^3.3.5",
9
9
  "@midwayjs/logger": "^2.15.0",
10
- "@midwayjs/simple-lock": "^1.1.4"
10
+ "@midwayjs/simple-lock": "^1.1.4",
11
+ "@midwayjs/serverless-http-parser": "^3.3.5"
11
12
  },
12
13
  "devDependencies": {
13
14
  "@midwayjs/decorator": "^3.3.4",