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

feat(typescript): getInternal type safety + other type improvements #1093

Merged
merged 31 commits into from Oct 8, 2023

Conversation

m-radzikowski
Copy link
Contributor

@m-radzikowski m-radzikowski commented Aug 26, 2023

Fixes #1023

So far, getInternal() returned any type:

declare function getInternal (
variables: any,
request: middy.Request
): Promise<any>

With those changes, the information on the data stored in the internal storage is passed through and extended by middlewares (as type). The getInternal() function validates passed variables (if they occur in the enriched type) and returns typed object (with passed-in keys and their matching value types).

The data type in the internal storage is passed in the new generic TInternal type.

Working example with SSM:

middy()
  .use(
    ssm({
      fetchData: {
        lorem: '/lorem',
        ipsum: '/ipsum',
      },
    }),
  )
  .before(async request => {
    const p = await getInternal(["lorem"], request); // ✅ output type: { lorem: unknown; }
    p.lorem // ✅
    p.ipsum // ✅ error - property does not exist 
    p.nonexisting // ✅ error - property does not exist 

    await getInternal(["lorem", "nonexisting"], request); // ✅ error -  TS2322: Type  "nonexisting"  is not assignable to type  "lorem" | "ipsum"
  })

WIP

To do:

  • support other getInternal() variables argument variants - with true and keys mapping object (this currently causes tsd tests to fail)
  • getInternal() output parameters have type unknown at the moment - the actual type of variable is available in the TInternal type, probably can be extracted to return proper parameter types
  • check SSM logic for adding parameters to TInternal - I've simply added all keys, but similar code for the Context type has more logic - check it
  • implement adding keys to TInternal for all other middleware
    • appconfig
    • dynamodb
    • rds-signer
    • s3
    • s3-object-response
    • secrets-manager
    • service-discovery
    • ssm
    • sts

@m-radzikowski m-radzikowski marked this pull request as draft August 26, 2023 20:31
@m-radzikowski
Copy link
Contributor Author

@lmammino here is the basic implementation :) I think most of the heavy job is done, although there are still a few things to improve in getInternal() types. And then updating all middlewares to add types to TInternal, which should be fairly easy.

I can't commit to spending more time on this right now - this part took me quite a moment... If you or anyone else want to continue the work - feel free to. Otherwise, I can try to get back to it, but don't know how soon (or late).

@lmammino
Copy link
Member

Hey @m-radzikowski, thanks for doing this! It's definitely a great starting point. I'll try to pick up the remaining work from here. I'll ask you more questions/help if I get stuck ;)

@m-radzikowski
Copy link
Contributor Author

Hey @m-radzikowski, thanks for doing this! It's definitely a great starting point. I'll try to pick up the remaining work from here. I'll ask you more questions/help if I get stuck ;)

Sure! Don't hesitate to ping me if needed.

@lmammino
Copy link
Member

lmammino commented Sep 8, 2023

I spent (quite) a bit of time trying to figure out how to improve the getInternal type definition:

This is what I came up with:

type Flattened<T> = T extends Array<infer U> ? Flattened<U> : T;

// single variable
declare function getInternal<TInternal extends Record<string, unknown>, TVars extends keyof TInternal | string> (
  variables: TVars,
  request: middy.Request<any, any, any, any, TInternal>
): Promise<{
  [P in TVars]: (TVars extends keyof TInternal ? TInternal[TVars] : unknown)
}>
// array of variables
declare function getInternal<TInternal extends Record<string, unknown>, TVars extends Array<keyof TInternal | string>> (
  variables: TVars,
  request: middy.Request<any, any, any, any, TInternal>
): Promise<{
  [P in Flattened<TVars>]: (P extends keyof TInternal ? TInternal[P] : unknown)
}>
// mapping object
declare function getInternal<TInternal extends Record<string, unknown>, TMap extends Record<string, keyof TInternal | string>> (
  variables: TMap,
  request: middy.Request<any, any, any, any, TInternal>
): Promise<{
  [P in keyof TMap]: (TMap[P] extends keyof TInternal ? TInternal[TMap[P]] : unknown)
}>
// all variables (with true)
declare function getInternal<TInternal extends Record<string, unknown>> (
  variables: true,
  request: middy.Request<any, any, any, any, TInternal>
): Promise<{
  [P in keyof TInternal]: TInternal[P]
}>

