@h4ad/serverless-adapter 2.0.3 → 2.3.0
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/README.md +111 -5
- package/lib/@types/huawei/huawei-api-gateway-event.d.ts +19 -0
- package/lib/@types/huawei/huawei-api-gateway-event.js +2 -0
- package/lib/@types/huawei/huawei-api-gateway-response.d.ts +7 -0
- package/lib/@types/huawei/huawei-api-gateway-response.js +2 -0
- package/lib/@types/huawei/huawei-context.d.ts +31 -0
- package/lib/@types/huawei/huawei-context.js +2 -0
- package/lib/@types/huawei/index.d.ts +3 -0
- package/lib/@types/huawei/index.js +15 -0
- package/lib/adapters/aws/api-gateway-v2.adapter.js +2 -2
- package/lib/adapters/dummy/dummy.adapter.d.ts +27 -0
- package/lib/adapters/dummy/dummy.adapter.js +47 -0
- package/lib/adapters/dummy/index.d.ts +1 -0
- package/lib/adapters/dummy/index.js +13 -0
- package/lib/adapters/huawei/huawei-api-gateway.adapter.d.ts +59 -0
- package/lib/adapters/huawei/huawei-api-gateway.adapter.js +113 -0
- package/lib/adapters/huawei/index.d.ts +1 -0
- package/lib/adapters/huawei/index.js +13 -0
- package/lib/frameworks/lazy/index.d.ts +0 -0
- package/lib/frameworks/lazy/index.js +1 -0
- package/lib/frameworks/lazy/lazy.framework.d.ts +51 -0
- package/lib/frameworks/lazy/lazy.framework.js +70 -0
- package/lib/handlers/default/default.handler.d.ts +1 -2
- package/lib/handlers/default/default.handler.js +1 -2
- package/lib/handlers/huawei/http-huawei.handler.d.ts +49 -0
- package/lib/handlers/huawei/http-huawei.handler.js +82 -0
- package/lib/handlers/huawei/index.d.ts +1 -0
- package/lib/handlers/huawei/index.js +13 -0
- package/lib/resolvers/dummy/dummy.resolver.d.ts +10 -0
- package/lib/resolvers/dummy/dummy.resolver.js +19 -0
- package/lib/resolvers/dummy/index.d.ts +1 -0
- package/lib/resolvers/dummy/index.js +13 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
<a href="#install">Install</a> |
|
|
7
7
|
<a href="#usage">Usage</a> |
|
|
8
8
|
<a href="#support">Support</a> |
|
|
9
|
+
<a href="#examples">Examples</a> |
|
|
9
10
|
<a href="#architecture">Architecture</a> |
|
|
10
11
|
<a href="#credits">Credits</a>
|
|
11
12
|
</p>
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
[![Semantic Release][semantic-release-img]][semantic-release-url]
|
|
20
21
|
|
|
21
22
|
Run REST APIs and other web applications using your existing Node.js application framework (Express, Koa, Hapi and
|
|
22
|
-
Fastify), on top of AWS Lambda,
|
|
23
|
+
Fastify), on top of AWS Lambda, Huawei and many other clouds.
|
|
23
24
|
|
|
24
25
|
This library was a refactored version of [@vendia/serverless-express](https://github.com/vendia/serverless-express), I
|
|
25
26
|
created a new way to interact and extend event sources by creating contracts to abstract the integrations between each
|
|
@@ -56,12 +57,16 @@ You can quickly use this library as follows:
|
|
|
56
57
|
|
|
57
58
|
```ts
|
|
58
59
|
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
|
|
59
|
-
import { ApiGatewayV2Adapter } from '@h4ad/serverless-adapter/lib/adapters/aws';
|
|
60
|
+
import { ApiGatewayV2Adapter, AlbAdapter, SQSAdapter, SNSAdapter } from '@h4ad/serverless-adapter/lib/adapters/aws';
|
|
60
61
|
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
|
|
61
62
|
import { DefaultHandler } from '@h4ad/serverless-adapter/lib/handlers/default';
|
|
62
63
|
import { PromiseResolver } from '@h4ad/serverless-adapter/lib/resolvers/promise';
|
|
63
64
|
import app from './app';
|
|
64
65
|
|
|
66
|
+
// if you create your app asynchronously
|
|
67
|
+
// check the docs about the LazyFramework.
|
|
68
|
+
// ServerlessAdapter.new(null)
|
|
69
|
+
// .setFramework(new LazyFramework(new ExpressFramework(), async () => createAsyncApp()))
|
|
65
70
|
export const handler = ServerlessAdapter.new(app)
|
|
66
71
|
.setFramework(new ExpressFramework())
|
|
67
72
|
.setHandler(new DefaultHandler())
|
|
@@ -70,8 +75,6 @@ export const handler = ServerlessAdapter.new(app)
|
|
|
70
75
|
.addAdapter(new SQSAdapter())
|
|
71
76
|
.addAdapter(new SNSAdapter())
|
|
72
77
|
.build();
|
|
73
|
-
|
|
74
|
-
export { handler };
|
|
75
78
|
```
|
|
76
79
|
|
|
77
80
|
Too fast? Ok, I can explain.
|
|
@@ -120,6 +123,9 @@ Currently, we support these frameworks:
|
|
|
120
123
|
- [Fastify](https://www.fastify.io/) by using ([FastifyFramework](src/frameworks/fastify/fastify.framework.ts))
|
|
121
124
|
- [Hapi](https://hapi.dev/) by using ([HapiFramework](src/frameworks/hapi/hapi.framework.ts))
|
|
122
125
|
- [Koa](https://koajs.com/) by using ([KoaFramework](src/frameworks/koa/koa.framework.ts))
|
|
126
|
+
- Async Initialization by using ([LazyFramework](src/frameworks/lazy/lazy.framework.ts))
|
|
127
|
+
- Use this framework to provide a way to create the instance of your app asynchronously.
|
|
128
|
+
- With him, you can create an instance of Express or Fastify asynchronously, [see the docs](src/frameworks/lazy/lazy.framework.ts).
|
|
123
129
|
|
|
124
130
|
We support these event sources:
|
|
125
131
|
|
|
@@ -140,9 +146,15 @@ We support these event sources:
|
|
|
140
146
|
using ([SNSAdapter](./src/adapters/aws/sns.adapter.ts))
|
|
141
147
|
- [AWS SQS](https://docs.aws.amazon.com/pt_br/lambda/latest/dg/with-sqs.html) by
|
|
142
148
|
using ([SQSAdapter](./src/adapters/aws/sqs.adapter.ts))
|
|
149
|
+
- Huawei
|
|
150
|
+
- [Http Function](https://support.huaweicloud.com/intl/en-us/usermanual-functiongraph/functiongraph_01_1442.html): Look [this section](#huawei-http-function) about Huawei support for Http Function.
|
|
151
|
+
- [Event Function](https://support.huaweicloud.com/intl/en-us/usermanual-functiongraph/functiongraph_01_1441.html):
|
|
152
|
+
- [Api Gateway](https://support.huaweicloud.com/intl/en-us/devg-functiongraph/functiongraph_02_0102.html#functiongraph_02_0102__li5178638110137) by using ([HuaweiApiGatewayAdapter](src/adapters/huawei/huawei-api-gateway.adapter.ts)).
|
|
143
153
|
- Azure
|
|
154
|
+
- [The support is coming soon.](https://github.com/H4ad/serverless-adapter/issues/3)
|
|
155
|
+
- Firebase
|
|
144
156
|
- The support is coming soon.
|
|
145
|
-
-
|
|
157
|
+
- GCP
|
|
146
158
|
- The support is coming soon.
|
|
147
159
|
|
|
148
160
|
We support these resolvers:
|
|
@@ -154,6 +166,94 @@ We support these resolvers:
|
|
|
154
166
|
We support these handlers:
|
|
155
167
|
|
|
156
168
|
- Default by using ([DefaultHandler](src/handlers/default/default.handler.ts))
|
|
169
|
+
- Huawei by using ([HttpHuaweiHandler](src/handlers/huawei/http-huawei.handler.ts)) and ([EventHuaweiHandler](#huawei-event-function))
|
|
170
|
+
|
|
171
|
+
## Huawei
|
|
172
|
+
|
|
173
|
+
In Huawei, we added support to FunctionGraphV2 with Http Function and Event Function.
|
|
174
|
+
|
|
175
|
+
The difference between Http Function and Event Function is that in Http Function you must expose port 8000 and Huawei will proxy Api Gateway requests to your application.
|
|
176
|
+
So, on implementation, this library will create an http server to listen on port 8000 and forward the request to your framework.
|
|
177
|
+
|
|
178
|
+
In Event Function, you will receive the event from event source in the same way you receive in AWS, an object with some structure, you can see the supported event sources [here](https://support.huaweicloud.com/intl/en-us/devg-functiongraph/functiongraph_02_0102.html).
|
|
179
|
+
|
|
180
|
+
### Huawei Http Function
|
|
181
|
+
|
|
182
|
+
To integrate your app with Huawei FunctionGrapth with the Http Function type, you must do the following:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
|
|
186
|
+
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
|
|
187
|
+
import { HttpHuaweiHandler } from '@h4ad/serverless-adapter/lib/handlers/huawei';
|
|
188
|
+
import { DummyResolver } from '@h4ad/serverless-adapter/lib/resolvers/dummy';
|
|
189
|
+
import { DummyAdapter } from '@h4ad/serverless-adapter/lib/adapters/dummy';
|
|
190
|
+
import app from './app';
|
|
191
|
+
|
|
192
|
+
// instead exposing handler, you have the dispose function
|
|
193
|
+
// this dispose function is never called
|
|
194
|
+
// but you can to close the http server created with him
|
|
195
|
+
const dispose = ServerlessAdapter.new(app)
|
|
196
|
+
.setHandler(new HttpHuaweiHandler())
|
|
197
|
+
.setFramework(new ExpressFramework())
|
|
198
|
+
// dummy resolver and adapter is used because
|
|
199
|
+
// they are necessary in the core of the library to build
|
|
200
|
+
// but is optional to make huawei http function works.
|
|
201
|
+
.setResolver(new DummyResolver())
|
|
202
|
+
.addAdapter(new DummyAdapter())
|
|
203
|
+
.build();
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
> You don't need to expose a variable called `handler` when you choose Http Function, you just need to call build to the library create a http server.
|
|
207
|
+
|
|
208
|
+
By the way of Huawei architecture in Http Function, they have no use for Resolvers and Adapters, so you need to use the dummy versions because the library requires it.
|
|
209
|
+
|
|
210
|
+
#### ONE IMPORTANT THING
|
|
211
|
+
|
|
212
|
+
You need to configure a file called `bootstrap` in the root of folder that you upload to Huawei, is like the file `Procfile` but for Huawei.
|
|
213
|
+
|
|
214
|
+
In my setup, I configure like:
|
|
215
|
+
```
|
|
216
|
+
node /opt/function/code/index.js
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The path `/opt/function/code` is where your code is uploaded when you deploy something and `index.js` is the file that contains the `ServerlessAdapter`.
|
|
220
|
+
|
|
221
|
+
In the end, the structure of the zip file you upload looks like this:
|
|
222
|
+
|
|
223
|
+
- `bootstrap`
|
|
224
|
+
- `index.js`
|
|
225
|
+
|
|
226
|
+
### Huawei Event Function
|
|
227
|
+
|
|
228
|
+
With Http Function you need to use [HttpHuaweiHandler](src/handlers/huawei/http-huawei.handler.ts),
|
|
229
|
+
but with Event Function you should use [DefaultHandler](src/handlers/default/default.handler.ts).
|
|
230
|
+
|
|
231
|
+
So, to add support to Api Gateway you do the following:
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
|
|
235
|
+
import { HuaweiApiGatewayAdapter } from '@h4ad/serverless-adapter/lib/adapters/huawei';
|
|
236
|
+
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
|
|
237
|
+
import { DefaultHandler } from '@h4ad/serverless-adapter/lib/handlers/default';
|
|
238
|
+
import { CallbackResolver } from '@h4ad/serverless-adapter/lib/resolvers/callback';
|
|
239
|
+
import app from './app';
|
|
240
|
+
|
|
241
|
+
export const handler = ServerlessAdapter.new(app)
|
|
242
|
+
.setFramework(new ExpressFramework())
|
|
243
|
+
.setHandler(new DefaultHandler())
|
|
244
|
+
.setResolver(new CallbackResolver())
|
|
245
|
+
.addAdapter(new HuaweiApiGatewayAdapter())
|
|
246
|
+
.build();
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### One important thing
|
|
250
|
+
|
|
251
|
+
You must use the callback resolver because I couldn't get it to work with the PromiseResolver.
|
|
252
|
+
Maybe it's a bug in the library or something specific in Huawei, if you have a tip please create an issue.
|
|
253
|
+
|
|
254
|
+
# Examples
|
|
255
|
+
|
|
256
|
+
You can see some examples of how to use this library [here](https://github.com/H4ad/serverless-adapter-examples).
|
|
157
257
|
|
|
158
258
|
# Architecture
|
|
159
259
|
|
|
@@ -207,6 +307,12 @@ PR just to extend the library's functionality :)
|
|
|
207
307
|
Honestly, I just refactored all the code that the @vendia team and many other contributors wrote, thanks so much to them
|
|
208
308
|
for existing and giving us a brilliant library that is the core of my current company.
|
|
209
309
|
|
|
310
|
+
# Sponsors
|
|
311
|
+
|
|
312
|
+
| <a href="https://liga.facens.br/"><img height="50" src="https://mlogu6g7z5ex.i.optimole.com/yEwfkqo-4R0ttNtd/w:auto/h:auto/q:mauto/f:avif/http://liga.facens.br/wp-content/uploads/2020/03/logo-1.png" title="The LIGA logo" width="100"/></a> |
|
|
313
|
+
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
314
|
+
|
|
315
|
+
|
|
210
316
|
[build-img]:https://github.com/H4ad/serverless-adapter/actions/workflows/release.yml/badge.svg
|
|
211
317
|
|
|
212
318
|
[build-url]:https://github.com/H4ad/serverless-adapter/actions/workflows/release.yml
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BothValueHeaders } from '../index';
|
|
2
|
+
export interface HuaweiApiGatewayEvent {
|
|
3
|
+
body: string;
|
|
4
|
+
headers: BothValueHeaders;
|
|
5
|
+
httpMethod: string;
|
|
6
|
+
isBase64Encoded: boolean;
|
|
7
|
+
path: string;
|
|
8
|
+
pathParameters: HuaweiRequestPathParameters;
|
|
9
|
+
queryStringParameters: HuaweiRequestQueryStringParameters;
|
|
10
|
+
requestContext: HuaweiRequestContext;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
export declare type HuaweiRequestPathParameters = Record<string, string>;
|
|
14
|
+
export declare type HuaweiRequestQueryStringParameters = Record<string, string | string[]>;
|
|
15
|
+
export interface HuaweiRequestContext {
|
|
16
|
+
apiId: string;
|
|
17
|
+
requestId: string;
|
|
18
|
+
stage: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare type GetRequestIDSecondsReturn = string;
|
|
2
|
+
export declare type GetRemainingTimeInMilliSecondsReturn = number;
|
|
3
|
+
export declare type GetAccessKeyReturn = string;
|
|
4
|
+
export declare type GetSecretKeyReturn = string;
|
|
5
|
+
export declare type GetUserDataKeyParameter = string;
|
|
6
|
+
export declare type GetUserDataReturn = any;
|
|
7
|
+
export declare type GetFunctionNameReturn = string;
|
|
8
|
+
export declare type GetRunningTimeInSecondsReturn = number;
|
|
9
|
+
export declare type GetVersionReturn = string;
|
|
10
|
+
export declare type GetMemorySizeReturn = number;
|
|
11
|
+
export declare type GetCPUNumberReturn = number;
|
|
12
|
+
export declare type GetProjectIdReturn = number;
|
|
13
|
+
export declare type GetPackageReturn = string;
|
|
14
|
+
export declare type GetLoggerReturn = {
|
|
15
|
+
info(message: string): void;
|
|
16
|
+
};
|
|
17
|
+
export interface HuaweiContext {
|
|
18
|
+
getRequestID(): GetRequestIDSecondsReturn;
|
|
19
|
+
getRemainingTimeInMilliSeconds(): GetRemainingTimeInMilliSecondsReturn;
|
|
20
|
+
getAccessKey(): GetAccessKeyReturn;
|
|
21
|
+
getSecretKey(): GetSecretKeyReturn;
|
|
22
|
+
getUserData(key: GetUserDataKeyParameter): GetUserDataReturn;
|
|
23
|
+
getFunctionName(): GetFunctionNameReturn;
|
|
24
|
+
getRunningTimeInSeconds(): GetRunningTimeInSecondsReturn;
|
|
25
|
+
getVersion(): GetVersionReturn;
|
|
26
|
+
getMemorySize(): GetMemorySizeReturn;
|
|
27
|
+
getCPUNumber(): GetCPUNumberReturn;
|
|
28
|
+
getProjectID(): GetProjectIdReturn;
|
|
29
|
+
getPackage(): GetPackageReturn;
|
|
30
|
+
getLogger(): GetLoggerReturn;
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./huawei-context"), exports);
|
|
14
|
+
__exportStar(require("./huawei-api-gateway-event"), exports);
|
|
15
|
+
__exportStar(require("./huawei-api-gateway-response"), exports);
|
|
@@ -73,10 +73,10 @@ class ApiGatewayV2Adapter {
|
|
|
73
73
|
const transferEncodingHeader = headers['transfer-encoding'];
|
|
74
74
|
const hasTransferEncodingChunked = transferEncodingHeader && transferEncodingHeader.includes('chunked');
|
|
75
75
|
if (hasTransferEncodingChunked) {
|
|
76
|
-
throw new Error('chunked encoding in headers is not supported by API Gateway
|
|
76
|
+
throw new Error('chunked encoding in headers is not supported by API Gateway V2');
|
|
77
77
|
}
|
|
78
78
|
if (response === null || response === void 0 ? void 0 : response.chunkedEncoding) {
|
|
79
|
-
throw new Error('chunked encoding in response is not supported by API Gateway
|
|
79
|
+
throw new Error('chunked encoding in response is not supported by API Gateway V2');
|
|
80
80
|
}
|
|
81
81
|
const cookies = multiValueHeaders['set-cookie'];
|
|
82
82
|
if (headers)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AdapterContract, AdapterRequest, OnErrorProps } from '../../contracts';
|
|
2
|
+
import { IEmptyResponse } from '../../core';
|
|
3
|
+
/**
|
|
4
|
+
* The class that represents a dummy adapter that does nothing and can be used by the cloud that doesn't use adapters.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DummyAdapter implements AdapterContract<any, any, void> {
|
|
7
|
+
/**
|
|
8
|
+
* @inheritDoc
|
|
9
|
+
*/
|
|
10
|
+
canHandle(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* @inheritDoc
|
|
13
|
+
*/
|
|
14
|
+
getAdapterName(): string;
|
|
15
|
+
/**
|
|
16
|
+
* @inheritDoc
|
|
17
|
+
*/
|
|
18
|
+
getRequest(): AdapterRequest;
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
getResponse(): IEmptyResponse;
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
onErrorWhileForwarding(props: OnErrorProps<any, void>): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DummyAdapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
//#endregion
|
|
7
|
+
/**
|
|
8
|
+
* The class that represents a dummy adapter that does nothing and can be used by the cloud that doesn't use adapters.
|
|
9
|
+
*/
|
|
10
|
+
class DummyAdapter {
|
|
11
|
+
/**
|
|
12
|
+
* @inheritDoc
|
|
13
|
+
*/
|
|
14
|
+
canHandle() {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
getAdapterName() {
|
|
21
|
+
return DummyAdapter.name;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
getRequest() {
|
|
27
|
+
return {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
body: void 0,
|
|
30
|
+
path: '/dummy',
|
|
31
|
+
headers: {},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @inheritDoc
|
|
36
|
+
*/
|
|
37
|
+
getResponse() {
|
|
38
|
+
return core_1.EmptyResponse;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @inheritDoc
|
|
42
|
+
*/
|
|
43
|
+
onErrorWhileForwarding(props) {
|
|
44
|
+
props.delegatedResolver.succeed();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.DummyAdapter = DummyAdapter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dummy.adapter';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./dummy.adapter"), exports);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { HuaweiApiGatewayEvent, HuaweiContext } from '../../@types/huawei';
|
|
2
|
+
import { HuaweiApiGatewayResponse } from '../../@types/huawei/huawei-api-gateway-response';
|
|
3
|
+
import { AdapterContract, AdapterRequest, GetResponseAdapterProps, OnErrorProps } from '../../contracts';
|
|
4
|
+
/**
|
|
5
|
+
* The options to customize the {@link HuaweiApiGatewayAdapter}
|
|
6
|
+
*/
|
|
7
|
+
export interface HuaweiApiGatewayOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Strip base path for custom domains
|
|
10
|
+
*
|
|
11
|
+
* @default ''
|
|
12
|
+
*/
|
|
13
|
+
stripBasePath?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The adapter to handle requests from Huawei Api Gateway
|
|
17
|
+
*
|
|
18
|
+
* @example```typescript
|
|
19
|
+
* const stripBasePath = '/any/custom/base/path'; // default ''
|
|
20
|
+
* const adapter = new ApiGatewayAdapter({ stripBasePath });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* {@link https://support.huaweicloud.com/intl/en-us/devg-functiongraph/functiongraph_02_0102.html#functiongraph_02_0102__li5178638110137 Event Reference}
|
|
24
|
+
*/
|
|
25
|
+
export declare class HuaweiApiGatewayAdapter implements AdapterContract<HuaweiApiGatewayEvent, HuaweiContext, HuaweiApiGatewayResponse> {
|
|
26
|
+
protected readonly options?: HuaweiApiGatewayOptions | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Default constructor
|
|
29
|
+
*
|
|
30
|
+
* @param options The options to customize the {@link HuaweiApiGatewayAdapter}
|
|
31
|
+
*/
|
|
32
|
+
constructor(options?: HuaweiApiGatewayOptions | undefined);
|
|
33
|
+
/**
|
|
34
|
+
* @inheritDoc
|
|
35
|
+
*/
|
|
36
|
+
getAdapterName(): string;
|
|
37
|
+
/**
|
|
38
|
+
* @inheritDoc
|
|
39
|
+
*/
|
|
40
|
+
canHandle(event: unknown): event is HuaweiApiGatewayEvent;
|
|
41
|
+
/**
|
|
42
|
+
* @inheritDoc
|
|
43
|
+
*/
|
|
44
|
+
getRequest(event: HuaweiApiGatewayEvent): AdapterRequest;
|
|
45
|
+
/**
|
|
46
|
+
* @inheritDoc
|
|
47
|
+
*/
|
|
48
|
+
getResponse({ headers: responseHeaders, body, isBase64Encoded, statusCode, }: GetResponseAdapterProps<HuaweiApiGatewayEvent>): HuaweiApiGatewayResponse;
|
|
49
|
+
/**
|
|
50
|
+
* @inheritDoc
|
|
51
|
+
*/
|
|
52
|
+
onErrorWhileForwarding({ error, delegatedResolver, respondWithErrors, event, log, }: OnErrorProps<HuaweiApiGatewayEvent, HuaweiApiGatewayResponse>): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get path from event with query strings
|
|
55
|
+
*
|
|
56
|
+
* @param event The event sent by serverless
|
|
57
|
+
*/
|
|
58
|
+
protected getPathFromEvent(event: HuaweiApiGatewayEvent): string;
|
|
59
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.HuaweiApiGatewayAdapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
/**
|
|
7
|
+
* The adapter to handle requests from Huawei Api Gateway
|
|
8
|
+
*
|
|
9
|
+
* @example```typescript
|
|
10
|
+
* const stripBasePath = '/any/custom/base/path'; // default ''
|
|
11
|
+
* const adapter = new ApiGatewayAdapter({ stripBasePath });
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* {@link https://support.huaweicloud.com/intl/en-us/devg-functiongraph/functiongraph_02_0102.html#functiongraph_02_0102__li5178638110137 Event Reference}
|
|
15
|
+
*/
|
|
16
|
+
class HuaweiApiGatewayAdapter {
|
|
17
|
+
//#region Constructor
|
|
18
|
+
/**
|
|
19
|
+
* Default constructor
|
|
20
|
+
*
|
|
21
|
+
* @param options The options to customize the {@link HuaweiApiGatewayAdapter}
|
|
22
|
+
*/
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region Public Methods
|
|
28
|
+
/**
|
|
29
|
+
* @inheritDoc
|
|
30
|
+
*/
|
|
31
|
+
getAdapterName() {
|
|
32
|
+
return HuaweiApiGatewayAdapter.name;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @inheritDoc
|
|
36
|
+
*/
|
|
37
|
+
canHandle(event) {
|
|
38
|
+
const apiGatewayEvent = event;
|
|
39
|
+
return !!(apiGatewayEvent &&
|
|
40
|
+
apiGatewayEvent.httpMethod &&
|
|
41
|
+
apiGatewayEvent.requestContext &&
|
|
42
|
+
apiGatewayEvent.requestContext.apiId &&
|
|
43
|
+
apiGatewayEvent.requestContext.stage &&
|
|
44
|
+
apiGatewayEvent.requestContext.requestId &&
|
|
45
|
+
// to avoid conflict with api gateway v1 of aws
|
|
46
|
+
!('multiValueQueryStringParameters' in apiGatewayEvent));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
getRequest(event) {
|
|
52
|
+
const method = event.httpMethod;
|
|
53
|
+
const path = this.getPathFromEvent(event);
|
|
54
|
+
const headers = (0, core_1.getFlattenedHeadersMap)(event.headers, ',', true);
|
|
55
|
+
let body;
|
|
56
|
+
if (event.body) {
|
|
57
|
+
const [bufferBody, contentLength] = (0, core_1.getEventBodyAsBuffer)(event.body, event.isBase64Encoded);
|
|
58
|
+
body = bufferBody;
|
|
59
|
+
headers['content-length'] = String(contentLength);
|
|
60
|
+
}
|
|
61
|
+
const remoteAddress = headers['x-real-ip'];
|
|
62
|
+
return {
|
|
63
|
+
method,
|
|
64
|
+
headers,
|
|
65
|
+
body,
|
|
66
|
+
remoteAddress,
|
|
67
|
+
path,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @inheritDoc
|
|
72
|
+
*/
|
|
73
|
+
getResponse({ headers: responseHeaders, body, isBase64Encoded, statusCode, }) {
|
|
74
|
+
const headers = (0, core_1.getMultiValueHeadersMap)(responseHeaders);
|
|
75
|
+
return {
|
|
76
|
+
statusCode,
|
|
77
|
+
body,
|
|
78
|
+
headers,
|
|
79
|
+
isBase64Encoded,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @inheritDoc
|
|
84
|
+
*/
|
|
85
|
+
onErrorWhileForwarding({ error, delegatedResolver, respondWithErrors, event, log, }) {
|
|
86
|
+
const body = respondWithErrors ? error.stack : '';
|
|
87
|
+
const errorResponse = this.getResponse({
|
|
88
|
+
event,
|
|
89
|
+
statusCode: 500,
|
|
90
|
+
body: body || '',
|
|
91
|
+
headers: {},
|
|
92
|
+
isBase64Encoded: false,
|
|
93
|
+
log,
|
|
94
|
+
});
|
|
95
|
+
delegatedResolver.succeed(errorResponse);
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region Protected Methods
|
|
99
|
+
/**
|
|
100
|
+
* Get path from event with query strings
|
|
101
|
+
*
|
|
102
|
+
* @param event The event sent by serverless
|
|
103
|
+
*/
|
|
104
|
+
getPathFromEvent(event) {
|
|
105
|
+
var _a;
|
|
106
|
+
const stripBasePath = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.stripBasePath, '');
|
|
107
|
+
const replaceRegex = new RegExp(`^${stripBasePath}`);
|
|
108
|
+
const path = event.path.replace(replaceRegex, '');
|
|
109
|
+
const queryParams = event.queryStringParameters;
|
|
110
|
+
return (0, core_1.getPathWithQueryStringParams)(path, queryParams);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.HuaweiApiGatewayAdapter = HuaweiApiGatewayAdapter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './huawei-api-gateway.adapter';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./huawei-api-gateway.adapter"), exports);
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import { FrameworkContract } from '../../contracts';
|
|
4
|
+
import { ILogger } from '../../core';
|
|
5
|
+
/**
|
|
6
|
+
* The framework that asynchronously instantiates your application and forwards the request to the framework as quickly as possible.
|
|
7
|
+
*
|
|
8
|
+
* @example```typescript
|
|
9
|
+
* import express from 'express';
|
|
10
|
+
* import { ServerlessAdapter } from '@h4ad/serverless-adapter';
|
|
11
|
+
* import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
|
|
12
|
+
* import { LazyFramework } from '@h4ad/serverless-adapter/lib/frameworks/lazy';
|
|
13
|
+
*
|
|
14
|
+
* const expressFramework = new ExpressFramework();
|
|
15
|
+
* const factory = async () => {
|
|
16
|
+
* const app = express();
|
|
17
|
+
*
|
|
18
|
+
* // do some asynchronous stuffs like create the database;
|
|
19
|
+
* await new Promise(resolve => setTimeout(resolve, 100);
|
|
20
|
+
*
|
|
21
|
+
* return app;
|
|
22
|
+
* };
|
|
23
|
+
* const framework = new LazyFramework(expressFramework, factory);
|
|
24
|
+
*
|
|
25
|
+
* export const handler = ServerlessAdapter.new(null)
|
|
26
|
+
* .setFramework(framework)
|
|
27
|
+
* // set other configurations and then build
|
|
28
|
+
* .build();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class LazyFramework<TApp> implements FrameworkContract<null> {
|
|
32
|
+
protected readonly framework: FrameworkContract<TApp>;
|
|
33
|
+
protected readonly factory: () => Promise<TApp>;
|
|
34
|
+
protected readonly logger: ILogger;
|
|
35
|
+
/**
|
|
36
|
+
* Default Constructor
|
|
37
|
+
*/
|
|
38
|
+
constructor(framework: FrameworkContract<TApp>, factory: () => Promise<TApp>, logger?: ILogger);
|
|
39
|
+
/**
|
|
40
|
+
* The cached version of the app
|
|
41
|
+
*/
|
|
42
|
+
protected cachedApp?: TApp;
|
|
43
|
+
/**
|
|
44
|
+
* The delayed factory to create an instance of the app
|
|
45
|
+
*/
|
|
46
|
+
protected readonly delayedFactory: Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* @inheritDoc
|
|
49
|
+
*/
|
|
50
|
+
sendRequest(app: null, request: IncomingMessage, response: ServerResponse): void;
|
|
51
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.LazyFramework = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
//#endregion
|
|
7
|
+
/**
|
|
8
|
+
* The framework that asynchronously instantiates your application and forwards the request to the framework as quickly as possible.
|
|
9
|
+
*
|
|
10
|
+
* @example```typescript
|
|
11
|
+
* import express from 'express';
|
|
12
|
+
* import { ServerlessAdapter } from '@h4ad/serverless-adapter';
|
|
13
|
+
* import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
|
|
14
|
+
* import { LazyFramework } from '@h4ad/serverless-adapter/lib/frameworks/lazy';
|
|
15
|
+
*
|
|
16
|
+
* const expressFramework = new ExpressFramework();
|
|
17
|
+
* const factory = async () => {
|
|
18
|
+
* const app = express();
|
|
19
|
+
*
|
|
20
|
+
* // do some asynchronous stuffs like create the database;
|
|
21
|
+
* await new Promise(resolve => setTimeout(resolve, 100);
|
|
22
|
+
*
|
|
23
|
+
* return app;
|
|
24
|
+
* };
|
|
25
|
+
* const framework = new LazyFramework(expressFramework, factory);
|
|
26
|
+
*
|
|
27
|
+
* export const handler = ServerlessAdapter.new(null)
|
|
28
|
+
* .setFramework(framework)
|
|
29
|
+
* // set other configurations and then build
|
|
30
|
+
* .build();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
class LazyFramework {
|
|
34
|
+
//#region Constructor
|
|
35
|
+
/**
|
|
36
|
+
* Default Constructor
|
|
37
|
+
*/
|
|
38
|
+
constructor(framework, factory, logger = (0, core_1.createDefaultLogger)()) {
|
|
39
|
+
this.framework = framework;
|
|
40
|
+
this.factory = factory;
|
|
41
|
+
this.logger = logger;
|
|
42
|
+
this.delayedFactory = Promise.resolve()
|
|
43
|
+
.then(() => factory())
|
|
44
|
+
.then(app => {
|
|
45
|
+
this.cachedApp = app;
|
|
46
|
+
})
|
|
47
|
+
.catch((error) => {
|
|
48
|
+
// deal with the error only when receive some request
|
|
49
|
+
// to be able to return some message to user
|
|
50
|
+
this.logger.error('SERVERLESS_ADAPTER:LAZY_FRAMEWORK: An error occours during the creation of your app.');
|
|
51
|
+
this.logger.error(error);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region Public Methods
|
|
56
|
+
/**
|
|
57
|
+
* @inheritDoc
|
|
58
|
+
*/
|
|
59
|
+
sendRequest(app, request, response) {
|
|
60
|
+
if (this.cachedApp)
|
|
61
|
+
return this.framework.sendRequest(this.cachedApp, request, response);
|
|
62
|
+
this.delayedFactory.then(() => {
|
|
63
|
+
if (!this.cachedApp) {
|
|
64
|
+
return response.emit('error', new Error('SERVERLESS_ADAPTER:LAZY_FRAMEWORK: The instance of the app returned by the factory is not valid, see the logs to learn more.'));
|
|
65
|
+
}
|
|
66
|
+
return this.framework.sendRequest(this.cachedApp, request, response);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.LazyFramework = LazyFramework;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BinarySettings, SingleValueHeaders } from '../../@types';
|
|
2
2
|
import { AdapterContract, AdapterRequest, FrameworkContract, ResolverContract, ServerlessHandler } from '../../contracts';
|
|
3
|
-
import { ILogger } from '../../core';
|
|
4
|
-
import { BaseHandler } from '../../core/base-handler';
|
|
3
|
+
import { BaseHandler, ILogger } from '../../core';
|
|
5
4
|
import { ServerlessResponse } from '../../network';
|
|
6
5
|
/**
|
|
7
6
|
* The class that implements a default serverless handler consisting of a function with event, context and callback parameters respectively
|
|
@@ -16,13 +16,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
16
16
|
exports.DefaultHandler = void 0;
|
|
17
17
|
const util_1 = __importDefault(require("util"));
|
|
18
18
|
const core_1 = require("../../core");
|
|
19
|
-
const base_handler_1 = require("../../core/base-handler");
|
|
20
19
|
const network_1 = require("../../network");
|
|
21
20
|
//#endregion
|
|
22
21
|
/**
|
|
23
22
|
* The class that implements a default serverless handler consisting of a function with event, context and callback parameters respectively
|
|
24
23
|
*/
|
|
25
|
-
class DefaultHandler extends
|
|
24
|
+
class DefaultHandler extends core_1.BaseHandler {
|
|
26
25
|
//#region Public Methods
|
|
27
26
|
/**
|
|
28
27
|
* @inheritDoc
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
import { RequestListener } from 'http';
|
|
4
|
+
import { BinarySettings } from '../../@types';
|
|
5
|
+
import { AdapterContract, FrameworkContract, HandlerContract, ResolverContract, ServerlessHandler } from '../../contracts';
|
|
6
|
+
import { ILogger } from '../../core';
|
|
7
|
+
/**
|
|
8
|
+
* The default port that huawei will proxy the request to your framework
|
|
9
|
+
*
|
|
10
|
+
* {@link https://support.huaweicloud.com/intl/en-us/ae-ad-1-usermanual-functiongraph/functiongraph_01_1442.html#functiongraph_01_1442__li194597302096 Reference}
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_HUAWEI_LISTEN_PORT: number;
|
|
13
|
+
/**
|
|
14
|
+
* The options to customize {@link HttpHuaweiHandler}
|
|
15
|
+
*/
|
|
16
|
+
export declare type HttpHuaweiHandlerOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* @default {@link DEFAULT_HUAWEI_LISTEN_PORT}
|
|
19
|
+
*/
|
|
20
|
+
port?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The factory to create a http server to use to listen huawei requests
|
|
23
|
+
*/
|
|
24
|
+
httpServerFactory?: (requestListener: RequestListener) => http.Server;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The class that implements a huawei serverless handler with http function that exposes a http server in specific port.
|
|
28
|
+
*
|
|
29
|
+
* In this Handler, you don't need to specific resolver and adapter, so you can use DummyAdapter and DummyResolver instead.
|
|
30
|
+
*
|
|
31
|
+
* @see https://support.huaweicloud.com/intl/en-us/ae-ad-1-usermanual-functiongraph/functiongraph_01_1442.html#functiongraph_01_1442__li194597302096
|
|
32
|
+
*/
|
|
33
|
+
export declare class HttpHuaweiHandler<TApp> implements HandlerContract<TApp, void, void, void, void, Promise<void>> {
|
|
34
|
+
protected readonly options?: HttpHuaweiHandlerOptions | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Construtor padrão
|
|
37
|
+
*/
|
|
38
|
+
constructor(options?: HttpHuaweiHandlerOptions | undefined);
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
getHandler(app: TApp, framework: FrameworkContract<TApp>, _: AdapterContract<void, void, void>[], __: ResolverContract<void, void, void, void, void>, binarySettings: BinarySettings, respondWithErrors: boolean, log: ILogger): ServerlessHandler<Promise<void>>;
|
|
43
|
+
/**
|
|
44
|
+
* The method that creates the instance of http server
|
|
45
|
+
*
|
|
46
|
+
* @param requestListener O método que lidará com as requisições recebidas
|
|
47
|
+
*/
|
|
48
|
+
protected createHttpServer(requestListener: RequestListener): http.Server;
|
|
49
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
6
|
+
}) : (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
o[k2] = m[k];
|
|
9
|
+
}));
|
|
10
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
11
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
12
|
+
}) : function(o, v) {
|
|
13
|
+
o["default"] = v;
|
|
14
|
+
});
|
|
15
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
16
|
+
if (mod && mod.__esModule) return mod;
|
|
17
|
+
var result = {};
|
|
18
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
19
|
+
__setModuleDefault(result, mod);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.HttpHuaweiHandler = exports.DEFAULT_HUAWEI_LISTEN_PORT = void 0;
|
|
24
|
+
const http = __importStar(require("http"));
|
|
25
|
+
const core_1 = require("../../core");
|
|
26
|
+
//#endregion
|
|
27
|
+
/**
|
|
28
|
+
* The default port that huawei will proxy the request to your framework
|
|
29
|
+
*
|
|
30
|
+
* {@link https://support.huaweicloud.com/intl/en-us/ae-ad-1-usermanual-functiongraph/functiongraph_01_1442.html#functiongraph_01_1442__li194597302096 Reference}
|
|
31
|
+
*/
|
|
32
|
+
exports.DEFAULT_HUAWEI_LISTEN_PORT = 8000;
|
|
33
|
+
/**
|
|
34
|
+
* The class that implements a huawei serverless handler with http function that exposes a http server in specific port.
|
|
35
|
+
*
|
|
36
|
+
* In this Handler, you don't need to specific resolver and adapter, so you can use DummyAdapter and DummyResolver instead.
|
|
37
|
+
*
|
|
38
|
+
* @see https://support.huaweicloud.com/intl/en-us/ae-ad-1-usermanual-functiongraph/functiongraph_01_1442.html#functiongraph_01_1442__li194597302096
|
|
39
|
+
*/
|
|
40
|
+
class HttpHuaweiHandler {
|
|
41
|
+
//#region Constructor
|
|
42
|
+
/**
|
|
43
|
+
* Construtor padrão
|
|
44
|
+
*/
|
|
45
|
+
constructor(options) {
|
|
46
|
+
this.options = options;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region Public Methods
|
|
50
|
+
/**
|
|
51
|
+
* @inheritDoc
|
|
52
|
+
*/
|
|
53
|
+
getHandler(app, framework, _, __, binarySettings, respondWithErrors, log) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const requestListener = (req, res) => {
|
|
56
|
+
framework.sendRequest(app, req, res);
|
|
57
|
+
};
|
|
58
|
+
const server = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.httpServerFactory, this.createHttpServer.bind(this))(requestListener);
|
|
59
|
+
const port = (0, core_1.getDefaultIfUndefined)((_b = this.options) === null || _b === void 0 ? void 0 : _b.port, exports.DEFAULT_HUAWEI_LISTEN_PORT);
|
|
60
|
+
server.listen(port, () => {
|
|
61
|
+
log.debug('SERVERLESS_ADAPTER:PROXY: Server started.');
|
|
62
|
+
log.debug(`SERVERLESS_ADAPTER:PROXY: Listening the Huawei Requests in port ${port}`);
|
|
63
|
+
});
|
|
64
|
+
return () => {
|
|
65
|
+
log.debug('SERVERLESS_ADAPTER:PROXY: Disposing the server');
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
server.close(err => (err ? reject(err) : resolve()));
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region Protected Methods
|
|
73
|
+
/**
|
|
74
|
+
* The method that creates the instance of http server
|
|
75
|
+
*
|
|
76
|
+
* @param requestListener O método que lidará com as requisições recebidas
|
|
77
|
+
*/
|
|
78
|
+
createHttpServer(requestListener) {
|
|
79
|
+
return http.createServer(requestListener);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.HttpHuaweiHandler = HttpHuaweiHandler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './http-huawei.handler';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./http-huawei.handler"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Resolver, ResolverContract } from '../../contracts';
|
|
2
|
+
/**
|
|
3
|
+
* The class that represents a dummy resolver that does nothing and can be used by the cloud that doesn't use resolvers.
|
|
4
|
+
*/
|
|
5
|
+
export declare class DummyResolver implements ResolverContract<any, any, any, any, any> {
|
|
6
|
+
/**
|
|
7
|
+
* @inheritDoc
|
|
8
|
+
*/
|
|
9
|
+
createResolver(): Resolver<any, void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DummyResolver = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* The class that represents a dummy resolver that does nothing and can be used by the cloud that doesn't use resolvers.
|
|
8
|
+
*/
|
|
9
|
+
class DummyResolver {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
createResolver() {
|
|
14
|
+
return {
|
|
15
|
+
run: () => Promise.resolve(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.DummyResolver = DummyResolver;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dummy.resolver';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./dummy.resolver"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h4ad/serverless-adapter",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "This library enables you to utilize any Cloud or Event Source to respond to web and API requests using your existing Node.js application framework.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
"hapi",
|
|
47
47
|
"fastify",
|
|
48
48
|
"node.js",
|
|
49
|
-
"http"
|
|
49
|
+
"http",
|
|
50
|
+
"huawei",
|
|
51
|
+
"functiongraph"
|
|
50
52
|
],
|
|
51
53
|
"bugs": {
|
|
52
54
|
"url": "https://github.com/H4ad/serverless-adapter/issues"
|
|
@@ -57,6 +59,7 @@
|
|
|
57
59
|
"@types/body-parser": "^1.19.2",
|
|
58
60
|
"@types/jest": "^27.4.0",
|
|
59
61
|
"@types/node": "12.20.43",
|
|
62
|
+
"@types/supertest": "^2.0.12",
|
|
60
63
|
"@typescript-eslint/eslint-plugin": "^5.12.1",
|
|
61
64
|
"@typescript-eslint/parser": "^5.12.1",
|
|
62
65
|
"body-parser": "^1.19.1",
|
|
@@ -75,6 +78,7 @@
|
|
|
75
78
|
"prettier": "^2.5.1",
|
|
76
79
|
"semantic-release": "^19.0.2",
|
|
77
80
|
"stream-mock": "^2.0.5",
|
|
81
|
+
"supertest": "^6.2.3",
|
|
78
82
|
"ts-jest": "^27.1.3",
|
|
79
83
|
"ts-node": "^10.4.0",
|
|
80
84
|
"typescript": "^4.5.5"
|