serverless-offline 8.2.0 → 8.5.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 +157 -116
- package/dist/ServerlessOffline.js +98 -26
- package/dist/config/commandOptions.js +4 -0
- package/dist/config/constants.js +1 -1
- package/dist/config/defaultOptions.js +1 -0
- package/dist/events/http/Endpoint.js +27 -9
- package/dist/events/http/Http.js +3 -3
- package/dist/events/http/HttpServer.js +355 -82
- package/dist/events/http/authFunctionNameExtractor.js +14 -8
- package/dist/events/http/authJWTSettingsExtractor.js +14 -7
- package/dist/events/http/createAuthScheme.js +44 -9
- package/dist/events/http/createJWTAuthScheme.js +52 -13
- package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +7 -6
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +38 -7
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +37 -6
- package/dist/events/http/lambda-events/VelocityContext.js +4 -4
- package/dist/events/http/lambda-events/index.js +4 -4
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +19 -7
- package/dist/events/schedule/Schedule.js +45 -10
- package/dist/events/websocket/HttpServer.js +24 -7
- package/dist/events/websocket/WebSocket.js +14 -6
- package/dist/events/websocket/WebSocketClients.js +127 -38
- package/dist/events/websocket/WebSocketServer.js +79 -11
- package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +9 -2
- package/dist/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +28 -5
- package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +5 -5
- package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +1 -1
- package/dist/events/websocket/lambda-events/WebSocketEvent.js +3 -3
- package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +4 -4
- package/dist/lambda/HttpServer.js +34 -10
- package/dist/lambda/Lambda.js +15 -7
- package/dist/lambda/LambdaContext.js +1 -1
- package/dist/lambda/LambdaFunction.js +40 -23
- package/dist/lambda/LambdaFunctionPool.js +9 -8
- package/dist/lambda/handler-runner/HandlerRunner.js +51 -16
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +21 -8
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +1 -10
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +168 -69
- package/dist/lambda/handler-runner/docker-runner/DockerImage.js +21 -5
- package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +4 -4
- package/dist/lambda/handler-runner/go-runner/GoRunner.js +211 -0
- package/dist/lambda/handler-runner/go-runner/index.js +15 -0
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +16 -22
- package/dist/lambda/handler-runner/java-runner/JavaRunner.js +26 -14
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +20 -7
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +22 -24
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -2
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +1 -11
- package/dist/lambda/routes/invocations/InvocationsController.js +30 -11
- package/dist/lambda/routes/invocations/invocationsRoute.js +4 -3
- package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +2 -6
- package/dist/serverlessLog.js +1 -1
- package/dist/utils/checkGoVersion.js +27 -0
- package/dist/utils/getHttpApiCorsConfig.js +18 -5
- package/dist/utils/index.js +24 -16
- package/package.json +86 -37
|
@@ -34,16 +34,7 @@ process.on('message', async messageData => {
|
|
|
34
34
|
} = messageData; // TODO we could probably cache this in the module scope?
|
|
35
35
|
|
|
36
36
|
const inProcessRunner = new _index.default(functionKey, handlerPath, handlerName, process.env, timeout, allowCache);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
result = await inProcessRunner.run(event, context);
|
|
41
|
-
} catch (err) {
|
|
42
|
-
// TODO logging
|
|
43
|
-
console.log(err);
|
|
44
|
-
throw err;
|
|
45
|
-
} // TODO check serializeability (contains function, symbol etc)
|
|
46
|
-
|
|
37
|
+
const result = await inProcessRunner.run(event, context); // TODO check serializeability (contains function, symbol etc)
|
|
47
38
|
|
|
48
39
|
process.send(result);
|
|
49
40
|
});
|
|
@@ -49,34 +49,34 @@ const {
|
|
|
49
49
|
keys
|
|
50
50
|
} = Object;
|
|
51
51
|
|
|
52
|
-
var _containerId = _classPrivateFieldLooseKey("containerId");
|
|
52
|
+
var _containerId = /*#__PURE__*/_classPrivateFieldLooseKey("containerId");
|
|
53
53
|
|
|
54
|
-
var _dockerOptions = _classPrivateFieldLooseKey("dockerOptions");
|
|
54
|
+
var _dockerOptions = /*#__PURE__*/_classPrivateFieldLooseKey("dockerOptions");
|
|
55
55
|
|
|
56
|
-
var _env = _classPrivateFieldLooseKey("env");
|
|
56
|
+
var _env = /*#__PURE__*/_classPrivateFieldLooseKey("env");
|
|
57
57
|
|
|
58
|
-
var _functionKey = _classPrivateFieldLooseKey("functionKey");
|
|
58
|
+
var _functionKey = /*#__PURE__*/_classPrivateFieldLooseKey("functionKey");
|
|
59
59
|
|
|
60
|
-
var _handler = _classPrivateFieldLooseKey("handler");
|
|
60
|
+
var _handler = /*#__PURE__*/_classPrivateFieldLooseKey("handler");
|
|
61
61
|
|
|
62
|
-
var _image = _classPrivateFieldLooseKey("image");
|
|
62
|
+
var _image = /*#__PURE__*/_classPrivateFieldLooseKey("image");
|
|
63
63
|
|
|
64
|
-
var _imageNameTag = _classPrivateFieldLooseKey("imageNameTag");
|
|
64
|
+
var _imageNameTag = /*#__PURE__*/_classPrivateFieldLooseKey("imageNameTag");
|
|
65
65
|
|
|
66
|
-
var _lambda = _classPrivateFieldLooseKey("lambda");
|
|
66
|
+
var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
|
|
67
67
|
|
|
68
|
-
var _layers = _classPrivateFieldLooseKey("layers");
|
|
68
|
+
var _layers = /*#__PURE__*/_classPrivateFieldLooseKey("layers");
|
|
69
69
|
|
|
70
|
-
var _port = _classPrivateFieldLooseKey("port");
|
|
70
|
+
var _port = /*#__PURE__*/_classPrivateFieldLooseKey("port");
|
|
71
71
|
|
|
72
|
-
var _provider = _classPrivateFieldLooseKey("provider");
|
|
72
|
+
var _provider = /*#__PURE__*/_classPrivateFieldLooseKey("provider");
|
|
73
73
|
|
|
74
|
-
var _runtime = _classPrivateFieldLooseKey("runtime");
|
|
74
|
+
var _runtime = /*#__PURE__*/_classPrivateFieldLooseKey("runtime");
|
|
75
75
|
|
|
76
|
-
var _servicePath = _classPrivateFieldLooseKey("servicePath");
|
|
76
|
+
var _servicePath = /*#__PURE__*/_classPrivateFieldLooseKey("servicePath");
|
|
77
77
|
|
|
78
78
|
class DockerContainer {
|
|
79
|
-
constructor(env, functionKey, handler, runtime, layers, provider, servicePath, dockerOptions) {
|
|
79
|
+
constructor(env, functionKey, handler, runtime, layers, provider, servicePath, dockerOptions, v3Utils) {
|
|
80
80
|
Object.defineProperty(this, _containerId, {
|
|
81
81
|
writable: true,
|
|
82
82
|
value: null
|
|
@@ -133,12 +133,19 @@ class DockerContainer {
|
|
|
133
133
|
_classPrivateFieldLooseBase(this, _functionKey)[_functionKey] = functionKey;
|
|
134
134
|
_classPrivateFieldLooseBase(this, _handler)[_handler] = handler;
|
|
135
135
|
_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag] = this._baseImage(runtime);
|
|
136
|
-
_classPrivateFieldLooseBase(this, _image)[_image] = new _DockerImage.default(_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag]);
|
|
136
|
+
_classPrivateFieldLooseBase(this, _image)[_image] = new _DockerImage.default(_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag], v3Utils);
|
|
137
137
|
_classPrivateFieldLooseBase(this, _runtime)[_runtime] = runtime;
|
|
138
138
|
_classPrivateFieldLooseBase(this, _layers)[_layers] = layers;
|
|
139
139
|
_classPrivateFieldLooseBase(this, _provider)[_provider] = provider;
|
|
140
140
|
_classPrivateFieldLooseBase(this, _servicePath)[_servicePath] = servicePath;
|
|
141
141
|
_classPrivateFieldLooseBase(this, _dockerOptions)[_dockerOptions] = dockerOptions;
|
|
142
|
+
|
|
143
|
+
if (v3Utils) {
|
|
144
|
+
this.log = v3Utils.log;
|
|
145
|
+
this.progress = v3Utils.progress;
|
|
146
|
+
this.writeText = v3Utils.writeText;
|
|
147
|
+
this.v3Utils = v3Utils;
|
|
148
|
+
}
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
_baseImage(runtime) {
|
|
@@ -147,7 +154,13 @@ class DockerContainer {
|
|
|
147
154
|
|
|
148
155
|
async start(codeDir) {
|
|
149
156
|
await _classPrivateFieldLooseBase(this, _image)[_image].pull();
|
|
150
|
-
|
|
157
|
+
|
|
158
|
+
if (this.log) {
|
|
159
|
+
this.log.debug('Run Docker container...');
|
|
160
|
+
} else {
|
|
161
|
+
(0, _debugLog.default)('Run Docker container...');
|
|
162
|
+
}
|
|
163
|
+
|
|
151
164
|
let permissions = 'ro';
|
|
152
165
|
|
|
153
166
|
if (!_classPrivateFieldLooseBase(this, _dockerOptions)[_dockerOptions].readOnly) {
|
|
@@ -160,10 +173,18 @@ class DockerContainer {
|
|
|
160
173
|
];
|
|
161
174
|
|
|
162
175
|
if (_classPrivateFieldLooseBase(this, _layers)[_layers].length > 0) {
|
|
163
|
-
(
|
|
176
|
+
if (this.log) {
|
|
177
|
+
this.log.verbose(`Found layers, checking provider type`);
|
|
178
|
+
} else {
|
|
179
|
+
(0, _serverlessLog.logLayers)(`Found layers, checking provider type`);
|
|
180
|
+
}
|
|
164
181
|
|
|
165
182
|
if (_classPrivateFieldLooseBase(this, _provider)[_provider].name.toLowerCase() !== 'aws') {
|
|
166
|
-
(
|
|
183
|
+
if (this.log) {
|
|
184
|
+
this.log.warning(`Provider ${_classPrivateFieldLooseBase(this, _provider)[_provider].name} is Unsupported. Layers are only supported on aws.`);
|
|
185
|
+
} else {
|
|
186
|
+
(0, _serverlessLog.logLayers)(`Provider ${_classPrivateFieldLooseBase(this, _provider)[_provider].name} is Unsupported. Layers are only supported on aws.`);
|
|
187
|
+
}
|
|
167
188
|
} else {
|
|
168
189
|
let layerDir = _classPrivateFieldLooseBase(this, _dockerOptions)[_dockerOptions].layersDir;
|
|
169
190
|
|
|
@@ -174,16 +195,31 @@ class DockerContainer {
|
|
|
174
195
|
layerDir = (0, _path.join)(layerDir, this._getLayersSha256());
|
|
175
196
|
|
|
176
197
|
if (await (0, _fsExtra.pathExists)(layerDir)) {
|
|
177
|
-
|
|
198
|
+
if (this.log) {
|
|
199
|
+
this.log.verbose(`Layers already exist for this function. Skipping download.`);
|
|
200
|
+
} else {
|
|
201
|
+
(0, _serverlessLog.logLayers)(`Layers already exist for this function. Skipping download.`);
|
|
202
|
+
}
|
|
178
203
|
} else {
|
|
179
204
|
const layers = [];
|
|
180
|
-
|
|
205
|
+
|
|
206
|
+
if (this.log) {
|
|
207
|
+
this.log.verbose(`Storing layers at ${layerDir}`);
|
|
208
|
+
} else {
|
|
209
|
+
(0, _serverlessLog.logLayers)(`Storing layers at ${layerDir}`);
|
|
210
|
+
} // Only initialise if we have layers, we're using AWS, and they don't already exist
|
|
211
|
+
|
|
181
212
|
|
|
182
213
|
_classPrivateFieldLooseBase(this, _lambda)[_lambda] = new _awsSdk.Lambda({
|
|
183
214
|
apiVersion: '2015-03-31',
|
|
184
215
|
region: _classPrivateFieldLooseBase(this, _provider)[_provider].region
|
|
185
216
|
});
|
|
186
|
-
|
|
217
|
+
|
|
218
|
+
if (this.log) {
|
|
219
|
+
this.log.verbose(`Getting layers`);
|
|
220
|
+
} else {
|
|
221
|
+
(0, _serverlessLog.logLayers)(`Getting layers`);
|
|
222
|
+
}
|
|
187
223
|
|
|
188
224
|
for (const layerArn of _classPrivateFieldLooseBase(this, _layers)[_layers]) {
|
|
189
225
|
layers.push(this._downloadLayer(layerArn, layerDir));
|
|
@@ -275,66 +311,119 @@ class DockerContainer {
|
|
|
275
311
|
async _downloadLayer(layerArn, layerDir) {
|
|
276
312
|
const layerName = layerArn.split(':layer:')[1];
|
|
277
313
|
const layerZipFile = `${layerDir}/${layerName}.zip`;
|
|
278
|
-
|
|
314
|
+
const layerProgress = this.log && this.progress.get(`layer-${layerName}`);
|
|
315
|
+
|
|
316
|
+
if (this.log) {
|
|
317
|
+
this.log.verbose(`[${layerName}] ARN: ${layerArn}`);
|
|
318
|
+
} else {
|
|
319
|
+
(0, _serverlessLog.logLayers)(`[${layerName}] ARN: ${layerArn}`);
|
|
320
|
+
}
|
|
321
|
+
|
|
279
322
|
const params = {
|
|
280
323
|
Arn: layerArn
|
|
281
324
|
};
|
|
282
|
-
(0, _serverlessLog.logLayers)(`[${layerName}] Getting Info`);
|
|
283
|
-
let layer = null;
|
|
284
325
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
326
|
+
if (this.log) {
|
|
327
|
+
this.log.verbose(`[${layerName}] Getting Info`);
|
|
328
|
+
layerProgress.notice(`Retrieving "${layerName}": Getting info`);
|
|
329
|
+
} else {
|
|
330
|
+
(0, _serverlessLog.logLayers)(`[${layerName}] Getting Info`);
|
|
290
331
|
}
|
|
291
332
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
333
|
+
try {
|
|
334
|
+
let layer = null;
|
|
296
335
|
|
|
297
|
-
|
|
336
|
+
try {
|
|
337
|
+
layer = await _classPrivateFieldLooseBase(this, _lambda)[_lambda].getLayerVersionByArn(params).promise();
|
|
338
|
+
} catch (e) {
|
|
339
|
+
if (this.log) {
|
|
340
|
+
this.log.warning(`[${layerName}] ${e.code}: ${e.message}`);
|
|
341
|
+
} else {
|
|
342
|
+
(0, _serverlessLog.logWarning)(`[${layerName}] ${e.code}: ${e.message}`);
|
|
343
|
+
}
|
|
298
344
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
(0, _serverlessLog.logLayers)(`[${layerName}] Downloading ${this._formatBytes(layerSize)}...`);
|
|
302
|
-
const res = await (0, _nodeFetch.default)(layerUrl, {
|
|
303
|
-
method: 'get'
|
|
304
|
-
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
305
347
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
348
|
+
if (Object.prototype.hasOwnProperty.call(layer, 'CompatibleRuntimes') && !layer.CompatibleRuntimes.includes(_classPrivateFieldLooseBase(this, _runtime)[_runtime])) {
|
|
349
|
+
if (this.log) {
|
|
350
|
+
this.log.warning(`[${layerName}] Layer is not compatible with ${_classPrivateFieldLooseBase(this, _runtime)[_runtime]} runtime`);
|
|
351
|
+
} else {
|
|
352
|
+
(0, _serverlessLog.logWarning)(`[${layerName}] Layer is not compatible with ${_classPrivateFieldLooseBase(this, _runtime)[_runtime]} runtime`);
|
|
353
|
+
}
|
|
310
354
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const layerUrl = layer.Content.Location; // const layerSha = layer.Content.CodeSha256
|
|
359
|
+
|
|
360
|
+
const layerSize = layer.Content.CodeSize;
|
|
361
|
+
await (0, _fsExtra.ensureDir)(layerDir);
|
|
362
|
+
|
|
363
|
+
if (this.log) {
|
|
364
|
+
this.log.verbose(`Retrieving "${layerName}": Downloading ${this._formatBytes(layerSize)}...`);
|
|
365
|
+
layerProgress.notice(`Retrieving "${layerName}": Downloading ${this._formatBytes(layerSize)}`);
|
|
366
|
+
} else {
|
|
367
|
+
(0, _serverlessLog.logLayers)(`[${layerName}] Downloading ${this._formatBytes(layerSize)}...`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const res = await (0, _nodeFetch.default)(layerUrl, {
|
|
371
|
+
method: 'get'
|
|
319
372
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
return
|
|
373
|
+
|
|
374
|
+
if (!res.ok) {
|
|
375
|
+
if (this.log) {
|
|
376
|
+
this.log.warning(`[${layerName}] Failed to fetch from ${layerUrl} with ${res.statusText}`);
|
|
377
|
+
} else {
|
|
378
|
+
(0, _serverlessLog.logWarning)(`[${layerName}] Failed to fetch from ${layerUrl} with ${res.statusText}`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return;
|
|
329
382
|
}
|
|
330
383
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
384
|
+
const fileStream = (0, _fs.createWriteStream)(`${layerZipFile}`);
|
|
385
|
+
await new Promise((resolve, reject) => {
|
|
386
|
+
res.body.pipe(fileStream);
|
|
387
|
+
res.body.on('error', err => {
|
|
388
|
+
reject(err);
|
|
389
|
+
});
|
|
390
|
+
fileStream.on('finish', () => {
|
|
391
|
+
resolve();
|
|
392
|
+
});
|
|
334
393
|
});
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
394
|
+
|
|
395
|
+
if (this.log) {
|
|
396
|
+
this.log.verbose(`Retrieving "${layerName}": Unzipping to .layers directory`);
|
|
397
|
+
layerProgress.notice(`Retrieving "${layerName}": Unzipping to .layers directory`);
|
|
398
|
+
} else {
|
|
399
|
+
(0, _serverlessLog.logLayers)(`[${layerName}] Unzipping to .layers directory`);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const data = await (0, _fsExtra.readFile)(`${layerZipFile}`);
|
|
403
|
+
const zip = await _jszip.default.loadAsync(data);
|
|
404
|
+
await Promise.all(keys(zip.files).map(async filename => {
|
|
405
|
+
const fileData = await zip.files[filename].async('nodebuffer');
|
|
406
|
+
|
|
407
|
+
if (filename.endsWith(_path.sep)) {
|
|
408
|
+
return Promise.resolve();
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
await (0, _fsExtra.ensureDir)((0, _path.join)(layerDir, (0, _path.dirname)(filename)));
|
|
412
|
+
return (0, _fsExtra.writeFile)((0, _path.join)(layerDir, filename), fileData, {
|
|
413
|
+
mode: zip.files[filename].unixPermissions
|
|
414
|
+
});
|
|
415
|
+
}));
|
|
416
|
+
|
|
417
|
+
if (this.log) {
|
|
418
|
+
this.log.verbose(`[${layerName}] Removing zip file`);
|
|
419
|
+
} else {
|
|
420
|
+
(0, _serverlessLog.logLayers)(`[${layerName}] Removing zip file`);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
(0, _fs.unlinkSync)(`${layerZipFile}`);
|
|
424
|
+
} finally {
|
|
425
|
+
if (this.log) layerProgress.remove();
|
|
426
|
+
}
|
|
338
427
|
}
|
|
339
428
|
|
|
340
429
|
async _getBridgeGatewayIp() {
|
|
@@ -346,7 +435,12 @@ class DockerContainer {
|
|
|
346
435
|
stdout: gateway
|
|
347
436
|
} = await (0, _execa.default)('docker', ['network', 'inspect', 'bridge', '--format', '{{(index .IPAM.Config 0).Gateway}}']));
|
|
348
437
|
} catch (err) {
|
|
349
|
-
|
|
438
|
+
if (this.log) {
|
|
439
|
+
this.log.error(err.stderr);
|
|
440
|
+
} else {
|
|
441
|
+
console.error(err.stderr);
|
|
442
|
+
}
|
|
443
|
+
|
|
350
444
|
throw err;
|
|
351
445
|
}
|
|
352
446
|
|
|
@@ -387,7 +481,12 @@ class DockerContainer {
|
|
|
387
481
|
await (0, _execa.default)('docker', ['stop', _classPrivateFieldLooseBase(this, _containerId)[_containerId]]);
|
|
388
482
|
await (0, _execa.default)('docker', ['rm', _classPrivateFieldLooseBase(this, _containerId)[_containerId]]);
|
|
389
483
|
} catch (err) {
|
|
390
|
-
|
|
484
|
+
if (this.log) {
|
|
485
|
+
this.log.error(err.stderr);
|
|
486
|
+
} else {
|
|
487
|
+
console.error(err.stderr);
|
|
488
|
+
}
|
|
489
|
+
|
|
391
490
|
throw err;
|
|
392
491
|
}
|
|
393
492
|
}
|
|
@@ -19,30 +19,46 @@ var id = 0;
|
|
|
19
19
|
|
|
20
20
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
21
21
|
|
|
22
|
-
var _imageNameTag = _classPrivateFieldLooseKey("imageNameTag");
|
|
22
|
+
var _imageNameTag = /*#__PURE__*/_classPrivateFieldLooseKey("imageNameTag");
|
|
23
23
|
|
|
24
24
|
class DockerImage {
|
|
25
|
-
constructor(imageNameTag) {
|
|
25
|
+
constructor(imageNameTag, v3Utils) {
|
|
26
26
|
Object.defineProperty(this, _imageNameTag, {
|
|
27
27
|
writable: true,
|
|
28
28
|
value: null
|
|
29
29
|
});
|
|
30
30
|
_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag] = imageNameTag;
|
|
31
|
+
|
|
32
|
+
if (v3Utils) {
|
|
33
|
+
this.log = v3Utils.log;
|
|
34
|
+
this.progress = v3Utils.progress;
|
|
35
|
+
this.writeText = v3Utils.writeText;
|
|
36
|
+
this.v3Utils = v3Utils;
|
|
37
|
+
}
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
static async _pullImage(imageNameTag) {
|
|
34
|
-
(
|
|
41
|
+
if (this.log) {
|
|
42
|
+
this.log.debug(`Downloading base Docker image... (${imageNameTag})`);
|
|
43
|
+
} else {
|
|
44
|
+
(0, _debugLog.default)(`Downloading base Docker image... (${imageNameTag})`);
|
|
45
|
+
}
|
|
35
46
|
|
|
36
47
|
try {
|
|
37
48
|
await (0, _execa.default)('docker', ['pull', '--disable-content-trust=false', imageNameTag]);
|
|
38
49
|
} catch (err) {
|
|
39
|
-
|
|
50
|
+
if (this.log) {
|
|
51
|
+
this.log.error(err.stderr);
|
|
52
|
+
} else {
|
|
53
|
+
console.error(err.stderr);
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
throw err;
|
|
41
57
|
}
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
async pull() {
|
|
45
|
-
return DockerImage._memoizedPull(_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag]);
|
|
61
|
+
return DockerImage._memoizedPull(_classPrivateFieldLooseBase(this, _imageNameTag)[_imageNameTag], this.v3Utils);
|
|
46
62
|
}
|
|
47
63
|
|
|
48
64
|
}
|
|
@@ -17,12 +17,12 @@ var id = 0;
|
|
|
17
17
|
|
|
18
18
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
19
19
|
|
|
20
|
-
var _codeDir = _classPrivateFieldLooseKey("codeDir");
|
|
20
|
+
var _codeDir = /*#__PURE__*/_classPrivateFieldLooseKey("codeDir");
|
|
21
21
|
|
|
22
|
-
var _container = _classPrivateFieldLooseKey("container");
|
|
22
|
+
var _container = /*#__PURE__*/_classPrivateFieldLooseKey("container");
|
|
23
23
|
|
|
24
24
|
class DockerRunner {
|
|
25
|
-
constructor(funOptions, env, dockerOptions) {
|
|
25
|
+
constructor(funOptions, env, dockerOptions, v3Utils) {
|
|
26
26
|
Object.defineProperty(this, _codeDir, {
|
|
27
27
|
writable: true,
|
|
28
28
|
value: null
|
|
@@ -46,7 +46,7 @@ class DockerRunner {
|
|
|
46
46
|
_classPrivateFieldLooseBase(this, _codeDir)[_codeDir] = _classPrivateFieldLooseBase(this, _codeDir)[_codeDir].replace(servicePath, dockerOptions.hostServicePath);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
_classPrivateFieldLooseBase(this, _container)[_container] = new _DockerContainer.default(env, functionKey, handler, runtime, layers, provider, servicePath, dockerOptions);
|
|
49
|
+
_classPrivateFieldLooseBase(this, _container)[_container] = new _DockerContainer.default(env, functionKey, handler, runtime, layers, provider, servicePath, dockerOptions, v3Utils);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
cleanup() {
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _os = require("os");
|
|
9
|
+
|
|
10
|
+
var _fs = require("fs");
|
|
11
|
+
|
|
12
|
+
var _path = require("path");
|
|
13
|
+
|
|
14
|
+
var _execa = _interopRequireWildcard(require("execa"));
|
|
15
|
+
|
|
16
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
+
|
|
18
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
+
|
|
20
|
+
function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|
21
|
+
|
|
22
|
+
var id = 0;
|
|
23
|
+
|
|
24
|
+
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
writeFile,
|
|
28
|
+
readFile,
|
|
29
|
+
mkdir,
|
|
30
|
+
rmdir
|
|
31
|
+
} = _fs.promises;
|
|
32
|
+
const {
|
|
33
|
+
parse,
|
|
34
|
+
stringify
|
|
35
|
+
} = JSON;
|
|
36
|
+
const {
|
|
37
|
+
cwd
|
|
38
|
+
} = process;
|
|
39
|
+
const PAYLOAD_IDENTIFIER = 'offline_payload';
|
|
40
|
+
|
|
41
|
+
var _env = /*#__PURE__*/_classPrivateFieldLooseKey("env");
|
|
42
|
+
|
|
43
|
+
var _handlerPath = /*#__PURE__*/_classPrivateFieldLooseKey("handlerPath");
|
|
44
|
+
|
|
45
|
+
var _tmpPath = /*#__PURE__*/_classPrivateFieldLooseKey("tmpPath");
|
|
46
|
+
|
|
47
|
+
var _tmpFile = /*#__PURE__*/_classPrivateFieldLooseKey("tmpFile");
|
|
48
|
+
|
|
49
|
+
var _goEnv = /*#__PURE__*/_classPrivateFieldLooseKey("goEnv");
|
|
50
|
+
|
|
51
|
+
class GoRunner {
|
|
52
|
+
constructor(funOptions, env, v3Utils) {
|
|
53
|
+
Object.defineProperty(this, _env, {
|
|
54
|
+
writable: true,
|
|
55
|
+
value: null
|
|
56
|
+
});
|
|
57
|
+
Object.defineProperty(this, _handlerPath, {
|
|
58
|
+
writable: true,
|
|
59
|
+
value: null
|
|
60
|
+
});
|
|
61
|
+
Object.defineProperty(this, _tmpPath, {
|
|
62
|
+
writable: true,
|
|
63
|
+
value: null
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(this, _tmpFile, {
|
|
66
|
+
writable: true,
|
|
67
|
+
value: null
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(this, _goEnv, {
|
|
70
|
+
writable: true,
|
|
71
|
+
value: null
|
|
72
|
+
});
|
|
73
|
+
const {
|
|
74
|
+
handlerPath
|
|
75
|
+
} = funOptions;
|
|
76
|
+
_classPrivateFieldLooseBase(this, _env)[_env] = env;
|
|
77
|
+
_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath] = handlerPath;
|
|
78
|
+
|
|
79
|
+
if (v3Utils) {
|
|
80
|
+
this.log = v3Utils.log;
|
|
81
|
+
this.progress = v3Utils.progress;
|
|
82
|
+
this.writeText = v3Utils.writeText;
|
|
83
|
+
this.v3Utils = v3Utils;
|
|
84
|
+
} // Make sure we have the mock-lambda runner
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
(0, _execa.sync)('go', ['get', 'github.com/icarus-sullivan/mock-lambda@e065469']);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async cleanup() {
|
|
91
|
+
try {
|
|
92
|
+
await rmdir(_classPrivateFieldLooseBase(this, _tmpPath)[_tmpPath], {
|
|
93
|
+
recursive: true
|
|
94
|
+
});
|
|
95
|
+
} catch (e) {// @ignore
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
_classPrivateFieldLooseBase(this, _tmpFile)[_tmpFile] = null;
|
|
99
|
+
_classPrivateFieldLooseBase(this, _tmpPath)[_tmpPath] = null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_parsePayload(value) {
|
|
103
|
+
const log = [];
|
|
104
|
+
let payload;
|
|
105
|
+
|
|
106
|
+
for (const item of value.split(_os.EOL)) {
|
|
107
|
+
if (item.indexOf(PAYLOAD_IDENTIFIER) === -1) {
|
|
108
|
+
log.push(item);
|
|
109
|
+
} else if (item.indexOf(PAYLOAD_IDENTIFIER) !== -1) {
|
|
110
|
+
try {
|
|
111
|
+
const {
|
|
112
|
+
offline_payload: {
|
|
113
|
+
success,
|
|
114
|
+
error
|
|
115
|
+
}
|
|
116
|
+
} = parse(item);
|
|
117
|
+
|
|
118
|
+
if (success) {
|
|
119
|
+
payload = success;
|
|
120
|
+
} else if (error) {
|
|
121
|
+
payload = error;
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {// @ignore
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} // Log to console in case engineers want to see the rest of the info
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
if (this.log) {
|
|
130
|
+
this.log(log.join(_os.EOL));
|
|
131
|
+
} else {
|
|
132
|
+
console.log(log.join(_os.EOL));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return payload;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async run(event, context) {
|
|
139
|
+
const {
|
|
140
|
+
dir
|
|
141
|
+
} = (0, _path.parse)(_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath]);
|
|
142
|
+
const handlerCodeRoot = dir.split(_path.sep).slice(0, -1).join(_path.sep);
|
|
143
|
+
const handlerCode = await readFile(`${_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath]}.go`, 'utf8');
|
|
144
|
+
_classPrivateFieldLooseBase(this, _tmpPath)[_tmpPath] = (0, _path.resolve)(handlerCodeRoot, 'tmp');
|
|
145
|
+
_classPrivateFieldLooseBase(this, _tmpFile)[_tmpFile] = (0, _path.resolve)(_classPrivateFieldLooseBase(this, _tmpPath)[_tmpPath], 'main.go');
|
|
146
|
+
const out = handlerCode.replace('"github.com/aws/aws-lambda-go/lambda"', 'lambda "github.com/icarus-sullivan/mock-lambda"');
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
await mkdir(_classPrivateFieldLooseBase(this, _tmpPath)[_tmpPath], {
|
|
150
|
+
recursive: true
|
|
151
|
+
});
|
|
152
|
+
} catch (e) {// @ignore
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
await writeFile(_classPrivateFieldLooseBase(this, _tmpFile)[_tmpFile], out, 'utf8');
|
|
157
|
+
} catch (e) {// @ignore
|
|
158
|
+
} // Get go env to run this locally
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if (!_classPrivateFieldLooseBase(this, _goEnv)[_goEnv]) {
|
|
162
|
+
const goEnvResponse = await (0, _execa.default)('go', ['env'], {
|
|
163
|
+
stdio: 'pipe',
|
|
164
|
+
encoding: 'utf-8'
|
|
165
|
+
});
|
|
166
|
+
const goEnvString = goEnvResponse.stdout || goEnvResponse.stderr;
|
|
167
|
+
_classPrivateFieldLooseBase(this, _goEnv)[_goEnv] = goEnvString.split(_os.EOL).reduce((a, b) => {
|
|
168
|
+
const [k, v] = b.split('="'); // eslint-disable-next-line no-param-reassign
|
|
169
|
+
|
|
170
|
+
a[k] = v ? v.slice(0, -1) : '';
|
|
171
|
+
return a;
|
|
172
|
+
}, {});
|
|
173
|
+
} // Remove our root, since we want to invoke go relatively
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
const cwdPath = `${_classPrivateFieldLooseBase(this, _tmpFile)[_tmpFile]}`.replace(`${cwd()}${_path.sep}`, '');
|
|
177
|
+
const {
|
|
178
|
+
stdout,
|
|
179
|
+
stderr
|
|
180
|
+
} = await (0, _execa.default)(`go`, ['run', cwdPath], {
|
|
181
|
+
stdio: 'pipe',
|
|
182
|
+
env: { ..._classPrivateFieldLooseBase(this, _env)[_env],
|
|
183
|
+
..._classPrivateFieldLooseBase(this, _goEnv)[_goEnv],
|
|
184
|
+
AWS_LAMBDA_LOG_GROUP_NAME: context.logGroupName,
|
|
185
|
+
AWS_LAMBDA_LOG_STREAM_NAME: context.logStreamName,
|
|
186
|
+
AWS_LAMBDA_FUNCTION_NAME: context.functionName,
|
|
187
|
+
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: context.memoryLimitInMB,
|
|
188
|
+
AWS_LAMBDA_FUNCTION_VERSION: context.functionVersion,
|
|
189
|
+
LAMBDA_EVENT: stringify(event),
|
|
190
|
+
LAMBDA_TEST_EVENT: `${event}`,
|
|
191
|
+
LAMBDA_CONTEXT: stringify(context),
|
|
192
|
+
IS_LAMBDA_AUTHORIZER: event.type === 'REQUEST' || event.type === 'TOKEN',
|
|
193
|
+
IS_LAMBDA_REQUEST_AUTHORIZER: event.type === 'REQUEST',
|
|
194
|
+
IS_LAMBDA_TOKEN_AUTHORIZER: event.type === 'TOKEN',
|
|
195
|
+
PATH: process.env.PATH
|
|
196
|
+
},
|
|
197
|
+
encoding: 'utf-8'
|
|
198
|
+
}); // Clean up after we created the temporary file
|
|
199
|
+
|
|
200
|
+
await this.cleanup();
|
|
201
|
+
|
|
202
|
+
if (stderr) {
|
|
203
|
+
return stderr;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return this._parsePayload(stdout);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
exports.default = GoRunner;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "default", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _GoRunner.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
var _GoRunner = _interopRequireDefault(require("./GoRunner.js"));
|
|
14
|
+
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|