serverless-offline 13.3.2 → 13.3.3

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 (112) hide show
  1. package/README.md +17 -17
  2. package/package.json +14 -13
  3. package/src/ServerlessOffline.js +42 -42
  4. package/src/config/colors.js +9 -9
  5. package/src/config/commandOptions.js +61 -61
  6. package/src/config/constants.js +5 -5
  7. package/src/config/defaultOptions.js +6 -6
  8. package/src/config/index.js +4 -4
  9. package/src/config/supportedRuntimes.js +18 -18
  10. package/src/errors/index.js +1 -1
  11. package/src/events/alb/Alb.js +2 -2
  12. package/src/events/alb/AlbEventDefinition.js +2 -2
  13. package/src/events/alb/HttpServer.js +54 -54
  14. package/src/events/alb/index.js +1 -1
  15. package/src/events/alb/lambda-events/LambdaAlbRequestEvent.js +2 -2
  16. package/src/events/alb/lambda-events/index.js +1 -1
  17. package/src/events/authCanExecuteResource.js +3 -3
  18. package/src/events/authFunctionNameExtractor.js +9 -9
  19. package/src/events/authMatchPolicyResource.js +8 -8
  20. package/src/events/authValidateContext.js +11 -11
  21. package/src/events/http/Endpoint.js +26 -26
  22. package/src/events/http/Http.js +2 -2
  23. package/src/events/http/HttpEventDefinition.js +2 -2
  24. package/src/events/http/HttpServer.js +156 -156
  25. package/src/events/http/OfflineEndpoint.js +7 -7
  26. package/src/events/http/authJWTSettingsExtractor.js +2 -2
  27. package/src/events/http/createAuthScheme.js +29 -27
  28. package/src/events/http/createJWTAuthScheme.js +12 -12
  29. package/src/events/http/index.js +1 -1
  30. package/src/events/http/javaHelpers.js +2 -2
  31. package/src/events/http/lambda-events/LambdaIntegrationEvent.js +5 -5
  32. package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +47 -47
  33. package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +27 -27
  34. package/src/events/http/lambda-events/VelocityContext.js +28 -32
  35. package/src/events/http/lambda-events/index.js +4 -4
  36. package/src/events/http/lambda-events/renderVelocityTemplateObject.js +13 -13
  37. package/src/events/http/parseResources.js +6 -6
  38. package/src/events/http/payloadSchemaValidator.js +2 -2
  39. package/src/events/schedule/Schedule.js +21 -21
  40. package/src/events/schedule/ScheduleEvent.js +7 -7
  41. package/src/events/schedule/ScheduleEventDefinition.js +1 -1
  42. package/src/events/schedule/index.js +1 -1
  43. package/src/events/websocket/HttpServer.js +9 -9
  44. package/src/events/websocket/WebSocket.js +4 -4
  45. package/src/events/websocket/WebSocketClients.js +29 -29
  46. package/src/events/websocket/WebSocketEventDefinition.js +1 -1
  47. package/src/events/websocket/WebSocketServer.js +9 -9
  48. package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +3 -3
  49. package/src/events/websocket/http-routes/_catchAll/index.js +1 -1
  50. package/src/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
  51. package/src/events/websocket/http-routes/connections/connectionsRoutes.js +6 -6
  52. package/src/events/websocket/http-routes/connections/index.js +1 -1
  53. package/src/events/websocket/http-routes/index.js +2 -2
  54. package/src/events/websocket/index.js +1 -1
  55. package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +5 -5
  56. package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +7 -6
  57. package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +5 -5
  58. package/src/events/websocket/lambda-events/WebSocketEvent.js +2 -2
  59. package/src/events/websocket/lambda-events/WebSocketRequestContext.js +12 -11
  60. package/src/events/websocket/lambda-events/index.js +4 -4
  61. package/src/index.js +1 -1
  62. package/src/lambda/HttpServer.js +11 -11
  63. package/src/lambda/Lambda.js +2 -2
  64. package/src/lambda/LambdaContext.js +1 -1
  65. package/src/lambda/LambdaFunction.js +34 -34
  66. package/src/lambda/LambdaFunctionPool.js +3 -3
  67. package/src/lambda/handler-runner/HandlerRunner.js +12 -12
  68. package/src/lambda/handler-runner/docker-runner/DockerContainer.js +59 -59
  69. package/src/lambda/handler-runner/docker-runner/DockerImage.js +6 -6
  70. package/src/lambda/handler-runner/docker-runner/DockerRunner.js +2 -2
  71. package/src/lambda/handler-runner/docker-runner/index.js +1 -1
  72. package/src/lambda/handler-runner/go-runner/GoRunner.js +34 -34
  73. package/src/lambda/handler-runner/go-runner/index.js +1 -1
  74. package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +7 -7
  75. package/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js +52 -52
  76. package/src/lambda/handler-runner/in-process-runner/index.js +1 -1
  77. package/src/lambda/handler-runner/index.js +1 -1
  78. package/src/lambda/handler-runner/java-runner/JavaRunner.js +13 -13
  79. package/src/lambda/handler-runner/java-runner/index.js +1 -1
  80. package/src/lambda/handler-runner/python-runner/PythonRunner.js +21 -21
  81. package/src/lambda/handler-runner/python-runner/index.js +1 -1
  82. package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +11 -11
  83. package/src/lambda/handler-runner/ruby-runner/index.js +1 -1
  84. package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +6 -6
  85. package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -1
  86. package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +4 -4
  87. package/src/lambda/index.js +1 -1
  88. package/src/lambda/routes/index.js +2 -2
  89. package/src/lambda/routes/invocations/InvocationsController.js +11 -11
  90. package/src/lambda/routes/invocations/index.js +1 -1
  91. package/src/lambda/routes/invocations/invocationsRoute.js +15 -15
  92. package/src/lambda/routes/invoke-async/index.js +1 -1
  93. package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +6 -6
  94. package/src/utils/checkDockerDaemon.js +8 -8
  95. package/src/utils/checkGoVersion.js +3 -3
  96. package/src/utils/createApiKey.js +2 -2
  97. package/src/utils/detectExecutable.js +2 -2
  98. package/src/utils/formatToClfTime.js +2 -2
  99. package/src/utils/generateHapiPath.js +8 -8
  100. package/src/utils/getApiKeysValues.js +2 -2
  101. package/src/utils/getHttpApiCorsConfig.js +11 -11
  102. package/src/utils/getRawQueryParams.js +2 -2
  103. package/src/utils/index.js +25 -26
  104. package/src/utils/jsonPath.js +1 -1
  105. package/src/utils/logRoutes.js +13 -13
  106. package/src/utils/parseHeaders.js +1 -1
  107. package/src/utils/parseMultiValueHeaders.js +1 -1
  108. package/src/utils/parseMultiValueQueryStringParameters.js +1 -1
  109. package/src/utils/parseQueryStringParameters.js +1 -1
  110. package/src/utils/parseQueryStringParametersForPayloadV2.js +1 -1
  111. package/src/utils/splitHandlerPathAndName.js +3 -3
  112. package/src/utils/createUniqueId.js +0 -5
