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.
Files changed (235) hide show
  1. package/README.md +3 -3
  2. package/package.json +33 -57
  3. package/src/ServerlessOffline.js +412 -0
  4. package/src/config/commandOptions.js +155 -0
  5. package/src/config/constants.js +22 -0
  6. package/{dist → src}/config/defaultOptions.js +8 -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 +1277 -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 +308 -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 +166 -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/resolveJoins.js +29 -0
  128. package/src/utils/splitHandlerPathAndName.js +31 -0
  129. package/src/utils/unflatten.js +11 -0
  130. package/CHANGELOG.md +0 -78
  131. package/dist/ServerlessOffline.js +0 -508
  132. package/dist/config/commandOptions.js +0 -149
  133. package/dist/config/constants.js +0 -30
  134. package/dist/config/index.js +0 -55
  135. package/dist/config/supportedRuntimes.js +0 -40
  136. package/dist/debugLog.js +0 -12
  137. package/dist/events/authCanExecuteResource.js +0 -35
  138. package/dist/events/authFunctionNameExtractor.js +0 -87
  139. package/dist/events/authMatchPolicyResource.js +0 -62
  140. package/dist/events/authValidateContext.js +0 -53
  141. package/dist/events/http/Endpoint.js +0 -173
  142. package/dist/events/http/Http.js +0 -77
  143. package/dist/events/http/HttpEventDefinition.js +0 -36
  144. package/dist/events/http/HttpServer.js +0 -1370
  145. package/dist/events/http/OfflineEndpoint.js +0 -38
  146. package/dist/events/http/authJWTSettingsExtractor.js +0 -76
  147. package/dist/events/http/createAuthScheme.js +0 -184
  148. package/dist/events/http/createJWTAuthScheme.js +0 -159
  149. package/dist/events/http/index.js +0 -15
  150. package/dist/events/http/javaHelpers.js +0 -99
  151. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +0 -87
  152. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +0 -246
  153. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +0 -225
  154. package/dist/events/http/lambda-events/VelocityContext.js +0 -170
  155. package/dist/events/http/lambda-events/index.js +0 -39
  156. package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +0 -111
  157. package/dist/events/http/payloadSchemaValidator.js +0 -13
  158. package/dist/events/schedule/Schedule.js +0 -183
  159. package/dist/events/schedule/ScheduleEvent.js +0 -27
  160. package/dist/events/schedule/ScheduleEventDefinition.js +0 -36
  161. package/dist/events/schedule/index.js +0 -15
  162. package/dist/events/websocket/HttpServer.js +0 -114
  163. package/dist/events/websocket/WebSocket.js +0 -78
  164. package/dist/events/websocket/WebSocketClients.js +0 -577
  165. package/dist/events/websocket/WebSocketEventDefinition.js +0 -32
  166. package/dist/events/websocket/WebSocketServer.js +0 -139
  167. package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +0 -33
  168. package/dist/events/websocket/http-routes/_catchAll/index.js +0 -15
  169. package/dist/events/websocket/http-routes/connections/ConnectionsController.js +0 -45
  170. package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +0 -95
  171. package/dist/events/websocket/http-routes/connections/index.js +0 -15
  172. package/dist/events/websocket/http-routes/index.js +0 -23
  173. package/dist/events/websocket/index.js +0 -15
  174. package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +0 -99
  175. package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +0 -101
  176. package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +0 -47
  177. package/dist/events/websocket/lambda-events/WebSocketEvent.js +0 -54
  178. package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +0 -98
  179. package/dist/events/websocket/lambda-events/index.js +0 -39
  180. package/dist/index.js +0 -15
  181. package/dist/lambda/HttpServer.js +0 -124
  182. package/dist/lambda/Lambda.js +0 -117
  183. package/dist/lambda/LambdaContext.js +0 -53
  184. package/dist/lambda/LambdaFunction.js +0 -390
  185. package/dist/lambda/LambdaFunctionPool.js +0 -127
  186. package/dist/lambda/handler-runner/HandlerRunner.js +0 -195
  187. package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +0 -124
  188. package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +0 -49
  189. package/dist/lambda/handler-runner/child-process-runner/index.js +0 -15
  190. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +0 -515
  191. package/dist/lambda/handler-runner/docker-runner/DockerImage.js +0 -67
  192. package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +0 -74
  193. package/dist/lambda/handler-runner/docker-runner/index.js +0 -15
  194. package/dist/lambda/handler-runner/go-runner/GoRunner.js +0 -230
  195. package/dist/lambda/handler-runner/go-runner/index.js +0 -15
  196. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +0 -228
  197. package/dist/lambda/handler-runner/in-process-runner/index.js +0 -15
  198. package/dist/lambda/handler-runner/index.js +0 -15
  199. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +0 -153
  200. package/dist/lambda/handler-runner/java-runner/index.js +0 -15
  201. package/dist/lambda/handler-runner/python-runner/PythonRunner.js +0 -185
  202. package/dist/lambda/handler-runner/python-runner/index.js +0 -15
  203. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -147
  204. package/dist/lambda/handler-runner/ruby-runner/index.js +0 -15
  205. package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +0 -92
  206. package/dist/lambda/handler-runner/worker-thread-runner/index.js +0 -15
  207. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +0 -31
  208. package/dist/lambda/index.js +0 -15
  209. package/dist/lambda/routes/index.js +0 -23
  210. package/dist/lambda/routes/invocations/InvocationsController.js +0 -142
  211. package/dist/lambda/routes/invocations/index.js +0 -15
  212. package/dist/lambda/routes/invocations/invocationsRoute.js +0 -90
  213. package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +0 -38
  214. package/dist/lambda/routes/invoke-async/index.js +0 -15
  215. package/dist/lambda/routes/invoke-async/invokeAsyncRoute.js +0 -43
  216. package/dist/main.js +0 -11
  217. package/dist/serverlessLog.js +0 -91
  218. package/dist/utils/checkDockerDaemon.js +0 -27
  219. package/dist/utils/checkGoVersion.js +0 -27
  220. package/dist/utils/createApiKey.js +0 -12
  221. package/dist/utils/createUniqueId.js +0 -14
  222. package/dist/utils/detectExecutable.js +0 -21
  223. package/dist/utils/generateHapiPath.js +0 -28
  224. package/dist/utils/getHttpApiCorsConfig.js +0 -40
  225. package/dist/utils/index.js +0 -165
  226. package/dist/utils/jsonPath.js +0 -21
  227. package/dist/utils/lowerCaseKeys.js +0 -14
  228. package/dist/utils/parseHeaders.js +0 -23
  229. package/dist/utils/parseMultiValueHeaders.js +0 -36
  230. package/dist/utils/parseMultiValueQueryStringParameters.js +0 -40
  231. package/dist/utils/parseQueryStringParameters.js +0 -26
  232. package/dist/utils/resolveJoins.js +0 -36
  233. package/dist/utils/satisfiesVersionRange.js +0 -20
  234. package/dist/utils/splitHandlerPathAndName.js +0 -37
  235. 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
+ }