Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't throw errors in http-event-normalizer #1132

Closed
Closed
Changes from 1 commit
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
886935d
fix(appconfig): #1009 rewrite to not use deprecated appconfig getConf…
mju-spyrosoft Mar 13, 2023
c2ac7e8
fix(appconfig): #1009 add internal cache for previous configuration
mju-spyrosoft Mar 13, 2023
09e2419
test(appconfig): #1009 update skipped tests
mju-spyrosoft Mar 13, 2023
2dab467
test(appconfig): #1009 add todos for missing tests cases
mju-spyrosoft Mar 13, 2023
e2c4c0a
Merge branch 'feature/appconfig' into fix/appconfig-throws-error-when…
willfarrell Mar 14, 2023
3f02a80
fix(appconfig): #1009 update types and type tests
mju-spyrosoft Mar 15, 2023
2cab2ff
fix(appconfig): #1009 uninstall @aws-sdk/client-appconfig
mju-spyrosoft Mar 15, 2023
5a1c2af
fix(appconfig): #1009 npm install
mju-spyrosoft Mar 15, 2023
9f898a4
fix(appconfig): #1009 add missing tests cases
mju-spyrosoft Mar 16, 2023
77ac83c
fix(appconfig): #1009 fix bug when configuration is returned as empty…
mju-spyrosoft Mar 16, 2023
27ec63d
chore(appconfig): #1009 lint d.ts files
mju-spyrosoft Mar 17, 2023
b637934
test(appconfig): add test for fetching multiple parameters
mju-spyrosoft Mar 20, 2023
f414b64
Merge branch 'feature/appconfig' into fix/appconfig-throws-error-when…
willfarrell Mar 25, 2023
58acca6
Merge pull request #1029 from mju-spyrosoft/fix/appconfig-throws-erro…
willfarrell Mar 25, 2023
f8fcdda
ci: fix lock file
willfarrell Mar 25, 2023
08c35e3
chore: bump node version
willfarrell Mar 25, 2023
8633ff6
ci: bump es version
willfarrell Mar 25, 2023
3c1df2b
feat: update all errors to be in consistent format
willfarrell Mar 25, 2023
1c86a6a
feat: update default options
willfarrell Mar 25, 2023
88c8b06
Merge branch 'main' into release/5.0
willfarrell Mar 25, 2023
d1b69b8
docs: add in iam
willfarrell Mar 25, 2023
aff55c8
Merge branch 'main' into release/5.0
willfarrell Mar 26, 2023
d34b7ec
docs: update required dep
willfarrell Mar 26, 2023
3ee08db
docs: add breaking change steps
willfarrell Mar 26, 2023
b2d8f20
feat: refactor to use fetch
willfarrell Mar 26, 2023
a8a91d3
chore: remove console
willfarrell Mar 26, 2023
bb2319c
fix: use structuredClone
willfarrell Mar 26, 2023
9d92432
Merge branch 'main' into release/5.0
willfarrell Apr 10, 2023
334e5a0
ci: fix test or error.cause
willfarrell Apr 10, 2023
6dafaef
fix: update to match ttp-content-negotiation
willfarrell Apr 10, 2023
fa02bec
Merge branch 'main' into release/5.0
willfarrell Apr 13, 2023
ac495f4
Merge branch '4.x' into release/5.0
willfarrell Apr 17, 2023
fce9e4f
Merge branch 'main' into release/5.0
willfarrell Apr 22, 2023
6f83c8f
fix: prefer no preflight response
willfarrell Apr 22, 2023
3bd8ecc
docs: fix middleware image
willfarrell Apr 27, 2023
122aa7d
Merge branch 'main' into release/5.0
willfarrell May 15, 2023
f8af3d6
fix: small perf improvement
willfarrell May 15, 2023
97743e3
Merge branch 'main' into release/5.0
willfarrell May 15, 2023
0759cc7
chore: dep update
willfarrell May 15, 2023
3626141
ci: dep update
willfarrell May 15, 2023
a1d6654
ci: bump node version
willfarrell May 15, 2023
b36df23
feat: allow access to context/event
willfarrell May 17, 2023
fd0c36d
feat: update to match middleware changes
willfarrell May 17, 2023
14e94db
docs: grammer
willfarrell May 17, 2023
0c55248
Merge branch 'main' into release/5.0
willfarrell May 18, 2023
d7a7db8
Merge branch 'main' into release/5.0
willfarrell Jun 9, 2023
a955b9b
Merge branch 'main' into release/5.0
willfarrell Jul 21, 2023
84c1f80
chore: dep update
willfarrell Jul 21, 2023
84ccf59
Merge branch '4.x' into release/5.0
willfarrell Aug 10, 2023
548ef2f
docs: add award
willfarrell Aug 22, 2023
ddd6619
Green CI for 5.0 (#1090)
lmammino Aug 25, 2023
5e78b0b
chore: dep update
willfarrell Aug 25, 2023
335f3d3
fix: appconfig unit tests
willfarrell Aug 25, 2023
8eafd4e
chore: dep update
willfarrell Aug 25, 2023
9a56a94
feat: type for Internal storage with partial ssm support
m-radzikowski Aug 26, 2023
68be775
chore: fix formatting
m-radzikowski Aug 27, 2023
510202c
Merge branch 'main' into release/5.0
willfarrell Sep 1, 2023
a0785be
feat: add in onError
willfarrell Sep 1, 2023
47f4f92
chore: dep update
willfarrell Sep 1, 2023
31caf32
Merge branch 'main' into release/5.0
willfarrell Sep 1, 2023
533162e
feat: type definition improvements for getInternal
lmammino Sep 8, 2023
4397f79
chore: made ts-lint happy
lmammino Sep 8, 2023
4d4ec6e
chore: added comment about the current state of `getInternal` type
lmammino Sep 8, 2023
35137d8
chore: ts-lint --fix the whole world, please
lmammino Sep 8, 2023
331f342
chore: updated SSM types and tests to make sure internal context is p…
lmammino Sep 8, 2023
f7e04d1
chore: type changes
lmammino Sep 8, 2023
d0966c6
feat(json-body-parser): allow specifying versioned events
naorpeled Sep 9, 2023
bcf035c
chore: cleanup
naorpeled Sep 9, 2023
653c035
chore: organize imports
naorpeled Sep 9, 2023
6abc083
chore: applied @wtfzambo suggestions
lmammino Sep 15, 2023
a76918a
feat: getInternal type supports resolving promises and property paths…
lmammino Sep 16, 2023
6f06dd4
chore: resolve conflict with packages/util/package-lock.json
lmammino Sep 16, 2023
50d42a0
feat: fixes issues with the SSM middleware removing type-fest and lim…
lmammino Sep 16, 2023
35ba1df
chore: ts-lint
lmammino Sep 16, 2023
70428f5
chore: replaces some never with unknown as suggested by @jfet97
lmammino Sep 17, 2023
b9430a5
Merge branch 'main' into release/5.0
willfarrell Sep 17, 2023
7364d6a
feat: make ajv-cmd optional
willfarrell Sep 17, 2023
2342b52
Merge pull request #1100 from naorpeled/feat/json-body-parser/support…
willfarrell Sep 17, 2023
2c2d858
Merge branch 'main' into release/5.0
willfarrell Sep 17, 2023
6eba6db
chore: resolve conflict with 5.0 branch
lmammino Sep 22, 2023
dc7b448
chore: resolve conflict with 5.0 branch, again
lmammino Sep 22, 2023
b3d1192
feat: added improved types for AppConfig middleware
lmammino Sep 22, 2023
705438d
Merge branch 'release/5.0' into internal-typing
lmammino Sep 22, 2023
49c8f22
chore: re-aligned appconfig with v5 branch
lmammino Sep 22, 2023
0b551d8
ci: drop cjs support
willfarrell Sep 25, 2023
1076c83
fix(http-json-body-parser): tests in Node 20
lmammino Sep 29, 2023
abd56f6
fix(ws-json-body-parser): tests in Node 20
lmammino Sep 29, 2023
05cd8ec
feat(dynamodb): improved typing
lmammino Sep 29, 2023
a2ab8d7
feat(s3): improved types
lmammino Sep 29, 2023
4716ef7
feat(s3): improved types
lmammino Sep 29, 2023
1ce5bdd
feat: updated types for rds-signer
lmammino Oct 6, 2023
6d376fd
feat: updated types for rds-signer
lmammino Oct 6, 2023
be5ccbf
feat(s3-object-response): improved type definitions and tests
lmammino Oct 7, 2023
b5d2415
feat(secrets-manager): improved type definitions and tests
lmammino Oct 7, 2023
4f5a619
feat(service-discovery): improved type definitions and tests
lmammino Oct 8, 2023
3c4c524
feat(sts): improved type definitions and tests
lmammino Oct 8, 2023
a673016
feat(rds-signer): removed unnecessary `database` property
lmammino Oct 8, 2023
43ec341
Merge branch 'main' into release/5.0
willfarrell Oct 8, 2023
776b2f0
Merge pull request #1093 from m-radzikowski/internal-typing
willfarrell Oct 8, 2023
24399d6
chore: dep update
willfarrell Oct 8, 2023
ebce8d5
chore: version bump
willfarrell Oct 8, 2023
2df9561
chore: version bump
willfarrell Oct 8, 2023
ad54041
fix: clean up database ref
willfarrell Oct 8, 2023
f28e53d
docs: update relase date
willfarrell Oct 8, 2023
a477a1b
Revert "chore: version bump"
willfarrell Oct 8, 2023
0a70604
chore: version bump
willfarrell Oct 8, 2023
504c482
fix(http-error-handler): non http errors will be handled as 'Internal…
qoomon Oct 27, 2023
e6c3889
docs: flag breaking change
willfarrell Nov 8, 2023
153d764
Merge branch 'main' into release/5.0
willfarrell Nov 8, 2023
ded7a13
chore: dep update
willfarrell Nov 8, 2023
4c99241
fix: extra )
willfarrell Nov 8, 2023
b843f9d
Merge pull request #1117 from qoomon/patch-1
willfarrell Nov 8, 2023
9b3e5dd
test: update to be cleaner and easier to use
willfarrell Nov 8, 2023
ef7656a
Merge branch 'main' into release/5.0
willfarrell Nov 8, 2023
b472ea4
docs: ensure all example use the same pattern
willfarrell Nov 8, 2023
60bbf17
feat(website): updated docusaurus v3 and minor style improvements
lmammino Nov 11, 2023
a98b28d
feat(website): update use with typescript
lmammino Nov 11, 2023
5644e76
Merge pull request #1130 from middyjs/feat-improve-ts-docs
willfarrell Nov 11, 2023
583a3b0
Merge pull request #1129 from middyjs/update-website-to-docusaurus3
willfarrell Nov 11, 2023
21828af
fix(middlewares/http-json-body-parser): narrow body type to string
naorpeled Nov 11, 2023
53c0166
fix(style): lint
naorpeled Nov 11, 2023
a996c81
Merge branch 'release/5.0' into fix/http-json-body-parser/resolve-typ…
naorpeled Nov 11, 2023
7effb08
Merge branch 'main' into release/5.0
willfarrell Nov 11, 2023
d1dd479
chore: rebase
naorpeled Nov 11, 2023
612d897
chore: rebase
naorpeled Nov 11, 2023
721ef58
chore: rebase
naorpeled Nov 11, 2023
1c4f5a2
chore: rebase
naorpeled Nov 11, 2023
2136d53
Merge pull request #1131 from naorpeled/fix/http-json-body-parser/res…
willfarrell Nov 11, 2023
a78c183
docs: update issue template
willfarrell Nov 11, 2023
a8fc81a
chore: clean up
willfarrell Nov 11, 2023
403c54b
chore: dep update
willfarrell Nov 11, 2023
581621f
chore: version bump
willfarrell Nov 11, 2023
483bb3f
docs: add in aka
willfarrell Nov 11, 2023
7cb665f
fix: don't throw errors in http-event-normalizer
robertbeal Nov 14, 2023
6711a20
chore: add back in removed comment
robertbeal Nov 15, 2023
75d1b50
fix: don't throw errors in http-event-normalizer
robertbeal Nov 14, 2023
ce7b18d
chore: rebase on to release/5.0:x
robertbeal Nov 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ci: fix test or error.cause
willfarrell committed Apr 10, 2023

