serverless-offline 8.7.0 → 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 +91 -95
- package/package.json +41 -69
- 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/dist/ServerlessOffline.js +0 -507
- package/dist/checkEngine.js +0 -21
- 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 -10
- package/dist/events/authCanExecuteResource.js +0 -35
- package/dist/events/authFunctionNameExtractor.js +0 -87
- package/dist/events/authMatchPolicyResource.js +0 -62
- package/dist/events/http/Endpoint.js +0 -171
- package/dist/events/http/Http.js +0 -77
- package/dist/events/http/HttpEventDefinition.js +0 -36
- package/dist/events/http/HttpServer.js +0 -1363
- package/dist/events/http/OfflineEndpoint.js +0 -40
- package/dist/events/http/authJWTSettingsExtractor.js +0 -76
- package/dist/events/http/authValidateContext.js +0 -48
- package/dist/events/http/createAuthScheme.js +0 -184
- package/dist/events/http/createJWTAuthScheme.js +0 -155
- 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 -85
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +0 -244
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +0 -221
- package/dist/events/http/lambda-events/VelocityContext.js +0 -168
- package/dist/events/http/lambda-events/index.js +0 -39
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +0 -108
- package/dist/events/http/payloadSchemaValidator.js +0 -13
- package/dist/events/schedule/Schedule.js +0 -182
- 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 -112
- package/dist/events/websocket/WebSocket.js +0 -78
- package/dist/events/websocket/WebSocketClients.js +0 -550
- package/dist/events/websocket/WebSocketEventDefinition.js +0 -32
- package/dist/events/websocket/WebSocketServer.js +0 -140
- 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 -19
- package/dist/lambda/HttpServer.js +0 -122
- package/dist/lambda/Lambda.js +0 -113
- package/dist/lambda/LambdaContext.js +0 -53
- package/dist/lambda/LambdaFunction.js +0 -391
- package/dist/lambda/LambdaFunctionPool.js +0 -127
- package/dist/lambda/handler-runner/HandlerRunner.js +0 -223
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +0 -132
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +0 -40
- package/dist/lambda/handler-runner/child-process-runner/index.js +0 -15
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +0 -517
- 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 -211
- package/dist/lambda/handler-runner/go-runner/index.js +0 -15
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +0 -234
- 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 -151
- package/dist/lambda/handler-runner/java-runner/index.js +0 -15
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +0 -180
- package/dist/lambda/handler-runner/python-runner/index.js +0 -15
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -148
- package/dist/lambda/handler-runner/ruby-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +0 -94
- package/dist/lambda/handler-runner/worker-thread-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +0 -30
- 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 -44
- package/dist/utils/index.js +0 -158
- package/dist/utils/jsonPath.js +0 -21
- 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 -34
- package/dist/utils/satisfiesVersionRange.js +0 -20
- package/dist/utils/splitHandlerPathAndName.js +0 -41
- package/dist/utils/unflatten.js +0 -18
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import WebSocketRequestContext from './WebSocketRequestContext.js'
|
|
2
|
+
import {
|
|
3
|
+
parseHeaders,
|
|
4
|
+
parseMultiValueHeaders,
|
|
5
|
+
parseMultiValueQueryStringParameters,
|
|
6
|
+
parseQueryStringParameters,
|
|
7
|
+
} from '../../../utils/index.js'
|
|
8
|
+
|
|
9
|
+
export default class WebSocketAuthorizerEvent {
|
|
10
|
+
#connectionId = null
|
|
11
|
+
|
|
12
|
+
#httpsProtocol = null
|
|
13
|
+
|
|
14
|
+
#provider = null
|
|
15
|
+
|
|
16
|
+
#rawHeaders = null
|
|
17
|
+
|
|
18
|
+
#url = null
|
|
19
|
+
|
|
20
|
+
#websocketPort = null
|
|
21
|
+
|
|
22
|
+
constructor(connectionId, request, provider, options) {
|
|
23
|
+
const { httpsProtocol, websocketPort } = options
|
|
24
|
+
const { rawHeaders, url } = request
|
|
25
|
+
|
|
26
|
+
this.#connectionId = connectionId
|
|
27
|
+
this.#httpsProtocol = httpsProtocol
|
|
28
|
+
this.#rawHeaders = rawHeaders
|
|
29
|
+
this.#url = url
|
|
30
|
+
this.#websocketPort = websocketPort
|
|
31
|
+
this.#provider = provider
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
create() {
|
|
35
|
+
const headers = parseHeaders(this.#rawHeaders)
|
|
36
|
+
const multiValueHeaders = parseMultiValueHeaders(this.#rawHeaders)
|
|
37
|
+
const multiValueQueryStringParameters =
|
|
38
|
+
parseMultiValueQueryStringParameters(this.#url)
|
|
39
|
+
const queryStringParameters = parseQueryStringParameters(this.#url)
|
|
40
|
+
|
|
41
|
+
const requestContext = new WebSocketRequestContext(
|
|
42
|
+
'CONNECT',
|
|
43
|
+
'$connect',
|
|
44
|
+
this.#connectionId,
|
|
45
|
+
).create()
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
headers,
|
|
49
|
+
methodArn: `arn:aws:execute-api:${this.#provider.region}:${
|
|
50
|
+
requestContext.accountId
|
|
51
|
+
}:${requestContext.apiId}/${requestContext.stage}/${
|
|
52
|
+
requestContext.routeKey
|
|
53
|
+
}`,
|
|
54
|
+
multiValueHeaders,
|
|
55
|
+
// NOTE: multiValueQueryStringParameters and queryStringParameters
|
|
56
|
+
// properties are only defined if they have values
|
|
57
|
+
...(multiValueQueryStringParameters && {
|
|
58
|
+
multiValueQueryStringParameters,
|
|
59
|
+
}),
|
|
60
|
+
...(queryStringParameters && { queryStringParameters }),
|
|
61
|
+
requestContext,
|
|
62
|
+
type: 'REQUEST',
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import WebSocketRequestContext from './WebSocketRequestContext.js'
|
|
2
|
+
import {
|
|
3
|
+
parseHeaders,
|
|
4
|
+
parseMultiValueHeaders,
|
|
5
|
+
parseMultiValueQueryStringParameters,
|
|
6
|
+
parseQueryStringParameters,
|
|
7
|
+
} from '../../../utils/index.js'
|
|
8
|
+
|
|
9
|
+
export default class WebSocketConnectEvent {
|
|
10
|
+
#connectionId = null
|
|
11
|
+
|
|
12
|
+
#httpsProtocol = null
|
|
13
|
+
|
|
14
|
+
#rawHeaders = null
|
|
15
|
+
|
|
16
|
+
#url = null
|
|
17
|
+
|
|
18
|
+
#websocketPort = null
|
|
19
|
+
|
|
20
|
+
constructor(connectionId, request, options) {
|
|
21
|
+
const { httpsProtocol, websocketPort } = options
|
|
22
|
+
const { rawHeaders, url } = request
|
|
23
|
+
|
|
24
|
+
this.#connectionId = connectionId
|
|
25
|
+
this.#httpsProtocol = httpsProtocol
|
|
26
|
+
this.#rawHeaders = rawHeaders
|
|
27
|
+
this.#url = url
|
|
28
|
+
this.#websocketPort = websocketPort
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
create() {
|
|
32
|
+
// const headers = {
|
|
33
|
+
// Host: 'localhost',
|
|
34
|
+
// 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
|
|
35
|
+
// 'Sec-WebSocket-Key': createUniqueId(),
|
|
36
|
+
// 'Sec-WebSocket-Version': '13',
|
|
37
|
+
// 'X-Amzn-Trace-Id': `Root=${createUniqueId()}`,
|
|
38
|
+
// 'X-Forwarded-For': '127.0.0.1',
|
|
39
|
+
// 'X-Forwarded-Port': String(this.#websocketPort),
|
|
40
|
+
// 'X-Forwarded-Proto': `http${this.#httpsProtocol ? 's' : ''}`,
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
const headers = parseHeaders(this.#rawHeaders)
|
|
44
|
+
const multiValueHeaders = parseMultiValueHeaders(this.#rawHeaders)
|
|
45
|
+
const multiValueQueryStringParameters =
|
|
46
|
+
parseMultiValueQueryStringParameters(this.#url)
|
|
47
|
+
const queryStringParameters = parseQueryStringParameters(this.#url)
|
|
48
|
+
|
|
49
|
+
const requestContext = new WebSocketRequestContext(
|
|
50
|
+
'CONNECT',
|
|
51
|
+
'$connect',
|
|
52
|
+
this.#connectionId,
|
|
53
|
+
).create()
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
headers,
|
|
57
|
+
isBase64Encoded: false,
|
|
58
|
+
multiValueHeaders,
|
|
59
|
+
// NOTE: multiValueQueryStringParameters and queryStringParameters
|
|
60
|
+
// properties are only defined if they have values
|
|
61
|
+
...(multiValueQueryStringParameters && {
|
|
62
|
+
multiValueQueryStringParameters,
|
|
63
|
+
}),
|
|
64
|
+
...(queryStringParameters && { queryStringParameters }),
|
|
65
|
+
requestContext,
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import WebSocketRequestContext from './WebSocketRequestContext.js'
|
|
2
|
+
import { parseHeaders, parseMultiValueHeaders } from '../../../utils/index.js'
|
|
3
|
+
|
|
4
|
+
export default class WebSocketDisconnectEvent {
|
|
5
|
+
#connectionId = null
|
|
6
|
+
|
|
7
|
+
constructor(connectionId) {
|
|
8
|
+
this.#connectionId = connectionId
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
create() {
|
|
12
|
+
// TODO FIXME not sure where the headers come from
|
|
13
|
+
const rawHeaders = ['Host', 'localhost', 'x-api-key', '', 'x-restapi', '']
|
|
14
|
+
|
|
15
|
+
const headers = parseHeaders(rawHeaders)
|
|
16
|
+
const multiValueHeaders = parseMultiValueHeaders(rawHeaders)
|
|
17
|
+
|
|
18
|
+
const requestContext = new WebSocketRequestContext(
|
|
19
|
+
'DISCONNECT',
|
|
20
|
+
'$disconnect',
|
|
21
|
+
this.#connectionId,
|
|
22
|
+
).create()
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
headers,
|
|
26
|
+
isBase64Encoded: false,
|
|
27
|
+
multiValueHeaders,
|
|
28
|
+
requestContext,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import WebSocketRequestContext from './WebSocketRequestContext.js'
|
|
2
|
+
|
|
3
|
+
export default class WebSocketEvent {
|
|
4
|
+
#connectionId = null
|
|
5
|
+
|
|
6
|
+
#payload = null
|
|
7
|
+
|
|
8
|
+
#route = null
|
|
9
|
+
|
|
10
|
+
constructor(connectionId, route, payload) {
|
|
11
|
+
this.#connectionId = connectionId
|
|
12
|
+
this.#payload = payload
|
|
13
|
+
this.#route = route
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
create() {
|
|
17
|
+
const requestContext = new WebSocketRequestContext(
|
|
18
|
+
'MESSAGE',
|
|
19
|
+
this.#route,
|
|
20
|
+
this.#connectionId,
|
|
21
|
+
).create()
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
body: this.#payload,
|
|
25
|
+
isBase64Encoded: false,
|
|
26
|
+
requestContext,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createUniqueId, formatToClfTime } from '../../../utils/index.js'
|
|
2
|
+
|
|
3
|
+
const { now } = Date
|
|
4
|
+
|
|
5
|
+
const connectedAt = new Map()
|
|
6
|
+
|
|
7
|
+
export default class WebSocketRequestContext {
|
|
8
|
+
#connectedAt = null
|
|
9
|
+
|
|
10
|
+
#connectionId = null
|
|
11
|
+
|
|
12
|
+
#eventType = null
|
|
13
|
+
|
|
14
|
+
#route = null
|
|
15
|
+
|
|
16
|
+
constructor(eventType, route, connectionId) {
|
|
17
|
+
this.#connectionId = connectionId
|
|
18
|
+
this.#eventType = eventType
|
|
19
|
+
this.#route = route
|
|
20
|
+
|
|
21
|
+
if (eventType === 'CONNECT') {
|
|
22
|
+
connectedAt.set(connectionId, now())
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.#connectedAt = connectedAt.get(connectionId)
|
|
26
|
+
|
|
27
|
+
if (eventType === 'DISCONNECT') {
|
|
28
|
+
connectedAt.delete(connectionId)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
create() {
|
|
33
|
+
const timeEpoch = now()
|
|
34
|
+
|
|
35
|
+
const requestContext = {
|
|
36
|
+
apiId: 'private',
|
|
37
|
+
connectedAt: this.#connectedAt,
|
|
38
|
+
connectionId: this.#connectionId,
|
|
39
|
+
domainName: 'localhost',
|
|
40
|
+
eventType: this.#eventType,
|
|
41
|
+
extendedRequestId: createUniqueId(),
|
|
42
|
+
identity: {
|
|
43
|
+
accessKey: null,
|
|
44
|
+
accountId: null,
|
|
45
|
+
caller: null,
|
|
46
|
+
cognitoAuthenticationProvider: null,
|
|
47
|
+
cognitoAuthenticationType: null,
|
|
48
|
+
cognitoIdentityId: null,
|
|
49
|
+
cognitoIdentityPoolId: null,
|
|
50
|
+
principalOrgId: null,
|
|
51
|
+
sourceIp: '127.0.0.1',
|
|
52
|
+
user: null,
|
|
53
|
+
userAgent: null,
|
|
54
|
+
userArn: null,
|
|
55
|
+
},
|
|
56
|
+
messageDirection: 'IN',
|
|
57
|
+
messageId: createUniqueId(),
|
|
58
|
+
requestId: createUniqueId(),
|
|
59
|
+
requestTime: formatToClfTime(timeEpoch),
|
|
60
|
+
requestTimeEpoch: timeEpoch,
|
|
61
|
+
routeKey: this.#route,
|
|
62
|
+
stage: 'local',
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return requestContext
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as WebSocketConnectEvent } from './WebSocketConnectEvent.js'
|
|
2
|
+
export { default as WebSocketDisconnectEvent } from './WebSocketDisconnectEvent.js'
|
|
3
|
+
export { default as WebSocketEvent } from './WebSocketEvent.js'
|
|
4
|
+
export { default as WebSocketAuthorizerEvent } from './WebSocketAuthorizerEvent.js'
|
package/src/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// TODO remove with node.js v16.9+ support
|
|
2
|
+
import 'object.hasown/auto'
|
|
3
|
+
|
|
4
|
+
// install global fetch
|
|
5
|
+
// TODO remove `node-fetch` module and use global built-in with node.js v18+ support
|
|
6
|
+
if (globalThis.fetch === undefined) {
|
|
7
|
+
const { default: fetch, Headers } = await import('node-fetch')
|
|
8
|
+
globalThis.fetch = fetch
|
|
9
|
+
globalThis.Headers = Headers
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { default } from './ServerlessOffline.js'
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { exit } from 'node:process'
|
|
2
|
+
import { Server } from '@hapi/hapi'
|
|
3
|
+
import { log } from '@serverless/utils/log.js'
|
|
4
|
+
import { invocationsRoute, invokeAsyncRoute } from './routes/index.js'
|
|
5
|
+
|
|
6
|
+
export default class HttpServer {
|
|
7
|
+
#lambda = null
|
|
8
|
+
|
|
9
|
+
#options = null
|
|
10
|
+
|
|
11
|
+
#server = null
|
|
12
|
+
|
|
13
|
+
constructor(options, lambda) {
|
|
14
|
+
this.#lambda = lambda
|
|
15
|
+
this.#options = options
|
|
16
|
+
|
|
17
|
+
const { host, lambdaPort } = options
|
|
18
|
+
|
|
19
|
+
const serverOptions = {
|
|
20
|
+
host,
|
|
21
|
+
port: lambdaPort,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.#server = new Server(serverOptions)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async start() {
|
|
28
|
+
// add routes
|
|
29
|
+
const invRoute = invocationsRoute(this.#lambda, this.#options)
|
|
30
|
+
const invAsyncRoute = invokeAsyncRoute(this.#lambda, this.#options)
|
|
31
|
+
|
|
32
|
+
this.#server.route([invAsyncRoute, invRoute])
|
|
33
|
+
|
|
34
|
+
const { host, httpsProtocol, lambdaPort } = this.#options
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
await this.#server.start()
|
|
38
|
+
} catch (err) {
|
|
39
|
+
log.error(
|
|
40
|
+
`Unexpected error while starting serverless-offline lambda server on port ${lambdaPort}:`,
|
|
41
|
+
err,
|
|
42
|
+
)
|
|
43
|
+
exit(1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
log.notice(
|
|
47
|
+
`Offline [http for lambda] listening on http${
|
|
48
|
+
httpsProtocol ? 's' : ''
|
|
49
|
+
}://${host}:${lambdaPort}`,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
// Print all the invocation routes to debug
|
|
53
|
+
const basePath = `http${httpsProtocol ? 's' : ''}://${host}:${lambdaPort}`
|
|
54
|
+
const funcNamePairs = this.#lambda.listFunctionNamePairs()
|
|
55
|
+
|
|
56
|
+
log.notice(
|
|
57
|
+
[
|
|
58
|
+
`Function names exposed for local invocation by aws-sdk:`,
|
|
59
|
+
...this.#lambda
|
|
60
|
+
.listFunctionNames()
|
|
61
|
+
.map(
|
|
62
|
+
(functionName) =>
|
|
63
|
+
` * ${funcNamePairs[functionName]}: ${functionName}`,
|
|
64
|
+
),
|
|
65
|
+
].join('\n'),
|
|
66
|
+
)
|
|
67
|
+
log.debug(
|
|
68
|
+
[
|
|
69
|
+
`Lambda Invocation Routes (for AWS SDK or AWS CLI):`,
|
|
70
|
+
...this.#lambda
|
|
71
|
+
.listFunctionNames()
|
|
72
|
+
.map(
|
|
73
|
+
(functionName) =>
|
|
74
|
+
` * ${
|
|
75
|
+
invRoute.method
|
|
76
|
+
} ${basePath}${invRoute.path.replace(
|
|
77
|
+
'{functionName}',
|
|
78
|
+
functionName,
|
|
79
|
+
)}`,
|
|
80
|
+
),
|
|
81
|
+
].join('\n'),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
log.debug(
|
|
85
|
+
[
|
|
86
|
+
`Lambda Async Invocation Routes (for AWS SDK or AWS CLI):`,
|
|
87
|
+
...this.#lambda
|
|
88
|
+
.listFunctionNames()
|
|
89
|
+
.map(
|
|
90
|
+
(functionName) =>
|
|
91
|
+
` * ${
|
|
92
|
+
invAsyncRoute.method
|
|
93
|
+
} ${basePath}${invAsyncRoute.path.replace(
|
|
94
|
+
'{functionName}',
|
|
95
|
+
functionName,
|
|
96
|
+
)}`,
|
|
97
|
+
),
|
|
98
|
+
].join('\n'),
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// stops the server
|
|
103
|
+
stop(timeout) {
|
|
104
|
+
return this.#server.stop({
|
|
105
|
+
timeout,
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import HttpServer from './HttpServer.js'
|
|
2
|
+
import LambdaFunctionPool from './LambdaFunctionPool.js'
|
|
3
|
+
|
|
4
|
+
const { assign } = Object
|
|
5
|
+
|
|
6
|
+
export default class Lambda {
|
|
7
|
+
#httpServer = null
|
|
8
|
+
|
|
9
|
+
#lambdas = new Map()
|
|
10
|
+
|
|
11
|
+
#lambdaFunctionNamesKeys = new Map()
|
|
12
|
+
|
|
13
|
+
#lambdaFunctionPool = null
|
|
14
|
+
|
|
15
|
+
constructor(serverless, options) {
|
|
16
|
+
this.#httpServer = new HttpServer(options, this)
|
|
17
|
+
this.#lambdaFunctionPool = new LambdaFunctionPool(serverless, options)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#createEvent(functionKey, functionDefinition) {
|
|
21
|
+
this.#lambdas.set(functionKey, functionDefinition)
|
|
22
|
+
this.#lambdaFunctionNamesKeys.set(functionDefinition.name, functionKey)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
create(lambdas) {
|
|
26
|
+
lambdas.forEach(({ functionKey, functionDefinition }) => {
|
|
27
|
+
this.#createEvent(functionKey, functionDefinition)
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get(functionKey) {
|
|
32
|
+
const functionDefinition = this.#lambdas.get(functionKey)
|
|
33
|
+
return this.#lambdaFunctionPool.get(functionKey, functionDefinition)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getByFunctionName(functionName) {
|
|
37
|
+
const functionKey = this.#lambdaFunctionNamesKeys.get(functionName)
|
|
38
|
+
return this.get(functionKey)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
listFunctionNames() {
|
|
42
|
+
const functionNames = Array.from(this.#lambdaFunctionNamesKeys.keys())
|
|
43
|
+
return functionNames
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
listFunctionNamePairs() {
|
|
47
|
+
const funcNamePairs = Array.from(this.#lambdaFunctionNamesKeys).reduce(
|
|
48
|
+
(obj, [key, value]) => assign(obj, { [key]: value }), // Be careful! Maps can have non-String keys; object literals can't.
|
|
49
|
+
{},
|
|
50
|
+
)
|
|
51
|
+
return funcNamePairs
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
start() {
|
|
55
|
+
this.#lambdaFunctionPool.start()
|
|
56
|
+
|
|
57
|
+
return this.#httpServer.start()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// stops the server
|
|
61
|
+
stop(timeout) {
|
|
62
|
+
return this.#httpServer.stop(timeout)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
cleanup() {
|
|
66
|
+
return this.#lambdaFunctionPool.cleanup()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// class for creating a LambdaContext
|
|
2
|
+
// http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
|
|
3
|
+
|
|
4
|
+
export default class LambdaContext {
|
|
5
|
+
#context = null
|
|
6
|
+
|
|
7
|
+
constructor(functionName, memorySize) {
|
|
8
|
+
this.#context = {
|
|
9
|
+
awsRequestId: undefined,
|
|
10
|
+
callbackWaitsForEmptyEventLoop: true,
|
|
11
|
+
clientContext: undefined,
|
|
12
|
+
functionName,
|
|
13
|
+
functionVersion: '$LATEST',
|
|
14
|
+
identity: undefined,
|
|
15
|
+
invokedFunctionArn: `offline_invokedFunctionArn_for_${functionName}`,
|
|
16
|
+
logGroupName: `offline_logGroupName_for_${functionName}`,
|
|
17
|
+
logStreamName: `offline_logStreamName_for_${functionName}`,
|
|
18
|
+
memoryLimitInMB: String(memorySize), // NOTE: string in AWS
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setClientContext(clientContext) {
|
|
23
|
+
this.#context.clientContext = clientContext
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setRequestId(requestId) {
|
|
27
|
+
this.#context.awsRequestId = requestId
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
create() {
|
|
31
|
+
return this.#context
|
|
32
|
+
}
|
|
33
|
+
}
|