It doesn't look pretty but it seems to work for the most part.

There are still a few advanced corner cases that are not properly handled yet.

For instance:

  • The remapping function can do nested remapping if using a dot syntax such as property.subproperty. This will currently be typed as unknown
  • If internal contains a promise, the return value should be the resolved version of that promise (right now it keeps the promise).

I am not sure if these additional improvements are worth it, so I wouldn't stress too much about them. This seems already like a big step forward.

Thoughts?

@gegham1
Copy link

gegham1 commented Sep 8, 2023

@lmammino

  • TVars extends keyof TInternal | string this does not bring any value, can be simplified to just string
  • Promise<{ [P in keyof TInternal]: TInternal[P] }> can be replaced with just Promise<TInternal>

Also, I noticed that in mapping version TMap is a Map<string... and returned object keys are the keys from TMap, which can be anything. Is this a desired behavior?
e.g.
// will inferred as { b: number }
let obj = await getInternal({b: 'ac'}, { resp: {ac: 4} });

@wtfzambo
Copy link

wtfzambo commented Sep 9, 2023

@lmammino alright if possible I made the code even uglier but I managed to achieve a bunch of things:

  1. Get rid of overloads
  2. Solve your problem with nested keys in TInternal (if I understood properly what the fuck was the issue in the first place)

I'm not too proud of this but it's all I could achieve in one day.

There's one caveat in the "mapping" case: TVars must be passed either as an object literal, OR the variable must be declared as const.

type Flattened<T> = T extends Array<infer U> ? Flattened<U> : T;

// finds TKey in TInternal, recursively, even if it's a deeply nested one
type Resolve<TInternal, TKey> = TKey extends keyof TInternal
  ? TInternal[TKey]
  : TKey extends string
  ? {
      [P in keyof TInternal]: TInternal[P] extends object
        ? Resolve<TInternal[P], TKey>
        : never;
    }[keyof TInternal]
  : never;

// for when TVars is an object, find all keys in TInternal that match the values in TVars
type DeepResolve<TInternal, TVars> = {
  [P in keyof TVars]: Resolve<TInternal, TVars[P]>;
};

// all possible shapes that TVars can have (this is based on your declarations)
type TVars<T, K> = true | keyof T | (keyof T)[] | Record<string, K>;

// all possible return values that getInternal() can produce (also based on your declaration)
type TGetInternalResults<TVars, TInternal> =
  TVars extends keyof TInternal
  ? { [P in TVars]: TInternal[TVars] }
  : TVars extends Array<keyof TInternal | string>
  ? {[P in Flattened<TVars>]: P extends keyof TInternal ? TInternal[P] : unknown}
  : TVars extends object
  ? DeepResolve<TInternal, TVars>  // <-- this is for the mapped case
  : TInternal;  // <-- this is for the "true" case


// "K extends string" seems useless but it isn't. Without it, the (nested) mapped case doesn't work
// I removed "TInternal extends Record<string, unknown>" part because it doesn't do anything useful in my examples.
declare function getInternal<TInternal, K extends string, T extends TVars<TInternal, K>>(
  variables: T,
  request: middy.Request<any, any, any, any, TInternal>
): Promise<TGetInternalResults<T, TInternal>>

// example of the nested mapped case
const request = {
  internal: {
    a: 'asd',
    b: 123,
    c: true,
    d: {
      e: new Promise(() => {})
    },
  },
};

let obj = getInternal({foo: 'e', bar: 'a'}, request);
obj.then((value) => value.foo);  // value.foo inferred as Promise<unknown>
obj.then((value) => value.bar);  // value.bar inferred as to string

@lmammino
Copy link
Member

After a good pairing session with @jfet97 yesterday and some reflection hours today, I think I finally have a solution that provides the correct types for util.getInternal including:

  • Resolves promises correctly
  • Resolves object paths correctly
  • Applies correct normalisation of keys

I needed to create a bunch of utility types so I ended up creating a type-utils.d.ts file to keep them isolated (and testable).

