@adobe/helix-deploy 10.3.3 → 11.0.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/CHANGELOG.md +19 -0
- package/README.md +11 -23
- package/index.js +0 -1
- package/package.json +2 -3
- package/src/bundler/WebpackBundler.js +1 -1
- package/src/deploy/AWSConfig.js +18 -3
- package/src/deploy/AWSDeployer.js +43 -4
- package/src/DevelopmentServer.js +0 -237
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [11.0.0](https://github.com/adobe/helix-deploy/compare/v10.4.0...v11.0.0) (2024-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* move development server to own package ([#659](https://github.com/adobe/helix-deploy/issues/659)) ([43cbb16](https://github.com/adobe/helix-deploy/commit/43cbb16bb74ebfab1759b7b8ae0f842db6ec3ebe)), closes [#654](https://github.com/adobe/helix-deploy/issues/654)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* import { DevelopmentServer } from @adobe/helix-universal-devserver
|
|
12
|
+
|
|
13
|
+
# [10.4.0](https://github.com/adobe/helix-deploy/compare/v10.3.3...v10.4.0) (2024-01-29)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add support for custom AWS tags which are set on the deployed Lambda. Fixes [#651](https://github.com/adobe/helix-deploy/issues/651) ([#652](https://github.com/adobe/helix-deploy/issues/652)) ([09e2055](https://github.com/adobe/helix-deploy/commit/09e2055928b7f67c70b64034c810a0ff48b5ce59))
|
|
19
|
+
|
|
1
20
|
## [10.3.3](https://github.com/adobe/helix-deploy/compare/v10.3.2...v10.3.3) (2024-01-29)
|
|
2
21
|
|
|
3
22
|
|
package/README.md
CHANGED
|
@@ -132,7 +132,8 @@ AWS Deployment Options
|
|
|
132
132
|
--aws-log-format The lambda log format. Can be either "JSON" or "Text". [string]
|
|
133
133
|
--aws-layers List of layers ARNs to attach to the lambda function. [array]
|
|
134
134
|
--aws-tracing-mode The lambda tracing mode. Can be either "Active" or "PassThrough". [string]
|
|
135
|
-
--aws-extra-permissions A list
|
|
135
|
+
--aws-extra-permissions A list of additional invoke permissions to add to the lambda function in the form <SourceARN>@<Principal>. [array]
|
|
136
|
+
--aws-tags A list of additional tags to attach to the lambda function in the form key=value. To remove a tag, use key= (i.e. without a value).[array]
|
|
136
137
|
|
|
137
138
|
Google Deployment Options
|
|
138
139
|
--google-project-id the Google Cloud project to deploy to. Optional when the key file is a JSON file [string] [default: ""]
|
|
@@ -346,38 +347,25 @@ destination filename. eg:
|
|
|
346
347
|
|
|
347
348
|
## Using the development server
|
|
348
349
|
|
|
349
|
-
Testing an
|
|
350
|
-
|
|
350
|
+
Testing an universal function can be done with the [development server](https://github.com/adobe/helix-universal-devserver).
|
|
351
|
+
|
|
352
|
+
Just create a `test/dev.js` file with:
|
|
351
353
|
|
|
352
354
|
```js
|
|
353
|
-
|
|
354
|
-
|
|
355
|
+
import { DevelopmentServer } from '@adobe/helix-universal-devserver';
|
|
356
|
+
import { main } from '../src/index.js';
|
|
355
357
|
|
|
356
358
|
async function run() {
|
|
357
|
-
const devServer = await new DevelopmentServer(
|
|
358
|
-
|
|
359
|
+
const devServer = await new DevelopmentServer(main).init();
|
|
360
|
+
await devServer.start();
|
|
359
361
|
}
|
|
360
362
|
|
|
361
|
-
|
|
362
|
-
run().catch(console.error);
|
|
363
|
+
run().then(process.stdout).catch(process.stderr);
|
|
363
364
|
```
|
|
364
365
|
|
|
365
366
|
and run `node test/dev.js`.
|
|
366
367
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
Sometimes it might be useful to specify action params that would be provided during deployment
|
|
370
|
-
but are not available during development. those can be specified by a `dev-params-file` `wsk`
|
|
371
|
-
property. those parameters are loaded an applied to every action call. eg:
|
|
372
|
-
|
|
373
|
-
```json
|
|
374
|
-
...
|
|
375
|
-
"wsk": {
|
|
376
|
-
...
|
|
377
|
-
"dev-params-file": ".dev-secrets.env"
|
|
378
|
-
}
|
|
379
|
-
...
|
|
380
|
-
```
|
|
368
|
+
for more information see https://github.com/adobe/helix-universal-devserver
|
|
381
369
|
|
|
382
370
|
## Notes
|
|
383
371
|
|
package/index.js
CHANGED
|
@@ -13,4 +13,3 @@ export { default as ActionBuilder } from './src/ActionBuilder.js';
|
|
|
13
13
|
export { default as Bundler } from './src/bundler/WebpackBundler.js';
|
|
14
14
|
export { default as BaseConfig } from './src/BaseConfig.js';
|
|
15
15
|
export { default as CLI } from './src/cli.js';
|
|
16
|
-
export { default as DevelopmentServer } from './src/DevelopmentServer.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-deploy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Library and Commandline Tools to build and deploy OpenWhisk Actions",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/adobe/helix-deploy#readme",
|
|
@@ -59,7 +59,6 @@
|
|
|
59
59
|
"chalk-template": "1.1.0",
|
|
60
60
|
"constants-browserify": "1.0.0",
|
|
61
61
|
"dotenv": "16.4.1",
|
|
62
|
-
"express": "4.18.2",
|
|
63
62
|
"form-data": "4.0.0",
|
|
64
63
|
"fs-extra": "11.2.0",
|
|
65
64
|
"isomorphic-git": "1.25.3",
|
|
@@ -77,7 +76,7 @@
|
|
|
77
76
|
"@semantic-release/git": "10.0.1",
|
|
78
77
|
"c8": "9.1.0",
|
|
79
78
|
"eslint": "8.56.0",
|
|
80
|
-
"husky": "
|
|
79
|
+
"husky": "9.0.7",
|
|
81
80
|
"lint-staged": "15.2.0",
|
|
82
81
|
"mocha": "10.2.0",
|
|
83
82
|
"mocha-junit-reporter": "2.2.1",
|
|
@@ -81,7 +81,7 @@ export default class WebpackBundler extends BaseBundler {
|
|
|
81
81
|
},
|
|
82
82
|
// use fixed conditions to omit the `development` condition.
|
|
83
83
|
// see: https://webpack.js.org/guides/package-exports/#conditions
|
|
84
|
-
conditionNames: ['node', 'require', 'import'],
|
|
84
|
+
conditionNames: ['node', 'require', 'import', 'module'],
|
|
85
85
|
},
|
|
86
86
|
node: {
|
|
87
87
|
__dirname: true,
|
package/src/deploy/AWSConfig.js
CHANGED
|
@@ -34,6 +34,7 @@ export default class AWSConfig {
|
|
|
34
34
|
layers: undefined,
|
|
35
35
|
tracingMode: undefined,
|
|
36
36
|
extraPermissions: undefined,
|
|
37
|
+
tags: undefined,
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
|
|
@@ -56,7 +57,8 @@ export default class AWSConfig {
|
|
|
56
57
|
.withAWSLogFormat(argv.awsLogFormat)
|
|
57
58
|
.withAWSLayers(argv.awsLayers)
|
|
58
59
|
.withAWSTracingMode(argv.awsTracingMode)
|
|
59
|
-
.withAWSExtraPermissions(argv.awsExtraPermissions)
|
|
60
|
+
.withAWSExtraPermissions(argv.awsExtraPermissions)
|
|
61
|
+
.withAWSTags(argv.awsTags);
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
withAWSRegion(value) {
|
|
@@ -152,13 +154,21 @@ export default class AWSConfig {
|
|
|
152
154
|
return this;
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
withAWSTags(value) {
|
|
158
|
+
if (value && !Array.isArray(value)) {
|
|
159
|
+
throw new Error('awsTags must be an array');
|
|
160
|
+
}
|
|
161
|
+
this.tags = value;
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
|
|
155
165
|
static yarg(yargs) {
|
|
156
166
|
return yargs
|
|
157
167
|
.group(['aws-region', 'aws-api', 'aws-role', 'aws-cleanup-buckets', 'aws-cleanup-integrations',
|
|
158
168
|
'aws-cleanup-versions', 'aws-create-routes', 'aws-create-authorizer', 'aws-attach-authorizer',
|
|
159
169
|
'aws-lambda-format', 'aws-parameter-manager', 'aws-deploy-template', 'aws-arch', 'aws-update-secrets',
|
|
160
170
|
'aws-deploy-bucket', 'aws-identity-source', 'aws-log-format', 'aws-layers',
|
|
161
|
-
'aws-tracing-mode', 'aws-extra-permissions'], 'AWS Deployment Options')
|
|
171
|
+
'aws-tracing-mode', 'aws-extra-permissions', 'aws-tags'], 'AWS Deployment Options')
|
|
162
172
|
.option('aws-region', {
|
|
163
173
|
description: 'the AWS region to deploy lambda functions to',
|
|
164
174
|
type: 'string',
|
|
@@ -245,9 +255,14 @@ export default class AWSConfig {
|
|
|
245
255
|
type: 'string',
|
|
246
256
|
})
|
|
247
257
|
.option('aws-extra-permissions', {
|
|
248
|
-
description: 'A list
|
|
258
|
+
description: 'A list of additional invoke permissions to add to the lambda function in the form <SourceARN>@<Principal>.',
|
|
249
259
|
type: 'string',
|
|
250
260
|
array: true,
|
|
261
|
+
})
|
|
262
|
+
.option('aws-tags', {
|
|
263
|
+
description: 'A list of additional tags to attach to the lambda function in the form key=value. To remove a tag, use key= (i.e. without a value).',
|
|
264
|
+
type: 'array',
|
|
265
|
+
array: true,
|
|
251
266
|
});
|
|
252
267
|
}
|
|
253
268
|
}
|
|
@@ -29,9 +29,9 @@ import {
|
|
|
29
29
|
CreateAliasCommand,
|
|
30
30
|
CreateFunctionCommand, DeleteAliasCommand, DeleteFunctionCommand, GetAliasCommand,
|
|
31
31
|
GetFunctionCommand,
|
|
32
|
-
LambdaClient, ListAliasesCommand, ListVersionsByFunctionCommand,
|
|
33
|
-
PublishVersionCommand,
|
|
34
|
-
UpdateFunctionConfigurationCommand,
|
|
32
|
+
LambdaClient, ListAliasesCommand, ListTagsCommand, ListVersionsByFunctionCommand,
|
|
33
|
+
PublishVersionCommand, TagResourceCommand, UntagResourceCommand, UpdateAliasCommand,
|
|
34
|
+
UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand,
|
|
35
35
|
} from '@aws-sdk/client-lambda';
|
|
36
36
|
|
|
37
37
|
import {
|
|
@@ -126,6 +126,16 @@ export default class AWSDeployer extends BaseDeployer {
|
|
|
126
126
|
}`;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
get additionalTags() {
|
|
130
|
+
return (this._cfg.tags || []).map((tag) => tag.split('=')).reduce((acc, tagSplit) => {
|
|
131
|
+
if (tagSplit.length >= 2) {
|
|
132
|
+
const [key, ...value] = tagSplit;
|
|
133
|
+
acc[key] = value.join('=');
|
|
134
|
+
}
|
|
135
|
+
return acc;
|
|
136
|
+
}, {});
|
|
137
|
+
}
|
|
138
|
+
|
|
129
139
|
validate() {
|
|
130
140
|
const req = [];
|
|
131
141
|
if (!this._cfg.role) {
|
|
@@ -206,7 +216,7 @@ export default class AWSDeployer extends BaseDeployer {
|
|
|
206
216
|
}
|
|
207
217
|
|
|
208
218
|
async createLambda() {
|
|
209
|
-
const { cfg, functionName } = this;
|
|
219
|
+
const { cfg, functionName, additionalTags } = this;
|
|
210
220
|
const functionVersion = cfg.version.replace(/\./g, '_');
|
|
211
221
|
|
|
212
222
|
const functionConfig = {
|
|
@@ -243,6 +253,13 @@ export default class AWSDeployer extends BaseDeployer {
|
|
|
243
253
|
TracingConfig: this._cfg.tracingMode ? { Mode: this._cfg.tracingMode } : undefined,
|
|
244
254
|
};
|
|
245
255
|
|
|
256
|
+
// add additional tags which are not empty
|
|
257
|
+
Object.entries(additionalTags).forEach(([key, value]) => {
|
|
258
|
+
if (value !== '') {
|
|
259
|
+
functionConfig.Tags[key] = value;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
246
263
|
this.log.info(`--: using lambda role "${this._cfg.role}"`);
|
|
247
264
|
|
|
248
265
|
// check if function already exists
|
|
@@ -272,6 +289,28 @@ export default class AWSDeployer extends BaseDeployer {
|
|
|
272
289
|
this.log.info(chalk`--: updating existing Lambda function configuration {yellow ${functionName}}`);
|
|
273
290
|
await this._lambda.send(new UpdateFunctionConfigurationCommand(functionConfig));
|
|
274
291
|
await this.checkFunctionReady(baseARN);
|
|
292
|
+
this.log.info(chalk`--: updating existing Lambda function tags {yellow ${functionName}}`);
|
|
293
|
+
// set all the tags in the current configuration
|
|
294
|
+
await this._lambda.send(new TagResourceCommand({
|
|
295
|
+
Resource: baseARN,
|
|
296
|
+
Tags: functionConfig.Tags,
|
|
297
|
+
}));
|
|
298
|
+
// then remove any tags with a blank value in the configuration (and are currently set),
|
|
299
|
+
// leaving other tags alone
|
|
300
|
+
const tagsToPotentiallyRemove = Object.entries(additionalTags).filter(([_, value]) => value === '').map(([key]) => key);
|
|
301
|
+
if (tagsToPotentiallyRemove.length) {
|
|
302
|
+
const { Tags: currentTags } = await this._lambda.send(new ListTagsCommand({
|
|
303
|
+
Resource: baseARN,
|
|
304
|
+
}));
|
|
305
|
+
const tagsToRemove = tagsToPotentiallyRemove.filter((key) => currentTags[key]);
|
|
306
|
+
if (tagsToRemove.length) {
|
|
307
|
+
await this._lambda.send(new UntagResourceCommand({
|
|
308
|
+
Resource: baseARN,
|
|
309
|
+
TagKeys: tagsToRemove,
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
await this.checkFunctionReady(baseARN);
|
|
275
314
|
this.log.info('--: updating Lambda function code...');
|
|
276
315
|
await this._lambda.send(new UpdateFunctionCodeCommand({
|
|
277
316
|
FunctionName: functionName,
|
package/src/DevelopmentServer.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
import crypto from 'crypto';
|
|
13
|
-
import fse from 'fs-extra';
|
|
14
|
-
import path from 'path';
|
|
15
|
-
import express from 'express';
|
|
16
|
-
import { createAdapter } from '@adobe/helix-universal/aws';
|
|
17
|
-
import ActionBuilder from './ActionBuilder.js';
|
|
18
|
-
import BaseConfig from './BaseConfig.js';
|
|
19
|
-
|
|
20
|
-
function rawBody() {
|
|
21
|
-
return (req, res, next) => {
|
|
22
|
-
if (req.method === 'GET' || req.method === 'HEAD') {
|
|
23
|
-
next();
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const chunks = [];
|
|
27
|
-
req.on('data', (chunk) => {
|
|
28
|
-
chunks.push(chunk);
|
|
29
|
-
});
|
|
30
|
-
req.on('end', () => {
|
|
31
|
-
req.rawBody = Buffer.concat(chunks);
|
|
32
|
-
next();
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function addRequestHeader(name, value) {
|
|
38
|
-
return (req, res, next) => {
|
|
39
|
-
req.headers[name] = value;
|
|
40
|
-
next();
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Development server for local development.
|
|
46
|
-
*
|
|
47
|
-
* Example:
|
|
48
|
-
*
|
|
49
|
-
* ```
|
|
50
|
-
* // test/dev.js
|
|
51
|
-
*
|
|
52
|
-
* const { DevelopmentServer } = require('@adobe/helix-deploy');
|
|
53
|
-
* const { main } = require('../src/index.js');
|
|
54
|
-
*
|
|
55
|
-
* async function run() {
|
|
56
|
-
* const devServer = await new DevelopmentServer(main).init();
|
|
57
|
-
* await devServer.start();
|
|
58
|
-
* }
|
|
59
|
-
*
|
|
60
|
-
* run().then(process.stdout).catch(process.stderr);
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
|
-
* @type {DevelopmentServer}
|
|
64
|
-
*/
|
|
65
|
-
export default class DevelopmentServer {
|
|
66
|
-
/**
|
|
67
|
-
* Creates a new development server using the given universal function.
|
|
68
|
-
* @param {UniversalFunction} main - The universal function
|
|
69
|
-
*/
|
|
70
|
-
constructor(main) {
|
|
71
|
-
this._main = main;
|
|
72
|
-
this._cwd = process.cwd();
|
|
73
|
-
this._port = process.env.WEBSERVER_PORT || 3000;
|
|
74
|
-
this._headers = {};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
withPort(value) {
|
|
78
|
-
this._port = value;
|
|
79
|
-
return this;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
withXFH(value) {
|
|
83
|
-
process.emitWarning('DevelopmentServer.withXFH is deprecated. Use withHeader(\'x-forwarded-host\') instead.', 'DeprecationWarning');
|
|
84
|
-
this._headers['x-forwarded-host'] = value;
|
|
85
|
-
return this;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
withHeader(name, value) {
|
|
89
|
-
this._headers[name] = value;
|
|
90
|
-
return this;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
withDirectory(value) {
|
|
94
|
-
this._cwd = value;
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get port() {
|
|
99
|
-
return this._port;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Initializes the development server.
|
|
104
|
-
* It uses the `wsk.package.params-file` and `wsk.params-file` to read the environment for
|
|
105
|
-
* the action params.
|
|
106
|
-
*
|
|
107
|
-
* @returns this
|
|
108
|
-
*/
|
|
109
|
-
async init() {
|
|
110
|
-
// load the action params
|
|
111
|
-
let pkgJson = {};
|
|
112
|
-
try {
|
|
113
|
-
pkgJson = await fse.readJson(path.resolve(this._cwd, 'package.json'));
|
|
114
|
-
} catch (e) {
|
|
115
|
-
// ignore
|
|
116
|
-
}
|
|
117
|
-
const config = new BaseConfig();
|
|
118
|
-
if (pkgJson.wsk) {
|
|
119
|
-
const withParamsFile = async (file) => {
|
|
120
|
-
if (!file) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
// eslint-disable-next-line no-param-reassign
|
|
124
|
-
const files = (Array.isArray(file) ? file : [file]).map((f) => path.resolve(this._cwd, f));
|
|
125
|
-
await Promise.all(files.map(async (f) => {
|
|
126
|
-
if (await fse.exists(f)) {
|
|
127
|
-
config.withParamsFile(f);
|
|
128
|
-
}
|
|
129
|
-
}));
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
await withParamsFile(pkgJson.wsk?.package?.['params-file']);
|
|
133
|
-
config.withParams(pkgJson.wsk?.package?.params);
|
|
134
|
-
await withParamsFile(pkgJson.wsk?.['params-file']);
|
|
135
|
-
config.withParams(pkgJson.wsk?.params);
|
|
136
|
-
await withParamsFile(pkgJson.wsk?.dev?.['params-file']);
|
|
137
|
-
config.withParams(pkgJson.wsk?.dev?.params);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const builder = new ActionBuilder().withConfig(config);
|
|
141
|
-
await builder.validate();
|
|
142
|
-
|
|
143
|
-
const region = process.env.AWS_REGION ?? 'us-east-1';
|
|
144
|
-
const accountId = process.env.AWS_ACCOUNT_ID ?? 'no-account';
|
|
145
|
-
|
|
146
|
-
const adapter = createAdapter({
|
|
147
|
-
factory: () => (req, ctx) => {
|
|
148
|
-
ctx.runtime.name = 'simulate';
|
|
149
|
-
return this._main(req, ctx);
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
this._handler = async (req, res) => {
|
|
153
|
-
const [rawPath, ...rest] = req.originalUrl.split('?');
|
|
154
|
-
const rawQueryString = rest.join('?');
|
|
155
|
-
const method = req.headers['x-http-method'] || req.method;
|
|
156
|
-
const event = {
|
|
157
|
-
body: req.rawBody,
|
|
158
|
-
headers: req.headers,
|
|
159
|
-
pathParameters: {
|
|
160
|
-
path: rawPath.substring(1),
|
|
161
|
-
},
|
|
162
|
-
requestContext: {
|
|
163
|
-
domainName: req.hostname,
|
|
164
|
-
http: {
|
|
165
|
-
method,
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
rawPath,
|
|
169
|
-
rawQueryString,
|
|
170
|
-
};
|
|
171
|
-
const context = {
|
|
172
|
-
awsRequestId: crypto.randomUUID(),
|
|
173
|
-
invokedFunctionArn: `arn:aws:lambda:${region}:${accountId}:function:${config.name}:${config.version}`,
|
|
174
|
-
getRemainingTimeInMillis: () => 60000,
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const {
|
|
178
|
-
statusCode,
|
|
179
|
-
headers,
|
|
180
|
-
isBase64Encoded,
|
|
181
|
-
body,
|
|
182
|
-
} = await adapter(event, context);
|
|
183
|
-
|
|
184
|
-
res.status(statusCode);
|
|
185
|
-
Object.entries(headers).forEach(([name, value]) => res.set(name, value));
|
|
186
|
-
res.send(isBase64Encoded ? Buffer.from(body, 'base64') : body);
|
|
187
|
-
};
|
|
188
|
-
this.params = config.params;
|
|
189
|
-
return this;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Starts the development server
|
|
194
|
-
* @returns {Promise<void>}
|
|
195
|
-
*/
|
|
196
|
-
async start() {
|
|
197
|
-
Object.entries(this.params).forEach(([key, value]) => {
|
|
198
|
-
if (!(key in process.env)) {
|
|
199
|
-
process.env[key] = value;
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
this.app = express();
|
|
203
|
-
await new Promise((resolve, reject) => {
|
|
204
|
-
try {
|
|
205
|
-
this.server = this.app.listen(this._port, () => {
|
|
206
|
-
this._port = this.server.address().port;
|
|
207
|
-
// eslint-disable-next-line no-console
|
|
208
|
-
console.log(`Started development server at http://localhost:${this._port}/`);
|
|
209
|
-
resolve();
|
|
210
|
-
});
|
|
211
|
-
} catch (e) {
|
|
212
|
-
reject(e);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
this.app.use(rawBody());
|
|
216
|
-
Object.entries(this._headers).forEach(([name, value]) => {
|
|
217
|
-
this.app.use(addRequestHeader(name, value.replace('{port}', this._port)));
|
|
218
|
-
});
|
|
219
|
-
this.app.all('*', this._handler);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Stops the development server.
|
|
224
|
-
* @returns {Promise<void>}
|
|
225
|
-
*/
|
|
226
|
-
async stop() {
|
|
227
|
-
return new Promise((resolve, reject) => {
|
|
228
|
-
this.server.close((err) => {
|
|
229
|
-
if (err) {
|
|
230
|
-
reject(err);
|
|
231
|
-
} else {
|
|
232
|
-
resolve();
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}
|