serverless-offline 8.8.0 → 9.1.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.
Files changed (233) hide show
  1. package/README.md +12 -11
  2. package/package.json +33 -58
  3. package/src/ServerlessOffline.js +409 -0
  4. package/src/config/commandOptions.js +159 -0
  5. package/src/config/constants.js +22 -0
  6. package/{dist → src}/config/defaultOptions.js +9 -17
  7. package/src/config/index.js +4 -0
  8. package/src/config/supportedRuntimes.js +47 -0
  9. package/src/events/authCanExecuteResource.js +35 -0
  10. package/src/events/authFunctionNameExtractor.js +75 -0
  11. package/src/events/authMatchPolicyResource.js +71 -0
  12. package/src/events/authValidateContext.js +51 -0
  13. package/src/events/http/Endpoint.js +135 -0
  14. package/src/events/http/Http.js +50 -0
  15. package/src/events/http/HttpEventDefinition.js +20 -0
  16. package/src/events/http/HttpServer.js +1242 -0
  17. package/src/events/http/OfflineEndpoint.js +33 -0
  18. package/src/events/http/authJWTSettingsExtractor.js +70 -0
  19. package/src/events/http/createAuthScheme.js +176 -0
  20. package/src/events/http/createJWTAuthScheme.js +106 -0
  21. package/src/events/http/index.js +1 -0
  22. package/src/events/http/javaHelpers.js +102 -0
  23. package/src/events/http/lambda-events/LambdaIntegrationEvent.js +57 -0
  24. package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +233 -0
  25. package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +190 -0
  26. package/src/events/http/lambda-events/VelocityContext.js +147 -0
  27. package/src/events/http/lambda-events/index.js +4 -0
  28. package/src/events/http/lambda-events/renderVelocityTemplateObject.js +93 -0
  29. package/{dist → src}/events/http/parseResources.js +73 -78
  30. package/src/events/http/payloadSchemaValidator.js +13 -0
  31. package/{dist → src}/events/http/templates/offline-default.req.vm +0 -0
  32. package/{dist → src}/events/http/templates/offline-default.res.vm +0 -0
  33. package/src/events/schedule/Schedule.js +131 -0
  34. package/src/events/schedule/ScheduleEvent.js +18 -0
  35. package/src/events/schedule/ScheduleEventDefinition.js +21 -0
  36. package/src/events/schedule/index.js +1 -0
  37. package/src/events/websocket/HttpServer.js +69 -0
  38. package/src/events/websocket/WebSocket.js +52 -0
  39. package/src/events/websocket/WebSocketClients.js +462 -0
  40. package/src/events/websocket/WebSocketEventDefinition.js +18 -0
  41. package/src/events/websocket/WebSocketServer.js +73 -0
  42. package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +16 -0
  43. package/src/events/websocket/http-routes/_catchAll/index.js +1 -0
  44. package/src/events/websocket/http-routes/connections/ConnectionsController.js +28 -0
  45. package/src/events/websocket/http-routes/connections/connectionsRoutes.js +70 -0
  46. package/src/events/websocket/http-routes/connections/index.js +1 -0
  47. package/src/events/websocket/http-routes/index.js +2 -0
  48. package/src/events/websocket/index.js +1 -0
  49. package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +65 -0
  50. package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +68 -0
  51. package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +31 -0
  52. package/src/events/websocket/lambda-events/WebSocketEvent.js +29 -0
  53. package/src/events/websocket/lambda-events/WebSocketRequestContext.js +67 -0
  54. package/src/events/websocket/lambda-events/index.js +4 -0
  55. package/src/index.js +12 -0
  56. package/src/lambda/HttpServer.js +108 -0
  57. package/src/lambda/Lambda.js +68 -0
  58. package/src/lambda/LambdaContext.js +33 -0
  59. package/src/lambda/LambdaFunction.js +309 -0
  60. package/src/lambda/LambdaFunctionPool.js +109 -0
  61. package/src/lambda/__tests__/LambdaContext.test.js +30 -0
  62. package/src/lambda/__tests__/LambdaFunction.test.js +196 -0
  63. package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsJSONObject.fixture.js +47 -0
  64. package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsNativeString.fixture.js +46 -0
  65. package/src/lambda/__tests__/fixtures/Lambda/package.json +3 -0
  66. package/src/lambda/__tests__/fixtures/lambdaFunction.fixture.js +145 -0
  67. package/src/lambda/__tests__/fixtures/package.json +3 -0
  68. package/src/lambda/__tests__/routes/invocations/InvocationsController.test.js +42 -0
  69. package/src/lambda/handler-runner/HandlerRunner.js +136 -0
  70. package/src/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +72 -0
  71. package/src/lambda/handler-runner/child-process-runner/childProcessHelper.js +42 -0
  72. package/src/lambda/handler-runner/child-process-runner/index.js +1 -0
  73. package/src/lambda/handler-runner/docker-runner/DockerContainer.js +417 -0
  74. package/src/lambda/handler-runner/docker-runner/DockerImage.js +35 -0
  75. package/src/lambda/handler-runner/docker-runner/DockerRunner.js +63 -0
  76. package/src/lambda/handler-runner/docker-runner/index.js +1 -0
  77. package/src/lambda/handler-runner/go-runner/GoRunner.js +167 -0
  78. package/src/lambda/handler-runner/go-runner/index.js +1 -0
  79. package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +125 -0
  80. package/src/lambda/handler-runner/in-process-runner/index.js +1 -0
  81. package/src/lambda/handler-runner/index.js +1 -0
  82. package/src/lambda/handler-runner/java-runner/JavaRunner.js +114 -0
  83. package/src/lambda/handler-runner/java-runner/index.js +1 -0
  84. package/src/lambda/handler-runner/python-runner/PythonRunner.js +138 -0
  85. package/src/lambda/handler-runner/python-runner/index.js +1 -0
  86. package/{dist → src}/lambda/handler-runner/python-runner/invoke.py +0 -0
  87. package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +107 -0
  88. package/src/lambda/handler-runner/ruby-runner/index.js +1 -0
  89. package/{dist → src}/lambda/handler-runner/ruby-runner/invoke.rb +0 -0
  90. package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +70 -0
  91. package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -0
  92. package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +29 -0
  93. package/src/lambda/index.js +1 -0
  94. package/src/lambda/routes/index.js +2 -0
  95. package/src/lambda/routes/invocations/InvocationsController.js +102 -0
  96. package/src/lambda/routes/invocations/index.js +1 -0
  97. package/src/lambda/routes/invocations/invocationsRoute.js +77 -0
  98. package/src/lambda/routes/invoke-async/InvokeAsyncController.js +20 -0
  99. package/src/lambda/routes/invoke-async/index.js +1 -0
  100. package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +33 -0
  101. package/src/utils/__tests__/createUniqueId.test.js +18 -0
  102. package/src/utils/__tests__/formatToClfTime.test.js +14 -0
  103. package/src/utils/__tests__/generateHapiPath.test.js +46 -0
  104. package/src/utils/__tests__/lowerCaseKeys.test.js +30 -0
  105. package/src/utils/__tests__/parseHeaders.test.js +13 -0
  106. package/src/utils/__tests__/parseMultiValueHeaders.test.js +24 -0
  107. package/src/utils/__tests__/parseMultiValueQueryStringParameters.test.js +159 -0
  108. package/src/utils/__tests__/parseQueryStringParameters.test.js +15 -0
  109. package/src/utils/__tests__/splitHandlerPathAndName.test.js +54 -0
  110. package/src/utils/__tests__/unflatten.test.js +32 -0
  111. package/src/utils/checkDockerDaemon.js +19 -0
  112. package/src/utils/checkGoVersion.js +16 -0
  113. package/src/utils/createApiKey.js +5 -0
  114. package/src/utils/createUniqueId.js +5 -0
  115. package/src/utils/detectExecutable.js +11 -0
  116. package/{dist → src}/utils/formatToClfTime.js +6 -14
  117. package/src/utils/generateHapiPath.js +26 -0
  118. package/src/utils/getHttpApiCorsConfig.js +28 -0
  119. package/src/utils/index.js +42 -0
  120. package/src/utils/jsonPath.js +13 -0
  121. package/src/utils/logRoutes.js +64 -0
  122. package/src/utils/lowerCaseKeys.js +6 -0
  123. package/src/utils/parseHeaders.js +14 -0
  124. package/src/utils/parseMultiValueHeaders.js +27 -0
  125. package/src/utils/parseMultiValueQueryStringParameters.js +31 -0
  126. package/src/utils/parseQueryStringParameters.js +15 -0
  127. package/src/utils/splitHandlerPathAndName.js +31 -0
  128. package/src/utils/unflatten.js +11 -0
  129. package/dist/ServerlessOffline.js +0 -514
  130. package/dist/config/commandOptions.js +0 -149
  131. package/dist/config/constants.js +0 -30
  132. package/dist/config/index.js +0 -55
  133. package/dist/config/supportedRuntimes.js +0 -40
  134. package/dist/debugLog.js +0 -12
  135. package/dist/events/authCanExecuteResource.js +0 -35
  136. package/dist/events/authFunctionNameExtractor.js +0 -87
  137. package/dist/events/authMatchPolicyResource.js +0 -62
  138. package/dist/events/authValidateContext.js +0 -53
  139. package/dist/events/http/Endpoint.js +0 -173
  140. package/dist/events/http/Http.js +0 -77
  141. package/dist/events/http/HttpEventDefinition.js +0 -36
  142. package/dist/events/http/HttpServer.js +0 -1370
  143. package/dist/events/http/OfflineEndpoint.js +0 -38
  144. package/dist/events/http/authJWTSettingsExtractor.js +0 -76
  145. package/dist/events/http/createAuthScheme.js +0 -184
  146. package/dist/events/http/createJWTAuthScheme.js +0 -159
  147. package/dist/events/http/index.js +0 -15
  148. package/dist/events/http/javaHelpers.js +0 -99
  149. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +0 -87
  150. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +0 -246
  151. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +0 -225
  152. package/dist/events/http/lambda-events/VelocityContext.js +0 -170
  153. package/dist/events/http/lambda-events/index.js +0 -39
  154. package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +0 -111
  155. package/dist/events/http/payloadSchemaValidator.js +0 -13
  156. package/dist/events/schedule/Schedule.js +0 -183
  157. package/dist/events/schedule/ScheduleEvent.js +0 -27
  158. package/dist/events/schedule/ScheduleEventDefinition.js +0 -36
  159. package/dist/events/schedule/index.js +0 -15
  160. package/dist/events/websocket/HttpServer.js +0 -114
  161. package/dist/events/websocket/WebSocket.js +0 -78
  162. package/dist/events/websocket/WebSocketClients.js +0 -577
  163. package/dist/events/websocket/WebSocketEventDefinition.js +0 -32
  164. package/dist/events/websocket/WebSocketServer.js +0 -139
  165. package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +0 -33
  166. package/dist/events/websocket/http-routes/_catchAll/index.js +0 -15
  167. package/dist/events/websocket/http-routes/connections/ConnectionsController.js +0 -45
  168. package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +0 -95
  169. package/dist/events/websocket/http-routes/connections/index.js +0 -15
  170. package/dist/events/websocket/http-routes/index.js +0 -23
  171. package/dist/events/websocket/index.js +0 -15
  172. package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +0 -99
  173. package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +0 -101
  174. package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +0 -47
  175. package/dist/events/websocket/lambda-events/WebSocketEvent.js +0 -54
  176. package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +0 -98
  177. package/dist/events/websocket/lambda-events/index.js +0 -39
  178. package/dist/index.js +0 -15
  179. package/dist/lambda/HttpServer.js +0 -124
  180. package/dist/lambda/Lambda.js +0 -117
  181. package/dist/lambda/LambdaContext.js +0 -53
  182. package/dist/lambda/LambdaFunction.js +0 -390
  183. package/dist/lambda/LambdaFunctionPool.js +0 -127
  184. package/dist/lambda/handler-runner/HandlerRunner.js +0 -195
  185. package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +0 -124
  186. package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +0 -49
  187. package/dist/lambda/handler-runner/child-process-runner/index.js +0 -15
  188. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +0 -515
  189. package/dist/lambda/handler-runner/docker-runner/DockerImage.js +0 -67
  190. package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +0 -74
  191. package/dist/lambda/handler-runner/docker-runner/index.js +0 -15
  192. package/dist/lambda/handler-runner/go-runner/GoRunner.js +0 -230
  193. package/dist/lambda/handler-runner/go-runner/index.js +0 -15
  194. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +0 -228
  195. package/dist/lambda/handler-runner/in-process-runner/index.js +0 -15
  196. package/dist/lambda/handler-runner/index.js +0 -15
  197. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +0 -153
  198. package/dist/lambda/handler-runner/java-runner/index.js +0 -15
  199. package/dist/lambda/handler-runner/python-runner/PythonRunner.js +0 -185
  200. package/dist/lambda/handler-runner/python-runner/index.js +0 -15
  201. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -147
  202. package/dist/lambda/handler-runner/ruby-runner/index.js +0 -15
  203. package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +0 -92
  204. package/dist/lambda/handler-runner/worker-thread-runner/index.js +0 -15
  205. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +0 -31
  206. package/dist/lambda/index.js +0 -15
  207. package/dist/lambda/routes/index.js +0 -23
  208. package/dist/lambda/routes/invocations/InvocationsController.js +0 -142
  209. package/dist/lambda/routes/invocations/index.js +0 -15
  210. package/dist/lambda/routes/invocations/invocationsRoute.js +0 -90
  211. package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +0 -38
  212. package/dist/lambda/routes/invoke-async/index.js +0 -15
  213. package/dist/lambda/routes/invoke-async/invokeAsyncRoute.js +0 -43
  214. package/dist/main.js +0 -11
  215. package/dist/serverlessLog.js +0 -91
  216. package/dist/utils/checkDockerDaemon.js +0 -27
  217. package/dist/utils/checkGoVersion.js +0 -27
  218. package/dist/utils/createApiKey.js +0 -12
  219. package/dist/utils/createUniqueId.js +0 -14
  220. package/dist/utils/detectExecutable.js +0 -21
  221. package/dist/utils/generateHapiPath.js +0 -28
  222. package/dist/utils/getHttpApiCorsConfig.js +0 -40
  223. package/dist/utils/index.js +0 -165
  224. package/dist/utils/jsonPath.js +0 -21
  225. package/dist/utils/lowerCaseKeys.js +0 -14
  226. package/dist/utils/parseHeaders.js +0 -23
  227. package/dist/utils/parseMultiValueHeaders.js +0 -36
  228. package/dist/utils/parseMultiValueQueryStringParameters.js +0 -40
  229. package/dist/utils/parseQueryStringParameters.js +0 -26
  230. package/dist/utils/resolveJoins.js +0 -36
  231. package/dist/utils/satisfiesVersionRange.js +0 -20
  232. package/dist/utils/splitHandlerPathAndName.js +0 -37
  233. 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
+ }