Verified

This commit was signed with the committer’s verified signature.
commit 334e5a00929bb9de69504278b9be8f4c63094077
4 changes: 2 additions & 2 deletions packages/appconfig/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -532,7 +532,7 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(mockService.send.callCount, 2)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})

@@ -562,7 +562,7 @@ test.serial(
} catch (e) {
t.is(mockService.send.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
}
)
931 changes: 482 additions & 449 deletions packages/appconfig/package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions packages/cloudwatch-metrics/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

138 changes: 135 additions & 3 deletions packages/core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -65,5 +65,8 @@
"@types/aws-lambda": "^8.10.76",
"@types/node": "^18.0.0"
},
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
"dependencies": {
"@datastream/core": "0.0.29"
}
}
8 changes: 4 additions & 4 deletions packages/do-not-wait-for-empty-event-loop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/dynamodb/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -305,6 +305,6 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})
969 changes: 501 additions & 468 deletions packages/dynamodb/package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions packages/error-logger/package-lock.json
22 changes: 11 additions & 11 deletions packages/event-normalizer/package-lock.json
6 changes: 3 additions & 3 deletions packages/http-content-encoding/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ test('It should encode string using deflate', async (t) => {
})
})

test('It should encode using br when event.preferredEncoding is gzip, but has overridePreferredEncoding set', async (t) => {
test('It should encode using br when context.preferredEncoding is gzip, but has overridePreferredEncoding set', async (t) => {
const body = compressibleBody
const handler = middy((event, context) => ({ statusCode: 200, body }))
handler.use(
@@ -93,7 +93,7 @@ test('It should encode using br when event.preferredEncoding is gzip, but has ov
})
})

test('It should not encode when missing event.preferredEncoding', async (t) => {
test('It should not encode when missing context.preferredEncoding', async (t) => {
const body = 'test'
const handler = middy((event, context) => ({ statusCode: 200, body }))
handler.use(httpContentEncoding())
@@ -105,7 +105,7 @@ test('It should not encode when missing event.preferredEncoding', async (t) => {
t.deepEqual(response, { statusCode: 200, body, headers: {} })
})

test('It should not encode when missing event.preferredEncoding === `identity`', async (t) => {
test('It should not encode when missing context.preferredEncoding === `identity`', async (t) => {
const body = 'test'
const handler = middy((event, context) => ({ statusCode: 200, body }))
handler.use(httpContentEncoding())
16 changes: 8 additions & 8 deletions packages/http-content-encoding/package-lock.json
315 changes: 146 additions & 169 deletions packages/http-content-negotiation/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -6,152 +6,149 @@ const context = {
getRemainingTimeInMillis: () => 1000
}

test('It should parse charset, encoding, language and media type', async (t) => {
const handler = middy((event, context) => event)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
availableEncodings: undefined,
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
})
)
test.serial(
'It should parse charset, encoding, language and media type',
async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
availableEncodings: undefined,
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
})
)

const event = {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
const event = {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
}
}
}

const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
preferredCharsets: ['utf-8'],
preferredCharset: 'utf-8',
preferredEncodings: ['*/*', 'identity'],
preferredEncoding: '*/*',
preferredLanguages: ['en-gb'],
preferredLanguage: 'en-gb',
preferredMediaTypes: ['text/x-dvi', 'text/plain'],
preferredMediaType: 'text/x-dvi'
})
})

test('It should parse charset, encoding, language and media type with lowercase headers', async (t) => {
const handler = middy((event, context) => event)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-16'],
availableEncodings: ['br', 'gzip'],
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
const resultingContext = await handler(event, context)

t.deepEqual(resultingContext, {
...context,
preferredCharsets: ['utf-8'],
preferredCharset: 'utf-8',
preferredEncodings: ['*/*', 'identity'],
preferredEncoding: '*/*',
preferredLanguages: ['en-gb'],
preferredLanguage: 'en-gb',
preferredMediaTypes: ['text/x-dvi', 'text/plain'],
preferredMediaType: 'text/x-dvi'
})
)

const event = {
headers: {
'accept-charset': 'utf-16, iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'gzip, br, deflate',
'accept-language': 'da, en-gb;q=0.8, en;q=0.7',
accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
}
}
)

test.serial(
'It should parse charset, encoding, language and media type with lowercase headers',
async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-16'],
availableEncodings: ['br', 'gzip'],
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
})
)