Huge thanks to @jfet97 but also to @gegham1 & @wtfzambo for providing very useful (and appreciated) suggestions and alternative approaches!

@jfet97
Copy link

jfet97 commented Sep 16, 2023

It's been a pleasure @lmammino , I'm glad you managed to complete the work 😄

@lmammino
Copy link
Member

The tests for the SSM middleware where failing because of infinite recursion type when using the new typing system for getInternal. The SSM middleware uses the type-fest package's JsonValue type.

In order to address this issue I did 2 things:

  1. I added limited recursion to the DeepAwaited type utility (@jfet97 if you could check that I'd be super happy!). This should also speed up a little the type inference.
  2. I removed type-fest entirely. As an alternative, I came up with an alternative approach that allows us to specify the expected types for every parameter very explicitly. I updated the docs as part of this PR as well to illustrate this idea. Here's an extract:

Usage with TypeScript

Data in SSM can be stored as arbitrary JSON values. It's not possible to know in advance what shape the fetched SSM parameters will have, so by default the fetched parameters will have type unknown.

You can provide some type hints by leveraging the ssmParam utility function. This function allows you to specify what's the expected type that will be fetched for every parameter.

The idea is that, for every parameter specified in the fetchData option, rather than just providing the parameter path as a string, you can wrap it in a ssmParam<ParamType>(parameterPath) call. Internally, ssmParam is a function that will return parameterPath as received, but it allows you to use generics to provide type hints for the expected type for that parameter.

This way TypeScript can understand how to treat the additional data attached to the context and stored in the internal storage.

The following example illustrates how to use ssmParam:

import middy from '@middy/core'
import { getInternal } from '@middy/util'
import ssm, {ssmParam} from '@middy/ssm'

const handler = middy((event, context) => {
  return {}
})

let globalDefaults = {}
handler
  .use(
    ssm({
      fetchData: {
        accessToken: ssmParam<string>('/dev/service_name/access_token'), // single value (will be typed as string)
        dbParams: ssmParam<{user: string, pass: string}>('/dev/service_name/database/') // object of values (typed as {user: string, pass: string})
      },
      cacheExpiry: 15 * 60 * 1000,
      cacheKey: 'ssm-secrets'
    })
  )
  // ... other middleware that fetch
  .before(async (request) => {
    const data = await getInternal(
      ['accessToken', 'dbParams', ],
      request
    )
    // data.accessToken (string)
    // data.dbParams ({user: string, pass: string})
  })

What do you think of this idea?
CC: @willfarrell , @m-radzikowski , @naorpeled

packages/util/index.d.ts Outdated Show resolved Hide resolved
@lmammino lmammino changed the title feat(typescript): getInternal type safety feat(typescript): getInternal type safety + other type improvements Sep 17, 2023
@naorpeled
Copy link
Contributor

The tests for the SSM middleware where failing because of infinite recursion type when using the new typing system for getInternal. The SSM middleware uses the type-fest package's JsonValue type.

In order to address this issue I did 2 things:

  1. I added limited recursion to the DeepAwaited type utility (@jfet97 if you could check that I'd be super happy!). This should also speed up a little the type inference.
  2. I removed type-fest entirely. As an alternative, I came up with an alternative approach that allows us to specify the expected types for every parameter very explicitly. I updated the docs as part of this PR as well to illustrate this idea. Here's an extract:

Usage with TypeScript

Data in SSM can be stored as arbitrary JSON values. It's not possible to know in advance what shape the fetched SSM parameters will have, so by default the fetched parameters will have type unknown.
You can provide some type hints by leveraging the ssmParam utility function. This function allows you to specify what's the expected type that will be fetched for every parameter.
The idea is that, for every parameter specified in the fetchData option, rather than just providing the parameter path as a string, you can wrap it in a ssmParam<ParamType>(parameterPath) call. Internally, ssmParam is a function that will return parameterPath as received, but it allows you to use generics to provide type hints for the expected type for that parameter.
This way TypeScript can understand how to treat the additional data attached to the context and stored in the internal storage.
The following example illustrates how to use ssmParam:

import middy from '@middy/core'
import { getInternal } from '@middy/util'
import ssm, {ssmParam} from '@middy/ssm'

const handler = middy((event, context) => {
  return {}
})

let globalDefaults = {}
handler
  .use(
    ssm({
      fetchData: {
        accessToken: ssmParam<string>('/dev/service_name/access_token'), // single value (will be typed as string)
        dbParams: ssmParam<{user: string, pass: string}>('/dev/service_name/database/') // object of values (typed as {user: string, pass: string})
      },
      cacheExpiry: 15 * 60 * 1000,
      cacheKey: 'ssm-secrets'
    })
  )
  // ... other middleware that fetch
  .before(async (request) => {
    const data = await getInternal(
      ['accessToken', 'dbParams', ],
      request
    )
    // data.accessToken (string)
    // data.dbParams ({user: string, pass: string})
  })

What do you think of this idea? CC: @willfarrell , @m-radzikowski , @naorpeled

Sounds good to me 😎
Will start reviewing the code now!

Copy link
Contributor

@naorpeled naorpeled left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Great job guys!

@willfarrell willfarrell changed the base branch from main to release/5.0 September 19, 2023 17:40
@socket-security
Copy link

New dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
@types/aws-lambda 8.10.122 None +0 137 kB types

@lmammino lmammino marked this pull request as ready for review October 8, 2023 15:43
@lmammino
Copy link
Member

lmammino commented Oct 8, 2023

I think I covered all the points in the TODO list. This is not ready for a final review :)

@willfarrell willfarrell merged commit 776b2f0 into middyjs:release/5.0 Oct 8, 2023
4 of 6 checks passed
mergify bot pushed a commit to SvenKirschbaum/share.kirschbaum.cloud that referenced this pull request Nov 17, 2023
[![Mend Renovate logo banner](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@middy/core](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fcore/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fcore/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fcore/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fcore/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fcore/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/error-logger](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2ferror-logger/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2ferror-logger/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2ferror-logger/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2ferror-logger/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2ferror-logger/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-content-negotiation](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-content-negotiation/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-content-negotiation/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-content-negotiation/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-content-negotiation/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-content-negotiation/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-error-handler](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-error-handler/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-error-handler/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-header-normalizer](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-header-normalizer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-header-normalizer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-json-body-parser](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-json-body-parser/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-json-body-parser/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-json-body-parser/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-json-body-parser/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-json-body-parser/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-response-serializer](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-response-serializer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-response-serializer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/validator](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fvalidator/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fvalidator/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fvalidator/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fvalidator/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fvalidator/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>middyjs/middy (@&#8203;middy/core)</summary>

### [`v5.0.2`](https://togithub.com/middyjs/middy/releases/tag/5.0.2)

[Compare Source](https://togithub.com/middyjs/middy/compare/5.0.1...5.0.2)

##### What's Changed

-   Validation error cause typo by [@&#8203;stepansib](https://togithub.com/stepansib) in [middyjs/middy#1138
    -   Update similar typo in other files

##### New Contributors

-   [@&#8203;stepansib](https://togithub.com/stepansib) made their first contribution in [middyjs/middy#1138

**Full Changelog**: middyjs/middy@5.0.1...5.0.2

### [`v5.0.1`](https://togithub.com/middyjs/middy/releases/tag/5.0.1)

[Compare Source](https://togithub.com/middyjs/middy/compare/5.0.0...5.0.1)

#### What's Changed

-   ci: Add in missing types file [@&#8203;lbevilacqua](https://togithub.com/lbevilacqua) [middyjs/middy#1136
-   chore(website): Update website-publish.yml by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1135

**Full Changelog**: middyjs/middy@5.0.0...5.0.1

### [`v5.0.0`](https://togithub.com/middyjs/middy/releases/tag/5.0.0)

[Compare Source](https://togithub.com/middyjs/middy/compare/4.7.0...5.0.0)

For full details and upgrade guide see https://middy.js.org/docs/upgrade/4-5

#### Notable changes

-   Middy no longer support Common JS modules.
-   Deprecate Node.js v16.x.
-   Add support for Node.js v20.x.
-   Update to use TypeScript v5 along with a refactor to most packages
-   Update all errors to be consistent `new Error('message', { cause: { package:'@&#8203;middy/***', data:*** } })`
-   If using multiple `http-*-body-parsers` on the same endpoint you'll need to set `{ disableContentTypeError: true }`

#### What's Changed

-   fix(appconfig): [#&#8203;1009](https://togithub.com/middyjs/middy/issues/1009) rewrite to not use deprecated appconfig getConfiguration command by [@&#8203;mju-spyrosoft](https://togithub.com/mju-spyrosoft) in [middyjs/middy#1029
-   Green CI for 5.0 by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1090
-   feat(json-body-parser): allow specifying versioned APIGW events by [@&#8203;naorpeled](https://togithub.com/naorpeled) in [middyjs/middy#1100
-   feat(typescript): getInternal type safety + other type improvements by [@&#8203;m-radzikowski](https://togithub.com/m-radzikowski) in [middyjs/middy#1093
-   Fix typo by [@&#8203;michael-k](https://togithub.com/michael-k) in [middyjs/middy#1110
-   docs: add Powertools idempotency + fix typo by [@&#8203;dreamorosi](https://togithub.com/dreamorosi) in [middyjs/middy#1115
-   fix(http-error-handler): non http errors will always be handled  by [@&#8203;qoomon](https://togithub.com/qoomon) in [middyjs/middy#1117
-   feat: add `@iress/middy-http-path-router` to third-party middleware docs by [@&#8203;RodneyMarsh](https://togithub.com/RodneyMarsh) in [middyjs/middy#1124
-   fix(website): extra padding on mobile by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1126
-   Feat: improve TS docs, mention Middeware-first, Handler-last pattern by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1130
-   Update website to docusaurus3 by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1129
-   fix(middlewares/http-json-body-parser): narrow body type to string by [@&#8203;naorpeled](https://togithub.com/naorpeled) in [middyjs/middy#1131
-   fix: don't throw error for non http event by [@&#8203;robertbeal](https://togithub.com/robertbeal) in [middyjs/middy#1133

#### New Contributors

-   [@&#8203;mju-spyrosoft](https://togithub.com/mju-spyrosoft) made their first contribution in [middyjs/middy#1029
-   [@&#8203;michael-k](https://togithub.com/michael-k) made their first contribution in [middyjs/middy#1110
-   [@&#8203;qoomon](https://togithub.com/qoomon) made their first contribution in [middyjs/middy#1117
-   [@&#8203;RodneyMarsh](https://togithub.com/RodneyMarsh) made their first contribution in [middyjs/middy#1124
-   [@&#8203;robertbeal](https://togithub.com/robertbeal) made their first contribution in [middyjs/middy#1133

Big tanks to everyone who made this release possible!

**Full Changelog**: middyjs/middy@4.7.0...5.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/SvenKirschbaum/share.kirschbaum.cloud).
mergify bot pushed a commit to SvenKirschbaum/aws-utils that referenced this pull request Nov 17, 2023
[![Mend Renovate logo banner](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@middy/core](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fcore/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fcore/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fcore/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fcore/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fcore/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/error-logger](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2ferror-logger/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2ferror-logger/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2ferror-logger/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2ferror-logger/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2ferror-logger/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-error-handler](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-error-handler/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-error-handler/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-error-handler/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-header-normalizer](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-header-normalizer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-header-normalizer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-header-normalizer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@middy/http-response-serializer](https://middy.js.org) ([source](https://togithub.com/middyjs/middy)) | [`4.7.0` -> `5.0.2`](https://renovatebot.com/diffs/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@middy%2fhttp-response-serializer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@middy%2fhttp-response-serializer/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@middy%2fhttp-response-serializer/4.7.0/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>middyjs/middy (@&#8203;middy/core)</summary>

### [`v5.0.2`](https://togithub.com/middyjs/middy/releases/tag/5.0.2)

[Compare Source](https://togithub.com/middyjs/middy/compare/5.0.1...5.0.2)

##### What's Changed

-   Validation error cause typo by [@&#8203;stepansib](https://togithub.com/stepansib) in [middyjs/middy#1138
    -   Update similar typo in other files

##### New Contributors

-   [@&#8203;stepansib](https://togithub.com/stepansib) made their first contribution in [middyjs/middy#1138

**Full Changelog**: middyjs/middy@5.0.1...5.0.2

### [`v5.0.1`](https://togithub.com/middyjs/middy/releases/tag/5.0.1)

[Compare Source](https://togithub.com/middyjs/middy/compare/5.0.0...5.0.1)

#### What's Changed

-   ci: Add in missing types file [@&#8203;lbevilacqua](https://togithub.com/lbevilacqua) [middyjs/middy#1136
-   chore(website): Update website-publish.yml by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1135

**Full Changelog**: middyjs/middy@5.0.0...5.0.1

### [`v5.0.0`](https://togithub.com/middyjs/middy/releases/tag/5.0.0)

[Compare Source](https://togithub.com/middyjs/middy/compare/4.7.0...5.0.0)

For full details and upgrade guide see https://middy.js.org/docs/upgrade/4-5

#### Notable changes

-   Middy no longer support Common JS modules.
-   Deprecate Node.js v16.x.
-   Add support for Node.js v20.x.
-   Update to use TypeScript v5 along with a refactor to most packages
-   Update all errors to be consistent `new Error('message', { cause: { package:'@&#8203;middy/***', data:*** } })`
-   If using multiple `http-*-body-parsers` on the same endpoint you'll need to set `{ disableContentTypeError: true }`

#### What's Changed

-   fix(appconfig): [#&#8203;1009](https://togithub.com/middyjs/middy/issues/1009) rewrite to not use deprecated appconfig getConfiguration command by [@&#8203;mju-spyrosoft](https://togithub.com/mju-spyrosoft) in [middyjs/middy#1029
-   Green CI for 5.0 by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1090
-   feat(json-body-parser): allow specifying versioned APIGW events by [@&#8203;naorpeled](https://togithub.com/naorpeled) in [middyjs/middy#1100
-   feat(typescript): getInternal type safety + other type improvements by [@&#8203;m-radzikowski](https://togithub.com/m-radzikowski) in [middyjs/middy#1093
-   Fix typo by [@&#8203;michael-k](https://togithub.com/michael-k) in [middyjs/middy#1110
-   docs: add Powertools idempotency + fix typo by [@&#8203;dreamorosi](https://togithub.com/dreamorosi) in [middyjs/middy#1115
-   fix(http-error-handler): non http errors will always be handled  by [@&#8203;qoomon](https://togithub.com/qoomon) in [middyjs/middy#1117
-   feat: add `@iress/middy-http-path-router` to third-party middleware docs by [@&#8203;RodneyMarsh](https://togithub.com/RodneyMarsh) in [middyjs/middy#1124
-   fix(website): extra padding on mobile by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1126
-   Feat: improve TS docs, mention Middeware-first, Handler-last pattern by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1130
-   Update website to docusaurus3 by [@&#8203;lmammino](https://togithub.com/lmammino) in [middyjs/middy#1129
-   fix(middlewares/http-json-body-parser): narrow body type to string by [@&#8203;naorpeled](https://togithub.com/naorpeled) in [middyjs/middy#1131
-   fix: don't throw error for non http event by [@&#8203;robertbeal](https://togithub.com/robertbeal) in [middyjs/middy#1133

#### New Contributors

-   [@&#8203;mju-spyrosoft](https://togithub.com/mju-spyrosoft) made their first contribution in [middyjs/middy#1029
-   [@&#8203;michael-k](https://togithub.com/michael-k) made their first contribution in [middyjs/middy#1110
-   [@&#8203;qoomon](https://togithub.com/qoomon) made their first contribution in [middyjs/middy#1117
-   [@&#8203;RodneyMarsh](https://togithub.com/RodneyMarsh) made their first contribution in [middyjs/middy#1124
-   [@&#8203;robertbeal](https://togithub.com/robertbeal) made their first contribution in [middyjs/middy#1133

Big tanks to everyone who made this release possible!

**Full Changelog**: middyjs/middy@4.7.0...5.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/SvenKirschbaum/aws-utils).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

TypeScript improvements - what should we address?
7 participants