@@ -1,14 +1,14 @@
1
- import { Buffer } from 'node:buffer'
2
- import { env } from 'node:process'
3
- import { log } from '@serverless/utils/log.js'
4
- import { decodeJwt } from 'jose'
1
+ import { Buffer } from "node:buffer"
2
+ import { env } from "node:process"
3
+ import { log } from "@serverless/utils/log.js"
4
+ import { decodeJwt } from "jose"
5
5
  import {
6
6
  formatToClfTime,
7
7
  lowerCaseKeys,
8
8
  nullIfEmpty,
9
9
  parseHeaders,
10
10
  parseQueryStringParametersForPayloadV2,
11
- } from '../../../utils/index.js'
11
+ } from "../../../utils/index.js"
12
12
 
13
13
  const { isArray } = Array
14
14
  const { parse } = JSON
@@ -49,7 +49,7 @@ export default class LambdaProxyIntegrationEventV2 {
49
49
  authAuthorizer = parse(env.AUTHORIZER)
50
50
  } catch {
51
51
  log.error(
52
- 'Could not parse process.env.AUTHORIZER, make sure it is correct JSON',
52
+ "Could not parse process.env.AUTHORIZER, make sure it is correct JSON",
53
53
  )
54
54
  }
55
55
  }
@@ -61,36 +61,36 @@ export default class LambdaProxyIntegrationEventV2 {
61
61
  // NOTE FIXME request.raw.req.rawHeaders can only be null for testing (hapi shot inject())
62
62
  const headers = lowerCaseKeys(parseHeaders(rawHeaders || [])) || {}
63
63
 
64
- if (headers['sls-offline-authorizer-override']) {
64
+ if (headers["sls-offline-authorizer-override"]) {
65
65
  try {
66
- authAuthorizer = parse(headers['sls-offline-authorizer-override'])
66
+ authAuthorizer = parse(headers["sls-offline-authorizer-override"])
67
67
  } catch {
68
68
  log.error(
69
- 'Could not parse header sls-offline-authorizer-override, make sure it is correct JSON',
69
+ "Could not parse header sls-offline-authorizer-override, make sure it is correct JSON",
70
70
  )
71
71
  }
72
72
  }
73
73
 
74
74
  if (body) {
75
- if (typeof body !== 'string') {
75
+ if (typeof body !== "string") {
76
76
  // this.#request.payload is NOT the same as the rawPayload
77
77
  body = this.#request.rawPayload
78
78
  }
79
79
 
80
80
  if (
81
- !headers['content-length'] &&
82
- (typeof body === 'string' ||
81
+ !headers["content-length"] &&
82
+ (typeof body === "string" ||
83
83
  body instanceof Buffer ||
84
84
  body instanceof ArrayBuffer)
85
85
  ) {
86
- headers['content-length'] = String(Buffer.byteLength(body))
86
+ headers["content-length"] = String(Buffer.byteLength(body))
87
87
  }
88
88
 
89
89
  // Set a default Content-Type if not provided.
90
- if (!headers['content-type']) {
91
- headers['content-type'] = 'application/json'
90
+ if (!headers["content-type"]) {
91
+ headers["content-type"] = "application/json"
92
92
  }
93
- } else if (body === undefined || body === '') {
93
+ } else if (body === undefined || body === "") {
94
94
  body = null
95
95
  }
96
96
 
@@ -99,8 +99,8 @@ export default class LambdaProxyIntegrationEventV2 {
99
99
 
100
100
  let token = headers.Authorization || headers.authorization
101
101
 
102
- if (token && token.split(' ')[0] === 'Bearer') {
103
- ;[, token] = token.split(' ')
102
+ if (token && token.split(" ")[0] === "Bearer") {
103
+ ;[, token] = token.split(" ")
104
104
  }
105
105
 
106
106
  let claims
@@ -110,7 +110,7 @@ export default class LambdaProxyIntegrationEventV2 {
110
110
  try {
111
111
  claims = decodeJwt(token)
112
112
  if (claims.scope) {
113
- scopes = claims.scope.split(' ')
113
+ scopes = claims.scope.split(" ")
114
114
  // In AWS HTTP Api the scope property is removed from the decoded JWT
115
115
  // I'm leaving this property because I'm not sure how all of the authorizers
116
116
  // for AWS REST Api handle JWT.
@@ -153,8 +153,8 @@ export default class LambdaProxyIntegrationEventV2 {
153
153
  rawPath: this.#request.url.pathname,
154
154
  rawQueryString: this.#request.url.searchParams.toString(),
155
155
  requestContext: {
156
- accountId: 'offlineContext_accountId',
157
- apiId: 'offlineContext_apiId',
156
+ accountId: "offlineContext_accountId",
157
+ apiId: "offlineContext_apiId",
158
158
  authorizer:
159
159
  authAuthorizer ||
160
160
  assign(lambdaAuthContext, {
@@ -163,17 +163,17 @@ export default class LambdaProxyIntegrationEventV2 {
163
163
  scopes,
164
164
  },
165
165
  }),
166
- domainName: 'offlineContext_domainName',
167
- domainPrefix: 'offlineContext_domainPrefix',
166
+ domainName: "offlineContext_domainName",
167
+ domainPrefix: "offlineContext_domainPrefix",
168
168
  http: {
169
169
  method: httpMethod,
170
170
  path: this.#request.url.pathname,
171
- protocol: 'HTTP/1.1',
171
+ protocol: "HTTP/1.1",
172
172
  sourceIp: remoteAddress,
173
- userAgent: _headers['user-agent'] || '',
173
+ userAgent: _headers["user-agent"] || "",
174
174
  },
175
175
  operationName: this.#additionalRequestContext.operationName,
176
- requestId: 'offlineContext_resourceId',
176
+ requestId: "offlineContext_resourceId",
177
177
  routeKey: this.#routeKey,
178
178
  stage: this.#stage,
179
179
  time: requestTime,
@@ -181,7 +181,7 @@ export default class LambdaProxyIntegrationEventV2 {
181
181
  },
182
182
  routeKey: this.#routeKey,
183
183
  stageVariables: null,
184
- version: '2.0',
184
+ version: "2.0",
185
185
  }
186
186
  }
187
187
  }
@@ -1,20 +1,16 @@
1
- import { Buffer } from 'node:buffer'
2
- import { env } from 'node:process'
3
- import jsEscapeString from 'js-string-escape'
4
- import { decodeJwt } from 'jose'
5
- import {
6
- createUniqueId,
7
- isPlainObject,
8
- jsonPath,
9
- parseHeaders,
10
- } from '../../../utils/index.js'
1
+ import { Buffer } from "node:buffer"
2
+ import crypto from "node:crypto"
3
+ import { env } from "node:process"
4
+ import jsEscapeString from "js-string-escape"
5
+ import { decodeJwt } from "jose"
6
+ import { isPlainObject, jsonPath, parseHeaders } from "../../../utils/index.js"
11
7
 
12
8
  const { parse, stringify } = JSON
13
9
  const { assign, entries, fromEntries } = Object
14
10
 
15
11
  function escapeJavaScript(x) {
16
- if (typeof x === 'string') {
17
- return jsEscapeString(x).replaceAll('\\n', '\n') // See #26,
12
+ if (typeof x === "string") {
13
+ return jsEscapeString(x).replaceAll("\\n", "\n") // See #26,
18
14
  }
19
15
 
20
16
  if (isPlainObject(x)) {
@@ -25,7 +21,7 @@ function escapeJavaScript(x) {
25
21
  return stringify(result) // Is this really how APIG does it?
26
22
  }
27
23
 
28
- if (typeof x.toString === 'function') {
24
+ if (typeof x.toString === "function") {
29
25
  return escapeJavaScript(x.toString())
30
26
  }
31
27
 
@@ -70,8 +66,8 @@ export default class VelocityContext {
70
66
 
71
67
  let token = headers && (headers.Authorization || headers.authorization)
72
68
 
73
- if (token && token.split(' ')[0] === 'Bearer') {
74
- ;[, token] = token.split(' ')
69
+ if (token && token.split(" ")[0] === "Bearer") {
70
+ ;[, token] = token.split(" ")
75
71
  }
76
72
 
77
73
  if (!authorizer) authorizer = {}
@@ -79,7 +75,7 @@ export default class VelocityContext {
79
75
  authorizer.principalId =
80
76
  authPrincipalId ||
81
77
  env.PRINCIPAL_ID ||
82
- 'offlineContext_authorizer_principalId' // See #24
78
+ "offlineContext_authorizer_principalId" // See #24
83
79
 
84
80
  if (token) {
85
81
  try {
@@ -91,24 +87,24 @@ export default class VelocityContext {
91
87
 
92
88
  return {
93
89
  context: {
94
- apiId: 'offlineContext_apiId',
90
+ apiId: "offlineContext_apiId",
95
91
  authorizer,
96
92
  httpMethod: this.#request.method.toUpperCase(),
97
93
  identity: {
98
- accountId: 'offlineContext_accountId',
99
- apiKey: 'offlineContext_apiKey',
100
- apiKeyId: 'offlineContext_apiKeyId',
101
- caller: 'offlineContext_caller',
94
+ accountId: "offlineContext_accountId",
95
+ apiKey: "offlineContext_apiKey",
96
+ apiKeyId: "offlineContext_apiKeyId",
97
+ caller: "offlineContext_caller",
102
98
  cognitoAuthenticationProvider:
103
- 'offlineContext_cognitoAuthenticationProvider',
104
- cognitoAuthenticationType: 'offlineContext_cognitoAuthenticationType',
99
+ "offlineContext_cognitoAuthenticationProvider",
100
+ cognitoAuthenticationType: "offlineContext_cognitoAuthenticationType",
105
101
  sourceIp: this.#request.info.remoteAddress,
106
- user: 'offlineContext_user',
107
- userAgent: this.#request.headers['user-agent'] || '',
108
- userArn: 'offlineContext_userArn',
102
+ user: "offlineContext_user",
103
+ userAgent: this.#request.headers["user-agent"] || "",
104
+ userArn: "offlineContext_userArn",
109
105
  },
110
- requestId: createUniqueId(),
111
- resourceId: 'offlineContext_resourceId',
106
+ requestId: crypto.randomUUID(),
107
+ resourceId: "offlineContext_resourceId",
112
108
  resourcePath: this.#path,
113
109
  stage: this.#stage,
114
110
  },
@@ -116,7 +112,7 @@ export default class VelocityContext {
116
112
  body: this.#payload, // Not a string yet, todo
117
113
  json: (x) => stringify(path(x)),
118
114
  params: (x) =>
119
- typeof x === 'string'
115
+ typeof x === "string"
120
116
  ? this.#request.params[x] || this.#request.query[x] || headers[x]
121
117
  : {
122
118
  header: headers,
@@ -131,12 +127,12 @@ export default class VelocityContext {
131
127
  },
132
128
  util: {
133
129
  base64Decode: (x) =>
134
- Buffer.from(x.toString(), 'base64').toString('binary'),
130
+ Buffer.from(x.toString(), "base64").toString("binary"),
135
131
  base64Encode: (x) =>
136
- Buffer.from(x.toString(), 'binary').toString('base64'),
132
+ Buffer.from(x.toString(), "binary").toString("base64"),
137
133
  escapeJavaScript,
138
134
  parseJson: parse,
139
- urlDecode: (x) => decodeURIComponent(x.replaceAll('+', ' ')),
135
+ urlDecode: (x) => decodeURIComponent(x.replaceAll("+", " ")),
140
136
  urlEncode: encodeURI,
141
137
  },
142
138
  }
@@ -1,4 +1,4 @@
1
- export { default as LambdaIntegrationEvent } from './LambdaIntegrationEvent.js'
2
- export { default as LambdaProxyIntegrationEvent } from './LambdaProxyIntegrationEvent.js'
3
- export { default as renderVelocityTemplateObject } from './renderVelocityTemplateObject.js'
4
- export { default as VelocityContext } from './VelocityContext.js'
1
+ export { default as LambdaIntegrationEvent } from "./LambdaIntegrationEvent.js"
2
+ export { default as LambdaProxyIntegrationEvent } from "./LambdaProxyIntegrationEvent.js"
3
+ export { default as renderVelocityTemplateObject } from "./renderVelocityTemplateObject.js"
4
+ export { default as VelocityContext } from "./VelocityContext.js"
@@ -1,7 +1,7 @@
1
- import { log } from '@serverless/utils/log.js'
2
- import velocityjs from 'velocityjs'
3
- import runInPollutedScope from '../javaHelpers.js'
4
- import { isPlainObject } from '../../../utils/index.js'
1
+ import { log } from "@serverless/utils/log.js"
2
+ import velocityjs from "velocityjs"
3
+ import runInPollutedScope from "../javaHelpers.js"
4
+ import { isPlainObject } from "../../../utils/index.js"
5
5
 
6
6
  const { parse } = JSON
7
7
  const { entries } = Object
@@ -29,23 +29,23 @@ function renderVelocityString(velocityString, context) {
29
29
  }).render(context, null, true),
30
30
  )
31
31
 
32
- log.debug('Velocity rendered:', renderResult || 'undefined')
32
+ log.debug("Velocity rendered:", renderResult || "undefined")
33
33
 
34
34
  // Haaaa Velocity... this language sure loves strings a lot
35
35
  switch (renderResult) {
36
- case 'undefined': {
36
+ case "undefined": {
37
37
  return undefined
38
38
  } // But we don't, we want JavaScript types
39
39
 
40
- case 'null': {
40
+ case "null": {
41
41
  return null
42
42
  }
43
43
 
44
- case 'true': {
44
+ case "true": {
45
45
  return true
46
46
  }
47
47
 
48
- case 'false': {
48
+ case "false": {
49
49
  return false
50
50
  }
51
51
 
@@ -65,16 +65,16 @@ export default function renderVelocityTemplateObject(templateObject, context) {
65
65
  let toProcess = templateObject
66
66
 
67
67
  // In some projects, the template object is a string, let us see if it's JSON
68
- if (typeof toProcess === 'string') {
68
+ if (typeof toProcess === "string") {
69
69
  toProcess = tryToParseJSON(toProcess)
70
70
  }
71
71
 
72
72
  // Let's check again
73
73
  if (isPlainObject(toProcess)) {
74
74
  entries(toProcess).forEach(([key, value]) => {
75
- log.debug('Processing key:', key, '- value:', value)
75
+ log.debug("Processing key:", key, "- value:", value)
76
76
 
77
- if (typeof value === 'string') {
77
+ if (typeof value === "string") {
78
78
  result[key] = renderVelocityString(value, context)
79
79
  // Go deeper
80
80
  } else if (isPlainObject(value)) {
@@ -85,7 +85,7 @@ export default function renderVelocityTemplateObject(templateObject, context) {
85
85
  }
86
86
  })
87
87
  // Still a string? Maybe it's some complex Velocity stuff
88
- } else if (typeof toProcess === 'string') {
88
+ } else if (typeof toProcess === "string") {
89
89
  // If the plugin threw here then you should consider reviewing your template or posting an issue.
90
90
  const alternativeResult = tryToParseJSON(
91
91
  renderVelocityString(toProcess, context),
@@ -1,9 +1,9 @@
1
1
  const { entries, fromEntries, keys } = Object
2
2
 
3
- const APIGATEWAY_INTEGRATION_TYPE_HTTP_PROXY = 'HTTP_PROXY'
4
- const APIGATEWAY_ROOT_ID = 'RootResourceId'
5
- const APIGATEWAY_TYPE_METHOD = 'AWS::ApiGateway::Method'
6
- const APIGATEWAY_TYPE_RESOURCE = 'AWS::ApiGateway::Resource'
3
+ const APIGATEWAY_INTEGRATION_TYPE_HTTP_PROXY = "HTTP_PROXY"
4
+ const APIGATEWAY_ROOT_ID = "RootResourceId"
5
+ const APIGATEWAY_TYPE_METHOD = "AWS::ApiGateway::Method"
6
+ const APIGATEWAY_TYPE_RESOURCE = "AWS::ApiGateway::Resource"
7
7
 
8
8
  function getApiGatewayTemplateObjects(resources) {
9
9
  const Resources = resources && resources.Resources
@@ -68,7 +68,7 @@ function getParentId(resourceObj) {
68
68
  const { Ref } = parentIdObj
69
69
  if (Ref) return Ref
70
70
 
71
- const getAtt = parentIdObj['Fn::GetAtt'] || []
71
+ const getAtt = parentIdObj["Fn::GetAtt"] || []
72
72
 
73
73
  return getAtt[1]
74
74
  }
@@ -91,7 +91,7 @@ function getFullPath(pathObjects, resourceId) {
91
91
  return undefined
92
92
  }
93
93
 
94
- return `/${arrPath.join('/')}`
94
+ return `/${arrPath.join("/")}`
95
95
  }
96
96
 
97
97
  /* Example of an HTTP Proxy Method Object
@@ -1,4 +1,4 @@
1
- import { validate } from 'jsonschema'
1
+ import { validate } from "jsonschema"
2
2
 
3
3
  export default function payloadSchemaValidator(model, body) {
4
4
  const result = validate(body, model)
@@ -7,7 +7,7 @@ export default function payloadSchemaValidator(model, body) {
7
7
  throw new Error(
8
8
  `Request body validation failed: ${result.errors
9
9
  .map((e) => e.message)
10
- .join(', ')}`,
10
+ .join(", ")}`,
11
11
  )
12
12
  }
13
13
  }
@@ -1,10 +1,10 @@
1
1
  // based on:
2
2
  // https://github.com/ajmath/serverless-offline-scheduler
3
3
 
4
- import { log } from '@serverless/utils/log.js'
5
- import nodeSchedule from 'node-schedule'
6
- import ScheduleEvent from './ScheduleEvent.js'
7
- import ScheduleEventDefinition from './ScheduleEventDefinition.js'
4
+ import { log } from "@serverless/utils/log.js"
5
+ import nodeSchedule from "node-schedule"
6
+ import ScheduleEvent from "./ScheduleEvent.js"
7
+ import ScheduleEventDefinition from "./ScheduleEventDefinition.js"
8
8
 
9
9
  const CRON_LENGTH_WITH_YEAR = 6
10
10
 
@@ -31,7 +31,7 @@ export default class Schedule {
31
31
 
32
32
  // Convert string rate to array to support Serverless v2.57.0 and lower.
33
33
  let rates = rate
34
- if (typeof rate === 'string') {
34
+ if (typeof rate === "string") {
35
35
  rates = [rate]
36
36
  }
37
37
 
@@ -40,7 +40,7 @@ export default class Schedule {
40
40
 
41
41
  log.notice(
42
42
  `Scheduling [${functionKey}] cron: [${cron}]${
43
- input ? ` input: ${stringify(input)}` : ''
43
+ input ? ` input: ${stringify(input)}` : ""
44
44
  }`,
45
45
  )
46
46
 
@@ -66,29 +66,29 @@ export default class Schedule {
66
66
  }
67
67
 
68
68
  #convertCronSyntax(cronString) {
69
- if (cronString.split(' ').length < CRON_LENGTH_WITH_YEAR) {
69
+ if (cronString.split(" ").length < CRON_LENGTH_WITH_YEAR) {
70
70
  return cronString
71
71
  }
72
72
 
73
- return cronString.replace(/\s\S+$/, '')
73
+ return cronString.replace(/\s\S+$/, "")
74
74
  }
75
75
 
76
76
  #convertRateToCron(rate) {
77
- const [number, unit] = rate.split(' ')
77
+ const [number, unit] = rate.split(" ")
78
78
 
79
79
  switch (unit) {
80
- case 'minute':
81
- case 'minutes': {
80
+ case "minute":
81
+ case "minutes": {
82
82
  return `*/${number} * * * *`
83
83
  }
84
84
 
85
- case 'hour':
86
- case 'hours': {
85
+ case "hour":
86
+ case "hours": {
87
87
  return `0 */${number} * * *`
88
88
  }
89
89
 
90
- case 'day':
91
- case 'days': {
90
+ case "day":
91
+ case "days": {
92
92
  return `0 0 */${number} * *`
93
93
  }
94
94
 
@@ -102,19 +102,19 @@ export default class Schedule {
102
102
 
103
103
  #convertExpressionToCron(scheduleEvent) {
104
104
  const params = scheduleEvent
105
- .replace('rate(', '')
106
- .replace('cron(', '')
107
- .replace(')', '')
105
+ .replace("rate(", "")
106
+ .replace("cron(", "")
107
+ .replace(")", "")
108
108
 
109
- if (scheduleEvent.startsWith('cron(')) {
109
+ if (scheduleEvent.startsWith("cron(")) {
110
110
  return this.#convertCronSyntax(params)
111
111
  }
112
112
 
113
- if (scheduleEvent.startsWith('rate(')) {
113
+ if (scheduleEvent.startsWith("rate(")) {
114
114
  return this.#convertRateToCron(params)
115
115
  }
116
116
 
117
- log.error('scheduler: invalid, schedule syntax')
117
+ log.error("scheduler: invalid, schedule syntax")
118
118
 
119
119
  return undefined
120
120
  }
@@ -1,24 +1,24 @@
1
- import { createUniqueId } from '../../utils/index.js'
1
+ import crypto from "node:crypto"
2
2
 
3
3
  export default class ScheduleEvent {
4
- account = createUniqueId()
4
+ account = crypto.randomUUID()
5
5
 
6
6
  detail = {};
7
7
 
8
- ['detail-type'] = 'Scheduled Event'
8
+ ["detail-type"] = "Scheduled Event"
9
9
 
10
- id = createUniqueId()
10
+ id = crypto.randomUUID()
11
11
 
12
12
  region = null
13
13
 
14
14
  resources = []
15
15
 
16
- source = 'aws.events'
16
+ source = "aws.events"
17
17
 
18
18
  // format of aws displaying the time, e.g.: 2020-02-09T14:13:57Z
19
- time = new Date().toISOString().replaceAll(/\.(.*)(?=Z)/g, '')
19
+ time = new Date().toISOString().replaceAll(/\.(.*)(?=Z)/g, "")
20
20
 
21
- version = '0'
21
+ version = "0"
22
22
 
23
23
  constructor(region) {
24
24
  this.region = region
@@ -6,7 +6,7 @@ export default class ScheduleEventDefinition {
6
6
  let rate
7
7
  let rest
8
8
 
9
- if (typeof rawHttpEventDefinition === 'string') {
9
+ if (typeof rawHttpEventDefinition === "string") {
10
10
  rate = rawHttpEventDefinition
11
11
  } else {
12
12
  ;({ enabled, rate, ...rest } = rawHttpEventDefinition)
@@ -1 +1 @@
1
- export { default } from './Schedule.js'
1
+ export { default } from "./Schedule.js"
@@ -1,9 +1,9 @@
1
- import { readFile } from 'node:fs/promises'
2
- import { resolve } from 'node:path'
3
- import { exit } from 'node:process'
4
- import { Server } from '@hapi/hapi'
5
- import { log } from '@serverless/utils/log.js'
6
- import { catchAllRoute, connectionsRoutes } from './http-routes/index.js'
1
+ import { readFile } from "node:fs/promises"
2
+ import { resolve } from "node:path"
3
+ import { exit } from "node:process"
4
+ import { Server } from "@hapi/hapi"
5
+ import { log } from "@serverless/utils/log.js"
6
+ import { catchAllRoute, connectionsRoutes } from "./http-routes/index.js"
7
7
 
8
8
  export default class HttpServer {
9
9
  #options = null
@@ -19,8 +19,8 @@ export default class HttpServer {
19
19
 
20
20
  async #loadCerts(httpsProtocol) {
21
21
  const [cert, key] = await Promise.all([
22
- readFile(resolve(httpsProtocol, 'cert.pem'), 'utf8'),
23
- readFile(resolve(httpsProtocol, 'key.pem'), 'utf8'),
22
+ readFile(resolve(httpsProtocol, "cert.pem"), "utf8"),
23
+ readFile(resolve(httpsProtocol, "key.pem"), "utf8"),
24
24
  ])
25
25
 
26
26
  return {
@@ -69,7 +69,7 @@ export default class HttpServer {
69
69
 
70
70
  log.notice(
71
71
  `Offline [http for websocket] listening on ${
72
- httpsProtocol ? 'https' : 'http'
72
+ httpsProtocol ? "https" : "http"
73
73
  }://${host}:${websocketPort}`,
74
74
  )
75
75
  }
@@ -1,7 +1,7 @@
1
- import HttpServer from './HttpServer.js'
2
- import WebSocketEventDefinition from './WebSocketEventDefinition.js'
3
- import WebSocketClients from './WebSocketClients.js'
4
- import WebSocketServer from './WebSocketServer.js'
1
+ import HttpServer from "./HttpServer.js"
2
+ import WebSocketEventDefinition from "./WebSocketEventDefinition.js"
3
+ import WebSocketClients from "./WebSocketClients.js"
4
+ import WebSocketServer from "./WebSocketServer.js"
5
5
 
6
6
  export default class WebSocket {
7
7
  #httpServer = null