const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'accept-charset': 'utf-16, iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'gzip, br, deflate',
'accept-language': 'da, en-gb;q=0.8, en;q=0.7',
accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
preferredCharsets: ['utf-16'],
preferredCharset: 'utf-16',
preferredEncodings: ['gzip', 'br'],
preferredEncoding: 'gzip',
preferredLanguages: ['en-gb'],
preferredLanguage: 'en-gb',
preferredMediaTypes: ['text/x-dvi', 'text/plain'],
preferredMediaType: 'text/x-dvi'
})
})
const event = {
headers: {
'accept-charset': 'utf-16, iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'gzip, br, deflate',
'accept-language': 'da, en-gb;q=0.8, en;q=0.7',
accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
}
}

test('It should default charset, encoding, language and media type when there is a mismatch', async (t) => {
const handler = middy((event, context) => event)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-16'],
defaultToFirstCharset: true,
availableEncodings: ['br', 'gzip'],
defaultToFirstEncoding: true,
availableLanguages: ['en'],
defaultToFirstLanguage: true,
availableMediaTypes: ['text/plain'],
defaultToFirstMediaType: true
const resultingContext = await handler(event, context)

t.deepEqual(resultingContext, {
...context,
preferredCharsets: ['utf-16'],
preferredCharset: 'utf-16',
preferredEncodings: ['gzip', 'br'],
preferredEncoding: 'gzip',
preferredLanguages: ['en-gb'],
preferredLanguage: 'en-gb',
preferredMediaTypes: ['text/x-dvi', 'text/plain'],
preferredMediaType: 'text/x-dvi'
})
)

const event = {
headers: {
'accept-charset': 'iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'deflate',
'accept-language': 'da, fr;q=0.8',
accept: 'text/html, text/x-dvi; q=0.8, text/x-c'
}
}
)

