serverless-offline 8.8.1 → 9.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/README.md +3 -3
- package/package.json +33 -57
- package/src/ServerlessOffline.js +412 -0
- package/src/config/commandOptions.js +155 -0
- package/src/config/constants.js +22 -0
- package/{dist → src}/config/defaultOptions.js +8 -17
- package/src/config/index.js +4 -0
- package/src/config/supportedRuntimes.js +47 -0
- package/src/events/authCanExecuteResource.js +35 -0
- package/src/events/authFunctionNameExtractor.js +75 -0
- package/src/events/authMatchPolicyResource.js +71 -0
- package/src/events/authValidateContext.js +51 -0
- package/src/events/http/Endpoint.js +135 -0
- package/src/events/http/Http.js +50 -0
- package/src/events/http/HttpEventDefinition.js +20 -0
- package/src/events/http/HttpServer.js +1277 -0
- package/src/events/http/OfflineEndpoint.js +33 -0
- package/src/events/http/authJWTSettingsExtractor.js +70 -0
- package/src/events/http/createAuthScheme.js +176 -0
- package/src/events/http/createJWTAuthScheme.js +106 -0
- package/src/events/http/index.js +1 -0
- package/src/events/http/javaHelpers.js +102 -0
- package/src/events/http/lambda-events/LambdaIntegrationEvent.js +57 -0
- package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +233 -0
- package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +190 -0
- package/src/events/http/lambda-events/VelocityContext.js +147 -0
- package/src/events/http/lambda-events/index.js +4 -0
- package/src/events/http/lambda-events/renderVelocityTemplateObject.js +93 -0
- package/{dist → src}/events/http/parseResources.js +73 -78
- package/src/events/http/payloadSchemaValidator.js +13 -0
- package/{dist → src}/events/http/templates/offline-default.req.vm +0 -0
- package/{dist → src}/events/http/templates/offline-default.res.vm +0 -0
- package/src/events/schedule/Schedule.js +131 -0
- package/src/events/schedule/ScheduleEvent.js +18 -0
- package/src/events/schedule/ScheduleEventDefinition.js +21 -0
- package/src/events/schedule/index.js +1 -0
- package/src/events/websocket/HttpServer.js +69 -0
- package/src/events/websocket/WebSocket.js +52 -0
- package/src/events/websocket/WebSocketClients.js +462 -0
- package/src/events/websocket/WebSocketEventDefinition.js +18 -0
- package/src/events/websocket/WebSocketServer.js +73 -0
- package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +16 -0
- package/src/events/websocket/http-routes/_catchAll/index.js +1 -0
- package/src/events/websocket/http-routes/connections/ConnectionsController.js +28 -0
- package/src/events/websocket/http-routes/connections/connectionsRoutes.js +70 -0
- package/src/events/websocket/http-routes/connections/index.js +1 -0
- package/src/events/websocket/http-routes/index.js +2 -0
- package/src/events/websocket/index.js +1 -0
- package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +65 -0
- package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +68 -0
- package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +31 -0
- package/src/events/websocket/lambda-events/WebSocketEvent.js +29 -0
- package/src/events/websocket/lambda-events/WebSocketRequestContext.js +67 -0
- package/src/events/websocket/lambda-events/index.js +4 -0
- package/src/index.js +12 -0
- package/src/lambda/HttpServer.js +108 -0
- package/src/lambda/Lambda.js +68 -0
- package/src/lambda/LambdaContext.js +33 -0
- package/src/lambda/LambdaFunction.js +308 -0
- package/src/lambda/LambdaFunctionPool.js +109 -0
- package/src/lambda/__tests__/LambdaContext.test.js +30 -0
- package/src/lambda/__tests__/LambdaFunction.test.js +196 -0
- package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsJSONObject.fixture.js +47 -0
- package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsNativeString.fixture.js +46 -0
- package/src/lambda/__tests__/fixtures/Lambda/package.json +3 -0
- package/src/lambda/__tests__/fixtures/lambdaFunction.fixture.js +145 -0
- package/src/lambda/__tests__/fixtures/package.json +3 -0
- package/src/lambda/__tests__/routes/invocations/InvocationsController.test.js +42 -0
- package/src/lambda/handler-runner/HandlerRunner.js +136 -0
- package/src/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +72 -0
- package/src/lambda/handler-runner/child-process-runner/childProcessHelper.js +42 -0
- package/src/lambda/handler-runner/child-process-runner/index.js +1 -0
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +417 -0
- package/src/lambda/handler-runner/docker-runner/DockerImage.js +35 -0
- package/src/lambda/handler-runner/docker-runner/DockerRunner.js +63 -0
- package/src/lambda/handler-runner/docker-runner/index.js +1 -0
- package/src/lambda/handler-runner/go-runner/GoRunner.js +166 -0
- package/src/lambda/handler-runner/go-runner/index.js +1 -0
- package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +125 -0
- package/src/lambda/handler-runner/in-process-runner/index.js +1 -0
- package/src/lambda/handler-runner/index.js +1 -0
- package/src/lambda/handler-runner/java-runner/JavaRunner.js +114 -0
- package/src/lambda/handler-runner/java-runner/index.js +1 -0
- package/src/lambda/handler-runner/python-runner/PythonRunner.js +138 -0
- package/src/lambda/handler-runner/python-runner/index.js +1 -0
- package/{dist → src}/lambda/handler-runner/python-runner/invoke.py +0 -0
- package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +107 -0
- package/src/lambda/handler-runner/ruby-runner/index.js +1 -0
- package/{dist → src}/lambda/handler-runner/ruby-runner/invoke.rb +0 -0
- package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +70 -0
- package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -0
- package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +29 -0
- package/src/lambda/index.js +1 -0
- package/src/lambda/routes/index.js +2 -0
- package/src/lambda/routes/invocations/InvocationsController.js +102 -0
- package/src/lambda/routes/invocations/index.js +1 -0
- package/src/lambda/routes/invocations/invocationsRoute.js +77 -0
- package/src/lambda/routes/invoke-async/InvokeAsyncController.js +20 -0
- package/src/lambda/routes/invoke-async/index.js +1 -0
- package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +33 -0
- package/src/utils/__tests__/createUniqueId.test.js +18 -0
- package/src/utils/__tests__/formatToClfTime.test.js +14 -0
- package/src/utils/__tests__/generateHapiPath.test.js +46 -0
- package/src/utils/__tests__/lowerCaseKeys.test.js +30 -0
- package/src/utils/__tests__/parseHeaders.test.js +13 -0
- package/src/utils/__tests__/parseMultiValueHeaders.test.js +24 -0
- package/src/utils/__tests__/parseMultiValueQueryStringParameters.test.js +159 -0
- package/src/utils/__tests__/parseQueryStringParameters.test.js +15 -0
- package/src/utils/__tests__/splitHandlerPathAndName.test.js +54 -0
- package/src/utils/__tests__/unflatten.test.js +32 -0
- package/src/utils/checkDockerDaemon.js +19 -0
- package/src/utils/checkGoVersion.js +16 -0
- package/src/utils/createApiKey.js +5 -0
- package/src/utils/createUniqueId.js +5 -0
- package/src/utils/detectExecutable.js +11 -0
- package/{dist → src}/utils/formatToClfTime.js +6 -14
- package/src/utils/generateHapiPath.js +26 -0
- package/src/utils/getHttpApiCorsConfig.js +28 -0
- package/src/utils/index.js +42 -0
- package/src/utils/jsonPath.js +13 -0
- package/src/utils/logRoutes.js +64 -0
- package/src/utils/lowerCaseKeys.js +6 -0
- package/src/utils/parseHeaders.js +14 -0
- package/src/utils/parseMultiValueHeaders.js +27 -0
- package/src/utils/parseMultiValueQueryStringParameters.js +31 -0
- package/src/utils/parseQueryStringParameters.js +15 -0
- package/src/utils/resolveJoins.js +29 -0
- package/src/utils/splitHandlerPathAndName.js +31 -0
- package/src/utils/unflatten.js +11 -0
- package/CHANGELOG.md +0 -78
- package/dist/ServerlessOffline.js +0 -508
- package/dist/config/commandOptions.js +0 -149
- package/dist/config/constants.js +0 -30
- package/dist/config/index.js +0 -55
- package/dist/config/supportedRuntimes.js +0 -40
- package/dist/debugLog.js +0 -12
- package/dist/events/authCanExecuteResource.js +0 -35
- package/dist/events/authFunctionNameExtractor.js +0 -87
- package/dist/events/authMatchPolicyResource.js +0 -62
- package/dist/events/authValidateContext.js +0 -53
- package/dist/events/http/Endpoint.js +0 -173
- package/dist/events/http/Http.js +0 -77
- package/dist/events/http/HttpEventDefinition.js +0 -36
- package/dist/events/http/HttpServer.js +0 -1370
- package/dist/events/http/OfflineEndpoint.js +0 -38
- package/dist/events/http/authJWTSettingsExtractor.js +0 -76
- package/dist/events/http/createAuthScheme.js +0 -184
- package/dist/events/http/createJWTAuthScheme.js +0 -159
- package/dist/events/http/index.js +0 -15
- package/dist/events/http/javaHelpers.js +0 -99
- package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +0 -87
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +0 -246
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +0 -225
- package/dist/events/http/lambda-events/VelocityContext.js +0 -170
- package/dist/events/http/lambda-events/index.js +0 -39
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +0 -111
- package/dist/events/http/payloadSchemaValidator.js +0 -13
- package/dist/events/schedule/Schedule.js +0 -183
- package/dist/events/schedule/ScheduleEvent.js +0 -27
- package/dist/events/schedule/ScheduleEventDefinition.js +0 -36
- package/dist/events/schedule/index.js +0 -15
- package/dist/events/websocket/HttpServer.js +0 -114
- package/dist/events/websocket/WebSocket.js +0 -78
- package/dist/events/websocket/WebSocketClients.js +0 -577
- package/dist/events/websocket/WebSocketEventDefinition.js +0 -32
- package/dist/events/websocket/WebSocketServer.js +0 -139
- package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +0 -33
- package/dist/events/websocket/http-routes/_catchAll/index.js +0 -15
- package/dist/events/websocket/http-routes/connections/ConnectionsController.js +0 -45
- package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +0 -95
- package/dist/events/websocket/http-routes/connections/index.js +0 -15
- package/dist/events/websocket/http-routes/index.js +0 -23
- package/dist/events/websocket/index.js +0 -15
- package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +0 -99
- package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +0 -101
- package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +0 -47
- package/dist/events/websocket/lambda-events/WebSocketEvent.js +0 -54
- package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +0 -98
- package/dist/events/websocket/lambda-events/index.js +0 -39
- package/dist/index.js +0 -15
- package/dist/lambda/HttpServer.js +0 -124
- package/dist/lambda/Lambda.js +0 -117
- package/dist/lambda/LambdaContext.js +0 -53
- package/dist/lambda/LambdaFunction.js +0 -390
- package/dist/lambda/LambdaFunctionPool.js +0 -127
- package/dist/lambda/handler-runner/HandlerRunner.js +0 -195
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +0 -124
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +0 -49
- package/dist/lambda/handler-runner/child-process-runner/index.js +0 -15
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +0 -515
- package/dist/lambda/handler-runner/docker-runner/DockerImage.js +0 -67
- package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +0 -74
- package/dist/lambda/handler-runner/docker-runner/index.js +0 -15
- package/dist/lambda/handler-runner/go-runner/GoRunner.js +0 -230
- package/dist/lambda/handler-runner/go-runner/index.js +0 -15
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +0 -228
- package/dist/lambda/handler-runner/in-process-runner/index.js +0 -15
- package/dist/lambda/handler-runner/index.js +0 -15
- package/dist/lambda/handler-runner/java-runner/JavaRunner.js +0 -153
- package/dist/lambda/handler-runner/java-runner/index.js +0 -15
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +0 -185
- package/dist/lambda/handler-runner/python-runner/index.js +0 -15
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -147
- package/dist/lambda/handler-runner/ruby-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +0 -92
- package/dist/lambda/handler-runner/worker-thread-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +0 -31
- package/dist/lambda/index.js +0 -15
- package/dist/lambda/routes/index.js +0 -23
- package/dist/lambda/routes/invocations/InvocationsController.js +0 -142
- package/dist/lambda/routes/invocations/index.js +0 -15
- package/dist/lambda/routes/invocations/invocationsRoute.js +0 -90
- package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +0 -38
- package/dist/lambda/routes/invoke-async/index.js +0 -15
- package/dist/lambda/routes/invoke-async/invokeAsyncRoute.js +0 -43
- package/dist/main.js +0 -11
- package/dist/serverlessLog.js +0 -91
- package/dist/utils/checkDockerDaemon.js +0 -27
- package/dist/utils/checkGoVersion.js +0 -27
- package/dist/utils/createApiKey.js +0 -12
- package/dist/utils/createUniqueId.js +0 -14
- package/dist/utils/detectExecutable.js +0 -21
- package/dist/utils/generateHapiPath.js +0 -28
- package/dist/utils/getHttpApiCorsConfig.js +0 -40
- package/dist/utils/index.js +0 -165
- package/dist/utils/jsonPath.js +0 -21
- package/dist/utils/lowerCaseKeys.js +0 -14
- package/dist/utils/parseHeaders.js +0 -23
- package/dist/utils/parseMultiValueHeaders.js +0 -36
- package/dist/utils/parseMultiValueQueryStringParameters.js +0 -40
- package/dist/utils/parseQueryStringParameters.js +0 -26
- package/dist/utils/resolveJoins.js +0 -36
- package/dist/utils/satisfiesVersionRange.js +0 -20
- package/dist/utils/splitHandlerPathAndName.js +0 -37
- package/dist/utils/unflatten.js +0 -18
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import LambdaFunction from '../../../LambdaFunction.js'
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
6
|
+
|
|
7
|
+
export default class LambdaFunctionThatReturnsNativeString {
|
|
8
|
+
#lambdaFunction
|
|
9
|
+
|
|
10
|
+
options = {}
|
|
11
|
+
|
|
12
|
+
serverless = {
|
|
13
|
+
config: {
|
|
14
|
+
serverlessPath: '',
|
|
15
|
+
servicePath: resolve(__dirname),
|
|
16
|
+
},
|
|
17
|
+
service: {
|
|
18
|
+
provider: {
|
|
19
|
+
runtime: 'nodejs12.x',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
listFunctionNames() {
|
|
25
|
+
return ['foo']
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getByFunctionName(functionName) {
|
|
29
|
+
const functionDefinition = {
|
|
30
|
+
handler: '../../fixtures/lambdaFunction.fixture.asyncFunctionHandler',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.#lambdaFunction = new LambdaFunction(
|
|
34
|
+
functionName,
|
|
35
|
+
functionDefinition,
|
|
36
|
+
this.serverless,
|
|
37
|
+
this.options,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return this.#lambdaFunction
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async cleanup() {
|
|
44
|
+
await this.#lambdaFunction.cleanup()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
exports.contextDoneHandler = function contextDoneHandler(event, context) {
|
|
4
|
+
context.done(null, 'foo')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
exports.contextDoneHandlerDeferred = function contextDoneHandlerDeferred(
|
|
8
|
+
event,
|
|
9
|
+
context,
|
|
10
|
+
) {
|
|
11
|
+
setTimeout(() => context.done(null, 'foo'), 100)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.contextSucceedHandler = function contextSucceedHandler(event, context) {
|
|
15
|
+
context.succeed('foo')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.contextSucceedHandlerDeferred = function contextSucceedHandlerDeferred(
|
|
19
|
+
event,
|
|
20
|
+
context,
|
|
21
|
+
) {
|
|
22
|
+
setTimeout(() => context.succeed('foo'), 100)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.callbackHandler = function callbackHandler(event, context, callback) {
|
|
26
|
+
callback(null, 'foo')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.callbackHandlerDeferred = function callbackHandlerDeferred(
|
|
30
|
+
event,
|
|
31
|
+
context,
|
|
32
|
+
callback,
|
|
33
|
+
) {
|
|
34
|
+
setTimeout(() => callback(null, 'foo'), 100)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.promiseHandler = function promiseHandler() {
|
|
38
|
+
return Promise.resolve('foo')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.promiseHandlerDeferred = function promiseDeferred() {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
setTimeout(() => resolve('foo'), 100)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
exports.asyncFunctionHandler = async function asyncFunctionHandler() {
|
|
48
|
+
return 'foo'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
exports.asyncFunctionHandlerObject = async function asyncFunctionHandler() {
|
|
52
|
+
return {
|
|
53
|
+
foo: 'bar',
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// we deliberately test the case where a 'callback' is defined
|
|
58
|
+
// in the handler, but a promise is being returned to protect from a
|
|
59
|
+
// potential naive implementation, e.g.
|
|
60
|
+
//
|
|
61
|
+
// const { promisify } = 'utils'
|
|
62
|
+
// const promisifiedHandler = handler.length === 3 ? promisify(handler) : handler
|
|
63
|
+
//
|
|
64
|
+
// if someone would return a promise, but also defines callback, without using it
|
|
65
|
+
// the handler would not be returning anything
|
|
66
|
+
exports.promiseWithDefinedCallbackHandler =
|
|
67
|
+
function promiseWithDefinedCallbackHandler(
|
|
68
|
+
event, // eslint-disable-line no-unused-vars
|
|
69
|
+
context, // eslint-disable-line no-unused-vars
|
|
70
|
+
callback, // eslint-disable-line no-unused-vars
|
|
71
|
+
) {
|
|
72
|
+
return Promise.resolve('Hello Promise!')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
exports.contextSucceedWithContextDoneHandler =
|
|
76
|
+
function contextSucceedWithContextDoneHandler(event, context) {
|
|
77
|
+
context.succeed('Hello Context.succeed!')
|
|
78
|
+
|
|
79
|
+
context.done(null, 'Hello Context.done!')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
exports.callbackWithContextDoneHandler =
|
|
83
|
+
function callbackWithContextDoneHandler(event, context, callback) {
|
|
84
|
+
callback(null, 'Hello Callback!')
|
|
85
|
+
|
|
86
|
+
context.done(null, 'Hello Context.done!')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
exports.callbackWithPromiseHandler = function callbackWithPromiseHandler(
|
|
90
|
+
event,
|
|
91
|
+
context,
|
|
92
|
+
callback,
|
|
93
|
+
) {
|
|
94
|
+
callback(null, 'Hello Callback!')
|
|
95
|
+
|
|
96
|
+
return Promise.resolve('Hello Promise!')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
exports.callbackInsidePromiseHandler = function callbackInsidePromiseHandler(
|
|
100
|
+
event,
|
|
101
|
+
context,
|
|
102
|
+
callback,
|
|
103
|
+
) {
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
callback(null, 'Hello Callback!')
|
|
106
|
+
|
|
107
|
+
resolve('Hello Promise!')
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
exports.requestIdHandler = async function requestIdHandler(event, context) {
|
|
112
|
+
return context.awsRequestId
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.remainingExecutionTimeHandler =
|
|
116
|
+
async function remainingExecutionTimeHandler(event, context) {
|
|
117
|
+
const first = context.getRemainingTimeInMillis()
|
|
118
|
+
|
|
119
|
+
await new Promise((resolve) => {
|
|
120
|
+
setTimeout(resolve, 100)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const second = context.getRemainingTimeInMillis()
|
|
124
|
+
|
|
125
|
+
await new Promise((resolve) => {
|
|
126
|
+
setTimeout(resolve, 200)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const third = context.getRemainingTimeInMillis()
|
|
130
|
+
|
|
131
|
+
return [first, second, third]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
exports.defaultTimeoutHandler = async function defaultTimeoutHandler(
|
|
135
|
+
event,
|
|
136
|
+
context,
|
|
137
|
+
) {
|
|
138
|
+
return context.getRemainingTimeInMillis()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
exports.executionTimeInMillisHandler = function executionTimeInMillisHandler() {
|
|
142
|
+
return new Promise((resolve) => {
|
|
143
|
+
setTimeout(resolve, 100)
|
|
144
|
+
})
|
|
145
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import InvocationsController from '../../../routes/invocations/InvocationsController.js'
|
|
3
|
+
import LambdaFunctionThatReturnsJSONObject from '../../fixtures/Lambda/LambdaFunctionThatReturnsJSONObject.fixture.js'
|
|
4
|
+
import LambdaFunctionThatReturnsNativeString from '../../fixtures/Lambda/LambdaFunctionThatReturnsNativeString.fixture.js'
|
|
5
|
+
|
|
6
|
+
describe('InvocationController', () => {
|
|
7
|
+
const functionName = 'foo'
|
|
8
|
+
|
|
9
|
+
describe('when event type is "RequestResponse"', () => {
|
|
10
|
+
const eventType = 'RequestResponse'
|
|
11
|
+
|
|
12
|
+
it('should return json object if lambda response is json', async () => {
|
|
13
|
+
const expected = {
|
|
14
|
+
Payload: {
|
|
15
|
+
foo: 'bar',
|
|
16
|
+
},
|
|
17
|
+
StatusCode: 200,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const lambdaFunction = new LambdaFunctionThatReturnsJSONObject()
|
|
21
|
+
const invocationController = new InvocationsController(lambdaFunction)
|
|
22
|
+
const result = await invocationController.invoke(functionName, eventType)
|
|
23
|
+
await lambdaFunction.cleanup()
|
|
24
|
+
|
|
25
|
+
assert.deepEqual(result, expected)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should wrap native string responses with ""', async () => {
|
|
29
|
+
const expected = {
|
|
30
|
+
Payload: '"foo"',
|
|
31
|
+
StatusCode: 200,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const lambdaFunction = new LambdaFunctionThatReturnsNativeString()
|
|
35
|
+
const invocationController = new InvocationsController(lambdaFunction)
|
|
36
|
+
const result = await invocationController.invoke(functionName, eventType)
|
|
37
|
+
await lambdaFunction.cleanup()
|
|
38
|
+
|
|
39
|
+
assert.deepEqual(result, expected)
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { log } from '@serverless/utils/log.js'
|
|
2
|
+
import {
|
|
3
|
+
supportedGo,
|
|
4
|
+
supportedJava,
|
|
5
|
+
supportedNodejs,
|
|
6
|
+
supportedPython,
|
|
7
|
+
supportedRuby,
|
|
8
|
+
} from '../../config/index.js'
|
|
9
|
+
|
|
10
|
+
export default class HandlerRunner {
|
|
11
|
+
#env = null
|
|
12
|
+
|
|
13
|
+
#funOptions = null
|
|
14
|
+
|
|
15
|
+
#options = null
|
|
16
|
+
|
|
17
|
+
#runner = null
|
|
18
|
+
|
|
19
|
+
constructor(funOptions, options, env) {
|
|
20
|
+
this.#env = env
|
|
21
|
+
this.#funOptions = funOptions
|
|
22
|
+
this.#options = options
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async #loadRunner() {
|
|
26
|
+
const { useChildProcesses, useDocker, useInProcess } = this.#options
|
|
27
|
+
|
|
28
|
+
const { functionKey, handlerName, handlerPath, runtime, timeout } =
|
|
29
|
+
this.#funOptions
|
|
30
|
+
|
|
31
|
+
log.debug(`Loading handler... (${handlerPath})`)
|
|
32
|
+
|
|
33
|
+
if (useDocker) {
|
|
34
|
+
// https://github.com/lambci/docker-lambda/issues/329
|
|
35
|
+
if (runtime === 'nodejs14.x') {
|
|
36
|
+
log.warning(
|
|
37
|
+
'"nodejs14.x" runtime is not supported with docker. See https://github.com/lambci/docker-lambda/issues/329',
|
|
38
|
+
)
|
|
39
|
+
throw new Error('Unsupported runtime')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (runtime === 'python3.9') {
|
|
43
|
+
log.warning('"python3.9" runtime is not supported with docker.')
|
|
44
|
+
throw new Error('Unsupported runtime')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const dockerOptions = {
|
|
48
|
+
host: this.#options.dockerHost,
|
|
49
|
+
hostServicePath: this.#options.dockerHostServicePath,
|
|
50
|
+
layersDir: this.#options.layersDir,
|
|
51
|
+
network: this.#options.dockerNetwork,
|
|
52
|
+
readOnly: this.#options.dockerReadOnly,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const { default: DockerRunner } = await import('./docker-runner/index.js')
|
|
56
|
+
|
|
57
|
+
return new DockerRunner(this.#funOptions, this.#env, dockerOptions)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (supportedNodejs.has(runtime)) {
|
|
61
|
+
if (useChildProcesses) {
|
|
62
|
+
const { default: ChildProcessRunner } = await import(
|
|
63
|
+
'./child-process-runner/index.js'
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return new ChildProcessRunner(this.#funOptions, this.#env)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (useInProcess) {
|
|
70
|
+
const { default: InProcessRunner } = await import(
|
|
71
|
+
'./in-process-runner/index.js'
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return new InProcessRunner(
|
|
75
|
+
functionKey,
|
|
76
|
+
handlerPath,
|
|
77
|
+
handlerName,
|
|
78
|
+
this.#env,
|
|
79
|
+
timeout,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { default: WorkerThreadRunner } = await import(
|
|
84
|
+
'./worker-thread-runner/index.js'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return new WorkerThreadRunner(this.#funOptions, this.#env)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (supportedGo.has(runtime)) {
|
|
91
|
+
const { default: GoRunner } = await import('./go-runner/index.js')
|
|
92
|
+
|
|
93
|
+
return new GoRunner(this.#funOptions, this.#env)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (supportedPython.has(runtime)) {
|
|
97
|
+
const { default: PythonRunner } = await import('./python-runner/index.js')
|
|
98
|
+
|
|
99
|
+
return new PythonRunner(this.#funOptions, this.#env)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (supportedRuby.has(runtime)) {
|
|
103
|
+
const { default: RubyRunner } = await import('./ruby-runner/index.js')
|
|
104
|
+
|
|
105
|
+
return new RubyRunner(this.#funOptions, this.#env)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (supportedJava.has(runtime)) {
|
|
109
|
+
const { default: JavaRunner } = await import('./java-runner/index.js')
|
|
110
|
+
|
|
111
|
+
return new JavaRunner(this.#funOptions, this.#env)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// TODO FIXME
|
|
115
|
+
throw new Error('Unsupported runtime')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// TEMP TODO FIXME
|
|
119
|
+
isDockerRunner() {
|
|
120
|
+
return this.#runner && this.#runner.constructor.name === 'DockerRunner'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// () => Promise<void>
|
|
124
|
+
cleanup() {
|
|
125
|
+
// TODO console.log('handler runner cleanup')
|
|
126
|
+
return this.#runner.cleanup()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async run(event, context) {
|
|
130
|
+
if (this.#runner == null) {
|
|
131
|
+
this.#runner = await this.#loadRunner()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return this.#runner.run(event, context)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { log } from '@serverless/utils/log.js'
|
|
4
|
+
import { execaNode } from 'execa'
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
const childProcessHelperPath = resolve(__dirname, 'childProcessHelper.js')
|
|
8
|
+
|
|
9
|
+
export default class ChildProcessRunner {
|
|
10
|
+
#env = null
|
|
11
|
+
|
|
12
|
+
#functionKey = null
|
|
13
|
+
|
|
14
|
+
#handlerName = null
|
|
15
|
+
|
|
16
|
+
#handlerPath = null
|
|
17
|
+
|
|
18
|
+
#timeout = null
|
|
19
|
+
|
|
20
|
+
constructor(funOptions, env) {
|
|
21
|
+
const { functionKey, handlerName, handlerPath, timeout } = funOptions
|
|
22
|
+
|
|
23
|
+
this.#env = env
|
|
24
|
+
this.#functionKey = functionKey
|
|
25
|
+
this.#handlerName = handlerName
|
|
26
|
+
this.#handlerPath = handlerPath
|
|
27
|
+
this.#timeout = timeout
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// no-op
|
|
31
|
+
// () => void
|
|
32
|
+
cleanup() {}
|
|
33
|
+
|
|
34
|
+
async run(event, context) {
|
|
35
|
+
const childProcess = execaNode(
|
|
36
|
+
childProcessHelperPath,
|
|
37
|
+
[this.#functionKey, this.#handlerName, this.#handlerPath],
|
|
38
|
+
{
|
|
39
|
+
env: this.#env,
|
|
40
|
+
stdio: 'inherit',
|
|
41
|
+
},
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
const message = new Promise((res, rej) => {
|
|
45
|
+
childProcess.on('message', (data) => {
|
|
46
|
+
if (data.error) rej(data.error)
|
|
47
|
+
else res(data)
|
|
48
|
+
})
|
|
49
|
+
}).finally(() => {
|
|
50
|
+
childProcess.kill()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
childProcess.send({
|
|
54
|
+
context,
|
|
55
|
+
event,
|
|
56
|
+
timeout: this.#timeout,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
let result
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
result = await message
|
|
63
|
+
} catch (err) {
|
|
64
|
+
// TODO
|
|
65
|
+
log.error(err)
|
|
66
|
+
|
|
67
|
+
throw err
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import process, { argv } from 'node:process'
|
|
2
|
+
import InProcessRunner from '../in-process-runner/index.js'
|
|
3
|
+
|
|
4
|
+
// TODO handle this:
|
|
5
|
+
process.on('uncaughtException', (err) => {
|
|
6
|
+
const {
|
|
7
|
+
constructor: { name },
|
|
8
|
+
message,
|
|
9
|
+
stack,
|
|
10
|
+
} = err
|
|
11
|
+
|
|
12
|
+
process.send({
|
|
13
|
+
// process.send() can't serialize an Error object, so we help it out a bit
|
|
14
|
+
error: {
|
|
15
|
+
constructor: {
|
|
16
|
+
name,
|
|
17
|
+
},
|
|
18
|
+
message,
|
|
19
|
+
stack,
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const [, , functionKey, handlerName, handlerPath] = argv
|
|
25
|
+
|
|
26
|
+
process.on('message', async (messageData) => {
|
|
27
|
+
const { context, event, timeout } = messageData
|
|
28
|
+
|
|
29
|
+
// TODO we could probably cache this in the module scope?
|
|
30
|
+
const inProcessRunner = new InProcessRunner(
|
|
31
|
+
functionKey,
|
|
32
|
+
handlerPath,
|
|
33
|
+
handlerName,
|
|
34
|
+
process.env,
|
|
35
|
+
timeout,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
const result = await inProcessRunner.run(event, context)
|
|
39
|
+
|
|
40
|
+
// TODO check serializeability (contains function, symbol etc)
|
|
41
|
+
process.send(result)
|
|
42
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './ChildProcessRunner.js'
|