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.
- package/README.md +17 -17
- package/package.json +14 -13
- package/src/ServerlessOffline.js +42 -42
- package/src/config/colors.js +9 -9
- package/src/config/commandOptions.js +61 -61
- package/src/config/constants.js +5 -5
- package/src/config/defaultOptions.js +6 -6
- package/src/config/index.js +4 -4
- package/src/config/supportedRuntimes.js +18 -18
- package/src/errors/index.js +1 -1
- package/src/events/alb/Alb.js +2 -2
- package/src/events/alb/AlbEventDefinition.js +2 -2
- package/src/events/alb/HttpServer.js +54 -54
- package/src/events/alb/index.js +1 -1
- package/src/events/alb/lambda-events/LambdaAlbRequestEvent.js +2 -2
- package/src/events/alb/lambda-events/index.js +1 -1
- package/src/events/authCanExecuteResource.js +3 -3
- package/src/events/authFunctionNameExtractor.js +9 -9
- package/src/events/authMatchPolicyResource.js +8 -8
- package/src/events/authValidateContext.js +11 -11
- package/src/events/http/Endpoint.js +26 -26
- package/src/events/http/Http.js +2 -2
- package/src/events/http/HttpEventDefinition.js +2 -2
- package/src/events/http/HttpServer.js +156 -156
- package/src/events/http/OfflineEndpoint.js +7 -7
- package/src/events/http/authJWTSettingsExtractor.js +2 -2
- package/src/events/http/createAuthScheme.js +29 -27
- package/src/events/http/createJWTAuthScheme.js +12 -12
- package/src/events/http/index.js +1 -1
- package/src/events/http/javaHelpers.js +2 -2
- package/src/events/http/lambda-events/LambdaIntegrationEvent.js +5 -5
- package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +47 -47
- package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +27 -27
- package/src/events/http/lambda-events/VelocityContext.js +28 -32
- package/src/events/http/lambda-events/index.js +4 -4
- package/src/events/http/lambda-events/renderVelocityTemplateObject.js +13 -13
- package/src/events/http/parseResources.js +6 -6
- package/src/events/http/payloadSchemaValidator.js +2 -2
- package/src/events/schedule/Schedule.js +21 -21
- package/src/events/schedule/ScheduleEvent.js +7 -7
- package/src/events/schedule/ScheduleEventDefinition.js +1 -1
- package/src/events/schedule/index.js +1 -1
- package/src/events/websocket/HttpServer.js +9 -9
- package/src/events/websocket/WebSocket.js +4 -4
- package/src/events/websocket/WebSocketClients.js +29 -29
- package/src/events/websocket/WebSocketEventDefinition.js +1 -1
- package/src/events/websocket/WebSocketServer.js +9 -9
- package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +3 -3
- package/src/events/websocket/http-routes/_catchAll/index.js +1 -1
- package/src/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/src/events/websocket/http-routes/connections/connectionsRoutes.js +6 -6
- package/src/events/websocket/http-routes/connections/index.js +1 -1
- package/src/events/websocket/http-routes/index.js +2 -2
- package/src/events/websocket/index.js +1 -1
- package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +5 -5
- package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +7 -6
- package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +5 -5
- package/src/events/websocket/lambda-events/WebSocketEvent.js +2 -2
- package/src/events/websocket/lambda-events/WebSocketRequestContext.js +12 -11
- package/src/events/websocket/lambda-events/index.js +4 -4
- package/src/index.js +1 -1
- package/src/lambda/HttpServer.js +11 -11
- package/src/lambda/Lambda.js +2 -2
- package/src/lambda/LambdaContext.js +1 -1
- package/src/lambda/LambdaFunction.js +34 -34
- package/src/lambda/LambdaFunctionPool.js +3 -3
- package/src/lambda/handler-runner/HandlerRunner.js +12 -12
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +59 -59
- package/src/lambda/handler-runner/docker-runner/DockerImage.js +6 -6
- package/src/lambda/handler-runner/docker-runner/DockerRunner.js +2 -2
- package/src/lambda/handler-runner/docker-runner/index.js +1 -1
- package/src/lambda/handler-runner/go-runner/GoRunner.js +34 -34
- package/src/lambda/handler-runner/go-runner/index.js +1 -1
- package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +7 -7
- package/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js +52 -52
- package/src/lambda/handler-runner/in-process-runner/index.js +1 -1
- package/src/lambda/handler-runner/index.js +1 -1
- package/src/lambda/handler-runner/java-runner/JavaRunner.js +13 -13
- package/src/lambda/handler-runner/java-runner/index.js +1 -1
- package/src/lambda/handler-runner/python-runner/PythonRunner.js +21 -21
- package/src/lambda/handler-runner/python-runner/index.js +1 -1
- package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +11 -11
- package/src/lambda/handler-runner/ruby-runner/index.js +1 -1
- package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +6 -6
- package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -1
- package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +4 -4
- package/src/lambda/index.js +1 -1
- package/src/lambda/routes/index.js +2 -2
- package/src/lambda/routes/invocations/InvocationsController.js +11 -11
- package/src/lambda/routes/invocations/index.js +1 -1
- package/src/lambda/routes/invocations/invocationsRoute.js +15 -15
- package/src/lambda/routes/invoke-async/index.js +1 -1
- package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +6 -6
- package/src/utils/checkDockerDaemon.js +8 -8
- package/src/utils/checkGoVersion.js +3 -3
- package/src/utils/createApiKey.js +2 -2
- package/src/utils/detectExecutable.js +2 -2
- package/src/utils/formatToClfTime.js +2 -2
- package/src/utils/generateHapiPath.js +8 -8
- package/src/utils/getApiKeysValues.js +2 -2
- package/src/utils/getHttpApiCorsConfig.js +11 -11
- package/src/utils/getRawQueryParams.js +2 -2
- package/src/utils/index.js +25 -26
- package/src/utils/jsonPath.js +1 -1
- package/src/utils/logRoutes.js +13 -13
- package/src/utils/parseHeaders.js +1 -1
- package/src/utils/parseMultiValueHeaders.js +1 -1
- package/src/utils/parseMultiValueQueryStringParameters.js +1 -1
- package/src/utils/parseQueryStringParameters.js +1 -1
- package/src/utils/parseQueryStringParametersForPayloadV2.js +1 -1
- package/src/utils/splitHandlerPathAndName.js +3 -3
- package/src/utils/createUniqueId.js +0 -5
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Buffer } from
|
|
2
|
-
import { env } from
|
|
3
|
-
import { log } from
|
|
4
|
-
import { decodeJwt } from
|
|
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
|
|
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
|
-
|
|
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[
|
|
64
|
+
if (headers["sls-offline-authorizer-override"]) {
|
|
65
65
|
try {
|
|
66
|
-
authAuthorizer = parse(headers[
|
|
66
|
+
authAuthorizer = parse(headers["sls-offline-authorizer-override"])
|
|
67
67
|
} catch {
|
|
68
68
|
log.error(
|
|
69
|
-
|
|
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 !==
|
|
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[
|
|
82
|
-
(typeof body ===
|
|
81
|
+
!headers["content-length"] &&
|
|
82
|
+
(typeof body === "string" ||
|
|
83
83
|
body instanceof Buffer ||
|
|
84
84
|
body instanceof ArrayBuffer)
|
|
85
85
|
) {
|
|
86
|
-
headers[
|
|
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[
|
|
91
|
-
headers[
|
|
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(
|
|
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:
|
|
157
|
-
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:
|
|
167
|
-
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:
|
|
171
|
+
protocol: "HTTP/1.1",
|
|
172
172
|
sourceIp: remoteAddress,
|
|
173
|
-
userAgent: _headers[
|
|
173
|
+
userAgent: _headers["user-agent"] || "",
|
|
174
174
|
},
|
|
175
175
|
operationName: this.#additionalRequestContext.operationName,
|
|
176
|
-
requestId:
|
|
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:
|
|
184
|
+
version: "2.0",
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import { Buffer } from
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
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 ===
|
|
17
|
-
return jsEscapeString(x).replaceAll(
|
|
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 ===
|
|
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(
|
|
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
|
-
|
|
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:
|
|
90
|
+
apiId: "offlineContext_apiId",
|
|
95
91
|
authorizer,
|
|
96
92
|
httpMethod: this.#request.method.toUpperCase(),
|
|
97
93
|
identity: {
|
|
98
|
-
accountId:
|
|
99
|
-
apiKey:
|
|
100
|
-
apiKeyId:
|
|
101
|
-
caller:
|
|
94
|
+
accountId: "offlineContext_accountId",
|
|
95
|
+
apiKey: "offlineContext_apiKey",
|
|
96
|
+
apiKeyId: "offlineContext_apiKeyId",
|
|
97
|
+
caller: "offlineContext_caller",
|
|
102
98
|
cognitoAuthenticationProvider:
|
|
103
|
-
|
|
104
|
-
cognitoAuthenticationType:
|
|
99
|
+
"offlineContext_cognitoAuthenticationProvider",
|
|
100
|
+
cognitoAuthenticationType: "offlineContext_cognitoAuthenticationType",
|
|
105
101
|
sourceIp: this.#request.info.remoteAddress,
|
|
106
|
-
user:
|
|
107
|
-
userAgent: this.#request.headers[
|
|
108
|
-
userArn:
|
|
102
|
+
user: "offlineContext_user",
|
|
103
|
+
userAgent: this.#request.headers["user-agent"] || "",
|
|
104
|
+
userArn: "offlineContext_userArn",
|
|
109
105
|
},
|
|
110
|
-
requestId:
|
|
111
|
-
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 ===
|
|
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(),
|
|
130
|
+
Buffer.from(x.toString(), "base64").toString("binary"),
|
|
135
131
|
base64Encode: (x) =>
|
|
136
|
-
Buffer.from(x.toString(),
|
|
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
|
|
2
|
-
export { default as LambdaProxyIntegrationEvent } from
|
|
3
|
-
export { default as renderVelocityTemplateObject } from
|
|
4
|
-
export { default as VelocityContext } from
|
|
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
|
|
2
|
-
import velocityjs from
|
|
3
|
-
import runInPollutedScope from
|
|
4
|
-
import { isPlainObject } from
|
|
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(
|
|
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
|
|
36
|
+
case "undefined": {
|
|
37
37
|
return undefined
|
|
38
38
|
} // But we don't, we want JavaScript types
|
|
39
39
|
|
|
40
|
-
case
|
|
40
|
+
case "null": {
|
|
41
41
|
return null
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
case
|
|
44
|
+
case "true": {
|
|
45
45
|
return true
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
case
|
|
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 ===
|
|
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(
|
|
75
|
+
log.debug("Processing key:", key, "- value:", value)
|
|
76
76
|
|
|
77
|
-
if (typeof value ===
|
|
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 ===
|
|
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 =
|
|
4
|
-
const APIGATEWAY_ROOT_ID =
|
|
5
|
-
const APIGATEWAY_TYPE_METHOD =
|
|
6
|
-
const APIGATEWAY_TYPE_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[
|
|
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
|
|
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
|
|
5
|
-
import nodeSchedule from
|
|
6
|
-
import ScheduleEvent from
|
|
7
|
-
import ScheduleEventDefinition from
|
|
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 ===
|
|
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(
|
|
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
|
|
81
|
-
case
|
|
80
|
+
case "minute":
|
|
81
|
+
case "minutes": {
|
|
82
82
|
return `*/${number} * * * *`
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
case
|
|
86
|
-
case
|
|
85
|
+
case "hour":
|
|
86
|
+
case "hours": {
|
|
87
87
|
return `0 */${number} * * *`
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
case
|
|
91
|
-
case
|
|
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(
|
|
106
|
-
.replace(
|
|
107
|
-
.replace(
|
|
105
|
+
.replace("rate(", "")
|
|
106
|
+
.replace("cron(", "")
|
|
107
|
+
.replace(")", "")
|
|
108
108
|
|
|
109
|
-
if (scheduleEvent.startsWith(
|
|
109
|
+
if (scheduleEvent.startsWith("cron(")) {
|
|
110
110
|
return this.#convertCronSyntax(params)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
if (scheduleEvent.startsWith(
|
|
113
|
+
if (scheduleEvent.startsWith("rate(")) {
|
|
114
114
|
return this.#convertRateToCron(params)
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
log.error(
|
|
117
|
+
log.error("scheduler: invalid, schedule syntax")
|
|
118
118
|
|
|
119
119
|
return undefined
|
|
120
120
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crypto from "node:crypto"
|
|
2
2
|
|
|
3
3
|
export default class ScheduleEvent {
|
|
4
|
-
account =
|
|
4
|
+
account = crypto.randomUUID()
|
|
5
5
|
|
|
6
6
|
detail = {};
|
|
7
7
|
|
|
8
|
-
[
|
|
8
|
+
["detail-type"] = "Scheduled Event"
|
|
9
9
|
|
|
10
|
-
id =
|
|
10
|
+
id = crypto.randomUUID()
|
|
11
11
|
|
|
12
12
|
region = null
|
|
13
13
|
|
|
14
14
|
resources = []
|
|
15
15
|
|
|
16
|
-
source =
|
|
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 =
|
|
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 ===
|
|
9
|
+
if (typeof rawHttpEventDefinition === "string") {
|
|
10
10
|
rate = rawHttpEventDefinition
|
|
11
11
|
} else {
|
|
12
12
|
;({ enabled, rate, ...rest } = rawHttpEventDefinition)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from
|
|
1
|
+
export { default } from "./Schedule.js"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { readFile } from
|
|
2
|
-
import { resolve } from
|
|
3
|
-
import { exit } from
|
|
4
|
-
import { Server } from
|
|
5
|
-
import { log } from
|
|
6
|
-
import { catchAllRoute, connectionsRoutes } from
|
|
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,
|
|
23
|
-
readFile(resolve(httpsProtocol,
|
|
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 ?
|
|
72
|
+
httpsProtocol ? "https" : "http"
|
|
73
73
|
}://${host}:${websocketPort}`,
|
|
74
74
|
)
|
|
75
75
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import HttpServer from
|
|
2
|
-
import WebSocketEventDefinition from
|
|
3
|
-
import WebSocketClients from
|
|
4
|
-
import WebSocketServer from
|
|
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
|