test.serial(
'It should default charset, encoding, language and media type when there is a mismatch',
async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-16'],
defaultToFirstCharset: true,
availableEncodings: ['br', 'gzip'],
defaultToFirstEncoding: true,
availableLanguages: ['en'],
defaultToFirstLanguage: true,
availableMediaTypes: ['text/plain'],
defaultToFirstMediaType: true
})
)

const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'accept-charset': 'iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'deflate',
'accept-language': 'da, fr;q=0.8',
accept: 'text/html, text/x-dvi; q=0.8, text/x-c'
},
preferredCharsets: [],
preferredCharset: 'utf-16',
preferredEncodings: [],
preferredEncoding: 'br',
preferredLanguages: [],
preferredLanguage: 'en',
preferredMediaTypes: [],
preferredMediaType: 'text/plain'
})
})
const event = {
headers: {
'accept-charset': 'iso-8859-5, unicode-1-1;q=0.8',
'accept-encoding': 'deflate',
'accept-language': 'da, fr;q=0.8',
accept: 'text/html, text/x-dvi; q=0.8, text/x-c'
}
}

test('It should skip the middleware if no headers are sent', async (t) => {
const handler = middy((event, context) => event)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
availableEncodings: undefined,
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
const resultingContext = await handler(event, context)

t.deepEqual(resultingContext, {
...context,
preferredCharsets: [],
preferredCharset: 'utf-16',
preferredEncodings: [],
preferredEncoding: 'br',
preferredLanguages: [],
preferredLanguage: 'en',
preferredMediaTypes: [],
preferredMediaType: 'text/plain'
})
)

const event = {
foo: 'bar'
}
)

