serverless-offline 12.0.2 → 12.0.4
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/package.json +14 -15
- package/src/events/http/Endpoint.js +3 -6
- package/src/events/http/HttpServer.js +15 -18
- package/src/events/http/createJWTAuthScheme.js +1 -1
- package/src/events/http/lambda-events/renderVelocityTemplateObject.js +11 -6
- package/src/events/schedule/Schedule.js +8 -4
- package/src/events/websocket/HttpServer.js +2 -2
- package/src/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +7 -7
- package/src/lambda/handler-runner/go-runner/GoRunner.js +2 -2
- package/src/lambda/handler-runner/python-runner/PythonRunner.js +4 -6
- package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +3 -5
- package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +14 -15
- package/src/lambda/routes/invocations/invocationsRoute.js +2 -2
- package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +1 -1
- package/src/utils/checkGoVersion.js +1 -1
- package/src/utils/parseHeaders.js +2 -2
- package/src/utils/parseMultiValueHeaders.js +2 -2
- package/src/utils/splitHandlerPathAndName.js +1 -1
- package/src/utils/unflatten.js +0 -11
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dedicatedTo": "Blue, a great migrating bird.",
|
|
3
3
|
"name": "serverless-offline",
|
|
4
|
-
"version": "12.0.
|
|
4
|
+
"version": "12.0.4",
|
|
5
5
|
"description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
@@ -24,12 +24,8 @@
|
|
|
24
24
|
"prettify:updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier --write",
|
|
25
25
|
"test": "mocha --require ./tests/mochaHooks.cjs",
|
|
26
26
|
"test:cov": "NODE_OPTIONS='--experimental-loader @istanbuljs/esm-loader-hook' nyc --reporter=html npm test",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"old-test:log": "npm run build && jest --verbose",
|
|
30
|
-
"old-test:noBuild": "jest --verbose --runInBand --bail",
|
|
31
|
-
"old-test:unit": "jest --verbose --silent --runInBand --config jest.config.units.js",
|
|
32
|
-
"old-test:watch": "SKIP_SETUP=true jest --verbose --watch"
|
|
27
|
+
"test:node": "TEST=unit mocha --require ./tests/mochaHooks.cjs",
|
|
28
|
+
"test:unit": "TEST=unit mocha --require ./tests/mochaHooks.cjs"
|
|
33
29
|
},
|
|
34
30
|
"repository": {
|
|
35
31
|
"type": "git",
|
|
@@ -82,23 +78,25 @@
|
|
|
82
78
|
]
|
|
83
79
|
},
|
|
84
80
|
"dependencies": {
|
|
85
|
-
"@aws-sdk/client-lambda": "^3.
|
|
81
|
+
"@aws-sdk/client-lambda": "^3.241.0",
|
|
86
82
|
"@hapi/boom": "^10.0.0",
|
|
87
83
|
"@hapi/h2o2": "^10.0.0",
|
|
88
84
|
"@hapi/hapi": "^21.1.0",
|
|
89
85
|
"@serverless/utils": "^6.8.2",
|
|
90
|
-
"
|
|
86
|
+
"array-unflat-js": "^0.1.3",
|
|
87
|
+
"boxen": "^7.0.1",
|
|
91
88
|
"chalk": "^5.2.0",
|
|
89
|
+
"desm": "^1.3.0",
|
|
92
90
|
"execa": "^6.1.0",
|
|
93
91
|
"fs-extra": "^11.1.0",
|
|
94
92
|
"is-wsl": "^2.2.0",
|
|
95
93
|
"java-invoke-local": "0.0.6",
|
|
96
|
-
"jose": "^4.11.
|
|
94
|
+
"jose": "^4.11.2",
|
|
97
95
|
"js-string-escape": "^1.0.1",
|
|
98
96
|
"jsonpath-plus": "^7.2.0",
|
|
99
97
|
"jsonschema": "^1.4.1",
|
|
100
98
|
"jszip": "^3.10.1",
|
|
101
|
-
"luxon": "^3.
|
|
99
|
+
"luxon": "^3.2.0",
|
|
102
100
|
"node-fetch": "^3.3.0",
|
|
103
101
|
"node-schedule": "^2.1.0",
|
|
104
102
|
"object.hasown": "^1.1.2",
|
|
@@ -110,18 +108,19 @@
|
|
|
110
108
|
"devDependencies": {
|
|
111
109
|
"@istanbuljs/esm-loader-hook": "^0.2.0",
|
|
112
110
|
"archiver": "^5.3.1",
|
|
113
|
-
"eslint": "^8.
|
|
111
|
+
"eslint": "^8.31.0",
|
|
114
112
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
115
|
-
"eslint-config-prettier": "^8.
|
|
113
|
+
"eslint-config-prettier": "^8.6.0",
|
|
116
114
|
"eslint-plugin-import": "^2.25.4",
|
|
117
115
|
"eslint-plugin-prettier": "^4.2.1",
|
|
116
|
+
"eslint-plugin-unicorn": "^45.0.2",
|
|
118
117
|
"git-list-updated": "^1.2.1",
|
|
119
|
-
"husky": "^8.0.
|
|
118
|
+
"husky": "^8.0.3",
|
|
120
119
|
"lint-staged": "^13.1.0",
|
|
121
120
|
"mocha": "^10.2.0",
|
|
122
121
|
"nyc": "^15.1.0",
|
|
123
122
|
"prettier": "^2.8.1",
|
|
124
|
-
"serverless": "^3.
|
|
123
|
+
"serverless": "^3.26.0",
|
|
125
124
|
"standard-version": "^9.5.0"
|
|
126
125
|
},
|
|
127
126
|
"peerDependencies": {
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
-
import { dirname, resolve } from 'node:path'
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
4
2
|
import { log } from '@serverless/utils/log.js'
|
|
3
|
+
import { join } from 'desm'
|
|
5
4
|
import OfflineEndpoint from './OfflineEndpoint.js'
|
|
6
5
|
|
|
7
6
|
const { entries } = Object
|
|
8
7
|
|
|
9
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
10
|
-
|
|
11
8
|
// velocity template defaults
|
|
12
9
|
const defaultRequestTemplate = readFileSync(
|
|
13
|
-
|
|
10
|
+
join(import.meta.url, 'templates/offline-default.req.vm'),
|
|
14
11
|
'utf8',
|
|
15
12
|
)
|
|
16
13
|
const defaultResponseTemplate = readFileSync(
|
|
17
|
-
|
|
14
|
+
join(import.meta.url, 'templates/offline-default.res.vm'),
|
|
18
15
|
'utf8',
|
|
19
16
|
)
|
|
20
17
|
|
|
@@ -57,8 +57,8 @@ export default class HttpServer {
|
|
|
57
57
|
|
|
58
58
|
async #loadCerts(httpsProtocol) {
|
|
59
59
|
const [cert, key] = await Promise.all([
|
|
60
|
-
readFile(resolve(httpsProtocol, 'cert.pem'), '
|
|
61
|
-
readFile(resolve(httpsProtocol, 'key.pem'), '
|
|
60
|
+
readFile(resolve(httpsProtocol, 'cert.pem'), 'utf8'),
|
|
61
|
+
readFile(resolve(httpsProtocol, 'key.pem'), 'utf8'),
|
|
62
62
|
])
|
|
63
63
|
|
|
64
64
|
return {
|
|
@@ -328,9 +328,9 @@ export default class HttpServer {
|
|
|
328
328
|
'method.request.header.Authorization',
|
|
329
329
|
identityValidationExpression:
|
|
330
330
|
serverlessAuthorizerOptions?.identityValidationExpression || '(.*)',
|
|
331
|
-
payloadVersion:
|
|
332
|
-
? '
|
|
333
|
-
:
|
|
331
|
+
payloadVersion: endpoint.isHttpApi
|
|
332
|
+
? serverlessAuthorizerOptions?.payloadVersion || '2.0'
|
|
333
|
+
: '1.0',
|
|
334
334
|
resultTtlInSeconds:
|
|
335
335
|
serverlessAuthorizerOptions?.resultTtlInSeconds || '300',
|
|
336
336
|
}
|
|
@@ -502,9 +502,9 @@ export default class HttpServer {
|
|
|
502
502
|
: ''
|
|
503
503
|
|
|
504
504
|
const schemas =
|
|
505
|
-
endpoint?.request?.schemas
|
|
506
|
-
?
|
|
507
|
-
:
|
|
505
|
+
endpoint?.request?.schemas === undefined
|
|
506
|
+
? ''
|
|
507
|
+
: endpoint.request.schemas[contentType]
|
|
508
508
|
|
|
509
509
|
// https://hapijs.com/api#route-configuration doesn't seem to support selectively parsing
|
|
510
510
|
// so we have to do it ourselves
|
|
@@ -519,7 +519,7 @@ export default class HttpServer {
|
|
|
519
519
|
request.payload.length > 1
|
|
520
520
|
) {
|
|
521
521
|
try {
|
|
522
|
-
if (!request.payload || request.payload.length
|
|
522
|
+
if (!request.payload || request.payload.length === 0) {
|
|
523
523
|
request.payload = '{}'
|
|
524
524
|
}
|
|
525
525
|
|
|
@@ -640,7 +640,7 @@ export default class HttpServer {
|
|
|
640
640
|
for (const [key, value] of entries(endpoint.responses)) {
|
|
641
641
|
if (
|
|
642
642
|
key !== 'default' &&
|
|
643
|
-
|
|
643
|
+
`^${value.selectionPattern || key}$`.test(errorMessage)
|
|
644
644
|
) {
|
|
645
645
|
responseName = key
|
|
646
646
|
break
|
|
@@ -685,11 +685,8 @@ export default class HttpServer {
|
|
|
685
685
|
headerValue = valueArray[3]
|
|
686
686
|
? jsonPath(result, valueArray.slice(3).join('.'))
|
|
687
687
|
: result
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
} else {
|
|
691
|
-
headerValue = headerValue.toString()
|
|
692
|
-
}
|
|
688
|
+
|
|
689
|
+
headerValue = headerValue == null ? '' : String(headerValue)
|
|
693
690
|
} else {
|
|
694
691
|
log.notice()
|
|
695
692
|
|
|
@@ -702,7 +699,7 @@ export default class HttpServer {
|
|
|
702
699
|
log.notice()
|
|
703
700
|
}
|
|
704
701
|
} else {
|
|
705
|
-
headerValue =
|
|
702
|
+
headerValue = /^'.*'$/.test(value) ? value.slice(1, -1) : value // See #34
|
|
706
703
|
}
|
|
707
704
|
// Applies the header;
|
|
708
705
|
if (headerValue === '') {
|
|
@@ -748,7 +745,7 @@ export default class HttpServer {
|
|
|
748
745
|
const { responseTemplates } = chosenResponse
|
|
749
746
|
|
|
750
747
|
if (typeof responseTemplates === 'object') {
|
|
751
|
-
if (keys(responseTemplates).length) {
|
|
748
|
+
if (keys(responseTemplates).length > 0) {
|
|
752
749
|
// BAD IMPLEMENTATION: first key in responseTemplates
|
|
753
750
|
const responseTemplate = responseTemplates[responseContentType]
|
|
754
751
|
|
|
@@ -1137,7 +1134,7 @@ export default class HttpServer {
|
|
|
1137
1134
|
|
|
1138
1135
|
const resourceRoutes = parseResources(this.#serverless.service.resources)
|
|
1139
1136
|
|
|
1140
|
-
if (!resourceRoutes ||
|
|
1137
|
+
if (!resourceRoutes || keys(resourceRoutes).length === 0) {
|
|
1141
1138
|
return
|
|
1142
1139
|
}
|
|
1143
1140
|
|
|
@@ -67,7 +67,7 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
let scopes = null
|
|
70
|
-
if (jwtOptions.scopes && jwtOptions.scopes.length) {
|
|
70
|
+
if (jwtOptions.scopes && jwtOptions.scopes.length > 0) {
|
|
71
71
|
if (!scope) {
|
|
72
72
|
log.notice(`JWT Token missing valid scope`)
|
|
73
73
|
|
|
@@ -33,20 +33,25 @@ function renderVelocityString(velocityString, context) {
|
|
|
33
33
|
|
|
34
34
|
// Haaaa Velocity... this language sure loves strings a lot
|
|
35
35
|
switch (renderResult) {
|
|
36
|
-
case 'undefined':
|
|
37
|
-
return undefined
|
|
36
|
+
case 'undefined': {
|
|
37
|
+
return undefined
|
|
38
|
+
} // But we don't, we want JavaScript types
|
|
38
39
|
|
|
39
|
-
case 'null':
|
|
40
|
+
case 'null': {
|
|
40
41
|
return null
|
|
42
|
+
}
|
|
41
43
|
|
|
42
|
-
case 'true':
|
|
44
|
+
case 'true': {
|
|
43
45
|
return true
|
|
46
|
+
}
|
|
44
47
|
|
|
45
|
-
case 'false':
|
|
48
|
+
case 'false': {
|
|
46
49
|
return false
|
|
50
|
+
}
|
|
47
51
|
|
|
48
|
-
default:
|
|
52
|
+
default: {
|
|
49
53
|
return tryToParseJSON(renderResult)
|
|
54
|
+
}
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
|
|
@@ -78,21 +78,25 @@ export default class Schedule {
|
|
|
78
78
|
|
|
79
79
|
switch (unit) {
|
|
80
80
|
case 'minute':
|
|
81
|
-
case 'minutes':
|
|
81
|
+
case 'minutes': {
|
|
82
82
|
return `*/${number} * * * *`
|
|
83
|
+
}
|
|
83
84
|
|
|
84
85
|
case 'hour':
|
|
85
|
-
case 'hours':
|
|
86
|
+
case 'hours': {
|
|
86
87
|
return `0 */${number} * * *`
|
|
88
|
+
}
|
|
87
89
|
|
|
88
90
|
case 'day':
|
|
89
|
-
case 'days':
|
|
91
|
+
case 'days': {
|
|
90
92
|
return `0 0 */${number} * *`
|
|
93
|
+
}
|
|
91
94
|
|
|
92
|
-
default:
|
|
95
|
+
default: {
|
|
93
96
|
log.error(`scheduler: Invalid rate syntax '${rate}', will not schedule`)
|
|
94
97
|
|
|
95
98
|
return null
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -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'), '
|
|
23
|
-
readFile(resolve(httpsProtocol, 'key.pem'), '
|
|
22
|
+
readFile(resolve(httpsProtocol, 'cert.pem'), 'utf8'),
|
|
23
|
+
readFile(resolve(httpsProtocol, 'key.pem'), 'utf8'),
|
|
24
24
|
])
|
|
25
25
|
|
|
26
26
|
return {
|
|
@@ -95,13 +95,7 @@ export default class DockerContainer {
|
|
|
95
95
|
if (this.#layers.length > 0) {
|
|
96
96
|
log.verbose(`Found layers, checking provider type`)
|
|
97
97
|
|
|
98
|
-
if (this.#provider.name.toLowerCase()
|
|
99
|
-
log.warning(
|
|
100
|
-
`Provider ${
|
|
101
|
-
this.#provider.name
|
|
102
|
-
} is Unsupported. Layers are only supported on aws.`,
|
|
103
|
-
)
|
|
104
|
-
} else {
|
|
98
|
+
if (this.#provider.name.toLowerCase() === 'aws') {
|
|
105
99
|
let layerDir = this.#dockerOptions.layersDir
|
|
106
100
|
|
|
107
101
|
if (!layerDir) {
|
|
@@ -142,6 +136,12 @@ export default class DockerContainer {
|
|
|
142
136
|
)
|
|
143
137
|
}
|
|
144
138
|
dockerArgs.push('-v', `${layerDir}:/opt:ro,delegated`)
|
|
139
|
+
} else {
|
|
140
|
+
log.warning(
|
|
141
|
+
`Provider ${
|
|
142
|
+
this.#provider.name
|
|
143
|
+
} is Unsupported. Layers are only supported on aws.`,
|
|
144
|
+
)
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -106,7 +106,7 @@ export default class GoRunner {
|
|
|
106
106
|
// Get go env to run this locally
|
|
107
107
|
if (!this.#goEnv) {
|
|
108
108
|
const goEnvResponse = await execa('go', ['env'], {
|
|
109
|
-
encoding: '
|
|
109
|
+
encoding: 'utf8',
|
|
110
110
|
stdio: 'pipe',
|
|
111
111
|
})
|
|
112
112
|
|
|
@@ -136,7 +136,7 @@ export default class GoRunner {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
const { stdout, stderr } = await execa(`./tmp`, {
|
|
139
|
-
encoding: '
|
|
139
|
+
encoding: 'utf8',
|
|
140
140
|
env: {
|
|
141
141
|
...this.#env,
|
|
142
142
|
...this.#goEnv,
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
2
|
import { EOL, platform } from 'node:os'
|
|
3
|
-
import { delimiter,
|
|
3
|
+
import { delimiter, join as pathJoin, relative } from 'node:path'
|
|
4
4
|
import process, { cwd, nextTick } from 'node:process'
|
|
5
5
|
import { createInterface } from 'node:readline'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
6
|
import { log } from '@serverless/utils/log.js'
|
|
7
|
+
import { join } from 'desm'
|
|
8
8
|
import { splitHandlerPathAndName } from '../../../utils/index.js'
|
|
9
9
|
|
|
10
10
|
const { parse, stringify } = JSON
|
|
11
11
|
const { assign, hasOwn } = Object
|
|
12
12
|
|
|
13
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
14
|
-
|
|
15
13
|
export default class PythonRunner {
|
|
16
14
|
static #payloadIdentifier = '__offline_payload__'
|
|
17
15
|
|
|
@@ -32,7 +30,7 @@ export default class PythonRunner {
|
|
|
32
30
|
const runtimeDir = platform() === 'win32' ? 'Scripts' : 'bin'
|
|
33
31
|
|
|
34
32
|
process.env.PATH = [
|
|
35
|
-
|
|
33
|
+
pathJoin(process.env.VIRTUAL_ENV, runtimeDir),
|
|
36
34
|
delimiter,
|
|
37
35
|
process.env.PATH,
|
|
38
36
|
].join('')
|
|
@@ -44,7 +42,7 @@ export default class PythonRunner {
|
|
|
44
42
|
pythonExecutable,
|
|
45
43
|
[
|
|
46
44
|
'-u',
|
|
47
|
-
|
|
45
|
+
join(import.meta.url, 'invoke.py'),
|
|
48
46
|
relative(cwd(), handlerPath),
|
|
49
47
|
handlerName,
|
|
50
48
|
],
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { EOL, platform } from 'node:os'
|
|
2
|
-
import {
|
|
2
|
+
import { relative } from 'node:path'
|
|
3
3
|
import { cwd } from 'node:process'
|
|
4
|
-
import { fileURLToPath } from 'node:url'
|
|
5
4
|
import { log } from '@serverless/utils/log.js'
|
|
5
|
+
import { join } from 'desm'
|
|
6
6
|
import { execa } from 'execa'
|
|
7
7
|
import { splitHandlerPathAndName } from '../../../utils/index.js'
|
|
8
8
|
|
|
9
9
|
const { parse, stringify } = JSON
|
|
10
10
|
const { hasOwn } = Object
|
|
11
11
|
|
|
12
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
13
|
-
|
|
14
12
|
export default class RubyRunner {
|
|
15
13
|
static #payloadIdentifier = '__offline_payload__'
|
|
16
14
|
|
|
@@ -86,7 +84,7 @@ export default class RubyRunner {
|
|
|
86
84
|
const { stderr, stdout } = await execa(
|
|
87
85
|
runtime,
|
|
88
86
|
[
|
|
89
|
-
|
|
87
|
+
join(import.meta.url, 'invoke.rb'),
|
|
90
88
|
relative(cwd(), this.#handlerPath),
|
|
91
89
|
this.#handlerName,
|
|
92
90
|
],
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import { dirname, resolve } from 'node:path'
|
|
2
|
-
import { fileURLToPath } from 'node:url'
|
|
3
1
|
import { MessageChannel, Worker } from 'node:worker_threads'
|
|
4
|
-
|
|
5
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
6
|
-
const workerThreadHelperPath = resolve(__dirname, 'workerThreadHelper.js')
|
|
2
|
+
import { join } from 'desm'
|
|
7
3
|
|
|
8
4
|
export default class WorkerThreadRunner {
|
|
9
5
|
#workerThread = null
|
|
@@ -11,17 +7,20 @@ export default class WorkerThreadRunner {
|
|
|
11
7
|
constructor(funOptions, env) {
|
|
12
8
|
const { codeDir, functionKey, handler, servicePath, timeout } = funOptions
|
|
13
9
|
|
|
14
|
-
this.#workerThread = new Worker(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
this.#workerThread = new Worker(
|
|
11
|
+
join(import.meta.url, 'workerThreadHelper.js'),
|
|
12
|
+
{
|
|
13
|
+
// don't pass process.env from the main process!
|
|
14
|
+
env,
|
|
15
|
+
workerData: {
|
|
16
|
+
codeDir,
|
|
17
|
+
functionKey,
|
|
18
|
+
handler,
|
|
19
|
+
servicePath,
|
|
20
|
+
timeout,
|
|
21
|
+
},
|
|
23
22
|
},
|
|
24
|
-
|
|
23
|
+
)
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
// () => Promise<number>
|
|
@@ -25,11 +25,11 @@ export default function invocationsRoute(lambda, options) {
|
|
|
25
25
|
// check client context header was set
|
|
26
26
|
if (clientContextHeader) {
|
|
27
27
|
const clientContextBuffer = Buffer.from(clientContextHeader, 'base64')
|
|
28
|
-
clientContext = parse(clientContextBuffer.toString('
|
|
28
|
+
clientContext = parse(clientContextBuffer.toString('utf8'))
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// check if payload was set, if not, default event is an empty object
|
|
32
|
-
const event = payload.length > 0 ? parse(payload.toString('
|
|
32
|
+
const event = payload.length > 0 ? parse(payload.toString('utf8')) : {}
|
|
33
33
|
|
|
34
34
|
const invokeResults = await invocationsController.invoke(
|
|
35
35
|
functionName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import unflat from 'array-unflat-js'
|
|
2
2
|
|
|
3
3
|
const { fromEntries } = Object
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ export default function parseHeaders(rawHeaders) {
|
|
|
8
8
|
return null
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const unflattened =
|
|
11
|
+
const unflattened = unflat(rawHeaders)
|
|
12
12
|
|
|
13
13
|
return fromEntries(unflattened)
|
|
14
14
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import unflat from 'array-unflat-js'
|
|
2
2
|
|
|
3
3
|
const { fromEntries } = Object
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export default function parseMultiValueHeaders(rawHeaders) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const map = new Map()
|
|
13
|
-
const unflattened =
|
|
13
|
+
const unflattened = unflat(rawHeaders)
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line no-restricted-syntax
|
|
16
16
|
for (const [key, value] of unflattened) {
|
|
@@ -8,7 +8,7 @@ export default function splitHandlerPathAndName(handler) {
|
|
|
8
8
|
// filename: source
|
|
9
9
|
// path: ./src/somefolder/source
|
|
10
10
|
// name: LambdaFunctions::Handler.process
|
|
11
|
-
if (handler
|
|
11
|
+
if (/::/.test(handler)) {
|
|
12
12
|
const prepathDelimiter = handler.lastIndexOf('/')
|
|
13
13
|
const prepath = handler.substr(0, prepathDelimiter + 1) // include '/' for path
|
|
14
14
|
const postpath = handler.substr(prepathDelimiter + 1)
|
package/src/utils/unflatten.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// [0, 1, 2, 3, 4 ,5] => [[0, 1], [2, 3], [4, 5]]
|
|
2
|
-
export default function unflatten(value, size) {
|
|
3
|
-
const unflattened = []
|
|
4
|
-
|
|
5
|
-
for (let i = 0; i < value.length; i += size) {
|
|
6
|
-
const slice = value.slice(i, i + size)
|
|
7
|
-
unflattened.push(slice)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return unflattened
|
|
11
|
-
}
|