diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e6df8e51..5f1389da 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -14,11 +14,11 @@ // Linting/formatting features: "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", + "esbenp.prettier-vscode", // Markdown/documentation features: - "bierner.markdown-preview-github-styles", - "bierner.markdown-mermaid", + "bierner.markdown-preview-github-styles", + "bierner.markdown-mermaid" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. diff --git a/CHANGELOG.md b/CHANGELOG.md index b7527c50..4970f80d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file. --- +# [2.1.0-next.1](https://github.com/Nerdware-LLC/fixit-api/compare/v2.0.1...v2.1.0-next.1) (2024-03-24) + + +### Bug Fixes + +* correct DateTime validity logic ([6273a0a](https://github.com/Nerdware-LLC/fixit-api/commit/6273a0a4e4d6df5b466272769ab5f621a1a9d9e4)) +* ensure every next call wraps an Error ([9efc8e5](https://github.com/Nerdware-LLC/fixit-api/commit/9efc8e58eedd6d54db2ab7f9bb58f30025bf986b)) +* update google OAuth related logic ([9fa247b](https://github.com/Nerdware-LLC/fixit-api/commit/9fa247b11d083166650e81f2eb75a57701b10dc2)) + + +### Features + +* add Google OAuth2 client ([5529074](https://github.com/Nerdware-LLC/fixit-api/commit/5529074517b445d8ab9b3814995ae68dfc837b3e)) +* add googleID/googleIDToken handling ([0f8df48](https://github.com/Nerdware-LLC/fixit-api/commit/0f8df48eb6f664346515e93083f825356a49438f)) +* add isValidTimestamp util ([ce20e7f](https://github.com/Nerdware-LLC/fixit-api/commit/ce20e7f2e928644764ddc20c77e2f950d7948f6c)) +* rm requirement for user.sca.id ([e46c681](https://github.com/Nerdware-LLC/fixit-api/commit/e46c6816f79592b4432629389c3b3653e673df36)) +* set 'phone' and sca fields to allow null ([4fa7ccf](https://github.com/Nerdware-LLC/fixit-api/commit/4fa7ccfdd39e6f443928c31b078ed27709ce6b22)) +* update codegen'd types ([7cf2141](https://github.com/Nerdware-LLC/fixit-api/commit/7cf21412be8bf58cb2afd2d25f0dc8ad0c6a548f)) +* update local gql shema file for nullable phone ([9e98c85](https://github.com/Nerdware-LLC/fixit-api/commit/9e98c85af321f17e6121b9a11646ee5b4de10104)) +* update logic to allow 'phone' to be optional ([b2df714](https://github.com/Nerdware-LLC/fixit-api/commit/b2df7145e91f70282fe57b786323900b58e9f9bc)) + ## [2.0.1](https://github.com/Nerdware-LLC/fixit-api/compare/v2.0.0...v2.0.1) (2024-03-10) ## [2.0.1-next.1](https://github.com/Nerdware-LLC/fixit-api/compare/v2.0.0...v2.0.1-next.1) (2024-03-10) diff --git a/README.md b/README.md index a5da096f..59b61773 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,8 @@ flowchart LR admin --> csp("/api/admin/csp-violation \n­\n • CSP #quot;report-to#quot;" target) admin --> healthcheck("/api/admin/healthcheck \n­\n • Healthchecks target") auth --> register("/api/auth/register \n­\n • User registration") - auth --> login("/api/auth/login \n­\n • User login requests. Accepts \n email+pw or Google OAuth") + auth --> login("/api/auth/login \n­\n • User logins via Local\n or OAuth mechanisms") + auth --> googleToken("/api/auth/google-token \n­\n • User logins via Google\nOAuth2 OneTap FedCM") auth --> token("/api/auth/token \n­\n • Refreshes auth tokens") connect --> accountLink("/api/connect/account-link \n­\n • Returns a link to the Stripe-hosted\nConnect onboarding portal") connect --> dashboardLink("/api/connect/dashboard-link \n­\n • Returns a link to the Stripe-hosted\naccount management portal") @@ -224,7 +225,7 @@ This API uses a single DynamoDB table with primary keys `pk` and `sk`, along wit ### Fixit-API Access Patterns - + - **USERS** - Find a User by their email @@ -247,11 +248,7 @@ This API uses a single DynamoDB table with primary keys `pk` and `sk`, along wit - Find a User's WorkOrders using their user ID - Find WorkOrders within a given date range - + ### Single Table Design diff --git a/docs/endpoints/auth.google-token.yaml b/docs/endpoints/auth.google-token.yaml new file mode 100644 index 00000000..1e481cb4 --- /dev/null +++ b/docs/endpoints/auth.google-token.yaml @@ -0,0 +1,17 @@ +## yaml-language-server: $schema=https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.yaml#/$defs/path-item + +# POST /auth/token + +post: + operationId: GoogleToken + summary: Processes JSON JWT payloads from GoogleID services (existing users only) + security: [] + tags: [auth] + requestBody: { $ref: "../open-api.yaml#/components/requestBodies/GoogleTokenRequest" } + responses: + # TODO Update 200 to use 200.AuthTokenAndPreFetchedUserItems, then run codegen + "200": { $ref: "../open-api.yaml#/components/responses/200AuthToken" } + "400": { $ref: "../open-api.yaml#/components/responses/400InvalidUserInput" } + "401": { $ref: "../open-api.yaml#/components/responses/401AuthenticationRequired" } + "5XX": { $ref: "../open-api.yaml#/components/responses/5xxInternalServerError" } + default: { $ref: "../open-api.yaml#/components/responses/UnexpectedResponse" } diff --git a/docs/objectProperties/googleAccessToken.yaml b/docs/objectProperties/googleAccessToken.yaml deleted file mode 100644 index d995c99d..00000000 --- a/docs/objectProperties/googleAccessToken.yaml +++ /dev/null @@ -1,2 +0,0 @@ -type: string -description: "The user's OAuth Google Access Token (auth: google-oauth)." diff --git a/docs/objectProperties/googleID.yaml b/docs/objectProperties/googleID.yaml deleted file mode 100644 index 1da0a006..00000000 --- a/docs/objectProperties/googleID.yaml +++ /dev/null @@ -1,2 +0,0 @@ -type: string -description: "The user's OAuth Google ID (auth: google-oauth)." diff --git a/docs/objectProperties/googleIDToken.yaml b/docs/objectProperties/googleIDToken.yaml new file mode 100644 index 00000000..3d1a2e83 --- /dev/null +++ b/docs/objectProperties/googleIDToken.yaml @@ -0,0 +1,2 @@ +type: string +description: "A base64-encoded JSON JWT from GoogleID services (auth: google-oauth)." diff --git a/docs/objectProperties/phone.yaml b/docs/objectProperties/phone.yaml index 9d942825..ea5167bd 100644 --- a/docs/objectProperties/phone.yaml +++ b/docs/objectProperties/phone.yaml @@ -1,4 +1,6 @@ -type: string +type: + - string + - "null" description: | A user's phone number. Currently this API only supports US phone numbers. All whitespace, non-numeric characters, and country/calling code prefixes will be diff --git a/docs/open-api.yaml b/docs/open-api.yaml index e99874ea..49ecdce3 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -3,7 +3,7 @@ openapi: "3.1.0" info: title: Fixit REST API - version: "1.23.0" + version: "2.0.1" description: API for Fixit auth and user account management. termsOfService: "https://gofixit.app/tos" contact: @@ -12,10 +12,11 @@ info: url: "https://github.com/trevor-anderson" license: name: Proprietary - url: "https://raw.githubusercontent.com/Nerdware-LLC/fixit-api/main/LICENSE?token=GHSAT0AAAAAACNMYXYE3P3MCJON2YGKRFQCZNWLHXQ" + url: "https://raw.githubusercontent.com/Nerdware-LLC/fixit-api/main/LICENSE" servers: - { url: "http://localhost:8080/api", description: Local Dev Server } - - { url: "https://gofixit.app/api", description: Production Server } + - { url: "https://gofixit.app/api", description: Production API } + - { url: "https://staging.gofixit.app/api", description: Staging API } tags: - { name: admin, description: Administrative endpoints } - { name: auth, description: Authentication endpoints } @@ -30,6 +31,7 @@ paths: "/auth/login": { $ref: "./endpoints/auth.login.yaml" } "/auth/register": { $ref: "./endpoints/auth.register.yaml" } "/auth/token": { $ref: "./endpoints/auth.token.yaml" } + "/auth/google-token": { $ref: "./endpoints/auth.google-token.yaml" } "/connect/account-link": { $ref: "./endpoints/connect.account-link.yaml" } "/connect/dashboard-link": { $ref: "./endpoints/connect.dashboard-link.yaml" } "/subscriptions/check-promo-code": { $ref: "./endpoints/subscriptions.check-promo-code.yaml" } @@ -40,17 +42,16 @@ components: JwtBearerAuth: { $ref: "./securitySchemes/JwtBearerAuth.yaml" } requestBodies: CheckPromoCodeRequest: { $ref: "./requestBodies/CheckPromoCodeRequest.yaml" } + GoogleTokenRequest: { $ref: "./requestBodies/GoogleTokenRequest.yaml" } LoginRequest: { $ref: "./requestBodies/LoginRequest.yaml" } RefreshAuthTokenRequest: { $ref: "./requestBodies/RefreshAuthTokenRequest.yaml" } StripeLinkRequest: { $ref: "./requestBodies/StripeLinkRequest.yaml" } UserRegistrationRequest: { $ref: "./requestBodies/UserRegistrationRequest.yaml" } + # prettier-ignore responses: 200AuthToken: { $ref: "./responses/200.AuthToken.yaml" } - 200AuthTokenAndPreFetchedUserItems: - { $ref: "./responses/200.AuthTokenAndPreFetchedUserItems.yaml" } - 200AuthTokenAndCheckoutCompletionInfo: { - $ref: "./responses/200.AuthTokenAndCheckoutCompletionInfo.yaml", - } # prettier-ignore + 200AuthTokenAndPreFetchedUserItems: { $ref: "./responses/200.AuthTokenAndPreFetchedUserItems.yaml" } + 200AuthTokenAndCheckoutCompletionInfo: { $ref: "./responses/200.AuthTokenAndCheckoutCompletionInfo.yaml" } 200CheckPromoCode: { $ref: "./responses/200.CheckPromoCode.yaml" } 200StripeLink: { $ref: "./responses/200.StripeLink.yaml" } 400InvalidUserInput: { $ref: "./responses/400.InvalidUserInput.yaml" } @@ -60,6 +61,7 @@ components: 404ResourceNotFound: { $ref: "./responses/404.ResourceNotFound.yaml" } 5xxInternalServerError: { $ref: "./responses/5xx.InternalServerError.yaml" } UnexpectedResponse: { $ref: "./responses/default.UnexpectedResponse.yaml" } + # prettier-ignore schemas: # REQUEST-RELATED SCHEMAS: UserRegistrationParams: { $ref: "./schemas/UserRegistrationParams.yaml" } @@ -67,6 +69,7 @@ components: LoginCredentials: { $ref: "./schemas/LoginCredentials.yaml" } LocalLoginCredentials: { $ref: "./schemas/LoginCredentials.Local.yaml" } GoogleOAuthLoginCredentials: { $ref: "./schemas/LoginCredentials.GoogleOAuth.yaml" } + GoogleIDTokenField: { $ref: "./schemas/GoogleIDTokenField.yaml" } UserProfileParams: { $ref: "./schemas/UserProfileParams.yaml" } ExpoPushTokenParam: { $ref: "./schemas/ExpoPushTokenParam.yaml" } # RESPONSE-RELATED SCHEMAS: @@ -78,9 +81,7 @@ components: WorkOrder: { $ref: "./schemas/WorkOrder.yaml" } PromoCodeInfoResponseField: { $ref: "./schemas/PromoCodeInfoResponseField.yaml" } PromoCodeInfo: { $ref: "./schemas/PromoCodeInfo.yaml" } - CheckoutCompletionInfoResponseField: { - $ref: "./schemas/CheckoutCompletionInfoResponseField.yaml", - } # prettier-ignore + CheckoutCompletionInfoResponseField: { $ref: "./schemas/CheckoutCompletionInfoResponseField.yaml" } CheckoutCompletionInfo: { $ref: "./schemas/CheckoutCompletionInfo.yaml" } StripeLinkResponseField: { $ref: "./schemas/StripeLinkResponseField.yaml" } # OTHER SCHEMAS: @@ -92,8 +93,7 @@ components: # OBJECT PROPERTIES: CreatedAt: { $ref: "./objectProperties/createdAt.yaml" } Email: { $ref: "./objectProperties/email.yaml" } - GoogleAccessToken: { $ref: "./objectProperties/googleAccessToken.yaml" } - GoogleID: { $ref: "./objectProperties/googleID.yaml" } + GoogleIDToken: { $ref: "./objectProperties/googleIDToken.yaml" } Handle: { $ref: "./objectProperties/handle.yaml" } Password: { $ref: "./objectProperties/password.yaml" } PaymentMethodID: { $ref: "./objectProperties/paymentMethodID.yaml" } diff --git a/docs/requestBodies/GoogleTokenRequest.yaml b/docs/requestBodies/GoogleTokenRequest.yaml new file mode 100644 index 00000000..e9e15c1d --- /dev/null +++ b/docs/requestBodies/GoogleTokenRequest.yaml @@ -0,0 +1,8 @@ +## yaml-language-server: $schema=https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.yaml#/$defs/request-body + +# req.body for /auth/google-token + +required: true +content: + application/json: + schema: { $ref: "../open-api.yaml#/components/schemas/GoogleIDTokenField" } diff --git a/docs/schemas/GoogleIDTokenField.yaml b/docs/schemas/GoogleIDTokenField.yaml new file mode 100644 index 00000000..c53da5ab --- /dev/null +++ b/docs/schemas/GoogleIDTokenField.yaml @@ -0,0 +1,12 @@ +## yaml-language-server: $schema=https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.yaml#/$defs/schema + +# REST Schema: GoogleIDTokenField + +type: object +description: | + An object which contains a base64-encoded JSON JWT from GoogleID services + under the key "googleIDToken". +properties: + googleIDToken: { $ref: "../open-api.yaml#/components/schemas/GoogleIDToken" } +required: + - googleIDToken diff --git a/docs/schemas/LoginCredentials.GoogleOAuth.yaml b/docs/schemas/LoginCredentials.GoogleOAuth.yaml index 39c09b64..b63f4e9f 100644 --- a/docs/schemas/LoginCredentials.GoogleOAuth.yaml +++ b/docs/schemas/LoginCredentials.GoogleOAuth.yaml @@ -6,9 +6,7 @@ type: object description: The user's login credentials for google-oauth authentication properties: email: { $ref: "../open-api.yaml#/components/schemas/Email" } - googleID: { $ref: "../open-api.yaml#/components/schemas/GoogleID" } - googleAccessToken: { $ref: "../open-api.yaml#/components/schemas/GoogleAccessToken" } + googleIDToken: { $ref: "../open-api.yaml#/components/schemas/GoogleIDToken" } required: - email - - googleID - - googleAccessToken + - googleIDToken diff --git a/docs/schemas/UserRegistrationParams.yaml b/docs/schemas/UserRegistrationParams.yaml index 652e269e..a2212847 100644 --- a/docs/schemas/UserRegistrationParams.yaml +++ b/docs/schemas/UserRegistrationParams.yaml @@ -14,4 +14,3 @@ allOf: required: - handle - email - - phone diff --git a/fixit@current.graphql b/fixit@current.graphql index fd98cc36..1dfad689 100644 --- a/fixit@current.graphql +++ b/fixit@current.graphql @@ -19,12 +19,12 @@ type Query { This query returns a paginated list of Users whose handle begins with the provided `handle` argument, which can be incomplete but must at least contain two characters: the beginning "@", and one character that's either alphanumeric or an underscore. - + Note that this query is intended to be used in conjunction with a pagination utility like [Apollo's `fetchMore` function](https://www.apollographql.com/docs/react/pagination/core-api#the-fetchmore-function). - + ### ROADMAP: - + - Matching Algorithm Change: In the future, the Contact selection method used in this query will either be replaced by a fuzzy-matching system based on the Levenshtein-Demerau model, or a cloud-based search service like ElasticSearch. This change will eliminate @@ -43,7 +43,7 @@ type Query { """ The number of searchable Users to skip before returning results (default 0, min 0). **This argument should only be used if all of the following conditions are true:** - + 1. A previous call to this query returned the maximum number of results (i.e., `limit`). 2. The User who made the previous call wants to retrieve more results. 3. The `handle` argument in the previous call is a valid substring of the `handle` @@ -119,7 +119,7 @@ interface FixitUser { email: Email! """Phone number of either a User or Contact""" - phone: String! + phone: String """Profile object of either a User or Contact""" profile: Profile! @@ -161,7 +161,7 @@ type Contact implements FixitUser { email: Email! """Contact phone number""" - phone: String! + phone: String """Contact Profile object""" profile: Profile! @@ -298,8 +298,8 @@ type User implements FixitUser { """(Immutable) User's own email address""" email: Email! - """(Immutable) User's own phone number""" - phone: String! + """User's own phone number""" + phone: String """ (Mobile-Only) User's Expo push token, used to send push notifications to the User's mobile device diff --git a/package-lock.json b/package-lock.json index 4b96b43a..819de53e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fixit-api", - "version": "2.0.1", + "version": "2.1.0-next.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fixit-api", - "version": "2.0.1", + "version": "2.1.0-next.1", "license": "LicenseRef-LICENSE", "dependencies": { "@apollo/server": "^4.10.1", @@ -15,7 +15,7 @@ "@aws-sdk/lib-dynamodb": "^3.391.0", "@graphql-tools/schema": "^10.0.0", "@nerdware/ddb-single-table": "^2.4.0", - "@nerdware/ts-string-helpers": "^1.1.1", + "@nerdware/ts-string-helpers": "^1.2.1", "@nerdware/ts-type-safety-utils": "^1.0.8", "@sentry/node": "^7.64.0", "bcrypt": "^5.1.1", @@ -24,6 +24,7 @@ "dayjs": "^1.11.9", "expo-server-sdk": "^3.7.0", "express": "^4.18.2", + "google-auth-library": "^9.7.0", "graphql": "^16.8.1", "graphql-tag": "^2.12.6", "helmet": "^7.0.0", @@ -930,52 +931,52 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.529.1.tgz", - "integrity": "sha512-oyMCMu4JUGUIwuLYm2WAI/wUbw3RwWwgPTPTxJdus79NVgQ0lGCZnS4cOd2LtzufRglShr5LZUvueVdyn8Hrjw==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.535.0.tgz", + "integrity": "sha512-Z4xP7uryereaLm2Q6oAZLOb6uK7IcQfsJhIm5ZGNT5bWX2W8gRf+A+J9whBYMeuTB5pDUGK3SbFi+TXZjlEmgg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.529.1", - "@aws-sdk/core": "3.529.1", - "@aws-sdk/credential-provider-node": "3.529.1", - "@aws-sdk/middleware-endpoint-discovery": "3.525.0", - "@aws-sdk/middleware-host-header": "3.523.0", - "@aws-sdk/middleware-logger": "3.523.0", - "@aws-sdk/middleware-recursion-detection": "3.523.0", - "@aws-sdk/middleware-user-agent": "3.525.0", - "@aws-sdk/region-config-resolver": "3.525.0", - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@aws-sdk/util-user-agent-browser": "3.523.0", - "@aws-sdk/util-user-agent-node": "3.525.0", - "@smithy/config-resolver": "^2.1.4", - "@smithy/core": "^1.3.5", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/hash-node": "^2.1.3", - "@smithy/invalid-dependency": "^2.1.3", - "@smithy/middleware-content-length": "^2.1.3", - "@smithy/middleware-endpoint": "^2.4.4", - "@smithy/middleware-retry": "^2.1.4", - "@smithy/middleware-serde": "^2.1.3", - "@smithy/middleware-stack": "^2.1.3", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/url-parser": "^2.1.3", - "@smithy/util-base64": "^2.1.1", - "@smithy/util-body-length-browser": "^2.1.1", - "@smithy/util-body-length-node": "^2.2.1", - "@smithy/util-defaults-mode-browser": "^2.1.4", - "@smithy/util-defaults-mode-node": "^2.2.3", - "@smithy/util-endpoints": "^1.1.4", - "@smithy/util-middleware": "^2.1.3", - "@smithy/util-retry": "^2.1.3", - "@smithy/util-utf8": "^2.1.1", - "@smithy/util-waiter": "^2.1.3", - "tslib": "^2.5.0", + "@aws-sdk/client-sts": "3.535.0", + "@aws-sdk/core": "3.535.0", + "@aws-sdk/credential-provider-node": "3.535.0", + "@aws-sdk/middleware-endpoint-discovery": "3.535.0", + "@aws-sdk/middleware-host-header": "3.535.0", + "@aws-sdk/middleware-logger": "3.535.0", + "@aws-sdk/middleware-recursion-detection": "3.535.0", + "@aws-sdk/middleware-user-agent": "3.535.0", + "@aws-sdk/region-config-resolver": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@aws-sdk/util-user-agent-browser": "3.535.0", + "@aws-sdk/util-user-agent-node": "3.535.0", + "@smithy/config-resolver": "^2.2.0", + "@smithy/core": "^1.4.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/hash-node": "^2.2.0", + "@smithy/invalid-dependency": "^2.2.0", + "@smithy/middleware-content-length": "^2.2.0", + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-body-length-browser": "^2.2.0", + "@smithy/util-body-length-node": "^2.3.0", + "@smithy/util-defaults-mode-browser": "^2.2.0", + "@smithy/util-defaults-mode-node": "^2.3.0", + "@smithy/util-endpoints": "^1.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "@smithy/util-waiter": "^2.2.0", + "tslib": "^2.6.2", "uuid": "^9.0.1" }, "engines": { @@ -983,372 +984,372 @@ } }, "node_modules/@aws-sdk/client-lambda": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.529.1.tgz", - "integrity": "sha512-It2r/Ge5WDGaY705Pw1F7EUAQp7+LDUF1XEqh0H8tTmjqIvqBIGjz//1bkNf489kBUnvGY4F1jzkwp7Cc5481A==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.535.0.tgz", + "integrity": "sha512-aR8/yblb3wEsPZ/U4XAx5k4Ek8+cEBzJIj6cFSa9OqBRHIWdu2f8bbQR7yDRYzq5Ta/nqFg2023gksee3KCSdw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.529.1", - "@aws-sdk/core": "3.529.1", - "@aws-sdk/credential-provider-node": "3.529.1", - "@aws-sdk/middleware-host-header": "3.523.0", - "@aws-sdk/middleware-logger": "3.523.0", - "@aws-sdk/middleware-recursion-detection": "3.523.0", - "@aws-sdk/middleware-user-agent": "3.525.0", - "@aws-sdk/region-config-resolver": "3.525.0", - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@aws-sdk/util-user-agent-browser": "3.523.0", - "@aws-sdk/util-user-agent-node": "3.525.0", - "@smithy/config-resolver": "^2.1.4", - "@smithy/core": "^1.3.5", - "@smithy/eventstream-serde-browser": "^2.1.3", - "@smithy/eventstream-serde-config-resolver": "^2.1.3", - "@smithy/eventstream-serde-node": "^2.1.3", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/hash-node": "^2.1.3", - "@smithy/invalid-dependency": "^2.1.3", - "@smithy/middleware-content-length": "^2.1.3", - "@smithy/middleware-endpoint": "^2.4.4", - "@smithy/middleware-retry": "^2.1.4", - "@smithy/middleware-serde": "^2.1.3", - "@smithy/middleware-stack": "^2.1.3", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/url-parser": "^2.1.3", - "@smithy/util-base64": "^2.1.1", - "@smithy/util-body-length-browser": "^2.1.1", - "@smithy/util-body-length-node": "^2.2.1", - "@smithy/util-defaults-mode-browser": "^2.1.4", - "@smithy/util-defaults-mode-node": "^2.2.3", - "@smithy/util-endpoints": "^1.1.4", - "@smithy/util-middleware": "^2.1.3", - "@smithy/util-retry": "^2.1.3", - "@smithy/util-stream": "^2.1.3", - "@smithy/util-utf8": "^2.1.1", - "@smithy/util-waiter": "^2.1.3", - "tslib": "^2.5.0" + "@aws-sdk/client-sts": "3.535.0", + "@aws-sdk/core": "3.535.0", + "@aws-sdk/credential-provider-node": "3.535.0", + "@aws-sdk/middleware-host-header": "3.535.0", + "@aws-sdk/middleware-logger": "3.535.0", + "@aws-sdk/middleware-recursion-detection": "3.535.0", + "@aws-sdk/middleware-user-agent": "3.535.0", + "@aws-sdk/region-config-resolver": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@aws-sdk/util-user-agent-browser": "3.535.0", + "@aws-sdk/util-user-agent-node": "3.535.0", + "@smithy/config-resolver": "^2.2.0", + "@smithy/core": "^1.4.0", + "@smithy/eventstream-serde-browser": "^2.2.0", + "@smithy/eventstream-serde-config-resolver": "^2.2.0", + "@smithy/eventstream-serde-node": "^2.2.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/hash-node": "^2.2.0", + "@smithy/invalid-dependency": "^2.2.0", + "@smithy/middleware-content-length": "^2.2.0", + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-body-length-browser": "^2.2.0", + "@smithy/util-body-length-node": "^2.3.0", + "@smithy/util-defaults-mode-browser": "^2.2.0", + "@smithy/util-defaults-mode-node": "^2.3.0", + "@smithy/util-endpoints": "^1.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "@smithy/util-stream": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "@smithy/util-waiter": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.529.1.tgz", - "integrity": "sha512-KT1U/ZNjDhVv2ZgjzaeAn9VM7l667yeSguMrRYC8qk5h91/61MbjZypi6eOuKuVM+0fsQvzKScTQz0Lio0eYag==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.535.0.tgz", + "integrity": "sha512-h9eQRdFnjDRVBnPJIKXuX7D+isSAioIfZPC4PQwsL5BscTRlk4c90DX0R0uk64YUtp7LZu8TNtrosFZ/1HtTrQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.529.1", - "@aws-sdk/middleware-host-header": "3.523.0", - "@aws-sdk/middleware-logger": "3.523.0", - "@aws-sdk/middleware-recursion-detection": "3.523.0", - "@aws-sdk/middleware-user-agent": "3.525.0", - "@aws-sdk/region-config-resolver": "3.525.0", - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@aws-sdk/util-user-agent-browser": "3.523.0", - "@aws-sdk/util-user-agent-node": "3.525.0", - "@smithy/config-resolver": "^2.1.4", - "@smithy/core": "^1.3.5", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/hash-node": "^2.1.3", - "@smithy/invalid-dependency": "^2.1.3", - "@smithy/middleware-content-length": "^2.1.3", - "@smithy/middleware-endpoint": "^2.4.4", - "@smithy/middleware-retry": "^2.1.4", - "@smithy/middleware-serde": "^2.1.3", - "@smithy/middleware-stack": "^2.1.3", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/url-parser": "^2.1.3", - "@smithy/util-base64": "^2.1.1", - "@smithy/util-body-length-browser": "^2.1.1", - "@smithy/util-body-length-node": "^2.2.1", - "@smithy/util-defaults-mode-browser": "^2.1.4", - "@smithy/util-defaults-mode-node": "^2.2.3", - "@smithy/util-endpoints": "^1.1.4", - "@smithy/util-middleware": "^2.1.3", - "@smithy/util-retry": "^2.1.3", - "@smithy/util-utf8": "^2.1.1", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.535.0", + "@aws-sdk/middleware-host-header": "3.535.0", + "@aws-sdk/middleware-logger": "3.535.0", + "@aws-sdk/middleware-recursion-detection": "3.535.0", + "@aws-sdk/middleware-user-agent": "3.535.0", + "@aws-sdk/region-config-resolver": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@aws-sdk/util-user-agent-browser": "3.535.0", + "@aws-sdk/util-user-agent-node": "3.535.0", + "@smithy/config-resolver": "^2.2.0", + "@smithy/core": "^1.4.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/hash-node": "^2.2.0", + "@smithy/invalid-dependency": "^2.2.0", + "@smithy/middleware-content-length": "^2.2.0", + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-body-length-browser": "^2.2.0", + "@smithy/util-body-length-node": "^2.3.0", + "@smithy/util-defaults-mode-browser": "^2.2.0", + "@smithy/util-defaults-mode-node": "^2.3.0", + "@smithy/util-endpoints": "^1.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.529.1.tgz", - "integrity": "sha512-bimxCWAvRnVcluWEQeadXvHyzWlBWsuGVligsaVZaGF0TLSn0eLpzpN9B1EhHzTf7m0Kh/wGtPSH1JxO6PpB+A==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.535.0.tgz", + "integrity": "sha512-M2cG4EQXDpAJQyq33ORIr6abmdX9p9zX0ssVy8XwFNB7lrgoIKxuVoGL+fX+XMgecl24x7ELz6b4QlILOevbCw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.529.1", - "@aws-sdk/core": "3.529.1", - "@aws-sdk/middleware-host-header": "3.523.0", - "@aws-sdk/middleware-logger": "3.523.0", - "@aws-sdk/middleware-recursion-detection": "3.523.0", - "@aws-sdk/middleware-user-agent": "3.525.0", - "@aws-sdk/region-config-resolver": "3.525.0", - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@aws-sdk/util-user-agent-browser": "3.523.0", - "@aws-sdk/util-user-agent-node": "3.525.0", - "@smithy/config-resolver": "^2.1.4", - "@smithy/core": "^1.3.5", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/hash-node": "^2.1.3", - "@smithy/invalid-dependency": "^2.1.3", - "@smithy/middleware-content-length": "^2.1.3", - "@smithy/middleware-endpoint": "^2.4.4", - "@smithy/middleware-retry": "^2.1.4", - "@smithy/middleware-serde": "^2.1.3", - "@smithy/middleware-stack": "^2.1.3", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/url-parser": "^2.1.3", - "@smithy/util-base64": "^2.1.1", - "@smithy/util-body-length-browser": "^2.1.1", - "@smithy/util-body-length-node": "^2.2.1", - "@smithy/util-defaults-mode-browser": "^2.1.4", - "@smithy/util-defaults-mode-node": "^2.2.3", - "@smithy/util-endpoints": "^1.1.4", - "@smithy/util-middleware": "^2.1.3", - "@smithy/util-retry": "^2.1.3", - "@smithy/util-utf8": "^2.1.1", - "tslib": "^2.5.0" + "@aws-sdk/client-sts": "3.535.0", + "@aws-sdk/core": "3.535.0", + "@aws-sdk/middleware-host-header": "3.535.0", + "@aws-sdk/middleware-logger": "3.535.0", + "@aws-sdk/middleware-recursion-detection": "3.535.0", + "@aws-sdk/middleware-user-agent": "3.535.0", + "@aws-sdk/region-config-resolver": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@aws-sdk/util-user-agent-browser": "3.535.0", + "@aws-sdk/util-user-agent-node": "3.535.0", + "@smithy/config-resolver": "^2.2.0", + "@smithy/core": "^1.4.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/hash-node": "^2.2.0", + "@smithy/invalid-dependency": "^2.2.0", + "@smithy/middleware-content-length": "^2.2.0", + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-body-length-browser": "^2.2.0", + "@smithy/util-body-length-node": "^2.3.0", + "@smithy/util-defaults-mode-browser": "^2.2.0", + "@smithy/util-defaults-mode-node": "^2.3.0", + "@smithy/util-endpoints": "^1.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "^3.529.1" + "@aws-sdk/credential-provider-node": "^3.535.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.529.1.tgz", - "integrity": "sha512-Rvk2Sr3MACQTOtngUU+omlf4E17k47dRVXR7OFRD6Ow5iGgC9tkN2q/ExDPW/ktPOmM0lSgzWyQ6/PC/Zq3HUg==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.535.0.tgz", + "integrity": "sha512-ii9OOm3TJwP3JmO1IVJXKWIShVKPl0VtdlgROc/SkDglO/kuAw9eDdlROgc+qbFl+gm6bBTguOVTUXt3tS3flw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.529.1", - "@aws-sdk/middleware-host-header": "3.523.0", - "@aws-sdk/middleware-logger": "3.523.0", - "@aws-sdk/middleware-recursion-detection": "3.523.0", - "@aws-sdk/middleware-user-agent": "3.525.0", - "@aws-sdk/region-config-resolver": "3.525.0", - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@aws-sdk/util-user-agent-browser": "3.523.0", - "@aws-sdk/util-user-agent-node": "3.525.0", - "@smithy/config-resolver": "^2.1.4", - "@smithy/core": "^1.3.5", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/hash-node": "^2.1.3", - "@smithy/invalid-dependency": "^2.1.3", - "@smithy/middleware-content-length": "^2.1.3", - "@smithy/middleware-endpoint": "^2.4.4", - "@smithy/middleware-retry": "^2.1.4", - "@smithy/middleware-serde": "^2.1.3", - "@smithy/middleware-stack": "^2.1.3", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/url-parser": "^2.1.3", - "@smithy/util-base64": "^2.1.1", - "@smithy/util-body-length-browser": "^2.1.1", - "@smithy/util-body-length-node": "^2.2.1", - "@smithy/util-defaults-mode-browser": "^2.1.4", - "@smithy/util-defaults-mode-node": "^2.2.3", - "@smithy/util-endpoints": "^1.1.4", - "@smithy/util-middleware": "^2.1.3", - "@smithy/util-retry": "^2.1.3", - "@smithy/util-utf8": "^2.1.1", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.535.0", + "@aws-sdk/middleware-host-header": "3.535.0", + "@aws-sdk/middleware-logger": "3.535.0", + "@aws-sdk/middleware-recursion-detection": "3.535.0", + "@aws-sdk/middleware-user-agent": "3.535.0", + "@aws-sdk/region-config-resolver": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@aws-sdk/util-user-agent-browser": "3.535.0", + "@aws-sdk/util-user-agent-node": "3.535.0", + "@smithy/config-resolver": "^2.2.0", + "@smithy/core": "^1.4.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/hash-node": "^2.2.0", + "@smithy/invalid-dependency": "^2.2.0", + "@smithy/middleware-content-length": "^2.2.0", + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-body-length-browser": "^2.2.0", + "@smithy/util-body-length-node": "^2.3.0", + "@smithy/util-defaults-mode-browser": "^2.2.0", + "@smithy/util-defaults-mode-node": "^2.3.0", + "@smithy/util-endpoints": "^1.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "^3.529.1" + "@aws-sdk/credential-provider-node": "^3.535.0" } }, "node_modules/@aws-sdk/core": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.529.1.tgz", - "integrity": "sha512-Sj42sYPfaL9PHvvciMICxhyrDZjqnnvFbPKDmQL5aFKyXy122qx7RdVqUOQERDmMQfvJh6+0W1zQlLnre89q4Q==", - "dependencies": { - "@smithy/core": "^1.3.5", - "@smithy/protocol-http": "^3.2.1", - "@smithy/signature-v4": "^2.1.3", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.535.0.tgz", + "integrity": "sha512-+Yusa9HziuaEDta1UaLEtMAtmgvxdxhPn7jgfRY6PplqAqgsfa5FR83sxy5qr2q7xjQTwHtV4MjQVuOjG9JsLw==", + "dependencies": { + "@smithy/core": "^1.4.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/signature-v4": "^2.2.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.523.0.tgz", - "integrity": "sha512-Y6DWdH6/OuMDoNKVzZlNeBc6f1Yjk1lYMjANKpIhMbkRCvLJw/PYZKOZa8WpXbTYdgg9XLjKybnLIb3ww3uuzA==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.535.0.tgz", + "integrity": "sha512-XppwO8c0GCGSAvdzyJOhbtktSEaShg14VJKg8mpMa1XcgqzmcqqHQjtDWbx5rZheY1VdpXZhpEzJkB6LpQejpA==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/property-provider": "^2.1.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.525.0.tgz", - "integrity": "sha512-RNWQGuSBQZhl3iqklOslUEfQ4br1V3DCPboMpeqFtddUWJV3m2u2extFur9/4Uy+1EHVF120IwZUKtd8dF+ibw==", - "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/fetch-http-handler": "^2.4.3", - "@smithy/node-http-handler": "^2.4.1", - "@smithy/property-provider": "^2.1.3", - "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "@smithy/util-stream": "^2.1.3", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.535.0.tgz", + "integrity": "sha512-kdj1wCmOMZ29jSlUskRqN04S6fJ4dvt0Nq9Z32SA6wO7UG8ht6Ot9h/au/eTWJM3E1somZ7D771oK7dQt9b8yw==", + "dependencies": { + "@aws-sdk/types": "3.535.0", + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/util-stream": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.529.1.tgz", - "integrity": "sha512-RjHsuTvHIwXG7a/3ERexemiD3c9riKMCZQzY2/b0Gg0ButEVbBcMfERtUzWmQ0V4ufe/PEZjP68MH1gupcoF9A==", - "dependencies": { - "@aws-sdk/client-sts": "3.529.1", - "@aws-sdk/credential-provider-env": "3.523.0", - "@aws-sdk/credential-provider-process": "3.523.0", - "@aws-sdk/credential-provider-sso": "3.529.1", - "@aws-sdk/credential-provider-web-identity": "3.529.1", - "@aws-sdk/types": "3.523.0", - "@smithy/credential-provider-imds": "^2.2.3", - "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.535.0.tgz", + "integrity": "sha512-bm3XOYlyCjtAb8eeHXLrxqRxYVRw2Iqv9IufdJb4gM13TbNSYniUT1WKaHxGIZ5p+FuNlXVhvk1OpHFM13+gXA==", + "dependencies": { + "@aws-sdk/client-sts": "3.535.0", + "@aws-sdk/credential-provider-env": "3.535.0", + "@aws-sdk/credential-provider-process": "3.535.0", + "@aws-sdk/credential-provider-sso": "3.535.0", + "@aws-sdk/credential-provider-web-identity": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/credential-provider-imds": "^2.3.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.529.1.tgz", - "integrity": "sha512-mvY7F3dMmk/0dZOCfl5sUI1bG0osureBjxhELGCF0KkJqhWI0hIzh8UnPkYytSg3vdc97CMv7pTcozxrdA3b0g==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.523.0", - "@aws-sdk/credential-provider-http": "3.525.0", - "@aws-sdk/credential-provider-ini": "3.529.1", - "@aws-sdk/credential-provider-process": "3.523.0", - "@aws-sdk/credential-provider-sso": "3.529.1", - "@aws-sdk/credential-provider-web-identity": "3.529.1", - "@aws-sdk/types": "3.523.0", - "@smithy/credential-provider-imds": "^2.2.3", - "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.535.0.tgz", + "integrity": "sha512-6JXp/EuL6euUkH5k4d+lQFF6gBwukrcCOWfNHCmq14mNJf/cqT3HAX1VMtWFRSK20am0IxfYQGccb0/nZykdKg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.535.0", + "@aws-sdk/credential-provider-http": "3.535.0", + "@aws-sdk/credential-provider-ini": "3.535.0", + "@aws-sdk/credential-provider-process": "3.535.0", + "@aws-sdk/credential-provider-sso": "3.535.0", + "@aws-sdk/credential-provider-web-identity": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/credential-provider-imds": "^2.3.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.523.0.tgz", - "integrity": "sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q==", - "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.535.0.tgz", + "integrity": "sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA==", + "dependencies": { + "@aws-sdk/types": "3.535.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.529.1.tgz", - "integrity": "sha512-KFMKkaoTGDgSJG+o9Ii7AglWG5JQeF6IFw9cXLMwDdIrp3KUmRcUIqe0cjOoCqeQEDGy0VHsimHmKKJ3894i/A==", - "dependencies": { - "@aws-sdk/client-sso": "3.529.1", - "@aws-sdk/token-providers": "3.529.1", - "@aws-sdk/types": "3.523.0", - "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.535.0.tgz", + "integrity": "sha512-2Dw0YIr8ETdFpq65CC4zK8ZIEbX78rXoNRZXUGNQW3oSKfL0tj8O8ErY6kg1IdEnYbGnEQ35q6luZ5GGNKLgDg==", + "dependencies": { + "@aws-sdk/client-sso": "3.535.0", + "@aws-sdk/token-providers": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.529.1.tgz", - "integrity": "sha512-AGuZDOKN+AttjwTjrF47WLqzeEut2YynyxjkXZhxZF/xn8i5Y51kUAUdXsXw1bgR25pAeXQIdhsrQlRa1Pm5kw==", - "dependencies": { - "@aws-sdk/client-sts": "3.529.1", - "@aws-sdk/types": "3.523.0", - "@smithy/property-provider": "^2.1.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.535.0.tgz", + "integrity": "sha512-t2/JWrKY0H66A7JW7CqX06/DG2YkJddikt5ymdQvx/Q7dRMJ3d+o/vgjoKr7RvEx/pNruCeyM1599HCvwrVMrg==", + "dependencies": { + "@aws-sdk/client-sts": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/endpoint-cache": { - "version": "3.495.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.495.0.tgz", - "integrity": "sha512-XCDrpiS50WaPzPzp7FwsChPHtX9PQQUU4nRzcn2N7IkUtpcFCUx8m1PAZe086VQr6hrbdeE4Z4j8hUPNwVdJGQ==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.535.0.tgz", + "integrity": "sha512-sPG2l00iVuporK9AmPWq4UBcJURs2RN+vKA8QLRQANmQS3WFHWHamvGltxCjK79izkeqri882V4XlFpZfWhemA==", "dependencies": { "mnemonist": "0.38.3", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/lib-dynamodb": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.529.1.tgz", - "integrity": "sha512-SLGDUoAyYQ5UlZzQ0+kXEZFEcqizE56uYSuR5ohRpeks6ghkwEC0iNJDJlFqTtzWP7f6Noh5pKjvtQ0OzhH88Q==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.535.0.tgz", + "integrity": "sha512-SJ3IcuN+BmwMv5ZlK04tCu/YhjqehdlYpQB+nK6h4Gvw7dfTTJua3p/OcWm5uDFvZvYi9SNAJFcepjZhxXdSNw==", "dependencies": { - "@aws-sdk/util-dynamodb": "3.529.1", - "@smithy/smithy-client": "^2.4.2", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/util-dynamodb": "3.535.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" @@ -1358,127 +1359,127 @@ } }, "node_modules/@aws-sdk/middleware-endpoint-discovery": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.525.0.tgz", - "integrity": "sha512-nT/XYP3RDRWPFCTEOZQbOC3HWmUkxB0fDuobmH8WzL92MCBGz9gBG/q9XBxiw9pHk9Dky/MIkLV50BlGB3kM7g==", - "dependencies": { - "@aws-sdk/endpoint-cache": "3.495.0", - "@aws-sdk/types": "3.523.0", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/protocol-http": "^3.2.1", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.535.0.tgz", + "integrity": "sha512-+EsqJB5A15RoTf0HxUdknF3hp+2WDg0HWc+QERUctzzYXy9l5LIQjmhQ96cWDyFttKmHE+4h6fjMZjJEeWOeYQ==", + "dependencies": { + "@aws-sdk/endpoint-cache": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.523.0.tgz", - "integrity": "sha512-4g3q7Ta9sdD9TMUuohBAkbx/e3I/juTqfKi7TPgP+8jxcYX72MOsgemAMHuP6CX27eyj4dpvjH+w4SIVDiDSmg==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.535.0.tgz", + "integrity": "sha512-0h6TWjBWtDaYwHMQJI9ulafeS4lLaw1vIxRjbpH0svFRt6Eve+Sy8NlVhECfTU2hNz/fLubvrUxsXoThaLBIew==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/protocol-http": "^3.2.1", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.523.0.tgz", - "integrity": "sha512-PeDNJNhfiaZx54LBaLTXzUaJ9LXFwDFFIksipjqjvxMafnoVcQwKbkoPUWLe5ytT4nnL1LogD3s55mERFUsnwg==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.535.0.tgz", + "integrity": "sha512-huNHpONOrEDrdRTvSQr1cJiRMNf0S52NDXtaPzdxiubTkP+vni2MohmZANMOai/qT0olmEVX01LhZ0ZAOgmg6A==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.523.0.tgz", - "integrity": "sha512-nZ3Vt7ehfSDYnrcg/aAfjjvpdE+61B3Zk68i6/hSUIegT3IH9H1vSW67NDKVp+50hcEfzWwM2HMPXxlzuyFyrw==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.535.0.tgz", + "integrity": "sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/protocol-http": "^3.2.1", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.525.0.tgz", - "integrity": "sha512-4al/6uO+t/QIYXK2OgqzDKQzzLAYJza1vWFS+S0lJ3jLNGyLB5BMU5KqWjDzevYZ4eCnz2Nn7z0FveUTNz8YdQ==", - "dependencies": { - "@aws-sdk/types": "3.523.0", - "@aws-sdk/util-endpoints": "3.525.0", - "@smithy/protocol-http": "^3.2.1", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.535.0.tgz", + "integrity": "sha512-Uvb2WJ+zdHdCOtsWVPI/M0BcfNrjOYsicDZWtaljucRJKLclY5gNWwD+RwIC+8b5TvfnVOlH+N5jhvpi5Impog==", + "dependencies": { + "@aws-sdk/types": "3.535.0", + "@aws-sdk/util-endpoints": "3.535.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.525.0.tgz", - "integrity": "sha512-8kFqXk6UyKgTMi7N7QlhA6qM4pGPWbiUXqEY2RgUWngtxqNFGeM9JTexZeuavQI+qLLe09VPShPNX71fEDcM6w==", - "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/types": "^2.10.1", - "@smithy/util-config-provider": "^2.2.1", - "@smithy/util-middleware": "^2.1.3", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.535.0.tgz", + "integrity": "sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg==", + "dependencies": { + "@aws-sdk/types": "3.535.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/types": "^2.12.0", + "@smithy/util-config-provider": "^2.3.0", + "@smithy/util-middleware": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.529.1.tgz", - "integrity": "sha512-NpgMjsfpqiugbxrYGXtta914N43Mx/H0niidqv8wKMTgWQEtsJvYtOni+kuLXB+LmpjaMFNlpadooFU/bK4buA==", - "dependencies": { - "@aws-sdk/client-sso-oidc": "3.529.1", - "@aws-sdk/types": "3.523.0", - "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.535.0.tgz", + "integrity": "sha512-4g+l/B9h1H/SiDtFRosW3pMwc+3PTXljZit+5NUBcET2XqcdUyHmgj3lBdu+CJ9CHdIMggRalYMAFXnRFe3Psg==", + "dependencies": { + "@aws-sdk/client-sso-oidc": "3.535.0", + "@aws-sdk/types": "3.535.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.523.0.tgz", - "integrity": "sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.535.0.tgz", + "integrity": "sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg==", "dependencies": { - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-dynamodb": { - "version": "3.529.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.529.1.tgz", - "integrity": "sha512-SXVK/eT7iJwLO4/Kq9Qvlm1zs5gUnpshE1EJ9+9yks9Q79KYI5FuRQxU0qZ0vxHuLHsesDAIJy59iKsWmVls6A==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.535.0.tgz", + "integrity": "sha512-zHvmKRmAkJKFXzeTMifoooC2mS8jSRHBHSFxxscrZDgvZgo2g9ogIy52qz/3cWKI/ZQnrBSLhPpGYDZHrSgO8g==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" @@ -1488,50 +1489,50 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.525.0.tgz", - "integrity": "sha512-DIW7WWU5tIGkeeKX6NJUyrEIdWMiqjLQG3XBzaUj+ufIENwNjdAHhlD8l2vX7Yr3JZRT6yN/84wBCj7Tw1xd1g==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.535.0.tgz", + "integrity": "sha512-c8TlaQsiPchOOmTTR6qvHCO2O7L7NJwlKWAoQJ2GqWDZuC5es/fyuF2rp1h+ZRrUVraUomS0YdGkAmaDC7hJQg==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/types": "^2.10.1", - "@smithy/util-endpoints": "^1.1.4", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/types": "^2.12.0", + "@smithy/util-endpoints": "^1.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.495.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.495.0.tgz", - "integrity": "sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.535.0.tgz", + "integrity": "sha512-PHJ3SL6d2jpcgbqdgiPxkXpu7Drc2PYViwxSIqvvMKhDwzSB1W3mMvtpzwKM4IE7zLFodZo0GKjJ9AsoXndXhA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.523.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.523.0.tgz", - "integrity": "sha512-6ZRNdGHX6+HQFqTbIA5+i8RWzxFyxsZv8D3soRfpdyWIKkzhSz8IyRKXRciwKBJDaC7OX2jzGE90wxRQft27nA==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.535.0.tgz", + "integrity": "sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/types": "^2.10.1", + "@aws-sdk/types": "3.535.0", + "@smithy/types": "^2.12.0", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.525.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.525.0.tgz", - "integrity": "sha512-88Wjt4efyUSBGcyIuh1dvoMqY1k15jpJc5A/3yi67clBQEFsu9QCodQCQPqmRjV3VRcMtBOk+jeCTiUzTY5dRQ==", + "version": "3.535.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.535.0.tgz", + "integrity": "sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ==", "dependencies": { - "@aws-sdk/types": "3.523.0", - "@smithy/node-config-provider": "^2.2.4", - "@smithy/types": "^2.10.1", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.535.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" @@ -3357,9 +3358,9 @@ } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", - "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.8.tgz", + "integrity": "sha512-rB+2P3oi9fD4TcsijkflJAQqOh4yZrPgOV4fGaDgCdOqqwTicJvL2nnVbr3comW8bxEuypOcyE1AtBtkpip0Gw==", "dev": true, "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", @@ -3452,12 +3453,12 @@ } }, "node_modules/@graphql-tools/executor": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.1.tgz", - "integrity": "sha512-BP5UI1etbNOXmTSt7q4NL1+zsURFgh2pG+Hyt9K/xO0LlsfbSx59L5dHLerqZP7Js0xI6GYqrUQ4m29rUwUHJg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.2.tgz", + "integrity": "sha512-wZkyjndwlzi01HTU3PDveoucKA8qVO0hdKmJhjIGK/vRN/A4w5rDdeqRGcyXVss0clCAy3R6jpixCVu5pWs2Qg==", "dev": true, "dependencies": { - "@graphql-tools/utils": "^10.0.13", + "@graphql-tools/utils": "^10.1.1", "@graphql-typed-document-node/core": "3.2.0", "@repeaterjs/repeater": "^3.0.4", "tslib": "^2.4.0", @@ -3534,9 +3535,9 @@ } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", - "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.8.tgz", + "integrity": "sha512-rB+2P3oi9fD4TcsijkflJAQqOh4yZrPgOV4fGaDgCdOqqwTicJvL2nnVbr3comW8bxEuypOcyE1AtBtkpip0Gw==", "dev": true, "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", @@ -3638,9 +3639,9 @@ } }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", - "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.8.tgz", + "integrity": "sha512-rB+2P3oi9fD4TcsijkflJAQqOh4yZrPgOV4fGaDgCdOqqwTicJvL2nnVbr3comW8bxEuypOcyE1AtBtkpip0Gw==", "dev": true, "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", @@ -3855,9 +3856,9 @@ } }, "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", - "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.8.tgz", + "integrity": "sha512-rB+2P3oi9fD4TcsijkflJAQqOh4yZrPgOV4fGaDgCdOqqwTicJvL2nnVbr3comW8bxEuypOcyE1AtBtkpip0Gw==", "dev": true, "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", @@ -3976,9 +3977,9 @@ } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", - "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.8.tgz", + "integrity": "sha512-rB+2P3oi9fD4TcsijkflJAQqOh4yZrPgOV4fGaDgCdOqqwTicJvL2nnVbr3comW8bxEuypOcyE1AtBtkpip0Gw==", "dev": true, "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", @@ -3998,9 +3999,9 @@ "dev": true }, "node_modules/@graphql-tools/utils": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.0.tgz", - "integrity": "sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.2.tgz", + "integrity": "sha512-fX13CYsDnX4yifIyNdiN0cVygz/muvkreWWem6BBw130+ODbRRgfiVveL0NizCEnKXkpvdeTy9Bxvo9LIKlhrw==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -4015,14 +4016,14 @@ } }, "node_modules/@graphql-tools/wrap": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-10.0.2.tgz", - "integrity": "sha512-nb/YjBcyF02KBCy3hiyw0nBKIC+qkiDY/tGMCcIe4pM6BPEcnreaPhXA28Rdge7lKtySF4Mhbc86XafFH5bIkQ==", + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-10.0.5.tgz", + "integrity": "sha512-Cbr5aYjr3HkwdPvetZp1cpDWTGdD1Owgsb3z/ClzhmrboiK86EnQDxDvOJiQkDCPWE9lNBwj8Y4HfxroY0D9DQ==", "dev": true, "dependencies": { "@graphql-tools/delegate": "^10.0.4", "@graphql-tools/schema": "^10.0.3", - "@graphql-tools/utils": "^10.0.13", + "@graphql-tools/utils": "^10.1.1", "tslib": "^2.4.0", "value-or-promise": "^1.0.12" }, @@ -4284,9 +4285,9 @@ } }, "node_modules/@nerdware/ts-string-helpers": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@nerdware/ts-string-helpers/-/ts-string-helpers-1.1.2.tgz", - "integrity": "sha512-wT8w3LxxdWT5OKgOeRrDzBFGAd6U7pD0Hva+dzqRoau8ehNBky0JPXZjdCA+BdBS+ccikRfs1xN+nabQcUg7nA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@nerdware/ts-string-helpers/-/ts-string-helpers-1.2.1.tgz", + "integrity": "sha512-0tBzMjXZbevJk7sWQd6gIUCuxCmfDQHuUXQWoXToRhKMYzx3mBPKFBmiOvkRr0mf5Ix5w3cIagPZIw7K2+vB1Q==", "engines": { "node": ">=16.0.0", "npm": ">=8.0.0" @@ -4337,9 +4338,9 @@ } }, "node_modules/@oclif/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.23.0.tgz", - "integrity": "sha512-giQ/8Ft8yXWg4IyPVtynPb7ihoQsa3A/1Q53UIJIhh+8k+EedE3lJ01yn6sq6Ha35IGqsG1WhkeHzlJIuldEaw==", + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.25.2.tgz", + "integrity": "sha512-OkW/cNa/3DhoCz2YlSpymVe8DXqkoRaLY4SPTVqNVzR4R1dFBE5KoCtuwKwnhxYLCRCqaViPgRnB5K26f0MnjA==", "dev": true, "dependencies": { "@types/cli-progress": "^3.11.5", @@ -4490,13 +4491,13 @@ } }, "node_modules/@oclif/plugin-help": { - "version": "6.0.17", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-6.0.17.tgz", - "integrity": "sha512-zHKRQf/SkaOyF8xwz9EJxQ4bsB9bK+ED+i0YF24dud/1DkTj5cEDvrNV6sj+YH34ONz7z4et230URdFM3SJKeQ==", + "version": "6.0.18", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-6.0.18.tgz", + "integrity": "sha512-Ly0gu/+eq7GfIMT76cirbHgElYGlu+PaZ5elrAKmDiegBh31AXqaPQAj8PH4+sG8RSv5srYtrkrygZaw8IF9CQ==", "dev": true, "hasShrinkwrap": true, "dependencies": { - "@oclif/core": "^3.21.0" + "@oclif/core": "^3.23.0" }, "engines": { "node": ">=18.0.0" @@ -8356,9 +8357,9 @@ } }, "node_modules/@oclif/plugin-help/node_modules/@oclif/core": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.21.0.tgz", - "integrity": "sha512-xR7qGPOWtOnYmdYocSn6oEh2oTQLsPOXoj3HYGpb26V3WulwF8Cm33WPnMsSISv4ben3Rtc5i59u9O5NnuG42g==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.23.0.tgz", + "integrity": "sha512-giQ/8Ft8yXWg4IyPVtynPb7ihoQsa3A/1Q53UIJIhh+8k+EedE3lJ01yn6sq6Ha35IGqsG1WhkeHzlJIuldEaw==", "dev": true, "license": "MIT", "dependencies": { @@ -8378,6 +8379,7 @@ "indent-string": "^4.0.0", "is-wsl": "^2.2.0", "js-yaml": "^3.14.1", + "minimatch": "^9.0.3", "natural-orderby": "^2.0.3", "object-treeify": "^1.1.33", "password-prompt": "^1.1.3", @@ -8418,6 +8420,22 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@oclif/plugin-help/node_modules/@oclif/core/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@oclif/plugin-help/node_modules/@oclif/core/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -8447,85 +8465,6 @@ "node": ">=18.0.0" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-help/node_modules/@oclif/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.20.0.tgz", - "integrity": "sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@types/cli-progress": "^3.11.5", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.12.0", - "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-help/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-help/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-help/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-3.0.10.tgz", @@ -8541,85 +8480,6 @@ "node": ">=18.0.0" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/@oclif/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.20.0.tgz", - "integrity": "sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@types/cli-progress": "^3.11.5", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.12.0", - "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/@oclif/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -8643,36 +8503,6 @@ "fastest-levenshtein": "^1.0.7" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-not-found/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available": { "version": "3.0.12", "resolved": "https://registry.npmjs.org/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-3.0.12.tgz", @@ -8690,85 +8520,6 @@ "node": ">=18.0.0" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/@oclif/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.20.0.tgz", - "integrity": "sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@types/cli-progress": "^3.11.5", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.12.0", - "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/@oclif/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -8782,36 +8533,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/plugin-warn-if-update-available/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-help/node_modules/@oclif/prettier-config": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/@oclif/prettier-config/-/prettier-config-0.2.1.tgz", @@ -8834,85 +8555,6 @@ "node": ">=18.0.0" } }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/test/node_modules/@oclif/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.20.0.tgz", - "integrity": "sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@types/cli-progress": "^3.11.5", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.12.0", - "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/test/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/test/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@oclif/plugin-help/node_modules/@oclif/test/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-help/node_modules/@octokit/auth-token": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", @@ -10877,9 +10519,9 @@ "license": "MIT" }, "node_modules/@oclif/plugin-help/node_modules/@types/node": { - "version": "18.19.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.21.tgz", - "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==", + "version": "18.19.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.22.tgz", + "integrity": "sha512-p3pDIfuMg/aXBmhkyanPshdfJuX5c5+bQjYLIikPLXAUycEogij/c50n/C+8XOA5L93cU4ZRXtn+dNQGi0IZqQ==", "extraneous": true, "license": "MIT", "dependencies": { @@ -11805,11 +11447,14 @@ } }, "node_modules/@oclif/plugin-help/node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "extraneous": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } }, "node_modules/@oclif/plugin-help/node_modules/cacache": { "version": "15.3.0", @@ -13394,15 +13039,15 @@ } }, "node_modules/@oclif/plugin-help/node_modules/eslint-config-oclif": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-5.0.3.tgz", - "integrity": "sha512-H3pvoSCfni23l81agc7/r8jxQ7bVIKNqbLsN8eYG8w2wEpsACskplK3VEPzIrO8NSFDcxQJIxoVXxp94kXexTA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-5.1.0.tgz", + "integrity": "sha512-T4pFAFV9g1hy797f817bzkBeQB0R9j3AShrI0ohfVecHU54GrzzOTFufh0Ex8bwb89un/NlF8TE5RTiy8SKURQ==", "extraneous": true, "license": "MIT", "dependencies": { "eslint-config-xo-space": "^0.35.0", "eslint-plugin-mocha": "^10.3.0", - "eslint-plugin-node": "^11.1.0", + "eslint-plugin-n": "^15.1.0", "eslint-plugin-unicorn": "^48.0.1" }, "engines": { @@ -13735,6 +13380,125 @@ "node": ">=10" } }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz", + "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "extraneous": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "extraneous": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-n/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/@oclif/plugin-help/node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -17921,85 +17685,6 @@ "node": ">=18.0.0" } }, - "node_modules/@oclif/plugin-help/node_modules/oclif/node_modules/@oclif/core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.20.0.tgz", - "integrity": "sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@types/cli-progress": "^3.11.5", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.12.0", - "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/oclif/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@oclif/plugin-help/node_modules/oclif/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@oclif/plugin-help/node_modules/oclif/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-help/node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -20560,9 +20245,9 @@ "license": "MIT" }, "node_modules/@oclif/plugin-help/node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "extraneous": true, "license": "Apache-2.0", "bin": { @@ -20718,6 +20403,13 @@ "builtins": "^1.0.3" } }, + "node_modules/@oclif/plugin-help/node_modules/validate-npm-package-name/node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "extraneous": true, + "license": "MIT" + }, "node_modules/@oclif/plugin-help/node_modules/vinyl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", @@ -21511,13 +21203,20 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/@redocly/config": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.1.3.tgz", + "integrity": "sha512-DjgGwhyolxDLO7hP1V8h6qQUUTkqN7P/xG2OMgsABJ1Pr40GG32+cqx9oBbKX9iN+JXh6kVUZgBMcPPB1fbyLA==", + "dev": true + }, "node_modules/@redocly/openapi-core": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.10.3.tgz", - "integrity": "sha512-4SnIWh8r3EM1ylcoHIJSnQnuvqRTpQMnf2RU3BfVdcCBa0A1uEyH6XSxgcO5ehxfQGuGGpUXJ+vPh32PUaQDkA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.10.4.tgz", + "integrity": "sha512-GzvAuoVtHk75q/HqaRNqRUTZWYKpZ16HCOWIrx2txAvZrMoWCUNRVsELY91W/ilH/Cepj6t/Nh+bpJ7o/mcN/g==", "dev": true, "dependencies": { "@redocly/ajv": "^8.11.0", + "@redocly/config": "^0.1.1", "colorette": "^1.2.0", "js-levenshtein": "^1.1.6", "js-yaml": "^4.1.0", @@ -21557,9 +21256,9 @@ "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", - "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", "cpu": [ "arm" ], @@ -21570,9 +21269,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", - "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", "cpu": [ "arm64" ], @@ -21583,9 +21282,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", - "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", "cpu": [ "arm64" ], @@ -21596,9 +21295,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", - "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", "cpu": [ "x64" ], @@ -21609,9 +21308,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", - "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", "cpu": [ "arm" ], @@ -21622,9 +21321,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", - "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", "cpu": [ "arm64" ], @@ -21635,9 +21334,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", - "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", "cpu": [ "arm64" ], @@ -21648,9 +21347,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", - "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", "cpu": [ "riscv64" ], @@ -21661,9 +21360,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", - "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", "cpu": [ "x64" ], @@ -21674,9 +21373,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", - "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", "cpu": [ "x64" ], @@ -21687,9 +21386,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", - "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", "cpu": [ "arm64" ], @@ -21700,9 +21399,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", - "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", "cpu": [ "ia32" ], @@ -21713,9 +21412,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", - "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", "cpu": [ "x64" ], @@ -21726,58 +21425,58 @@ ] }, "node_modules/@sentry-internal/tracing": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.106.0.tgz", - "integrity": "sha512-O8Es6Sa/tP80nfl+8soNfWzeRNFcT484SvjLR8BS3pHM9KDAlwNXyoQhFr2BKNYL1irbq6UF6eku4xCnUKVmqA==", + "version": "7.107.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.107.0.tgz", + "integrity": "sha512-le9wM8+OHBbq7m/8P7JUJ1UhSPIty+Z/HmRXc5Z64ODZcOwFV6TmDpYx729IXDdz36XUKmeI+BeM7yQdTTZPfQ==", "dependencies": { - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" + "@sentry/core": "7.107.0", + "@sentry/types": "7.107.0", + "@sentry/utils": "7.107.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/core": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.106.0.tgz", - "integrity": "sha512-Dc13XtnyFaXup2E4vCbzuG0QKAVjrJBk4qfGwvSJaTuopEaEWBs2MpK6hRzFhsz9S3T0La7c1F/62NptvTUWsQ==", + "version": "7.107.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.107.0.tgz", + "integrity": "sha512-C7ogye6+KPyBi8NVL0P8Rxx3Ur7Td8ufnjxosVy678lqY+dcYPk/HONROrzUFYW5fMKWL4/KYnwP+x9uHnkDmw==", "dependencies": { - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" + "@sentry/types": "7.107.0", + "@sentry/utils": "7.107.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.106.0.tgz", - "integrity": "sha512-4DIqbu5K7//lK/k2nV8lqKeGQzhu2T1OpJFmiUrjN6fUKWivGFjZrcmQDS7tvhAAyJezkL3LlrNU4tjPHUElPA==", + "version": "7.107.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.107.0.tgz", + "integrity": "sha512-UZXkG7uThT2YyPW8AOSKRXp1LbVcBHufa4r1XAwBukA2FKO6HHJPjMUgY6DYVQ6k+BmA56CNfVjYrdLbyjBYYA==", "dependencies": { - "@sentry-internal/tracing": "7.106.0", - "@sentry/core": "7.106.0", - "@sentry/types": "7.106.0", - "@sentry/utils": "7.106.0" + "@sentry-internal/tracing": "7.107.0", + "@sentry/core": "7.107.0", + "@sentry/types": "7.107.0", + "@sentry/utils": "7.107.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.106.0.tgz", - "integrity": "sha512-oKTkDaL6P9xJC5/zHLRemHTWboUqRYjkJNaZCN63j4kJqGy56wee4vDtDese/NWWn4U4C1QV1h+Mifm2HmDcQg==", + "version": "7.107.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.107.0.tgz", + "integrity": "sha512-H7qcPjPSUWHE/Zf5bR1EE24G0pGVuJgrSx8Tvvl5nKEepswMYlbXHRVSDN0gTk/E5Z7cqf+hUBOpkQgZyps77w==", "engines": { "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "7.106.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.106.0.tgz", - "integrity": "sha512-bVsePsXLpFu/1sH4rpJrPcnVxW2fXXfGfGxKs6Bm+dkOMbuVTlk/KAzIbdjCDIpVlrMDJmMNEv5xgTFjgWDkjw==", + "version": "7.107.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.107.0.tgz", + "integrity": "sha512-C6PbN5gHh73MRHohnReeQ60N8rrLYa9LciHue3Ru2290eSThg4CzsPnx4SzkGpkSeVlhhptKtKZ+hp/ha3iVuw==", "dependencies": { - "@sentry/types": "7.106.0" + "@sentry/types": "7.107.0" }, "engines": { "node": ">=8" @@ -21871,216 +21570,216 @@ "dev": true }, "node_modules/@smithy/abort-controller": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.1.4.tgz", - "integrity": "sha512-66HO817oIZ2otLIqy06R5muapqZjkgF1jfU0wyNko8cuqZNu8nbS9ljlhcRYw/M/uWRJzB9ih81DLSHhYbBLlQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.2.0.tgz", + "integrity": "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/config-resolver": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.1.5.tgz", - "integrity": "sha512-LcBB5JQC3Tx2ZExIJzfvWaajhFIwHrUNQeqxhred2r5nnqrdly9uoCrvM1sxOOdghYuWWm2Kr8tBCDOmxsgeTA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.2.0.tgz", + "integrity": "sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA==", "dependencies": { - "@smithy/node-config-provider": "^2.2.5", - "@smithy/types": "^2.11.0", - "@smithy/util-config-provider": "^2.2.1", - "@smithy/util-middleware": "^2.1.4", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^2.3.0", + "@smithy/types": "^2.12.0", + "@smithy/util-config-provider": "^2.3.0", + "@smithy/util-middleware": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/core": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.7.tgz", - "integrity": "sha512-zHrrstOO78g+/rOJoHi4j3mGUBtsljRhcKNzloWPv1XIwgcFUi+F1YFKr2qPQ3z7Ls5dNc4L2SPrVarNFIQqog==", - "dependencies": { - "@smithy/middleware-endpoint": "^2.4.6", - "@smithy/middleware-retry": "^2.1.6", - "@smithy/middleware-serde": "^2.2.1", - "@smithy/protocol-http": "^3.2.2", - "@smithy/smithy-client": "^2.4.4", - "@smithy/types": "^2.11.0", - "@smithy/util-middleware": "^2.1.4", - "tslib": "^2.5.0" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.4.0.tgz", + "integrity": "sha512-uu9ZDI95Uij4qk+L6kyFjdk11zqBkcJ3Lv0sc6jZrqHvLyr0+oeekD3CnqMafBn/5PRI6uv6ulW3kNLRBUHeVw==", + "dependencies": { + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-retry": "^2.2.0", + "@smithy/middleware-serde": "^2.3.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/util-middleware": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.6.tgz", - "integrity": "sha512-+xQe4Pite0kdk9qn0Vyw5BRVh0iSlj+T4TEKRXr4E1wZKtVgIzGlkCrfICSjiPVFkPxk4jMpVboMYdEiiA88/w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.3.0.tgz", + "integrity": "sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w==", "dependencies": { - "@smithy/node-config-provider": "^2.2.5", - "@smithy/property-provider": "^2.1.4", - "@smithy/types": "^2.11.0", - "@smithy/url-parser": "^2.1.4", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^2.3.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.1.4.tgz", - "integrity": "sha512-UkiieTztP7adg8EuqZvB0Y4LewdleZCJU7Kgt9RDutMsRYqO32fMpWeQHeTHaIMosmzcRZUykMRrhwGJe9mP3A==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz", + "integrity": "sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==", "dependencies": { "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.11.0", - "@smithy/util-hex-encoding": "^2.1.1", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "@smithy/util-hex-encoding": "^2.2.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.1.4.tgz", - "integrity": "sha512-K0SyvrUu/vARKzNW+Wp9HImiC/cJ6K88/n7FTH1slY+MErdKoiSbRLaXbJ9qD6x1Hu28cplHMlhADwZelUx/Ww==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.2.0.tgz", + "integrity": "sha512-UaPf8jKbcP71BGiO0CdeLmlg+RhWnlN8ipsMSdwvqBFigl5nil3rHOI/5GE3tfiuX8LvY5Z9N0meuU7Rab7jWw==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.1.4.tgz", - "integrity": "sha512-FH+2AwOwZ0kHPB9sciWJtUqx81V4vizfT3P6T9eslmIC2hi8ch/KFvQlF7jDmwR1aLlPlq6qqLKLqzK/71Ki4A==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.2.0.tgz", + "integrity": "sha512-RHhbTw/JW3+r8QQH7PrganjNCiuiEZmpi6fYUAetFfPLfZ6EkiA08uN3EFfcyKubXQxOwTeJRZSQmDDCdUshaA==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.1.4.tgz", - "integrity": "sha512-gsc5ZTvVcB9sleLQzsK/rOhgn52+AAsmhEr41WDwAcctccBjh429+b8gT9t+SU8QyajypfsLOZfJQu0+zE515Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.2.0.tgz", + "integrity": "sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.1.4.tgz", - "integrity": "sha512-NKLAsYnZA5s+ntipJRKo1RrRbhYHrsEnmiUoz0EhVYrAih+UELY9sKR+A1ujGaFm3nKDs5fPfiozC2wpXq2zUA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.2.0.tgz", + "integrity": "sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==", "dependencies": { - "@smithy/eventstream-codec": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/eventstream-codec": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.4.4.tgz", - "integrity": "sha512-DSUtmsnIx26tPuyyrK49dk2DAhPgEw6xRW7V62nMHIB5dk3NqhGnwcKO2fMdt/l3NUVgia34ZsSJA8bD+3nh7g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz", + "integrity": "sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==", "dependencies": { - "@smithy/protocol-http": "^3.2.2", - "@smithy/querystring-builder": "^2.1.4", - "@smithy/types": "^2.11.0", - "@smithy/util-base64": "^2.2.0", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^3.3.0", + "@smithy/querystring-builder": "^2.2.0", + "@smithy/types": "^2.12.0", + "@smithy/util-base64": "^2.3.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/hash-node": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.1.4.tgz", - "integrity": "sha512-uvCcpDLXaTTL0X/9ezF8T8sS77UglTfZVQaUOBiCvR0QydeSyio3t0Hj3QooVdyFsKTubR8gCk/ubLk3vAyDng==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.2.0.tgz", + "integrity": "sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g==", "dependencies": { - "@smithy/types": "^2.11.0", - "@smithy/util-buffer-from": "^2.1.1", - "@smithy/util-utf8": "^2.2.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "@smithy/util-buffer-from": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.1.4.tgz", - "integrity": "sha512-QzlNBl6jt3nb9jNnE51wTegReVvUdozyMMrFEyb/rc6AzPID1O+qMJYjAAoNw098y0CZVfCpEnoK2+mfBOd8XA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.2.0.tgz", + "integrity": "sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/is-array-buffer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.1.1.tgz", - "integrity": "sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.1.4.tgz", - "integrity": "sha512-C6VRwfcr0w9qRFhDGCpWMVhlEIBFlmlPRP1aX9Cv9xDj9SUwlDrNvoV1oP1vjRYuLxCDgovBBynCwwcluS2wLw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.2.0.tgz", + "integrity": "sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ==", "dependencies": { - "@smithy/protocol-http": "^3.2.2", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.6.tgz", - "integrity": "sha512-AsXtUXHPOAS0EGZUSFOsVJvc7p0KL29PGkLxLfycPOcFVLru/oinYB6yvyL73ZZPX2OB8sMYUMrj7eH2kI7V/w==", - "dependencies": { - "@smithy/middleware-serde": "^2.2.1", - "@smithy/node-config-provider": "^2.2.5", - "@smithy/shared-ini-file-loader": "^2.3.5", - "@smithy/types": "^2.11.0", - "@smithy/url-parser": "^2.1.4", - "@smithy/util-middleware": "^2.1.4", - "tslib": "^2.5.0" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.0.tgz", + "integrity": "sha512-OBhI9ZEAG8Xen0xsFJwwNOt44WE2CWkfYIxTognC8x42Lfsdf0VN/wCMqpdkySMDio/vts10BiovAxQp0T0faA==", + "dependencies": { + "@smithy/middleware-serde": "^2.3.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-middleware": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/middleware-retry": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.1.6.tgz", - "integrity": "sha512-khpSV0NxqMHfa06kfG4WYv+978sVvfTFmn0hIFKKwOXtIxyYtPKiQWFT4nnwZD07fGdYGbtCBu3YALc8SsA5mA==", - "dependencies": { - "@smithy/node-config-provider": "^2.2.5", - "@smithy/protocol-http": "^3.2.2", - "@smithy/service-error-classification": "^2.1.4", - "@smithy/smithy-client": "^2.4.4", - "@smithy/types": "^2.11.0", - "@smithy/util-middleware": "^2.1.4", - "@smithy/util-retry": "^2.1.4", - "tslib": "^2.5.0", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.2.0.tgz", + "integrity": "sha512-PsjDOLpbevgn37yJbawmfVoanru40qVA8UEf2+YA1lvOefmhuhL6ZbKtGsLAWDRnE1OlAmedsbA/htH6iSZjNA==", + "dependencies": { + "@smithy/node-config-provider": "^2.3.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/service-error-classification": "^2.1.5", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-retry": "^2.2.0", + "tslib": "^2.6.2", "uuid": "^8.3.2" }, "engines": { @@ -22096,370 +21795,370 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.2.1.tgz", - "integrity": "sha512-VAWRWqnNjgccebndpyK94om4ZTYzXLQxUmNCXYzM/3O9MTfQjTNBgtFtQwyIIez6z7LWcCsXmnKVIOE9mLqAHQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz", + "integrity": "sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/middleware-stack": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.1.4.tgz", - "integrity": "sha512-Qqs2ba8Ax1rGKOSGJS2JN23fhhox2WMdRuzx0NYHtXzhxbJOIMmz9uQY6Hf4PY8FPteBPp1+h0j5Fmr+oW12sg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz", + "integrity": "sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/node-config-provider": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.2.5.tgz", - "integrity": "sha512-CxPf2CXhjO79IypHJLBATB66Dw6suvr1Yc2ccY39hpR6wdse3pZ3E8RF83SODiNH0Wjmkd0ze4OF8exugEixgA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz", + "integrity": "sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==", "dependencies": { - "@smithy/property-provider": "^2.1.4", - "@smithy/shared-ini-file-loader": "^2.3.5", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/node-http-handler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.4.2.tgz", - "integrity": "sha512-yrj3c1g145uiK5io+1UPbJAHo8BSGORkBzrmzvAsOmBKb+1p3jmM8ZwNLDH/HTTxVLm9iM5rMszx+iAh1HUC4Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz", + "integrity": "sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==", "dependencies": { - "@smithy/abort-controller": "^2.1.4", - "@smithy/protocol-http": "^3.2.2", - "@smithy/querystring-builder": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^2.2.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/querystring-builder": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/property-provider": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.1.4.tgz", - "integrity": "sha512-nWaY/MImj1BiXZ9WY65h45dcxOx8pl06KYoHxwojDxDL+Q9yLU1YnZpgv8zsHhEftlj9KhePENjQTlNowWVyug==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz", + "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/protocol-http": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.2.2.tgz", - "integrity": "sha512-xYBlllOQcOuLoxzhF2u8kRHhIFGQpDeTQj/dBSnw4kfI29WMKL5RnW1m9YjnJAJ49miuIvrkJR+gW5bCQ+Mchw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.3.0.tgz", + "integrity": "sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/querystring-builder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.1.4.tgz", - "integrity": "sha512-LXSL0J/nRWvGT+jIj+Fip3j0J1ZmHkUyBFRzg/4SmPNCLeDrtVu7ptKOnTboPsFZu5BxmpYok3kJuQzzRdrhbw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz", + "integrity": "sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==", "dependencies": { - "@smithy/types": "^2.11.0", - "@smithy/util-uri-escape": "^2.1.1", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "@smithy/util-uri-escape": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/querystring-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.1.4.tgz", - "integrity": "sha512-U2b8olKXgZAs0eRo7Op11jTNmmcC/sqYmsA7vN6A+jkGnDvJlEl7AetUegbBzU8q3D6WzC5rhR/joIy8tXPzIg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.2.0.tgz", + "integrity": "sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/service-error-classification": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.4.tgz", - "integrity": "sha512-JW2Hthy21evnvDmYYk1kItOmbp3X5XI5iqorXgFEunb6hQfSDZ7O1g0Clyxg7k/Pcr9pfLk5xDIR2To/IohlsQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz", + "integrity": "sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==", "dependencies": { - "@smithy/types": "^2.11.0" + "@smithy/types": "^2.12.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.5.tgz", - "integrity": "sha512-oI99+hOvsM8oAJtxAGmoL/YCcGXtbP0fjPseYGaNmJ4X5xOFTer0KPk7AIH3AL6c5AlYErivEi1X/X78HgTVIw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz", + "integrity": "sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/signature-v4": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.1.4.tgz", - "integrity": "sha512-gnu9gCn0qQ8IdhNjs6o3QVCXzUs33znSDYwVMWo3nX4dM6j7z9u6FC302ShYyVWfO4MkVMuGCCJ6nl3PcH7V1Q==", - "dependencies": { - "@smithy/eventstream-codec": "^2.1.4", - "@smithy/is-array-buffer": "^2.1.1", - "@smithy/types": "^2.11.0", - "@smithy/util-hex-encoding": "^2.1.1", - "@smithy/util-middleware": "^2.1.4", - "@smithy/util-uri-escape": "^2.1.1", - "@smithy/util-utf8": "^2.2.0", - "tslib": "^2.5.0" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.2.0.tgz", + "integrity": "sha512-+B5TNzj/fRZzVW3z8UUJOkNx15+4E0CLuvJmJUA1JUIZFp3rdJ/M2H5r2SqltaVPXL0oIxv/6YK92T9TsFGbFg==", + "dependencies": { + "@smithy/eventstream-codec": "^2.2.0", + "@smithy/is-array-buffer": "^2.2.0", + "@smithy/types": "^2.12.0", + "@smithy/util-hex-encoding": "^2.2.0", + "@smithy/util-middleware": "^2.2.0", + "@smithy/util-uri-escape": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/smithy-client": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.4.4.tgz", - "integrity": "sha512-SNE17wjycPZIJ2P5sv6wMTteV/vQVPdaqQkoK1KeGoWHXx79t3iLhQXj1uqRdlkMUS9pXJrLOAS+VvUSOYwQKw==", - "dependencies": { - "@smithy/middleware-endpoint": "^2.4.6", - "@smithy/middleware-stack": "^2.1.4", - "@smithy/protocol-http": "^3.2.2", - "@smithy/types": "^2.11.0", - "@smithy/util-stream": "^2.1.4", - "tslib": "^2.5.0" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.5.0.tgz", + "integrity": "sha512-DDXWHWdimtS3y/Kw1Jo46KQ0ZYsDKcldFynQERUGBPDpkW1lXOTHy491ALHjwfiBQvzsVKVxl5+ocXNIgJuX4g==", + "dependencies": { + "@smithy/middleware-endpoint": "^2.5.0", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "@smithy/util-stream": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/types": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.11.0.tgz", - "integrity": "sha512-AR0SXO7FuAskfNhyGfSTThpLRntDI5bOrU0xrpVYU0rZyjl3LBXInZFMTP/NNSd7IS6Ksdtar0QvnrPRIhVrLQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", + "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/url-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.1.4.tgz", - "integrity": "sha512-1hTy6UYRYqOZlHKH2/2NzdNQ4NNmW2Lp0sYYvztKy+dEQuLvZL9w88zCzFQqqFer3DMcscYOshImxkJTGdV+rg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.2.0.tgz", + "integrity": "sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==", "dependencies": { - "@smithy/querystring-parser": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/querystring-parser": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/util-base64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.2.0.tgz", - "integrity": "sha512-RiQI/Txu0SxCR38Ky5BMEVaFfkNTBjpbxlr2UhhxggSmnsHDQPZJWMtPoXs7TWZaseslIlAWMiHmqRT3AV/P2w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.3.0.tgz", + "integrity": "sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==", "dependencies": { - "@smithy/util-buffer-from": "^2.1.1", - "@smithy/util-utf8": "^2.2.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-body-length-browser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.1.1.tgz", - "integrity": "sha512-ekOGBLvs1VS2d1zM2ER4JEeBWAvIOUKeaFch29UjjJsxmZ/f0L3K3x0dEETgh3Q9bkZNHgT+rkdl/J/VUqSRag==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.2.0.tgz", + "integrity": "sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@smithy/util-body-length-node": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.2.1.tgz", - "integrity": "sha512-/ggJG+ta3IDtpNVq4ktmEUtOkH1LW64RHB5B0hcr5ZaWBmo96UX2cIOVbjCqqDickTXqBWZ4ZO0APuaPrD7Abg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.3.0.tgz", + "integrity": "sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-buffer-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.1.1.tgz", - "integrity": "sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", "dependencies": { - "@smithy/is-array-buffer": "^2.1.1", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-config-provider": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.2.1.tgz", - "integrity": "sha512-50VL/tx9oYYcjJn/qKqNy7sCtpD0+s8XEBamIFo4mFFTclKMNp+rsnymD796uybjiIquB7VCB/DeafduL0y2kw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.3.0.tgz", + "integrity": "sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.6.tgz", - "integrity": "sha512-lM2JMYCilrejfGf8WWnVfrKly3vf+mc5x9TrTpT++qIKP452uWfLqlaUxbz1TkSfhqm8RjrlY22589B9aI8A9w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.2.0.tgz", + "integrity": "sha512-2okTdZaCBvOJszAPU/KSvlimMe35zLOKbQpHhamFJmR7t95HSe0K3C92jQPjKY3PmDBD+7iMkOnuW05F5OlF4g==", "dependencies": { - "@smithy/property-provider": "^2.1.4", - "@smithy/smithy-client": "^2.4.4", - "@smithy/types": "^2.11.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.6.tgz", - "integrity": "sha512-UmUbPHbkBJCXRFbq+FPLpVwiFPHj1oPWXJS2f2sy23PtXM94c9X5EceI6JKuKdBty+tzhrAs5JbmPM/HvmDB8Q==", - "dependencies": { - "@smithy/config-resolver": "^2.1.5", - "@smithy/credential-provider-imds": "^2.2.6", - "@smithy/node-config-provider": "^2.2.5", - "@smithy/property-provider": "^2.1.4", - "@smithy/smithy-client": "^2.4.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.3.0.tgz", + "integrity": "sha512-hfKXnNLmsW9cmLb/JXKIvtuO6Cf4SuqN5PN1C2Ru/TBIws+m1wSgb+A53vo0r66xzB6E82inKG2J7qtwdi+Kkw==", + "dependencies": { + "@smithy/config-resolver": "^2.2.0", + "@smithy/credential-provider-imds": "^2.3.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/property-provider": "^2.2.0", + "@smithy/smithy-client": "^2.5.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@smithy/util-endpoints": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.1.5.tgz", - "integrity": "sha512-tgDpaUNsUtRvNiBulKU1VnpoXU1GINMfZZXunRhUXOTBEAufG1Wp79uDXLau2gg1RZ4dpAR6lXCkrmddihCGUg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.2.0.tgz", + "integrity": "sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ==", "dependencies": { - "@smithy/node-config-provider": "^2.2.5", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^2.3.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@smithy/util-hex-encoding": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.1.1.tgz", - "integrity": "sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", + "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-middleware": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.1.4.tgz", - "integrity": "sha512-5yYNOgCN0DL0OplME0pthoUR/sCfipnROkbTO7m872o0GHCVNJj5xOFJ143rvHNA54+pIPMLum4z2DhPC2pVGA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz", + "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==", "dependencies": { - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-retry": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.1.4.tgz", - "integrity": "sha512-JRZwhA3fhkdenSEYIWatC8oLwt4Bdf2LhHbNQApqb7yFoIGMl4twcYI3BcJZ7YIBZrACA9jGveW6tuCd836XzQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.2.0.tgz", + "integrity": "sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==", "dependencies": { - "@smithy/service-error-classification": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/service-error-classification": "^2.1.5", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@smithy/util-stream": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.1.4.tgz", - "integrity": "sha512-CiWaFPXstoR7v/PGHddFckovkhJb28wgQR7LwIt6RsQCJeRIHvUTVWhXw/Pco6Jm6nz/vfzN9FFdj/JN7RTkxQ==", - "dependencies": { - "@smithy/fetch-http-handler": "^2.4.4", - "@smithy/node-http-handler": "^2.4.2", - "@smithy/types": "^2.11.0", - "@smithy/util-base64": "^2.2.0", - "@smithy/util-buffer-from": "^2.1.1", - "@smithy/util-hex-encoding": "^2.1.1", - "@smithy/util-utf8": "^2.2.0", - "tslib": "^2.5.0" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.2.0.tgz", + "integrity": "sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==", + "dependencies": { + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-buffer-from": "^2.2.0", + "@smithy/util-hex-encoding": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-uri-escape": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.1.1.tgz", - "integrity": "sha512-saVzI1h6iRBUVSqtnlOnc9ssU09ypo7n+shdQ8hBTZno/9rZ3AuRYvoHInV57VF7Qn7B+pFJG7qTzFiHxWlWBw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz", + "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-utf8": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.2.0.tgz", - "integrity": "sha512-hBsKr5BqrDrKS8qy+YcV7/htmMGxriA1PREOf/8AGBhHIZnfilVv1Waf1OyKhSbFW15U/8+gcMUQ9/Kk5qwpHQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", "dependencies": { - "@smithy/util-buffer-from": "^2.1.1", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/util-waiter": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.1.4.tgz", - "integrity": "sha512-AK17WaC0hx1wR9juAOsQkJ6DjDxBGEf5TrKhpXtNFEn+cVto9Li3MVsdpAO97AF7bhFXSyC8tJA3F4ThhqwCdg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.2.0.tgz", + "integrity": "sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==", "dependencies": { - "@smithy/abort-controller": "^2.1.4", - "@smithy/types": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" @@ -22527,9 +22226,9 @@ } }, "node_modules/@swc/core": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.6.tgz", - "integrity": "sha512-A7iK9+1qzTCIuc3IYcS8gPHCm9bZVKUJrfNnwveZYyo6OFp3jLno4WOM2yBy5uqedgYATEiWgBYHKq37KrU6IA==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.8.tgz", + "integrity": "sha512-uY2RSJcFPgNOEg12RQZL197LZX+MunGiKxsbxmh22VfVxrOYGRvh4mPANFlrD1yb38CgmW1wI6YgIi8LkIwmWg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -22544,16 +22243,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.4.6", - "@swc/core-darwin-x64": "1.4.6", - "@swc/core-linux-arm-gnueabihf": "1.4.6", - "@swc/core-linux-arm64-gnu": "1.4.6", - "@swc/core-linux-arm64-musl": "1.4.6", - "@swc/core-linux-x64-gnu": "1.4.6", - "@swc/core-linux-x64-musl": "1.4.6", - "@swc/core-win32-arm64-msvc": "1.4.6", - "@swc/core-win32-ia32-msvc": "1.4.6", - "@swc/core-win32-x64-msvc": "1.4.6" + "@swc/core-darwin-arm64": "1.4.8", + "@swc/core-darwin-x64": "1.4.8", + "@swc/core-linux-arm-gnueabihf": "1.4.8", + "@swc/core-linux-arm64-gnu": "1.4.8", + "@swc/core-linux-arm64-musl": "1.4.8", + "@swc/core-linux-x64-gnu": "1.4.8", + "@swc/core-linux-x64-musl": "1.4.8", + "@swc/core-win32-arm64-msvc": "1.4.8", + "@swc/core-win32-ia32-msvc": "1.4.8", + "@swc/core-win32-x64-msvc": "1.4.8" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -22565,9 +22264,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.6.tgz", - "integrity": "sha512-bpggpx/BfLFyy48aUKq1PsNUxb7J6CINlpAUk0V4yXfmGnpZH80Gp1pM3GkFDQyCfq7L7IpjPrIjWQwCrL4hYw==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.8.tgz", + "integrity": "sha512-hhQCffRTgzpTIbngSnC30vV6IJVTI9FFBF954WEsshsecVoCGFiMwazBbrkLG+RwXENTrMhgeREEFh6R3KRgKQ==", "cpu": [ "arm64" ], @@ -22581,9 +22280,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.6.tgz", - "integrity": "sha512-vJn+/ZuBTg+vtNkcmgZdH6FQpa0hFVdnB9bAeqYwKkyqP15zaPe6jfC+qL2y/cIeC7ASvHXEKrnCZgBLxfVQ9w==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.8.tgz", + "integrity": "sha512-P3ZBw8Jr8rKhY/J8d+6WqWriqngGTgHwtFeJ8MIakQJTbdYbFgXSZxcvDiERg3psbGeFXaUaPI0GO6BXv9k/OQ==", "cpu": [ "x64" ], @@ -22597,9 +22296,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.6.tgz", - "integrity": "sha512-hEmYcB/9XBAl02MtuVHszhNjQpjBzhk/NFulnU33tBMbNZpy2TN5yTsitezMq090QXdDz8sKIALApDyg07ZR8g==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.8.tgz", + "integrity": "sha512-PP9JIJt19bUWhAGcQW6qMwTjZOcMyzkvZa0/LWSlDm0ORYVLmDXUoeQbGD3e0Zju9UiZxyulnpjEN0ZihJgPTA==", "cpu": [ "arm" ], @@ -22613,9 +22312,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.6.tgz", - "integrity": "sha512-/UCYIVoGpm2YVvGHZM2QOA3dexa28BjcpLAIYnoCbgH5f7ulDhE8FAIO/9pasj+kixDBsdqewHfsNXFYlgGJjQ==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.8.tgz", + "integrity": "sha512-HvEWnwKHkoVUr5iftWirTApFJ13hGzhAY2CMw4lz9lur2m+zhPviRRED0FCI6T95Knpv7+8eUOr98Z7ctrG6DQ==", "cpu": [ "arm64" ], @@ -22629,9 +22328,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.6.tgz", - "integrity": "sha512-LGQsKJ8MA9zZ8xHCkbGkcPSmpkZL2O7drvwsGKynyCttHhpwVjj9lguhD4DWU3+FWIsjvho5Vu0Ggei8OYi/Lw==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.8.tgz", + "integrity": "sha512-kY8+qa7k/dEeBq9p0Hrta18QnJPpsiJvDQSLNaTIFpdM3aEM9zbkshWz8gaX5VVGUEALowCBUWqmzO4VaqM+2w==", "cpu": [ "arm64" ], @@ -22645,9 +22344,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.6.tgz", - "integrity": "sha512-10JL2nLIreMQDKvq2TECnQe5fCuoqBHu1yW8aChqgHUyg9d7gfZX/kppUsuimqcgRBnS0AjTDAA+JF6UsG/2Yg==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.8.tgz", + "integrity": "sha512-0WWyIw432wpO/zeGblwq4f2YWam4pn8Z/Ig4KzHMgthR/KmiLU3f0Z7eo45eVmq5vcU7Os1zi/Zb65OOt09q/w==", "cpu": [ "x64" ], @@ -22661,9 +22360,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.6.tgz", - "integrity": "sha512-EGyjFVzVY6Do89x8sfah7I3cuP4MwtwzmA6OlfD/KASqfCFf5eIaEBMbajgR41bVfMV7lK72lwAIea5xEyq1AQ==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.8.tgz", + "integrity": "sha512-p4yxvVS05rBNCrBaSTa20KK88vOwtg8ifTW7ec/yoab0bD5EwzzB8KbDmLLxE6uziFa0sdjF0dfRDwSZPex37Q==", "cpu": [ "x64" ], @@ -22677,9 +22376,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.6.tgz", - "integrity": "sha512-gfW9AuXvwSyK07Vb8Y8E9m2oJZk21WqcD+X4BZhkbKB0TCZK0zk1j/HpS2UFlr1JB2zPKPpSWLU3ll0GEHRG2A==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.8.tgz", + "integrity": "sha512-jKuXihxAaqUnbFfvPxtmxjdJfs87F1GdBf33il+VUmSyWCP4BE6vW+/ReDAe8sRNsKyrZ3UH1vI5q1n64csBUA==", "cpu": [ "arm64" ], @@ -22693,9 +22392,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.6.tgz", - "integrity": "sha512-ZuQm81FhhvNVYtVb9GfZ+Du6e7fZlkisWvuCeBeRiyseNt1tcrQ8J3V67jD2nxje8CVXrwG3oUIbPcybv2rxfQ==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.8.tgz", + "integrity": "sha512-O0wT4AGHrX8aBeH6c2ADMHgagAJc5Kf6W48U5moyYDAkkVnKvtSc4kGhjWhe1Yl0sI0cpYh2In2FxvYsb44eWw==", "cpu": [ "ia32" ], @@ -22709,9 +22408,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.6.tgz", - "integrity": "sha512-UagPb7w5V0uzWSjrXwOavGa7s9iv3wrVdEgWy+/inm0OwY4lj3zpK9qDnMWAwYLuFwkI3UG4Q3dH8wD+CUUcjw==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.8.tgz", + "integrity": "sha512-C2AYc3A2o+ECciqsJWRgIpp83Vk5EaRzHe7ed/xOWzVd0MsWR+fweEsyOjlmzHfpUxJSi46Ak3/BIZJlhZbXbg==", "cpu": [ "x64" ], @@ -22928,9 +22627,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.14.202", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", "dev": true }, "node_modules/@types/lodash.merge": { @@ -22959,9 +22658,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "20.11.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", + "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", "dependencies": { "undici-types": "~5.26.4" } @@ -23071,16 +22770,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz", - "integrity": "sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", + "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.1.1", - "@typescript-eslint/type-utils": "7.1.1", - "@typescript-eslint/utils": "7.1.1", - "@typescript-eslint/visitor-keys": "7.1.1", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/type-utils": "7.2.0", + "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -23133,15 +22832,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.1.tgz", - "integrity": "sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", + "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.1.1", - "@typescript-eslint/types": "7.1.1", - "@typescript-eslint/typescript-estree": "7.1.1", - "@typescript-eslint/visitor-keys": "7.1.1", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4" }, "engines": { @@ -23161,13 +22860,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz", - "integrity": "sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.1", - "@typescript-eslint/visitor-keys": "7.1.1" + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -23178,13 +22877,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz", - "integrity": "sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", + "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.1.1", - "@typescript-eslint/utils": "7.1.1", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/utils": "7.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -23205,9 +22904,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.1.tgz", - "integrity": "sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -23218,13 +22917,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz", - "integrity": "sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.1", - "@typescript-eslint/visitor-keys": "7.1.1", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -23273,17 +22972,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.1.tgz", - "integrity": "sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.1.1", - "@typescript-eslint/types": "7.1.1", - "@typescript-eslint/typescript-estree": "7.1.1", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", "semver": "^7.5.4" }, "engines": { @@ -23325,12 +23024,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz", - "integrity": "sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/types": "7.2.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -23348,9 +23047,9 @@ "dev": true }, "node_modules/@vitest/coverage-v8": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.3.1.tgz", - "integrity": "sha512-UuBnkSJUNE9rdHjDCPyJ4fYuMkoMtnghes1XohYa4At0MS3OQSAo97FrbwSLRshYsXThMZy1+ybD/byK5llyIg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.4.0.tgz", + "integrity": "sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -23358,12 +23057,13 @@ "debug": "^4.3.4", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^4.0.1", + "istanbul-lib-source-maps": "^5.0.4", "istanbul-reports": "^3.1.6", "magic-string": "^0.30.5", "magicast": "^0.3.3", "picocolors": "^1.0.0", "std-env": "^3.5.0", + "strip-literal": "^2.0.0", "test-exclude": "^6.0.0", "v8-to-istanbul": "^9.2.0" }, @@ -23371,17 +23071,17 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "1.3.1" + "vitest": "1.4.0" } }, "node_modules/@vitest/expect": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", - "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", + "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", "dev": true, "dependencies": { - "@vitest/spy": "1.3.1", - "@vitest/utils": "1.3.1", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", "chai": "^4.3.10" }, "funding": { @@ -23389,12 +23089,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.1.tgz", - "integrity": "sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", + "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", "dev": true, "dependencies": { - "@vitest/utils": "1.3.1", + "@vitest/utils": "1.4.0", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -23430,9 +23130,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.1.tgz", - "integrity": "sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", + "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -23444,9 +23144,9 @@ } }, "node_modules/@vitest/spy": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", - "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", + "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", "dev": true, "dependencies": { "tinyspy": "^2.2.0" @@ -23456,9 +23156,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", - "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", "dev": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -23553,7 +23253,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, "dependencies": { "debug": "^4.3.4" }, @@ -24028,7 +23727,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -24057,6 +23755,14 @@ "node": ">= 10.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/bin-check": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", @@ -24190,12 +23896,15 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/binary-install": { @@ -24515,9 +24224,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001596", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", - "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", + "version": "1.0.30001597", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", + "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", "dev": true, "funding": [ { @@ -25383,9 +25092,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.699", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz", - "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==", + "version": "1.4.708", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.708.tgz", + "integrity": "sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==", "dev": true }, "node_modules/emoji-regex": { @@ -25411,9 +25120,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", - "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -25919,9 +25628,9 @@ } }, "node_modules/eslint-plugin-vitest": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.24.tgz", - "integrity": "sha512-MjxQCfOzLVJwi5EBHZYtv6zKHVUMRDh269D3KHCxHW0skoJhNDgE5MKvuxQ0Rh6B1aa6KuGUcvffRCdtN4Bg7A==", + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.26.tgz", + "integrity": "sha512-oxe5JSPgRjco8caVLTh7Ti8PxpwJdhSV0hTQAmkFcNcmy/9DnqLB/oNVRA11RmVRP//2+jIIT6JuBEcpW3obYg==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^7.1.1" @@ -26327,6 +26036,11 @@ "node": ">=4" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -26686,9 +26400,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -26867,6 +26581,43 @@ "node": ">=10" } }, + "node_modules/gaxios": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.3.0.tgz", + "integrity": "sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -27060,6 +26811,22 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "node_modules/google-auth-library": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", + "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -27211,6 +26978,18 @@ "graphql": ">=0.11 <=16" } }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -27283,9 +27062,9 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -27419,7 +27198,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "dev": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -28141,28 +27919,19 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz", + "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "istanbul-lib-coverage": "^3.0.0" }, "engines": { "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", @@ -28295,6 +28064,14 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -28425,6 +28202,25 @@ "npm": ">=6" } }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/jsonwebtoken/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -28457,9 +28253,9 @@ "dev": true }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -28467,11 +28263,11 @@ } }, "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -33633,9 +33429,9 @@ } }, "node_modules/rollup": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", - "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -33648,19 +33444,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.12.1", - "@rollup/rollup-android-arm64": "4.12.1", - "@rollup/rollup-darwin-arm64": "4.12.1", - "@rollup/rollup-darwin-x64": "4.12.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", - "@rollup/rollup-linux-arm64-gnu": "4.12.1", - "@rollup/rollup-linux-arm64-musl": "4.12.1", - "@rollup/rollup-linux-riscv64-gnu": "4.12.1", - "@rollup/rollup-linux-x64-gnu": "4.12.1", - "@rollup/rollup-linux-x64-musl": "4.12.1", - "@rollup/rollup-win32-arm64-msvc": "4.12.1", - "@rollup/rollup-win32-ia32-msvc": "4.12.1", - "@rollup/rollup-win32-x64-msvc": "4.12.1", + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", "fsevents": "~2.3.2" } }, @@ -33706,13 +33502,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -33904,16 +33700,16 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -35083,13 +34879,13 @@ } }, "node_modules/typescript-eslint": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.1.1.tgz", - "integrity": "sha512-vScnjSkm0pjZqySB5o8ZbfywfGWamVOqIGtJeOnUuDDGFaGKwMqdZWVa7EYKBnLCUSuwD8MN2a2ur9OgaKu6Tg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.2.0.tgz", + "integrity": "sha512-VqXEBqzPxJlR8Lfg2Dywe4XpIk637kwp2sfMQ+vudNHo48TUvnlHzAyFMQknv0AdhvZFXQN0a0t9SPI3rsAYew==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.1.1", - "@typescript-eslint/parser": "7.1.1" + "@typescript-eslint/eslint-plugin": "7.2.0", + "@typescript-eslint/parser": "7.2.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -35131,9 +34927,9 @@ } }, "node_modules/ufo": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", - "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.1.tgz", + "integrity": "sha512-HGyF79+/qZ4soRvM+nHERR2pJ3VXDZ/8sL1uLahdgEDf580NkgiWOxLk33FetExqOWp352JZRsgXbG/4MaGOSg==", "dev": true }, "node_modules/unbox-primitive": { @@ -35370,9 +35166,9 @@ } }, "node_modules/vite": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz", - "integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", + "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", "dev": true, "dependencies": { "esbuild": "^0.19.3", @@ -35425,9 +35221,9 @@ } }, "node_modules/vite-node": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.1.tgz", - "integrity": "sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", + "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -35447,14 +35243,14 @@ } }, "node_modules/vite-tsconfig-paths": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.1.tgz", - "integrity": "sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", "dev": true, "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", - "tsconfck": "^3.0.1" + "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" @@ -35466,16 +35262,16 @@ } }, "node_modules/vitest": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.1.tgz", - "integrity": "sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", + "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", "dev": true, "dependencies": { - "@vitest/expect": "1.3.1", - "@vitest/runner": "1.3.1", - "@vitest/snapshot": "1.3.1", - "@vitest/spy": "1.3.1", - "@vitest/utils": "1.3.1", + "@vitest/expect": "1.4.0", + "@vitest/runner": "1.4.0", + "@vitest/snapshot": "1.4.0", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", @@ -35489,7 +35285,7 @@ "tinybench": "^2.5.1", "tinypool": "^0.8.2", "vite": "^5.0.0", - "vite-node": "1.3.1", + "vite-node": "1.4.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -35504,8 +35300,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.3.1", - "@vitest/ui": "1.3.1", + "@vitest/browser": "1.4.0", + "@vitest/ui": "1.4.0", "happy-dom": "*", "jsdom": "*" }, @@ -35770,16 +35566,16 @@ "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -35930,9 +35726,9 @@ } }, "node_modules/yarn": { - "version": "1.22.21", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.21.tgz", - "integrity": "sha512-ynXaJsADJ9JiZ84zU25XkPGOvVMmZ5b7tmTSpKURYwgELdjucAOydqIOrOfTxVYcNXe91xvLZwcRh68SR3liCg==", + "version": "1.22.22", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz", + "integrity": "sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==", "dev": true, "hasInstallScript": true, "bin": { diff --git a/package.json b/package.json index 3679e44f..66d85596 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fixit-api", - "version": "2.0.1", + "version": "2.1.0-next.1", "description": "Fixit API services built on NodeJS and Apollo GraphQL.", "author": { "name": "Trevor Anderson", @@ -43,7 +43,7 @@ "@aws-sdk/lib-dynamodb": "^3.391.0", "@graphql-tools/schema": "^10.0.0", "@nerdware/ddb-single-table": "^2.4.0", - "@nerdware/ts-string-helpers": "^1.1.1", + "@nerdware/ts-string-helpers": "^1.2.1", "@nerdware/ts-type-safety-utils": "^1.0.8", "@sentry/node": "^7.64.0", "bcrypt": "^5.1.1", @@ -52,6 +52,7 @@ "dayjs": "^1.11.9", "expo-server-sdk": "^3.7.0", "express": "^4.18.2", + "google-auth-library": "^9.7.0", "graphql": "^16.8.1", "graphql-tag": "^2.12.6", "helmet": "^7.0.0", diff --git a/src/graphql/AuthToken/typeDefs.ts b/src/graphql/AuthToken/typeDefs.ts index 33b7c13b..2b1d804f 100644 --- a/src/graphql/AuthToken/typeDefs.ts +++ b/src/graphql/AuthToken/typeDefs.ts @@ -5,11 +5,11 @@ export const typeDefs = gql` id: ID! handle: String! email: String! - phone: String! + phone: String profile: Profile! stripeCustomerID: String! subscription: AuthTokenPayloadSubscriptionInfo - stripeConnectAccount: AuthTokenPayloadStripeConnectAccountInfo! + stripeConnectAccount: AuthTokenPayloadStripeConnectAccountInfo createdAt: DateTime! updatedAt: DateTime! } diff --git a/src/graphql/Contact/resolvers.ts b/src/graphql/Contact/resolvers.ts index 00a74924..bf43113d 100644 --- a/src/graphql/Contact/resolvers.ts +++ b/src/graphql/Contact/resolvers.ts @@ -69,11 +69,7 @@ export const resolvers: Partial = { user ||= await User.getItem({ id: parent.contactUserID }); - if (!user?.phone) { - throw new GqlInternalServerError("Contact phone could not be found."); - } - - return user.phone; + return user?.phone ?? null; }, profile: async (parent) => { let user = usersCache.get(parent.handle); diff --git a/src/graphql/Contact/typeDefs.ts b/src/graphql/Contact/typeDefs.ts index 561429ec..662504e0 100644 --- a/src/graphql/Contact/typeDefs.ts +++ b/src/graphql/Contact/typeDefs.ts @@ -15,7 +15,7 @@ export const typeDefs = gql` "Contact email address" email: Email! "Contact phone number" - phone: String! + phone: String "Contact Profile object" profile: Profile! "(Immutable) Contact creation timestamp" diff --git a/src/graphql/FixitUser/typeDefs.ts b/src/graphql/FixitUser/typeDefs.ts index 2707370c..aa274d9a 100644 --- a/src/graphql/FixitUser/typeDefs.ts +++ b/src/graphql/FixitUser/typeDefs.ts @@ -15,7 +15,7 @@ export const typeDefs = gql` "Email address of either a User or Contact" email: Email! "Phone number of either a User or Contact" - phone: String! + phone: String "Profile object of either a User or Contact" profile: Profile! createdAt: DateTime! diff --git a/src/graphql/User/typeDefs.ts b/src/graphql/User/typeDefs.ts index 8eecc14c..6f8e05e3 100644 --- a/src/graphql/User/typeDefs.ts +++ b/src/graphql/User/typeDefs.ts @@ -34,8 +34,8 @@ export const typeDefs = gql` handle: String! "(Immutable) User's own email address" email: Email! - "(Immutable) User's own phone number" - phone: String! + "User's own phone number" + phone: String "(Mobile-Only) User's Expo push token, used to send push notifications to the User's mobile device" expoPushToken: String "User's own Profile object" diff --git a/src/graphql/_customScalars/DateTime/resolvers.ts b/src/graphql/_customScalars/DateTime/resolvers.ts index 1411f349..d48a5cc5 100644 --- a/src/graphql/_customScalars/DateTime/resolvers.ts +++ b/src/graphql/_customScalars/DateTime/resolvers.ts @@ -1,15 +1,8 @@ -import dayjs from "dayjs"; import { GraphQLScalarType, Kind } from "graphql"; import { logger } from "@/utils/logger.js"; +import { isValidTimestamp } from "@/utils/timestamps.js"; import { helpers } from "../helpers.js"; -/** @returns boolean indicating whether the value is a valid DateTime scalar. */ -const isValidGqlDateTimeScalar = (value: unknown) => { - return ( - value !== undefined && value !== null && !dayjs(value as Parameters[0]).isValid() - ); -}; - export const resolvers = { DateTime: new GraphQLScalarType({ name: "DateTime", @@ -17,7 +10,7 @@ export const resolvers = { // parseValue = value from the client parseValue(value: unknown) { - if (!isValidGqlDateTimeScalar(value)) { + if (!isValidTimestamp(value)) { const errMsg = helpers.getScalarErrMsg("DateTime", value); logger.gql(errMsg); throw new TypeError(errMsg); @@ -27,7 +20,7 @@ export const resolvers = { // serialize = value sent to the client serialize(value: unknown) { - if (!isValidGqlDateTimeScalar(value)) { + if (!isValidTimestamp(value)) { const errMsg = helpers.getScalarErrMsg("DateTime", value); logger.gql(errMsg); throw new TypeError(errMsg); diff --git a/src/graphql/_helpers/formatAsGqlFixitUser.ts b/src/graphql/_helpers/formatAsGqlFixitUser.ts index c97fef84..600ca480 100644 --- a/src/graphql/_helpers/formatAsGqlFixitUser.ts +++ b/src/graphql/_helpers/formatAsGqlFixitUser.ts @@ -35,7 +35,7 @@ export const formatAsGqlFixitUser = async ( id: userAuthToken.id, handle: userAuthToken.handle, email: userAuthToken.email, - phone: userAuthToken.phone, + phone: userAuthToken.phone ?? null, profile: userAuthToken.profile, createdAt: userAuthToken.createdAt, updatedAt: userAuthToken.updatedAt, diff --git a/src/lib/cache/usersCache.ts b/src/lib/cache/usersCache.ts index fc76388b..56e0dc64 100644 --- a/src/lib/cache/usersCache.ts +++ b/src/lib/cache/usersCache.ts @@ -27,10 +27,10 @@ if (/^(dev|staging|prod)/.test(ENV.NODE_ENV)) { items.forEach((dbItem) => { // prettier-ignore const { - pk: id, data: email, handle, phone, profile, createdAt, updatedAt, + pk: id, data: email, handle, phone = null, profile, createdAt, updatedAt, } = dbItem as UnaliasedUserItem - if (id && email && handle && phone && profile && createdAt && updatedAt) { + if (id && email && handle && profile && createdAt && updatedAt) { // Only users' public fields are cached for search initialCacheEntries.push([ handle, diff --git a/src/lib/googleOAuth2Client/googleOAuth2Client.ts b/src/lib/googleOAuth2Client/googleOAuth2Client.ts new file mode 100644 index 00000000..fe7b352a --- /dev/null +++ b/src/lib/googleOAuth2Client/googleOAuth2Client.ts @@ -0,0 +1,12 @@ +import { OAuth2Client } from "google-auth-library"; +import { ENV } from "@/server/env"; + +/** + * Google OAuth2 Client + * + * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token + */ +export const googleOAuth2Client = new OAuth2Client({ + clientId: ENV.GOOGLE_OAUTH.CLIENT_ID, + clientSecret: ENV.GOOGLE_OAUTH.CLIENT_SECRET, +}); diff --git a/src/lib/googleOAuth2Client/helpers.ts b/src/lib/googleOAuth2Client/helpers.ts new file mode 100644 index 00000000..b706fb5e --- /dev/null +++ b/src/lib/googleOAuth2Client/helpers.ts @@ -0,0 +1,101 @@ +import { + sanitizeID, + isValidID, + sanitizeEmail, + isValidEmail, + sanitizeAlphabetic, + isValidAlphabetic, + sanitizeURL, + isValidURL, +} from "@nerdware/ts-string-helpers"; +import { getTypeSafeError } from "@nerdware/ts-type-safety-utils"; +import { AuthError } from "@/utils/httpErrors.js"; +import { googleOAuth2Client } from "./googleOAuth2Client"; +import type { TokenPayload as GoogleOAuth2IDTokenPayload } from "google-auth-library"; + +/** + * This function validates and parses a Google OAuth2 ID token, including the + * relevant payload fields extracted from it. + * + * > **The structure of Google JWT ID tokens is available here:** + * > https://developers.google.com/identity/gsi/web/reference/js-reference#credential + * + * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token + */ +export const parseGoogleOAuth2IDToken = async ( + rawGoogleIDToken: string +): Promise => { + // Initialize variable to hold the token payload: + let tokenPayload: GoogleOAuth2IDTokenPayload | undefined; + + try { + const ticket = await googleOAuth2Client.verifyIdToken({ idToken: rawGoogleIDToken }); + + tokenPayload = ticket.getPayload(); + } catch (err) { + // Re-throw as AuthError + throw new AuthError( + getTypeSafeError(err, { fallBackErrMsg: DEFAULT_GOOGLE_OAUTH_ERR_MSG }).message + ); + } + + if (!tokenPayload) throw new AuthError(DEFAULT_GOOGLE_OAUTH_ERR_MSG); + + const { + email: unsanitized_email, + sub: unsanitized_googleID, + given_name: unsanitized_givenName, + family_name: unsanitized_familyName, + picture: unsanitized_profilePhotoURL, + } = tokenPayload; + + // Ensure the payload includes an `email`: + if (!unsanitized_email) throw new AuthError(DEFAULT_GOOGLE_OAUTH_ERR_MSG); + + // Sanitize the relevant payload fields (optional fields use `let`, default to null if invalid) + + const email = sanitizeEmail(unsanitized_email); + const googleID = sanitizeID(unsanitized_googleID); + let givenName = unsanitized_givenName ? sanitizeAlphabetic(unsanitized_givenName) : null; + let familyName = unsanitized_familyName ? sanitizeAlphabetic(unsanitized_familyName) : null; + let profilePhotoUrl = unsanitized_profilePhotoURL + ? sanitizeURL(unsanitized_profilePhotoURL) + : null; + + // Validate the REQUIRED payload fields (if invalid, throw error) + if (!isValidEmail(email) || !isValidID(googleID)) { + throw new AuthError(DEFAULT_GOOGLE_OAUTH_ERR_MSG); + } + + // Validate the OPTIONAL payload fields (if invalid, set to null) + if (!isValidAlphabetic(givenName)) givenName = null; + if (!isValidAlphabetic(familyName)) familyName = null; + if (!isValidURL(profilePhotoUrl)) profilePhotoUrl = null; + + return { + _isValid: true, + email, + googleID, + profile: { + givenName, + familyName, + photoUrl: profilePhotoUrl, + }, + }; +}; + +const DEFAULT_GOOGLE_OAUTH_ERR_MSG = "Invalid credentials"; + +/** + * The fields returned by {@link parseGoogleOAuth2IDToken} + */ +export type ParsedGoogleOAuth2IDTokenFields = { + _isValid: boolean; + email: string; + googleID: string; + profile: { + givenName: string | null; + familyName: string | null; + photoUrl: string | null; + }; +}; diff --git a/src/lib/googleOAuth2Client/index.ts b/src/lib/googleOAuth2Client/index.ts new file mode 100644 index 00000000..3119bee1 --- /dev/null +++ b/src/lib/googleOAuth2Client/index.ts @@ -0,0 +1,2 @@ +export * from "./googleOAuth2Client"; +export * from "./helpers"; diff --git a/src/lib/stripe/__mocks__/_mockStripeCustomer.ts b/src/lib/stripe/__mocks__/_mockStripeCustomer.ts index 77423f5f..22cb162b 100644 --- a/src/lib/stripe/__mocks__/_mockStripeCustomer.ts +++ b/src/lib/stripe/__mocks__/_mockStripeCustomer.ts @@ -13,7 +13,7 @@ export const mockStripeCustomer = ( mockUser: UserItem & { subscription: UserSubscriptionItem }, customerUpdateParams?: Stripe.CustomerUpdateParams ): Stripe.Customer => { - const { stripeCustomerID, email, phone, profile, createdAt } = mockUser; + const { stripeCustomerID, email, phone = null, profile, createdAt } = mockUser; const defaultPaymentMethodID = customerUpdateParams?.invoice_settings?.default_payment_method ?? "pm_TestTestTest"; diff --git a/src/lib/stripe/__mocks__/_mockStripeInvoice.ts b/src/lib/stripe/__mocks__/_mockStripeInvoice.ts index 570166d3..210239a6 100644 --- a/src/lib/stripe/__mocks__/_mockStripeInvoice.ts +++ b/src/lib/stripe/__mocks__/_mockStripeInvoice.ts @@ -15,7 +15,7 @@ export const mockStripeInvoice = ( { stripeCustomerID, email, - phone, + phone = null, profile, subscription, }: UserItem & { subscription?: UserSubscriptionItem }, diff --git a/src/lib/stripe/__mocks__/_mockStripePaymentMethod.ts b/src/lib/stripe/__mocks__/_mockStripePaymentMethod.ts index 96573eab..a54bd2fb 100644 --- a/src/lib/stripe/__mocks__/_mockStripePaymentMethod.ts +++ b/src/lib/stripe/__mocks__/_mockStripePaymentMethod.ts @@ -9,7 +9,7 @@ import type { SetRequired } from "type-fest"; * @see https://stripe.com/docs/api/payment_methods/object */ export const mockStripePaymentMethod = ( - { stripeCustomerID, email, phone, profile, createdAt }: UserItem, + { stripeCustomerID, email, phone = null, profile, createdAt }: UserItem, { id: paymentMethodID, ...customValues }: SetRequired, "id"> ): Stripe.PaymentMethod => { // Default mock PaymentMethod object diff --git a/src/middleware/auth/findUserByEmail.ts b/src/middleware/auth/findUserByEmail.ts index 3dd7f236..ebf16fa0 100644 --- a/src/middleware/auth/findUserByEmail.ts +++ b/src/middleware/auth/findUserByEmail.ts @@ -6,7 +6,7 @@ import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; * This middleware simply queries the DB for a User with the given email address. */ export const findUserByEmail = mwAsyncCatchWrapper< - RestApiRequestBodyByPath["/auth/register" | "/auth/login"] + Pick >(async (req, res, next) => { const [user] = await User.query({ where: { email: req.body.email }, diff --git a/src/middleware/auth/generateAuthToken.ts b/src/middleware/auth/generateAuthToken.ts index d4d8d467..cd7a4876 100644 --- a/src/middleware/auth/generateAuthToken.ts +++ b/src/middleware/auth/generateAuthToken.ts @@ -1,22 +1,20 @@ -import { mwCatchWrapper } from "@/middleware/helpers.js"; import { AuthToken } from "@/utils/AuthToken.js"; +import { AuthError } from "@/utils/httpErrors.js"; +import type { RestApiRequestHandler } from "@/middleware/helpers.js"; /** * This middleware generates an AuthToken for the authenticated User to be * included in the returned response. If the User is not found or the User's * Stripe Connect account is not found, an error message is passed to `next`. */ -export const generateAuthToken = mwCatchWrapper((req, res, next) => { +export const generateAuthToken: RestApiRequestHandler = (req, res, next) => { const { authenticatedUser } = res.locals; - if (!authenticatedUser?.id) return next("User not found"); - if (!authenticatedUser?.stripeConnectAccount?.id) { - return next("User's Stripe Connect account not found"); - } + if (!authenticatedUser?.id) return next(new AuthError("User not found")); const authToken = new AuthToken(authenticatedUser); res.locals.authToken = authToken.toString(); next(); -}); +}; diff --git a/src/middleware/auth/index.ts b/src/middleware/auth/index.ts index 7bb826f6..0a3a6257 100644 --- a/src/middleware/auth/index.ts +++ b/src/middleware/auth/index.ts @@ -1,8 +1,9 @@ export * from "./findUserByEmail.js"; export * from "./generateAuthToken.js"; export * from "./getUserFromAuthHeaderToken.js"; +export * from "./parseGoogleIDToken.js"; export * from "./queryUserItems.js"; export * from "./registerNewUser.js"; export * from "./shouldUserLoginExist.js"; export * from "./validateGqlReqContext.js"; -export * from "./validatePassword.js"; +export * from "./validateLogin.js"; diff --git a/src/middleware/auth/parseGoogleIDToken.ts b/src/middleware/auth/parseGoogleIDToken.ts new file mode 100644 index 00000000..e2a1c9c2 --- /dev/null +++ b/src/middleware/auth/parseGoogleIDToken.ts @@ -0,0 +1,55 @@ +import { parseGoogleOAuth2IDToken } from "@/lib/googleOAuth2Client"; +import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; +import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; + +/** + * This middleware parses and validates a `googleIDToken` if provided. If valid, + * it is decoded to obtain the fields listed below. These fields are then used to + * create login args, which are added to `res.locals.googleIDTokenFields` and + * `req.body` to be read by downstream auth middleware. + * + * **Fields obtained from the `googleIDToken`:** + * + * - `googleID` + * - `email` + * - `givenName` + * - `familyName` + * - `picture` (profile photo URL) + * + * > **The structure of Google JWT ID tokens is available here:** + * > https://developers.google.com/identity/gsi/web/reference/js-reference#credential + * + * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token + */ +export const parseGoogleIDToken = mwAsyncCatchWrapper< + /** + * Since this mw creates user login args from the supplied Google ID token and adds + * them to the `req.body` object, an intersection is used for the type param here to + * tell downstream mw that `req.body` will include fields they require. Without this + * intersection, TS complains about the perceived `req.body` type mismatch. + */ + RestApiRequestBodyByPath["/auth/google-token"] & + RestApiRequestBodyByPath["/auth/login"] & + RestApiRequestBodyByPath["/auth/register"] +>(async (req, res, next) => { + // Since this mw is used on routes where auth via GoogleIDToken is optional, check if provided. + if (!req.body.googleIDToken) return next(); + + // Parse the google ID token: + const { _isValid, email, googleID, profile } = await parseGoogleOAuth2IDToken( + req.body.googleIDToken + ); + + // Add the fields to res.locals.googleIDTokenFields: + res.locals.googleIDTokenFields = { + _isValid, + email, + googleID, + profile, + }; + + // If not already present, add email to req.body for use by downstream mw (used by findUserByEmail) + if (!req.body.email) req.body.email = email; + + next(); +}); diff --git a/src/middleware/auth/queryUserItems.ts b/src/middleware/auth/queryUserItems.ts index b59afe8d..081a5557 100644 --- a/src/middleware/auth/queryUserItems.ts +++ b/src/middleware/auth/queryUserItems.ts @@ -39,7 +39,7 @@ import type { WorkOrderItem } from "@/models/WorkOrder/WorkOrder.js"; * interactions with the API. */ export const queryUserItems = mwAsyncCatchWrapper(async (req, res, next) => { - if (!res.locals?.authenticatedUser) return next("User not found"); + if (!res.locals?.authenticatedUser) return next(new AuthError("User not found")); // We want to retrieve items of multiple types, so we don't use a Model-instance here. const response = await ddbTable.ddbClient.query({ diff --git a/src/middleware/auth/registerNewUser.ts b/src/middleware/auth/registerNewUser.ts index 840a0d5b..b93bea64 100644 --- a/src/middleware/auth/registerNewUser.ts +++ b/src/middleware/auth/registerNewUser.ts @@ -14,15 +14,15 @@ export const registerNewUser = mwAsyncCatchWrapper< body: { handle, email, - phone, - expoPushToken, // Only mobile-app logins will have this - profile: profileParams, // Only Google OAuth logins will have this at reg time - password, // Only local logins will have this - googleID, // Only Google OAuth logins will have this - googleAccessToken, // Only Google OAuth logins will have this + phone = null, + expoPushToken, // Only mobile-app logins will have this + password, // Only local logins will have this }, } = req; + // For Google OAuth logins, get fields from the relevant res.locals object: + const { googleID, profile: profileParams } = res.locals.googleIDTokenFields ?? {}; + // Set the authenticatedUser res.locals field used by `generateAuthToken` res.locals.authenticatedUser = await User.createOne({ handle, @@ -32,7 +32,6 @@ export const registerNewUser = mwAsyncCatchWrapper< ...(profileParams && { profile: Profile.fromParams(profileParams) }), password, googleID, - googleAccessToken, }); /* Data from this endpoint is returned to the sending client, so there's diff --git a/src/middleware/auth/validateLogin.ts b/src/middleware/auth/validateLogin.ts new file mode 100644 index 00000000..4404a65c --- /dev/null +++ b/src/middleware/auth/validateLogin.ts @@ -0,0 +1,52 @@ +import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; +import { AuthError, InternalServerError } from "@/utils/httpErrors.js"; +import { passwordHasher } from "@/utils/passwordHasher.js"; +import type { CombineUnionOfObjects } from "@/types/helpers.js"; +import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; + +/** + * This middleware validates User's Login objects. + * + * - If the User's login type is `"LOCAL"`, it compares the provided password + * against the passwordHash stored in the db. + * + * - If the User's login type is `"GOOGLE_OAUTH"`, it checks the value of + * `res.locals.googleIDTokenFields?._isValid`, which is set by the `parseGoogleIDToken` + * middleware. + * + * If it's invalid, an AuthError is thrown. + */ +export const validateLogin = mwAsyncCatchWrapper< + CombineUnionOfObjects +>(async (req, res, next) => { + const userItem = res.locals?.user; + + if (!userItem) return next(new AuthError("User not found")); + + // LOCAL LOGIN — validate password + if (userItem.login.type === "LOCAL") { + // Ensure password was provided + if (!req.body?.password) return next(new AuthError("Password is required")); + + const isValidPassword = await passwordHasher.validate( + req.body.password, + userItem.login.passwordHash + ); + + if (!isValidPassword) next(new AuthError("Invalid email or password")); + + /* Note: res.locals.user does not have `subscription`/`stripeConnectAccount` fields. + For `generateAuthToken`, these fields are obtained from the `queryUserItems` mw. */ + res.locals.authenticatedUser = userItem; + + // GOOGLE_OAUTH LOGIN — check res.locals.googleIDTokenFields._isValid + } else if (userItem.login.type === "GOOGLE_OAUTH") { + // The parseGoogleIDToken mw provides this res.locals field, check `_isValid`. The + // field should always be true here, else the fn would throw, but it provides clarity. + if (res.locals.googleIDTokenFields?._isValid) res.locals.authenticatedUser = userItem; + } else { + next(new InternalServerError("Invalid login")); + } + + next(); +}); diff --git a/src/middleware/auth/validatePassword.ts b/src/middleware/auth/validatePassword.ts deleted file mode 100644 index fa69b800..00000000 --- a/src/middleware/auth/validatePassword.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; -import { AuthError } from "@/utils/httpErrors.js"; -import { passwordHasher } from "@/utils/passwordHasher.js"; -import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; - -/** - * This middleware checks if the authenticated User's login type is "LOCAL", - * and if so, compares the provided password against the passwordHash stored - * in the db. If it's invalid, an AuthError is thrown. - */ -export const validatePassword = mwAsyncCatchWrapper( - async (req, res, next) => { - const userItem = res.locals?.user; - - if (!userItem) return next("User not found"); - - if (userItem.login.type === "LOCAL") { - // Ensure password was provided - if (!("password" in req.body) || !req.body.password) - return next(new AuthError("Password is required")); - - const isValidPassword = await passwordHasher.validate( - req.body.password, - userItem.login.passwordHash - ); - - if (isValidPassword === true) { - /* Note: res.locals.user does not have `subscription`/`stripeConnectAccount` fields. - For `generateAuthToken`, these fields are obtained from the `queryUserItems` mw. */ - res.locals.authenticatedUser = userItem; - } else { - next(new AuthError("Invalid email or password")); - } - } - - next(); - } -); diff --git a/src/middleware/errorHandlers/handle404.ts b/src/middleware/errorHandlers/handle404.ts index d639bc59..7536e8a3 100644 --- a/src/middleware/errorHandlers/handle404.ts +++ b/src/middleware/errorHandlers/handle404.ts @@ -1,11 +1,11 @@ -import { mwCatchWrapper } from "@/middleware/helpers.js"; import { NotFoundError } from "@/utils/httpErrors.js"; import { logger } from "@/utils/logger.js"; +import type { RestApiRequestHandler } from "@/middleware/helpers.js"; /** * This middleware function captures all 404 errors and throws a NotFoundError. */ -export const handle404 = mwCatchWrapper(({ originalUrl }) => { +export const handle404: RestApiRequestHandler = ({ originalUrl }) => { logger.error(`Request received for non-existent path, req.originalUrl: "${originalUrl}"`); throw new NotFoundError(`Unable to find the requested resource at "${originalUrl}"`); -}); +}; diff --git a/src/middleware/helpers.ts b/src/middleware/helpers.ts index 108dd294..74e2bdfd 100644 --- a/src/middleware/helpers.ts +++ b/src/middleware/helpers.ts @@ -27,21 +27,6 @@ export const mwAsyncCatchWrapper = < }; }; -/** - * Generic catch wrapper for non-async middleware functions. - */ -export const mwCatchWrapper = = Record>( - middlewareFn: RestApiRequestHandler -): RestApiRequestHandler => { - return (req, res, next) => { - try { - middlewareFn(req, res, next); - } catch (error) { - next(error); - } - }; -}; - /** * This type wraps the Express `RequestHandler` type with app global defaults. * Provide the `ReqBody` type param to specify a `req.body` object type. @@ -113,8 +98,10 @@ export const sanitizeAndValidateRequestBody = (async (req, res, next) => { const { authenticatedUser } = res.locals; - if (!authenticatedUser) return next("User not found"); + if (!authenticatedUser) return next(new AuthError("User not found")); const { expoPushToken } = req.body; diff --git a/src/middleware/stripeConnect/checkOnboardingStatus.ts b/src/middleware/stripeConnect/checkOnboardingStatus.ts index e6f5c102..45410404 100644 --- a/src/middleware/stripeConnect/checkOnboardingStatus.ts +++ b/src/middleware/stripeConnect/checkOnboardingStatus.ts @@ -1,18 +1,19 @@ import { stripe } from "@/lib/stripe/stripeClient.js"; import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; import { UserStripeConnectAccount } from "@/models/UserStripeConnectAccount/UserStripeConnectAccount.js"; +import { AuthError, InternalServerError } from "@/utils/httpErrors.js"; /** * Checks the status of the user's Stripe Connect account capabilities and updates the DB * if the values are stale (`details_submitted`, `charges_enabled`, and `payouts_enabled`). */ export const checkOnboardingStatus = mwAsyncCatchWrapper(async (req, res, next) => { - if (!res.locals?.authenticatedUser) return next("User not found"); + if (!res.locals?.authenticatedUser) return next(new AuthError("User not found")); const { authenticatedUser } = res.locals; if (!authenticatedUser?.stripeConnectAccount) - return next("User's Stripe Connect account not found"); + return next(new InternalServerError("User's Stripe Connect account not found")); const { id: userID, diff --git a/src/middleware/stripeConnect/createDashboardLink.ts b/src/middleware/stripeConnect/createDashboardLink.ts index 8c10a14a..e6181257 100644 --- a/src/middleware/stripeConnect/createDashboardLink.ts +++ b/src/middleware/stripeConnect/createDashboardLink.ts @@ -1,5 +1,6 @@ import { stripe } from "@/lib/stripe/stripeClient.js"; import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; +import { AuthError } from "@/utils/httpErrors.js"; /** * This middleware creates a Stripe dashboard link for authenticated users. @@ -17,7 +18,7 @@ import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; export const createDashboardLink = mwAsyncCatchWrapper(async (req, res, next) => { const { authenticatedUser } = res.locals; - if (!authenticatedUser) return next("User not found"); + if (!authenticatedUser) return next(new AuthError("User not found")); if (!authenticatedUser?.stripeConnectAccount) return next("User's Stripe Connect account not found."); diff --git a/src/middleware/stripeSubscriptions/checkPromoCode.ts b/src/middleware/stripeSubscriptions/checkPromoCode.ts index 34660e4c..397fad2b 100644 --- a/src/middleware/stripeSubscriptions/checkPromoCode.ts +++ b/src/middleware/stripeSubscriptions/checkPromoCode.ts @@ -1,14 +1,14 @@ import { promoCodesCache } from "@/lib/cache/promoCodesCache.js"; -import { mwCatchWrapper } from "@/middleware/helpers.js"; +import type { RestApiRequestHandler } from "@/middleware/helpers.js"; import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; /** * This middlware serves as an endpoint which receives a `promoCode` string, and responds with * information regarding the `promoCode`s validity and discount percentage (if valid/applicable). */ -export const checkPromoCode = mwCatchWrapper< +export const checkPromoCode: RestApiRequestHandler< RestApiRequestBodyByPath["/subscriptions/check-promo-code"] ->((req, res) => { +> = (req, res) => { // Destructure req.body const { promoCode: maybePromoCode } = req.body; @@ -21,4 +21,4 @@ export const checkPromoCode = mwCatchWrapper< ...(!!maybeDiscountPercentage && { discountPercentage: maybeDiscountPercentage }), }, }); -}); +}; diff --git a/src/middleware/stripeSubscriptions/checkSubscriptionStatus.ts b/src/middleware/stripeSubscriptions/checkSubscriptionStatus.ts index 7e266f78..49dc40c3 100644 --- a/src/middleware/stripeSubscriptions/checkSubscriptionStatus.ts +++ b/src/middleware/stripeSubscriptions/checkSubscriptionStatus.ts @@ -1,6 +1,7 @@ import { stripe } from "@/lib/stripe/stripeClient.js"; import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; import { UserSubscription } from "@/models/UserSubscription/UserSubscription.js"; +import { AuthError, InternalServerError } from "@/utils/httpErrors.js"; /** * This middleware checks if the User is authenticated, and if so, queries Stripe for @@ -10,7 +11,7 @@ import { UserSubscription } from "@/models/UserSubscription/UserSubscription.js" * auth token payload values are updated as well. */ export const checkSubscriptionStatus = mwAsyncCatchWrapper(async (req, res, next) => { - if (!res.locals?.authenticatedUser) return next("User not found"); + if (!res.locals?.authenticatedUser) return next(new AuthError("User not found")); const { subscription, id: userID } = res.locals.authenticatedUser; @@ -35,7 +36,8 @@ export const checkSubscriptionStatus = mwAsyncCatchWrapper(async (req, res, next /* Do NOT use Stripe's `createdAt` value for the UserSubscription SK, because it may not match the value in the DB. Instead, use the value from res.locals.userSubscription (should always be present here). */ - if (!res.locals?.userSubscription?.createdAt) return next("Invalid subscription details"); + if (!res.locals?.userSubscription?.createdAt) + return next(new InternalServerError("Invalid subscription details")); const updatedSub = await UserSubscription.updateItem( { diff --git a/src/middleware/stripeSubscriptions/createCustomerPortalLink.ts b/src/middleware/stripeSubscriptions/createCustomerPortalLink.ts index 8dbb367a..e9a1f94d 100644 --- a/src/middleware/stripeSubscriptions/createCustomerPortalLink.ts +++ b/src/middleware/stripeSubscriptions/createCustomerPortalLink.ts @@ -1,6 +1,7 @@ import { stripe } from "@/lib/stripe/stripeClient.js"; import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; +import { AuthError } from "@/utils/httpErrors.js"; /** * This middleware creates a Stripe Customer Portal link, which allows the User to @@ -9,7 +10,7 @@ import type { RestApiRequestBodyByPath } from "@/types/open-api.js"; export const createCustomerPortalLink = mwAsyncCatchWrapper< RestApiRequestBodyByPath["/subscriptions/customer-portal"] >(async (req, res, next) => { - if (!res.locals?.authenticatedUser) return next("User not found"); + if (!res.locals?.authenticatedUser) return next(new AuthError("User not found")); const stripeLink = await stripe.billingPortal.sessions.create({ customer: res.locals.authenticatedUser.stripeCustomerID, diff --git a/src/middleware/stripeSubscriptions/findOrCreateStripeSubscription.ts b/src/middleware/stripeSubscriptions/findOrCreateStripeSubscription.ts index e3f20348..17109996 100644 --- a/src/middleware/stripeSubscriptions/findOrCreateStripeSubscription.ts +++ b/src/middleware/stripeSubscriptions/findOrCreateStripeSubscription.ts @@ -2,7 +2,7 @@ import { isString, getTypeSafeError } from "@nerdware/ts-type-safety-utils"; import { stripe } from "@/lib/stripe/stripeClient.js"; import { mwAsyncCatchWrapper } from "@/middleware/helpers.js"; import { UserSubscription } from "@/models/UserSubscription/UserSubscription.js"; -import { PaymentRequiredError } from "@/utils/httpErrors.js"; +import { PaymentRequiredError, AuthError } from "@/utils/httpErrors.js"; import { logger } from "@/utils/logger.js"; import type { StripeSubscriptionWithClientSecret, @@ -43,7 +43,7 @@ import type Stripe from "stripe"; export const findOrCreateStripeSubscription = mwAsyncCatchWrapper< RestApiRequestBodyByPath["/subscriptions/submit-payment"] >(async (req, res, next) => { - if (!res.locals?.authenticatedUser) return next("User not found"); + if (!res.locals?.authenticatedUser) return next(new AuthError("User not found")); try { const { paymentMethodID, selectedSubscription, promoCode } = req.body; diff --git a/src/middleware/util-mw/sendRESTJsonResponse.ts b/src/middleware/util-mw/sendRESTJsonResponse.ts index c8739a75..6babe376 100644 --- a/src/middleware/util-mw/sendRESTJsonResponse.ts +++ b/src/middleware/util-mw/sendRESTJsonResponse.ts @@ -1,4 +1,4 @@ -import { mwCatchWrapper } from "@/middleware/helpers.js"; +import type { RestApiRequestHandler } from "@/middleware/helpers.js"; /** * This middleware is a fallback response handler which reads the `res.locals` object and returns @@ -31,7 +31,7 @@ import { mwCatchWrapper } from "@/middleware/helpers.js"; * | `stripeLink` | `stripeLink: res.locals.stripeLink` | * | `userItems` | `userItems: res.locals.userItems` | */ -export const sendRESTJsonResponse = mwCatchWrapper((req, res) => { +export const sendRESTJsonResponse: RestApiRequestHandler = (req, res) => { // Get available `res.locals` fields which are associated with a response field: const { authToken, promoCodeInfo, checkoutCompletionInfo, stripeLink, userItems } = res.locals; @@ -44,4 +44,4 @@ export const sendRESTJsonResponse = mwCatchWrapper((req, res) => { ...(!!stripeLink && { stripeLink }), ...(!!userItems && { userItems }), }); -}); +}; diff --git a/src/models/User/User.ts b/src/models/User/User.ts index 5d5fde62..a158629e 100644 --- a/src/models/User/User.ts +++ b/src/models/User/User.ts @@ -43,7 +43,7 @@ class UserModel extends Model isPlainObject(login) && @@ -73,7 +72,7 @@ class UserModel extends Model, + "profile" + > +>; + /** * `User.createOne` creates the following items: * - `User` (created in the DB) @@ -20,12 +29,11 @@ export const createOne = async function ( { handle, email, - phone, - expoPushToken, // Only mobile users will have this - profile, // Only Google logins will have this at reg-time + phone = null, + expoPushToken, // Only mobile-app users will have this password, // Only local logins will have this - googleID, // Only Google logins will have this - googleAccessToken, // Only Google logins will have this + profile, // Only Google OAuth logins will have this at reg-time + googleID, // Only Google OAuth logins will have this }: UserCreateOneParams ) { let newUser: UserItem; @@ -37,7 +45,7 @@ export const createOne = async function ( // Create Stripe Customer via Stripe API const { id: stripeCustomerID } = await stripe.customers.create({ email, - phone, + ...(phone && { phone }), ...(newUserProfile.displayName.length > 0 && { name: newUserProfile.displayName }), }); @@ -54,7 +62,7 @@ export const createOne = async function ( ...(expoPushToken && { expoPushToken }), stripeCustomerID, profile: { ...newUserProfile }, - login: await UserLogin.createLogin({ password, googleID, googleAccessToken }), + login: await UserLogin.createLogin({ password, googleID }), }); newUserID = newUser.id; @@ -74,7 +82,7 @@ export const createOne = async function ( id: newUser.id, handle: newUser.handle, email: newUser.email, - phone: newUser.phone, + phone: newUser.phone ?? null, profile: newUser.profile, createdAt: newUser.createdAt, updatedAt: newUser.updatedAt, @@ -119,12 +127,3 @@ export const createOne = async function ( stripeConnectAccount: newUserStripeConnectAccount, }; }; - -/** `User.createOne()` method params. */ -export type UserCreateOneParams = Simplify< - CreateLoginParams & - SetOptional< - Pick, - "profile" - > ->; diff --git a/src/models/UserLogin/UserLogin.test.ts b/src/models/UserLogin/UserLogin.test.ts index 0019307d..5ab241ee 100644 --- a/src/models/UserLogin/UserLogin.test.ts +++ b/src/models/UserLogin/UserLogin.test.ts @@ -11,11 +11,9 @@ describe("UserLogin", () => { test("returns a GOOGLE_OAUTH UserLogin when called with a Google ID and access token", async () => { const googleID = "gid_123"; - const googleAccessToken = "gat_123"; - const result = await UserLogin.createLogin({ googleID, googleAccessToken }); + const result = await UserLogin.createLogin({ googleID }); expect(result.type).toBe("GOOGLE_OAUTH"); expect(result.googleID).toBe(googleID); - expect(result.googleAccessToken).toBe(googleAccessToken); }); test("throws an error when called without any params", async () => { @@ -30,18 +28,7 @@ describe("UserLogin", () => { test(`throws an error when called with an invalid "googleID" arg`, async () => { const googleID = "bad"; - const googleAccessToken = "gat_123"; - await expect(UserLogin.createLogin({ googleID, googleAccessToken })).rejects.toThrow( - "Invalid Google ID" - ); - }); - - test(`throws an error when called with an invalid "googleAccessToken" arg`, async () => { - const googleID = "gid_123"; - const googleAccessToken = "bad"; - await expect(UserLogin.createLogin({ googleID, googleAccessToken })).rejects.toThrow( - "Invalid Google access token" - ); + await expect(UserLogin.createLogin({ googleID })).rejects.toThrow("Invalid Google ID"); }); }); }); diff --git a/src/models/UserLogin/UserLogin.ts b/src/models/UserLogin/UserLogin.ts index 1fd514b0..77e20ef5 100644 --- a/src/models/UserLogin/UserLogin.ts +++ b/src/models/UserLogin/UserLogin.ts @@ -1,14 +1,20 @@ import { isValidPassword } from "@nerdware/ts-string-helpers"; import { isString } from "@nerdware/ts-type-safety-utils"; import { passwordHasher } from "@/utils/passwordHasher.js"; +import type { Simplify } from "type-fest"; /** * Represents a User login object that can be created with either a password or * Google OAuth credentials. */ export class UserLogin { + public static readonly TYPES = { + LOCAL: "LOCAL", + GOOGLE_OAUTH: "GOOGLE_OAUTH", + } as const; + /** - * Creates a UserLogin object based on the provided parameters. + * Creates a UserLogin object of a `type` determined by the provided parameters. * @param params - The parameters for creating the UserLogin login object. * @returns A promise that resolves to the created UserLogin object. * @throws Error if the provided parameters are invalid. @@ -16,63 +22,95 @@ export class UserLogin { public static readonly createLogin = async ({ password, googleID, - googleAccessToken, - }: Params): Promise> => { - let userLogin; + }: Params) => { + // Run the appropriate method based on the provided params + const userLogin = isString(password) + ? await UserLogin.createLoginLocal(password) + : isString(googleID) + ? UserLogin.createLoginGoogleOAuth(googleID) + : null; + + // Ensure that the userLogin object is not null: + if (!userLogin) throw new Error("Invalid login credentials"); - if (isString(password)) { - // Validate the password - if (!isValidPassword(password)) { - throw new Error("The provided password does not meet the required criteria"); - } + return userLogin as Params extends { password: string } + ? UserLoginLocal + : Params extends { googleID: string } + ? UserLoginGoogleOAuth + : never; + }; - userLogin = { - type: "LOCAL", - passwordHash: await passwordHasher.getHash(password), - }; - } else if (isString(googleID) && isString(googleAccessToken)) { - // Perform some basic validation on the Google OAuth params - if (googleID.length < 5) throw new Error("Invalid Google ID"); - if (googleAccessToken.length < 5) throw new Error("Invalid Google access token"); + /** + * Alias for {@link UserLogin.createLogin} + */ + public static readonly fromParams = UserLogin.createLogin; - userLogin = { - type: "GOOGLE_OAUTH", - googleID, - googleAccessToken, - }; - } else { - throw new Error("Invalid login credentials"); + /** + * Creates a {@link UserLoginLocal} object from the provided password (if it's valid). + */ + public static readonly createLoginLocal = async (password: string): Promise => { + // Validate the password + if (!isValidPassword(password)) { + throw new Error("The provided password does not meet the required criteria"); } + return { + type: UserLogin.TYPES.LOCAL, + passwordHash: await passwordHasher.getHash(password), + }; + }; - return userLogin as CreateLoginResult; + /** + * Creates a {@link UserLoginGoogleOAuth} object from the provided googleID (if it's valid). + */ + public static readonly createLoginGoogleOAuth = (googleID: string): UserLoginGoogleOAuth => { + // Perform some basic validation on the Google OAuth params + if (googleID.length < 5) throw new Error("Invalid Google ID"); + return { + type: UserLogin.TYPES.GOOGLE_OAUTH, + googleID, + }; }; } -// TODO Use open-api schema types to replace/modify the Login types below +///////////////////////////////////////////////////////////////////// +// LOGIN TYPES: -/** This type is used in `User.createOne()`. */ -export type CreateLoginParams = - | { password: string; [key: string]: string | undefined } - | { googleID: string; googleAccessToken: string; [key: string]: string | undefined } - | { - password?: string | undefined; - googleID?: string | undefined; - googleAccessToken?: string | undefined; - }; - -type CreateLoginResult = T extends { password: string } - ? UserLoginLocal - : T extends { googleID: string; googleAccessToken: string } - ? UserLoginGoogleOAuth - : never; +/** + * Parameters for creating a `UserLogin` object. + */ +export type CreateLoginParams = { + password?: string | undefined; // <-- UserLogin class currently hashes passwords + googleID?: string | undefined; // <-- googleIDToken is processed by upstream mw +}; // TODO Consider mv'ind gidToken here, or pw elsewhere -/** This type is used in `UserItem`. */ +/** + * A union of `UserLogin` object types, discriminated by the + * {@link FixitApiLoginAuthType|`type` string literal property}. + */ export type UserLoginU = UserLoginLocal | UserLoginGoogleOAuth; -type UserLoginLocal = { type: "LOCAL"; passwordHash: string }; +/** + * A `UserLogin` object that was created via the local JWT auth mechanism. + */ +export type UserLoginLocal = Simplify< + BaseUserLoginType & { passwordHash: string } +>; + +/** + * A `UserLogin` object that was created via Google OAuth. + */ +export type UserLoginGoogleOAuth = Simplify< + BaseUserLoginType & { googleID: string } +>; + +/** + * This base type for all UserLogin types defines the `type` discriminant property. + */ +interface BaseUserLoginType { + type: AuthType; +} -type UserLoginGoogleOAuth = { - type: "GOOGLE_OAUTH"; - googleID: string; - googleAccessToken: string; -}; +/** + * A union of string literals for the `type` discriminant property of `UserLogin` objects. + */ +type FixitApiLoginAuthType = keyof typeof UserLogin.TYPES; diff --git a/src/models/UserStripeConnectAccount/createOne.ts b/src/models/UserStripeConnectAccount/createOne.ts index 5dd9e0d4..3401c956 100644 --- a/src/models/UserStripeConnectAccount/createOne.ts +++ b/src/models/UserStripeConnectAccount/createOne.ts @@ -40,19 +40,19 @@ export const createOne = async function ( }, business_type: "individual", company: { + ...(phone && { phone }), ...(profile?.businessName && { name: profile.businessName }), - phone, }, individual: { email, - phone, + ...(phone && { phone }), ...(profile?.givenName && { first_name: profile.givenName }), ...(profile?.familyName && { last_name: profile.familyName }), }, business_profile: { - ...(profile?.businessName && { name: profile.businessName }), support_email: email, - support_phone: phone, + ...(phone && { support_phone: phone }), + ...(profile?.businessName && { name: profile.businessName }), }, tos_acceptance: { service_agreement: "full", diff --git a/src/models/_common/modelAttributes.ts b/src/models/_common/modelAttributes.ts index 5a5a794d..effcd6bd 100644 --- a/src/models/_common/modelAttributes.ts +++ b/src/models/_common/modelAttributes.ts @@ -1,8 +1,8 @@ import { isValidPhone } from "@nerdware/ts-string-helpers"; import { isString } from "@nerdware/ts-type-safety-utils"; -import dayjs from "dayjs"; import { fmt } from "@/utils/formatters"; import { normalize } from "@/utils/normalize.js"; +import { isValidTimestamp } from "@/utils/timestamps.js"; import type { ModelSchemaAttributeConfig } from "@nerdware/ddb-single-table"; export const COMMON_ATTRIBUTE_TYPES = { @@ -19,7 +19,7 @@ export const COMMON_ATTRIBUTE_TYPES = { DATETIME: { type: "Date", - validate: (value: unknown) => !!value && dayjs(value as Parameters[0]).isValid(), + validate: isValidTimestamp, }, } as const satisfies Record>; diff --git a/src/routers/authRouter.ts b/src/routers/authRouter.ts index 0a3f036b..1907fd24 100644 --- a/src/routers/authRouter.ts +++ b/src/routers/authRouter.ts @@ -7,20 +7,17 @@ import { isValidEmail, sanitizePassword, isValidPassword, - sanitizeID, - isValidID, - sanitizeToken, - isValidToken, } from "@nerdware/ts-string-helpers"; -import { hasKey, hasKeys } from "@nerdware/ts-type-safety-utils"; +import { hasKey } from "@nerdware/ts-type-safety-utils"; import express from "express"; import { findUserByEmail, userLoginShouldExist, userLoginShouldNotExist, registerNewUser, - validatePassword, + validateLogin, getUserFromAuthHeaderToken, + parseGoogleIDToken, updateExpoPushToken, queryUserItems, checkSubscriptionStatus, @@ -34,6 +31,7 @@ import type { RequestBodyFieldsSchema, RequestBodyValidatorFn } from "@/middlewa * This router handles all `/api/auth` request paths: * - `/api/auth/register` * - `/api/auth/login` + * - `/api/auth/google-token` * - `/api/auth/token` */ export const authRouter = express.Router(); @@ -42,7 +40,7 @@ export const authRouter = express.Router(); * A {@link RequestBodyFieldsSchema} that configures sanitzation and * validation for request body parameters used in auth routes. */ -export const LOGIN_REQ_BODY_FIELDS_SCHEMA: RequestBodyFieldsSchema = { +export const LOGIN_REQ_BODY_FIELDS_SCHEMA = { email: { required: true, type: "string", @@ -55,31 +53,27 @@ export const LOGIN_REQ_BODY_FIELDS_SCHEMA: RequestBodyFieldsSchema = { sanitize: sanitizePassword, validate: isValidPassword, }, - googleID: { + googleIDToken: { required: false, type: "string", - sanitize: sanitizeID, - validate: isValidID, + // The Google JWT includes alphanumerics, as well as "-", ".", and "_" chars. + // Note that in the below regex patterns, "-" is escaped so as to not create character ranges. + sanitize: (value) => value.replace(/[^a-zA-Z0-9+/\-._=]/g, ""), + validate: (value) => /^[a-zA-Z0-9+/\-._]+={0,3}$/.test(value), }, - googleAccessToken: { - required: false, - type: "string", - sanitize: sanitizeToken, - validate: isValidToken, - }, -} as const; +} as const satisfies RequestBodyFieldsSchema; /** * A {@link RequestBodyValidatorFn} that asserts that the request body - * contains either a password or a Google OAuth ID and access token. + * contains either a password or Google OAuth2 ID token. */ export const requirePasswordOrGoogleOAuth: RequestBodyValidatorFn = (reqBody) => { - if (!hasKey(reqBody, "password") && !hasKeys(reqBody, ["googleID", "googleAccessToken"])) { + if (!hasKey(reqBody, "password") && !hasKey(reqBody, "googleIDToken")) { throw new Error("Invalid registration credentials"); } }; -authRouter.use( +authRouter.post( "/register", sanitizeAndValidateRequestBody({ requestBodySchema: { @@ -91,7 +85,7 @@ authRouter.use( validate: isValidHandle, }, phone: { - required: true, + required: false, type: "string", sanitize: sanitizePhone, validate: isValidPhone, @@ -99,27 +93,49 @@ authRouter.use( }, validateRequestBody: requirePasswordOrGoogleOAuth, }), + parseGoogleIDToken, // does nothing for local-auth users findUserByEmail, userLoginShouldNotExist, registerNewUser ); -authRouter.use( +authRouter.post( "/login", sanitizeAndValidateRequestBody({ requestBodySchema: LOGIN_REQ_BODY_FIELDS_SCHEMA, validateRequestBody: requirePasswordOrGoogleOAuth, }), + parseGoogleIDToken, // does nothing for local-auth users + findUserByEmail, + userLoginShouldExist, + validateLogin, + queryUserItems, + updateExpoPushToken, + checkSubscriptionStatus, + checkOnboardingStatus +); + +authRouter.post( + "/google-token", + sanitizeAndValidateRequestBody({ + requestBodySchema: { + googleIDToken: { + ...LOGIN_REQ_BODY_FIELDS_SCHEMA.googleIDToken, + required: true, + }, + }, + }), + parseGoogleIDToken, findUserByEmail, userLoginShouldExist, - validatePassword, + validateLogin, queryUserItems, updateExpoPushToken, checkSubscriptionStatus, checkOnboardingStatus ); -authRouter.use( +authRouter.post( "/token", getUserFromAuthHeaderToken, queryUserItems, diff --git a/src/server/env/__mocks__/index.ts b/src/server/env/__mocks__/index.ts index d2ac12ab..555190b8 100644 --- a/src/server/env/__mocks__/index.ts +++ b/src/server/env/__mocks__/index.ts @@ -25,6 +25,8 @@ const { VITE_STRIPE_PUBLISHABLE_KEY: STRIPE_PUBLISHABLE_KEY = "pk_fake_TestTestTest", VITE_STRIPE_SECRET_KEY: STRIPE_SECRET_KEY = "sk_fake_TestTestTest", VITE_STRIPE_WEBHOOKS_SECRET: STRIPE_WEBHOOKS_SECRET = "whsec_TestTestTest", + VITE_GOOGLE_OAUTH_CLIENT_ID: GOOGLE_OAUTH_CLIENT_ID = "TestTestTest.apps.googleusercontent.com", + VITE_GOOGLE_OAUTH_CLIENT_SECRET: GOOGLE_OAUTH_CLIENT_SECRET = "TestTestTest", } = process.env; // eslint-disable-line node/no-process-env export const ENV = createEnvObject({ @@ -46,4 +48,6 @@ export const ENV = createEnvObject({ STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOKS_SECRET, + GOOGLE_OAUTH_CLIENT_ID, + GOOGLE_OAUTH_CLIENT_SECRET, }); diff --git a/src/server/env/helpers.ts b/src/server/env/helpers.ts index f5a33f3d..bd2add59 100644 --- a/src/server/env/helpers.ts +++ b/src/server/env/helpers.ts @@ -23,6 +23,8 @@ export const createEnvObject = ({ STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOKS_SECRET, + GOOGLE_OAUTH_CLIENT_ID, + GOOGLE_OAUTH_CLIENT_SECRET, }: typeof process.env) => { // Ensure necessary env vars have been provided if ( @@ -41,7 +43,9 @@ export const createEnvObject = ({ !STRIPE_API_VERSION || !STRIPE_PUBLISHABLE_KEY || !STRIPE_SECRET_KEY || - !STRIPE_WEBHOOKS_SECRET + !STRIPE_WEBHOOKS_SECRET || + !GOOGLE_OAUTH_CLIENT_ID || + !GOOGLE_OAUTH_CLIENT_SECRET ) { throw new Error("Missing required environment variables."); } @@ -89,5 +93,9 @@ export const createEnvObject = ({ SECRET_KEY: STRIPE_SECRET_KEY, WEBHOOKS_SECRET: STRIPE_WEBHOOKS_SECRET, }, + GOOGLE_OAUTH: { + CLIENT_ID: GOOGLE_OAUTH_CLIENT_ID, + CLIENT_SECRET: GOOGLE_OAUTH_CLIENT_SECRET, + }, } as const; }; diff --git a/src/tests/staticMockItems/users.ts b/src/tests/staticMockItems/users.ts index c64fcdf0..a38d06e2 100644 --- a/src/tests/staticMockItems/users.ts +++ b/src/tests/staticMockItems/users.ts @@ -39,7 +39,6 @@ export const MOCK_USERS = { login: { type: "GOOGLE_OAUTH", googleID: "userB_googleID", - googleAccessToken: "userB_gat", }, profile: { displayName: "Rick Sanchez", diff --git a/src/types/__codegen__/graphql.ts b/src/types/__codegen__/graphql.ts index c752c1ef..8f7cc409 100644 --- a/src/types/__codegen__/graphql.ts +++ b/src/types/__codegen__/graphql.ts @@ -84,7 +84,7 @@ export type Contact = FixitUser & { /** Contact ID internally identifies a user's contact */ id: Scalars['ID']['output']; /** Contact phone number */ - phone: Scalars['String']['output']; + phone?: Maybe; /** Contact Profile object */ profile: Profile; /** Timestamp of the most recent Contact object update */ @@ -138,7 +138,7 @@ export type FixitUser = { /** User ID internally identifies individual User accounts */ id: Scalars['ID']['output']; /** Phone number of either a User or Contact */ - phone: Scalars['String']['output']; + phone?: Maybe; /** Profile object of either a User or Contact */ profile: Profile; updatedAt: Scalars['DateTime']['output']; @@ -441,8 +441,8 @@ export type User = FixitUser & { handle: Scalars['String']['output']; /** (Immutable) User ID internally identifies individual User accounts */ id: Scalars['ID']['output']; - /** (Immutable) User's own phone number */ - phone: Scalars['String']['output']; + /** User's own phone number */ + phone?: Maybe; /** User's own Profile object */ profile: Profile; /** User Stripe Connect Account info */ @@ -744,7 +744,7 @@ export type ContactResolvers; handle?: Resolver; id?: Resolver; - phone?: Resolver; + phone?: Resolver, ParentType, ContextType>; profile?: Resolver; updatedAt?: Resolver; __isTypeOf?: IsTypeOfResolverFn; @@ -770,7 +770,7 @@ export type FixitUserResolvers; handle?: Resolver; id?: Resolver; - phone?: Resolver; + phone?: Resolver, ParentType, ContextType>; profile?: Resolver; updatedAt?: Resolver; }>; @@ -861,7 +861,7 @@ export type UserResolvers, ParentType, ContextType>; handle?: Resolver; id?: Resolver; - phone?: Resolver; + phone?: Resolver, ParentType, ContextType>; profile?: Resolver; stripeConnectAccount?: Resolver, ParentType, ContextType>; stripeCustomerID?: Resolver; diff --git a/src/types/__codegen__/open-api.ts b/src/types/__codegen__/open-api.ts index d2f8c1fd..50645754 100644 --- a/src/types/__codegen__/open-api.ts +++ b/src/types/__codegen__/open-api.ts @@ -89,6 +89,23 @@ export interface paths { patch?: never; trace?: never; }; + "/auth/google-token": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Processes JSON JWT payloads from GoogleID services (existing users only) */ + post: operations["GoogleToken"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/connect/account-link": { parameters: { query?: never; @@ -181,13 +198,19 @@ export interface components { UserRegistrationParams: components["schemas"]["LoginCredentials"] & components["schemas"]["ExpoPushTokenParam"] & { handle: components["schemas"]["handle"]; email: components["schemas"]["email"]; - phone: components["schemas"]["phone"]; + phone?: components["schemas"]["phone"]; profile?: components["schemas"]["UserProfileParams"]; }; LoginParams: components["schemas"]["LoginCredentials"] & components["schemas"]["ExpoPushTokenParam"]; LoginCredentials: components["schemas"]["LoginCredentials.Local"] | components["schemas"]["LoginCredentials.GoogleOAuth"]; LocalLoginCredentials: components["schemas"]["LoginCredentials.Local"]; GoogleOAuthLoginCredentials: components["schemas"]["LoginCredentials.GoogleOAuth"]; + /** @description An object which contains a base64-encoded JSON JWT from GoogleID services + * under the key "googleIDToken". + * */ + GoogleIDTokenField: { + googleIDToken: components["schemas"]["googleIDToken"]; + }; /** @description Parameters for a user's profile. */ UserProfileParams: { /** @description The user's display name. */ @@ -484,8 +507,7 @@ export interface components { }; CreatedAt: components["schemas"]["createdAt"]; Email: components["schemas"]["email"]; - GoogleAccessToken: components["schemas"]["googleAccessToken"]; - GoogleID: components["schemas"]["googleID"]; + GoogleIDToken: components["schemas"]["googleIDToken"]; Handle: components["schemas"]["handle"]; Password: components["schemas"]["password"]; PaymentMethodID: components["schemas"]["paymentMethodID"]; @@ -515,15 +537,12 @@ export interface components { email: components["schemas"]["email"]; password: components["schemas"]["password"]; }; - /** @description The user's OAuth Google ID (auth: google-oauth). */ - googleID: string; - /** @description The user's OAuth Google Access Token (auth: google-oauth). */ - googleAccessToken: string; + /** @description A base64-encoded JSON JWT from GoogleID services (auth: google-oauth). */ + googleIDToken: string; /** @description The user's login credentials for google-oauth authentication */ "LoginCredentials.GoogleOAuth": { email: components["schemas"]["email"]; - googleID: components["schemas"]["googleID"]; - googleAccessToken: components["schemas"]["googleAccessToken"]; + googleIDToken: components["schemas"]["googleIDToken"]; }; /** * Format: date-time @@ -542,7 +561,7 @@ export interface components { * stripped from the phone number upon receipt, so "+1 (555) 555-5555" will be * treated the same as "5555555555". * */ - phone: string; + phone: string | null; /** * Format: uri * @description The URL Stripe should redirect the user to upon exiting the Stripe portal. @@ -744,6 +763,11 @@ export interface components { }; }; }; + GoogleTokenRequest: { + content: { + "application/json": components["schemas"]["GoogleIDTokenField"]; + }; + }; LoginRequest: { content: { "application/json": components["schemas"]["LoginParams"]; @@ -870,6 +894,22 @@ export interface operations { default: components["responses"]["default.UnexpectedResponse"]; }; }; + GoogleToken: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: components["requestBodies"]["GoogleTokenRequest"]; + responses: { + 200: components["responses"]["200.AuthToken"]; + 400: components["responses"]["400.InvalidUserInput"]; + 401: components["responses"]["401.AuthenticationRequired"]; + "5XX": components["responses"]["5xx.InternalServerError"]; + default: components["responses"]["default.UnexpectedResponse"]; + }; + }; ConnectAccountLink: { parameters: { query?: never; diff --git a/src/types/express.ts b/src/types/express.ts index d79e0401..9bfa4446 100644 --- a/src/types/express.ts +++ b/src/types/express.ts @@ -1,3 +1,4 @@ +import type { ParsedGoogleOAuth2IDTokenFields } from "@/lib/googleOAuth2Client"; import type { UserItem } from "@/models/User/User.js"; import type { UserSubscriptionItem } from "@/models/UserSubscription"; import type { FixitApiAuthTokenPayload } from "@/utils/AuthToken.js"; @@ -11,6 +12,8 @@ export type RestApiLocals = { /** An AuthToken payload object from an authenticated request's auth token. */ authenticatedUser?: FixitApiAuthTokenPayload | undefined; + /** Fields provided by a validated Google OAuth2 ID token. */ + googleIDTokenFields?: ParsedGoogleOAuth2IDTokenFields; /** A User object from the database. */ user?: UserItem | undefined; /** A UserSubscription object from the database (e.g., for sub-updating mw). */ diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index fbc422be..feb1f5ee 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -25,6 +25,8 @@ declare global { STRIPE_WEBHOOKS_SECRET?: string; STRIPE_PUBLISHABLE_KEY?: string; STRIPE_SECRET_KEY?: string; + GOOGLE_OAUTH_CLIENT_ID?: string; + GOOGLE_OAUTH_CLIENT_SECRET?: string; } } diff --git a/src/types/helpers.ts b/src/types/helpers.ts new file mode 100644 index 00000000..11624cea --- /dev/null +++ b/src/types/helpers.ts @@ -0,0 +1,37 @@ +/** + * This file contains helpful generic util types used throughout the project that + * achieve behavior that's not offered by type-fest's util types nor TypeScript's + * built-in generics. + */ + +/** Intermediate type used by {@link CombineUnionOfObjects}. */ +type AddMissingFieldsAsPartial< + T extends Record, + K extends PropertyKey = T extends unknown ? keyof T : never, +> = T extends unknown ? T & Partial, undefined>> : never; + +/** + * This generic is similar to type-fest's `UnionToIntersection`, but object properties that + * aren't present in all union members are made optional and unioned with `undefined`. The + * result always includes _every_ field from every union member — even `never` value types. + * + * @example + * ```ts + * type A = { a: "foo"; b: string; c?: string }; + * + * type B = { a: "bar"; b: unknown; c: number; x: "X"; y: never }; + * + * type C = CombineUnionOfObjects; + * /* Type C is equivalent to: + * { + * a: "foo" | "bar"; <-- "foo" | "bar" because both A and B use literals + * b: unknown; <-- More generic types always override more specific types + * c?: string | number; <-- Types of equal specificity are unioned + * x?: "X" | undefined; <-- Only B contains x, so it's optional and unioned with `undefined` + * y?: undefined; <-- The result always includes EVERY key — even `never` value types + * } + * ``` + */ +export type CombineUnionOfObjects> = { + [Key in keyof AddMissingFieldsAsPartial]: AddMissingFieldsAsPartial[Key]; +}; diff --git a/src/types/index.ts b/src/types/index.ts index f46af957..d4aad06a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -4,3 +4,6 @@ export * from "./express.js"; // GraphQL Codegen Types export * from "./graphql.js"; + +// Other Types +export * from "./helpers.js"; diff --git a/src/utils/AuthToken.ts b/src/utils/AuthToken.ts index 6806b506..d99f1db8 100644 --- a/src/utils/AuthToken.ts +++ b/src/utils/AuthToken.ts @@ -23,7 +23,7 @@ export class AuthToken { id: userData.id, handle: userData.handle, email: userData.email, - phone: userData.phone, + phone: userData.phone ?? null, profile: userData.profile, stripeCustomerID: userData.stripeCustomerID, ...(userData.stripeConnectAccount && { @@ -49,7 +49,6 @@ export class AuthToken { } /** - * Returns the encoded auth token string. * @returns The encoded auth token string. */ toString() { diff --git a/src/utils/timestamps.ts b/src/utils/timestamps.ts new file mode 100644 index 00000000..cfb307f1 --- /dev/null +++ b/src/utils/timestamps.ts @@ -0,0 +1,66 @@ +import { isSafeInteger } from "@nerdware/ts-type-safety-utils"; +import dayjs, { type ConfigType as DayJsCtorParamType } from "dayjs"; + +/** + * This type reflects values that can be converted to a valid DayJS timestamp. + * + * The `dayjs` constructor accepts {@link DayJsCtorParamType|multiple arg types}; + * this type excludes `null` and `undefined` from the union of permitted values + * since they'll never result in a valid timestamp. + */ +export type ValidTimestamp = Exclude; + +/** + * `typeof` strings of value-types which should not be provided to the `dayjs` + * constructor in {@link isValidTimestamp}. + */ +const INVALID_TIMESTAMP_VALUE_TYPES = new Set([ + "symbol", // <-- causes `dayjs()` to throw + "bigint", // <-- causes `dayjs()` to throw + "boolean", // <-- causes false positives in `dayjs.isValid` +]); + +/** + * This `dayjs` helper checks if the provided `value` is a valid type which may be converted into + * a timestamp. + * + * @param value - The value to check. + * @param onlyAllow13DigitNumbers - If `true`, only 13-digit numbers are considered valid (see below). + * + * ### Numerical Timestamp Range + * + * If `onlyAllow13DigitNumbers` is `true` (default: `true`), the fn will only consider 13-digit + * numbers to be valid timestamps. This setting ensures unix timestamps — _in SECONDS_ — are not + * accidentally interpreted as milliseconds. If this fn is used to validate timestamps in seconds, + * or if the fn is being used to validate timestamps out of the lower/upper bounds of the 13-digit + * range, set `onlyAllow13DigitNumbers` to `false`. + * + * **13 Digit Timestamp Range:** + * + * - **Lower Bound:** `1000000000000` (Sun Sep 09 2001 01:46:40 GMT+0000) + * - **Upper Bound:** `9999999999999` (Tue Nov 20 2286 17:46:39 GMT+0000) + * + * ### `dayjs.isValid` Notes: + * + * - The fn will only throw when given a `Symbol` or `BigInt`. + * - The fn will return `false` for `null`, `""` (empty string), and invalid objects. + * - The fn will return `true` for `undefined` and `0`, which for this project's purposes are not + * valid timestamps, so the conditional contains a truthy-check to weed out these false positives. + */ +export const isValidTimestamp = ( + value?: unknown, + onlyAllow13DigitNumbers: boolean = true +): value is ValidTimestamp => { + // Check for values types that break the dayjs ctor: + if (!value || INVALID_TIMESTAMP_VALUE_TYPES.has(typeof value)) { + return false; + } + + // If onlyAllow13DigitNumbers is true, check for non-13-digit numbers: + if (isSafeInteger(value) && onlyAllow13DigitNumbers && `${value}`.length !== 13) { + return false; + } + + // `value` is cast to any, bc the previous checks ensure it won't throw + return dayjs(value as any).isValid(); +};