test.serial(
'It should skip the middleware if no headers are sent',
async (t) => {
const handler = middy((event, context) => event)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
availableEncodings: undefined,
availableLanguages: ['en-gb'],
availableMediaTypes: ['text/plain', 'text/x-dvi']
})
)

const resultingEvent = await handler(event, context)
const event = {
foo: 'bar'
}

t.deepEqual(resultingEvent, { foo: 'bar' })
})
const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent, { foo: 'bar' })
}
)

test('It should not parse charset if disabled', async (t) => {
const handler = middy((event, context) => event)
test.serial('It should not parse charset if disabled', async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
parseCharsets: false,
@@ -170,15 +167,10 @@ test('It should not parse charset if disabled', async (t) => {
}
}

const resultingEvent = await handler(event, context)
const resultingContext = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
t.deepEqual(resultingContext, {
...context,
preferredEncodings: ['*/*', 'identity'],
preferredEncoding: '*/*',
preferredLanguages: ['en-gb'],
@@ -188,8 +180,8 @@ test('It should not parse charset if disabled', async (t) => {
})
})

test('It should not parse encoding if disabled', async (t) => {
const handler = middy((event, context) => event)
test.serial('It should not parse encoding if disabled', async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
@@ -208,15 +200,10 @@ test('It should not parse encoding if disabled', async (t) => {
}
}

const resultingEvent = await handler(event, context)
const resultingContext = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
t.deepEqual(resultingContext, {
...context,
preferredCharsets: ['utf-8'],
preferredCharset: 'utf-8',
preferredLanguages: ['en-gb'],
@@ -227,7 +214,7 @@ test('It should not parse encoding if disabled', async (t) => {
})

test('It should not parse language if disabled', async (t) => {
const handler = middy((event, context) => event)
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
@@ -246,15 +233,10 @@ test('It should not parse language if disabled', async (t) => {
}
}

const resultingEvent = await handler(event, context)
const resultingContext = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
t.deepEqual(resultingContext, {
...context,
preferredCharsets: ['utf-8'],
preferredCharset: 'utf-8',
preferredEncodings: ['*/*', 'identity'],
@@ -264,8 +246,8 @@ test('It should not parse language if disabled', async (t) => {
})
})

test('It should not parse media types if disabled', async (t) => {
const handler = middy((event, context) => event)
test.serial('It should not parse media types if disabled', async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableCharsets: ['utf-8'],
@@ -284,15 +266,10 @@ test('It should not parse media types if disabled', async (t) => {
}
}

const resultingEvent = await handler(event, context)
const resultingContext = await handler(event, context)

t.deepEqual(resultingEvent, {
headers: {
'Accept-Charset': 'utf-8, iso-8859-5, unicode-1-1;q=0.8',
'Accept-Encoding': '*/*',
'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7',
Accept: 'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c'
},
t.deepEqual(resultingContext, {
...context,
preferredCharsets: ['utf-8'],
preferredCharset: 'utf-8',
preferredEncodings: ['*/*', 'identity'],
@@ -302,8 +279,8 @@ test('It should not parse media types if disabled', async (t) => {
})
})

test('It should fail when mismatching', async (t) => {
const handler = middy((event, context) => event)
test.serial('It should fail when mismatching', async (t) => {
const handler = middy((event, context) => context)
handler.use(
httpContentNegotiation({
availableMediaTypes: ['text/plain', 'text/x-dvi']
6 changes: 4 additions & 2 deletions packages/http-content-negotiation/index.d.ts
Original file line number Diff line number Diff line change
@@ -12,7 +12,9 @@ interface Options {
failOnMismatch?: boolean
}

export interface Event {
export interface Event {}

export interface Context {
preferredCharsets: string[]
preferredCharset: string
preferredEncodings: string[]
@@ -23,7 +25,7 @@ export interface Event {
preferredMediaType: string
}

declare function httpContentNegotiation (
declare function httpContentNegotiation(
options?: Options
): middy.MiddlewareObj<Event>

30 changes: 18 additions & 12 deletions packages/http-content-negotiation/index.js
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ const defaults = {
// defaultToFirstEncoding: false, // Should not be used
parseLanguages: true,
availableLanguages: undefined,
defaultToFirstLanguage: false,
// defaultToFirstLanguage: false, // Should not be used
parseMediaTypes: true,
availableMediaTypes: undefined,
// defaultToFirstMediaType: false, // Should not be used
@@ -31,7 +31,7 @@ const httpContentNegotiationMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts }

const httpContentNegotiationMiddlewareBefore = async (request) => {
const { event } = request
const { event, context } = request
if (!event.headers) return
if (options.parseCharsets) {
parseHeader(
@@ -40,7 +40,8 @@ const httpContentNegotiationMiddleware = (opts = {}) => {
options.availableCharsets,
options.defaultToFirstCharset,
options.failOnMismatch,
event
event,
context
)
}

@@ -51,7 +52,8 @@ const httpContentNegotiationMiddleware = (opts = {}) => {
options.availableEncodings,
options.defaultToFirstEncoding,
options.failOnMismatch,
event
event,
context
)
}

@@ -62,7 +64,8 @@ const httpContentNegotiationMiddleware = (opts = {}) => {
options.availableLanguages,
options.defaultToFirstLanguage,
options.failOnMismatch,
event
event,
context
)
}

@@ -73,7 +76,8 @@ const httpContentNegotiationMiddleware = (opts = {}) => {
options.availableMediaTypes,
options.defaultToFirstMediaType,
options.failOnMismatch,
event
event,
context
)
}
}
@@ -89,19 +93,21 @@ const parseHeader = (
availableValues,
defaultToFirstValue,
failOnMismatch,
event
event,
context
) => {
const resultsName = `preferred${type}s`
const resultName = `preferred${type}`
const headerValue =
event.headers[headerName] ?? event.headers[headerName.toLowerCase()]
event[resultsName] = parseFn[type](headerValue, availableValues)
event[resultName] = event[resultsName][0]

if (defaultToFirstValue && event[resultName] === undefined) {
event[resultName] = availableValues[0]
context[resultsName] = parseFn[type](headerValue, availableValues)
context[resultName] = context[resultsName][0]

if (defaultToFirstValue && context[resultName] === undefined) {
context[resultName] = availableValues[0]
}
if (failOnMismatch && event[resultName] === undefined) {
if (failOnMismatch && context[resultName] === undefined) {
// NotAcceptable
throw createError(
406,
16 changes: 8 additions & 8 deletions packages/http-content-negotiation/package-lock.json
16 changes: 8 additions & 8 deletions packages/http-cors/package-lock.json
22 changes: 11 additions & 11 deletions packages/http-error-handler/package-lock.json
8 changes: 4 additions & 4 deletions packages/http-event-normalizer/package-lock.json
8 changes: 4 additions & 4 deletions packages/http-header-normalizer/package-lock.json
22 changes: 11 additions & 11 deletions packages/http-json-body-parser/package-lock.json
22 changes: 11 additions & 11 deletions packages/http-multipart-body-parser/package-lock.json
16 changes: 8 additions & 8 deletions packages/http-partial-response/package-lock.json
16 changes: 8 additions & 8 deletions packages/http-response-serializer/package-lock.json
16 changes: 8 additions & 8 deletions packages/http-router/package-lock.json
16 changes: 8 additions & 8 deletions packages/http-security-headers/package-lock.json
22 changes: 11 additions & 11 deletions packages/http-urlencode-body-parser/package-lock.json
14 changes: 7 additions & 7 deletions packages/http-urlencode-path-parser/package-lock.json
29 changes: 7 additions & 22 deletions packages/input-output-logger/package-lock.json
4 changes: 2 additions & 2 deletions packages/rds-signer/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -281,7 +281,7 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(stub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})

@@ -313,7 +313,7 @@ test.serial(
} catch (e) {
t.is(stub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [
t.deepEqual(e.cause.data, [
new Error('X-Amz-Security-Token Missing', {
cause: { package: '@middy/rds-signer' }
})
1,523 changes: 1,048 additions & 475 deletions packages/rds-signer/package-lock.json

Large diffs are not rendered by default.

1,169 changes: 601 additions & 568 deletions packages/s3-object-response/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/s3/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -272,6 +272,6 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})
1,169 changes: 601 additions & 568 deletions packages/s3/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/secrets-manager/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -259,6 +259,6 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})
931 changes: 482 additions & 449 deletions packages/secrets-manager/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/service-discovery/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -337,6 +337,6 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})
931 changes: 482 additions & 449 deletions packages/service-discovery/package-lock.json

Large diffs are not rendered by default.

844 changes: 422 additions & 422 deletions packages/sqs-partial-batch-failure/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/ssm/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -416,7 +416,7 @@ test('It should throw error if InvalidParameters returned', async (t) => {
t.true(false)
} catch (e) {
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [
t.deepEqual(e.cause.data, [
new Error('InvalidParameter invalid-ssm-param-name', {
cause: { pacakge: '@middy/ssm' }
}),
@@ -451,7 +451,7 @@ test.serial(
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
}
)
@@ -480,7 +480,7 @@ test.serial(
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
}
)
933 changes: 483 additions & 450 deletions packages/ssm/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/sts/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -258,6 +258,6 @@ test.serial('It should catch if an error is returned from fetch', async (t) => {
} catch (e) {
t.is(sendStub.callCount, 1)
t.is(e.message, 'Failed to resolve internal values')
t.deepEqual(e.cause, [new Error('timeout')])
t.deepEqual(e.cause.data, [new Error('timeout')])
}
})
861 changes: 447 additions & 414 deletions packages/sts/package-lock.json

Large diffs are not rendered by default.

919 changes: 476 additions & 443 deletions packages/util/package-lock.json

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions packages/validator/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -349,12 +349,11 @@ for (const c of cases) {

// invokes the handler, note that property foo is missing
const event = {
preferredLanguage: c.lang,
body: JSON.stringify({ something: 'somethingelse' })
}

try {
await handler(event, context)
await handler(event, { ...context, preferredLanguage: c.lang })
} catch (e) {
t.is(e.message, 'Event object failed validation')
t.deepEqual(e.cause.data, [
@@ -401,12 +400,11 @@ test('It should handle invalid schema as a BadRequest in a different language (w

// invokes the handler, note that property foo is missing
const event = {
preferredLanguage: 'pt-BR',
body: JSON.stringify({ something: 'somethingelse' })
}

try {
await handler(event, context)
await handler(event, { ...context, preferredLanguage: 'pt-BR' })
} catch (e) {
t.is(e.message, 'Event object failed validation')
t.deepEqual(e.cause.data, [
@@ -449,12 +447,11 @@ test('It should handle invalid schema as a BadRequest without i18n', async (t) =

// invokes the handler, note that property foo is missing
const event = {
preferredLanguage: 'pt-BR',
body: JSON.stringify({ something: 'somethingelse' })
}

try {
await handler(event, context)
await handler(event, { ...context, preferredLanguage: 'pt-BR' })
} catch (e) {
t.is(e.message, 'Event object failed validation')
t.deepEqual(e.cause.data, [
2 changes: 1 addition & 1 deletion packages/validator/index.js
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ const validatorMiddleware = (opts = {}) => {

if (!validEvent) {
const localize =
languages[request.event.preferredLanguage] ??
languages[request.context.preferredLanguage] ??
languages[defaultLanguage]
localize?.(eventSchema.errors)

22 changes: 11 additions & 11 deletions packages/validator/package-lock.json
8 changes: 4 additions & 4 deletions packages/warmup/package-lock.json
22 changes: 11 additions & 11 deletions packages/ws-json-body-parser/package-lock.json
931 changes: 482 additions & 449 deletions packages/ws-response/package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions packages/ws-router/package-lock.json
29 changes: 16 additions & 13 deletions website/docs/middlewares/http-content-negotiation.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ title: http-content-negotiation
This middleware parses `Accept-*` headers and provides utilities for [HTTP content negotiation](https://tools.ietf.org/html/rfc7231#section-5.3) (charset, encoding, language and media type).

By default the middleware parses charsets (`Accept-Charset`), languages (`Accept-Language`), encodings (`Accept-Encoding`) and media types (`Accept`) during the
`before` phase and expands the `event` object by adding the following properties:
`before` phase and expands the `context` object by adding the following properties:

- `preferredCharsets` (`array`) - The list of charsets that can be safely used by the app (as the result of the negotiation)
- `preferredCharset` (`string`) - The preferred charset (as the result of the negotiation)
@@ -19,7 +19,6 @@ By default the middleware parses charsets (`Accept-Charset`), languages (`Accept
This middleware expects the headers in canonical format, so it should be attached after the [`httpHeaderNormalizer`](#httpheadernormalizer) middleware.
It also can throw an HTTP exception, so it can be convenient to use it in combination with the [`httpErrorHandler`](#httperrorhandler).


## Install

To install this middleware you can use NPM:
@@ -28,7 +27,6 @@ To install this middleware you can use NPM:
npm install --save @middy/http-content-negotiation
```


## Options

- `parseCharsets` (defaults to `true`) - Allows enabling/disabling the charsets parsing
@@ -41,7 +39,6 @@ npm install --save @middy/http-content-negotiation
- `availableMediaTypes` (defaults to `undefined`) - Allows defining the list of media types supported by the Lambda function
- `failOnMismatch` (defaults to `true`) - If set to true it will throw an HTTP `NotAcceptable` (406) exception when the negotiation fails for one of the headers (e.g. none of the languages requested are supported by the app)


## Sample usage

```javascript
@@ -53,7 +50,7 @@ import httpErrorHandler from '@middy/http-error-handler'
export const handler = middy((event, context) => {
let message, body

switch (event.preferredLanguage) {
switch (context.preferredLanguage) {
case 'it-it':
message = 'Ciao Mondo'
break
@@ -64,7 +61,7 @@ export const handler = middy((event, context) => {
message = 'Hello world'
}

switch (event.preferredMediaType) {
switch (context.preferredMediaType) {
case 'application/xml':
body = `<message>${message}</message>`
break
@@ -86,12 +83,18 @@ export const handler = middy((event, context) => {

handler
.use(httpHeaderNormalizer())
.use(httpContentNegotiation({
parseCharsets: false,
parseEncodings: false,
availableLanguages: ['it-it', 'fr-fr', 'en'],
availableMediaTypes: ['application/xml', 'application/yaml', 'application/json', 'text/plain']
}))
.use(
httpContentNegotiation({
parseCharsets: false,
parseEncodings: false,
availableLanguages: ['it-it', 'fr-fr', 'en'],
availableMediaTypes: [
'application/xml',
'application/yaml',
'application/json',
'text/plain'
]
})
)
.use(httpErrorHandler())

```
32 changes: 15 additions & 17 deletions website/docs/middlewares/http-response-serializer.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ title: http-response-serializer

The Http Serializer middleware lets you define serialization mechanisms based on the current content negotiation.


## Install

To install this middleware you can use NPM:
@@ -13,6 +12,9 @@ To install this middleware you can use NPM:
npm install --save @middy/http-response-serializer
```

## Options

- `defaultContentType` (optional): used if the request and handler don't specify what type is wanted.

## Configuration

@@ -34,13 +36,10 @@ The middleware is configured by defining some `serializers`.
serializer: ({ body }) => body
}
],
default: 'application/json'
defaultContentType: 'application/json'
}
```

The `default` (optional) option is used if the request and handler don't specify what type is wanted.


## Serializer Functions

When a matching serializer is found, the `Content-Type` header is set and the serializer function is run.
@@ -51,22 +50,20 @@ If a string is returned, the `body` attribute of the response is updated.

If an object with a `body` attribute is returned, the entire response object is replaced. This is useful if you want to manipulate headers or add additional attributes in the Lambda response.


## Content Type Negotiation

The header is not the only way the middleware decides which serializer to execute.

The content type is determined in the following order:

* `event.requiredContentType` -- allows the handler to override everything else
* The `Accept` header via [accept](https://www.npmjs.com/package/accept)
* `event.preferredContentType` -- allows the handler to override the default, but lets the request ask first
* `default` middleware configuration
- `context.requiredContentType` -- allows the handler to override everything else
- The `Accept` header via [accept](https://www.npmjs.com/package/accept)
- `context.preferredContentType` -- allows the handler to override the default, but lets the request ask first
- `defaultContentType` middleware configuration

All options allow for multiple types to be specified in your order of preference, and the first matching serializer will be executed.
When planning to use `Accept`, an external input, it is recommended to validate that it is an expected value.


## Sample usage

```javascript
@@ -82,12 +79,12 @@ const handler = middy((event, context) => {
}
})

handler
.use(httpResponseSerializer({
handler.use(
httpResponseSerializer({
serializers: [
{
regex: /^application\/xml$/,
serializer: ({ body }) => `<message>${body}</message>`,
serializer: ({ body }) => `<message>${body}</message>`
},
{
regex: /^application\/json$/,
@@ -99,15 +96,16 @@ handler
}
],
defaultContentType: 'application/json'
}))
})
)

const event = {
headers: {
'Accept': 'application/xml;q=0.9, text/x-dvi; q=0.8, text/x-c'
Accept: 'application/xml;q=0.9, text/x-dvi; q=0.8, text/x-c'
}
}

handler(event, {}, (_, response) => {
t.is(response.body,'<message>Hello World</message>')
t.is(response.body, '<message>Hello World</message>')
})
```