From c6a3f41dc53fd8b8f3eeda045e0588ad1aec7a8d Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Wed, 27 Nov 2024 15:07:29 +0100 Subject: [PATCH 01/24] [DEV-2016] Connect cognito event to active campaign (#1253) * connect add contant to AC * update and delete * Add test and refactor handlers * Refactor get user from cognito * Fix active campaing client * Update packages/active-campaign-client/src/__tests__/helpers/deleteContact.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/__tests__/helpers/updateContact.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/.env.example Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Unify AC integration tests * Merge tests * Add changeset --------- Co-authored-by: t Co-authored-by: tommaso1 Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/stale-wombats-cover.md | 5 + package-lock.json | 1155 ++++++++++++++++- packages/active-campaign-client/.env.example | 2 + packages/active-campaign-client/package.json | 6 +- .../src/__tests__/contact_flow.test.ts | 43 + .../src/__tests__/empty-test.test.ts | 5 - .../src/__tests__/handlers/addContact.test.ts | 39 - .../__tests__/handlers/deleteContact.test.ts | 34 - .../__tests__/handlers/updateContact.test.ts | 39 - .../{handlers => helpers}/createList.test.ts | 2 +- .../{handlers => helpers}/deleteList.test.ts | 2 +- .../listUsersCommandOutputToUser.test.ts | 82 ++ .../activeCampaignClient.ts | 8 +- .../src/clients/cognitoClient.ts | 5 + .../src/handlers/addContact.ts | 52 - .../src/handlers/updateContact.ts | 64 - .../src/helpers/addContact.ts | 46 + .../src/{handlers => helpers}/createList.ts | 2 +- .../{handlers => helpers}/deleteContact.ts | 14 +- .../src/{handlers => helpers}/deleteList.ts | 2 +- .../src/helpers/getUserFromCognito.ts | 19 + .../helpers/listUsersCommandOutputToUser.ts | 21 + .../src/helpers/updateContact.ts | 54 + packages/active-campaign-client/src/index.ts | 38 +- .../src/types/queueEvent.ts | 13 + .../active-campaign-client/src/types/user.ts | 9 + 26 files changed, 1500 insertions(+), 261 deletions(-) create mode 100644 .changeset/stale-wombats-cover.md create mode 100644 packages/active-campaign-client/src/__tests__/contact_flow.test.ts delete mode 100644 packages/active-campaign-client/src/__tests__/empty-test.test.ts delete mode 100644 packages/active-campaign-client/src/__tests__/handlers/addContact.test.ts delete mode 100644 packages/active-campaign-client/src/__tests__/handlers/deleteContact.test.ts delete mode 100644 packages/active-campaign-client/src/__tests__/handlers/updateContact.test.ts rename packages/active-campaign-client/src/__tests__/{handlers => helpers}/createList.test.ts (95%) rename packages/active-campaign-client/src/__tests__/{handlers => helpers}/deleteList.test.ts (93%) create mode 100644 packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts rename packages/active-campaign-client/src/{utils => clients}/activeCampaignClient.ts (93%) create mode 100644 packages/active-campaign-client/src/clients/cognitoClient.ts delete mode 100644 packages/active-campaign-client/src/handlers/addContact.ts delete mode 100644 packages/active-campaign-client/src/handlers/updateContact.ts create mode 100644 packages/active-campaign-client/src/helpers/addContact.ts rename packages/active-campaign-client/src/{handlers => helpers}/createList.ts (94%) rename packages/active-campaign-client/src/{handlers => helpers}/deleteContact.ts (58%) rename packages/active-campaign-client/src/{handlers => helpers}/deleteList.ts (94%) create mode 100644 packages/active-campaign-client/src/helpers/getUserFromCognito.ts create mode 100644 packages/active-campaign-client/src/helpers/listUsersCommandOutputToUser.ts create mode 100644 packages/active-campaign-client/src/helpers/updateContact.ts create mode 100644 packages/active-campaign-client/src/types/queueEvent.ts create mode 100644 packages/active-campaign-client/src/types/user.ts diff --git a/.changeset/stale-wombats-cover.md b/.changeset/stale-wombats-cover.md new file mode 100644 index 0000000000..bd6172cb1b --- /dev/null +++ b/.changeset/stale-wombats-cover.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": minor +--- + +Refactor active campaign pacakge and create index file diff --git a/package-lock.json b/package-lock.json index 5ed9e06ff0..3b410b8de4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1790,6 +1790,1155 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-cognito-identity-provider": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.696.0.tgz", + "integrity": "sha512-hC31OhTlchMkIVExJTLtisay9BgWkHkV1qW/OZhaLiUeiM3FlDi+80ZGaiSg1hoFgOUR5SQL1kEf177/6PWJgg==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.696.0", + "@aws-sdk/client-sts": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "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.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "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.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/client-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", + "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.696.0.tgz", + "integrity": "sha512-ikxQ3mo86d1mAq5zTaQAh8rLBERwL+I4MUYu/IVYW2hhl9J2SDsl0SgnKeXQG6S8zWuHcBO587zsZaRta1MQ/g==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/client-sts": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.696.0.tgz", + "integrity": "sha512-eJOxR8/UyI7kGSRyE751Ea7MKEzllQs7eNveDJy9OP4t/jsN/P19HJ1YHeA1np40JRTUBfqa6WLAAiIXsk8rkg==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/core": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", + "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", + "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", + "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.696.0.tgz", + "integrity": "sha512-9WsZZofjPjNAAZhIh7c7FOhLK8CR3RnGgUm1tdZzV6ZSM1BuS2m6rdwIilRxAh3fxxKDkmW/r/aYmmCYwA+AYA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.696.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.696.0.tgz", + "integrity": "sha512-8F6y5FcfRuMJouC5s207Ko1mcVvOXReBOlJmhIwE4QH1CnO/CliIyepnAZrRQ659mo5wIuquz6gXnpYbitEVMg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.696.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", + "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.696.0.tgz", + "integrity": "sha512-4SSZ9Nk08JSu4/rX1a+dEac/Ims1HCXfV7YLUe5LGdtRLSKRoQQUy+hkFaGYoSugP/p1UfUPl3BuTO9Vv8z1pA==", + "dependencies": { + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/token-providers": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", + "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", + "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/middleware-logger": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", + "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", + "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", + "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", + "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/token-providers": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.696.0.tgz", + "integrity": "sha512-fvTcMADrkwRdNwVmJXi2pSPf1iizmUqczrR1KusH4XehI/KybS4U6ViskRT0v07vpxwL7x+iaD/8fR0PUu5L/g==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/types": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", + "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/util-endpoints": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", + "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "@smithy/util-endpoints": "^2.1.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", + "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", + "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/abort-controller": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/config-resolver": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", + "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/core": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz", + "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==", + "dependencies": { + "@smithy/middleware-serde": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-stream": "^3.3.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/credential-provider-imds": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", + "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/hash-node": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", + "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", + "dependencies": { + "@smithy/types": "^3.7.1", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/invalid-dependency": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", + "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/middleware-content-length": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", + "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/middleware-endpoint": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz", + "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==", + "dependencies": { + "@smithy/core": "^2.5.3", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/middleware-retry": { + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz", + "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.7", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/middleware-serde": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", + "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/middleware-stack": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", + "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/node-config-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", + "dependencies": { + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/node-http-handler": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", + "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", + "dependencies": { + "@smithy/abort-controller": "^3.1.8", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/property-provider": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/protocol-http": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", + "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/querystring-builder": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", + "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/querystring-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", + "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/service-error-classification": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", + "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", + "dependencies": { + "@smithy/types": "^3.7.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/signature-v4": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", + "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/smithy-client": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz", + "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==", + "dependencies": { + "@smithy/core": "^2.5.3", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/types": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/url-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", + "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", + "dependencies": { + "@smithy/querystring-parser": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-defaults-mode-browser": { + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz", + "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==", + "dependencies": { + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz", + "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==", + "dependencies": { + "@smithy/config-resolver": "^3.0.12", + "@smithy/credential-provider-imds": "^3.2.7", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-endpoints": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", + "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-middleware": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-retry": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", + "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", + "dependencies": { + "@smithy/service-error-classification": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-stream": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", + "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", + "dependencies": { + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@aws-sdk/client-cognito-identity/node_modules/@aws-crypto/ie11-detection": { "version": "3.0.0", "license": "Apache-2.0", @@ -32774,7 +33923,9 @@ "version": "1.0.0" }, "node_modules/fast-xml-parser": { - "version": "4.3.2", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "funding": [ { "type": "github", @@ -32785,7 +33936,6 @@ "url": "https://paypal.me/naturalintelligence" } ], - "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -51792,6 +52942,7 @@ "packages/active-campaign-client": { "version": "0.1.1", "dependencies": { + "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@types/aws-lambda": "^8.10.126", "@types/jest": "^29.5.1", "aws-lambda": "^1.0.7", diff --git a/packages/active-campaign-client/.env.example b/packages/active-campaign-client/.env.example index aabb8523e9..eca72b4959 100644 --- a/packages/active-campaign-client/.env.example +++ b/packages/active-campaign-client/.env.example @@ -1,3 +1,5 @@ AC_BASE_URL=your_account_url AC_API_KEY=your_api_key SENDER_URL=localhost:3000 +AWS_REGION="region" +AWS_USER_POOL_ID="region_DFWF81fRa" diff --git a/packages/active-campaign-client/package.json b/packages/active-campaign-client/package.json index ef972019b7..385348bc3f 100644 --- a/packages/active-campaign-client/package.json +++ b/packages/active-campaign-client/package.json @@ -4,13 +4,15 @@ "description": "Implements ActiveCampaign API to add, update and delete Accounts and to add and update lists", "scripts": { "lint": "eslint src", - "test": "jest" + "test": "jest", + "build": "tsc" }, "devDependencies": { + "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "^8.57.1", - "eslint": "^8.57.1", "dotenv": "16.4.5", + "eslint": "^8.57.1", "eslint-config-custom": "^0.1.0" }, "dependencies": { diff --git a/packages/active-campaign-client/src/__tests__/contact_flow.test.ts b/packages/active-campaign-client/src/__tests__/contact_flow.test.ts new file mode 100644 index 0000000000..b830db1d57 --- /dev/null +++ b/packages/active-campaign-client/src/__tests__/contact_flow.test.ts @@ -0,0 +1,43 @@ +import { addContact } from '../helpers/addContact'; +import { deleteContact } from '../helpers/deleteContact'; +import { updateContact } from '../helpers/updateContact'; +import { User } from '../types/user'; + +const user: User = { + username: '466e0280-9061-7007-c3e0-beb6be672f68', + email: `test@example${new Date().getTime()}e.com`, + given_name: 'Giovanni', + family_name: 'Doe', + 'custom:mailinglist_accepted': 'true', + 'custom:company_type': 'Test Co', + 'custom:job_role': 'Developer', +}; + +// remove .skip to run the test, be aware it does a real API call so it will create, update and delete a contact in the active campaign account +// NB: this test is not idempotent and it must run in this order +describe.skip('Active campaign integration contact flow', () => { + it('should create a contact successfully', async () => { + const response = await addContact(user); + expect(response.statusCode).toBe(200); + }); + + it('should update a contact successfully', async () => { + const updatedUser: User = { + ...user, + email: `test@example${new Date().getTime()}e.com`, + given_name: 'new given_name', + family_name: 'new family_name', + 'custom:mailinglist_accepted': 'true', + 'custom:company_type': 'new company_type', + 'custom:job_role': 'new job_role', + }; + + const response = await updateContact(updatedUser); + expect(response.statusCode).toBe(200); + }); + + it('should delete a contact successfully', async () => { + const response = await deleteContact(user.username); + expect(response.statusCode).toBe(200); + }); +}); diff --git a/packages/active-campaign-client/src/__tests__/empty-test.test.ts b/packages/active-campaign-client/src/__tests__/empty-test.test.ts deleted file mode 100644 index ec129970f5..0000000000 --- a/packages/active-campaign-client/src/__tests__/empty-test.test.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('nothing', () => { - it('should not fail tests without tests but it does', async () => { - expect(1).toBe(1); - }); -}); diff --git a/packages/active-campaign-client/src/__tests__/handlers/addContact.test.ts b/packages/active-campaign-client/src/__tests__/handlers/addContact.test.ts deleted file mode 100644 index f912c7cc39..0000000000 --- a/packages/active-campaign-client/src/__tests__/handlers/addContact.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { addContact } from '../../handlers/addContact'; -import { SQSEvent } from 'aws-lambda'; - -// remove .skip to run the test, be aware it does a real API call so it will create a contact in the active campaign account -describe.skip('addContact handler', () => { - it('should create a contact successfully', async () => { - const event: SQSEvent = { - Records: [ - { - messageId: '1', - receiptHandle: '1', - body: JSON.stringify({ - username: `test@example${new Date().getTime()}e.com`, - firstName: 'Giovanni', - cognitoId: '466e0280-9061-7007-c3e0-beb6be672f68', - lastName: 'Doe', - company: 'Test Co', - role: 'Developer', - mailinglistAccepted: true, - }), - attributes: { - ApproximateReceiveCount: '1', - SentTimestamp: '1', - SenderId: '1', - ApproximateFirstReceiveTimestamp: '1', - }, - messageAttributes: {}, - md5OfBody: '1', - eventSource: 'aws:sqs', - eventSourceARN: 'arn:aws:sqs:region:account-id:queue-name', - awsRegion: 'region', - }, - ], - }; - - const response = await addContact(event); - expect(response.statusCode).toBe(200); - }); -}); diff --git a/packages/active-campaign-client/src/__tests__/handlers/deleteContact.test.ts b/packages/active-campaign-client/src/__tests__/handlers/deleteContact.test.ts deleted file mode 100644 index f6b809496b..0000000000 --- a/packages/active-campaign-client/src/__tests__/handlers/deleteContact.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { deleteContact } from '../../handlers/deleteContact'; -import { SQSEvent } from 'aws-lambda'; - -// remove .skip to run the test, be aware it does a real API call so it will create a contact in the active campaign account -describe.skip('deleteContact handler', () => { - it('should delete a contact successfully', async () => { - const event: SQSEvent = { - Records: [ - { - messageId: '1', - receiptHandle: '1', - body: JSON.stringify({ - // Replace this with the existing email of the contact you want to delete, otherwise the test will fail - cognitoId: `466e0280-9061-7007-c3e0-beb6be672f68`, - }), - attributes: { - ApproximateReceiveCount: '1', - SentTimestamp: '1', - SenderId: '1', - ApproximateFirstReceiveTimestamp: '1', - }, - messageAttributes: {}, - md5OfBody: '1', - eventSource: 'aws:sqs', - eventSourceARN: 'arn:aws:sqs:region:account-id:queue-name', - awsRegion: 'region', - }, - ], - }; - - const response = await deleteContact(event); - expect(response.statusCode).toBe(200); - }); -}); diff --git a/packages/active-campaign-client/src/__tests__/handlers/updateContact.test.ts b/packages/active-campaign-client/src/__tests__/handlers/updateContact.test.ts deleted file mode 100644 index 521c774cf9..0000000000 --- a/packages/active-campaign-client/src/__tests__/handlers/updateContact.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { updateContact } from '../../handlers/updateContact'; -import { SQSEvent } from 'aws-lambda'; - -// remove .skip to run the test, be aware it does a real API call so it will create a contact in the active campaign account -describe.skip('updateContact handler', () => { - it('should update a contact successfully', async () => { - const event: SQSEvent = { - Records: [ - { - messageId: '1', - receiptHandle: '1', - body: JSON.stringify({ - username: `test@example1731961399739e.com`, - firstName: 'Alberto', - lastName: 'Doe', - company: 'Test Co', - role: 'Developer', - mailinglistAccepted: true, - cognitoId: '466e0280-9061-7007-c3e0-beb6be672f68', - }), - attributes: { - ApproximateReceiveCount: '1', - SentTimestamp: '1', - SenderId: '1', - ApproximateFirstReceiveTimestamp: '1', - }, - messageAttributes: {}, - md5OfBody: '1', - eventSource: 'aws:sqs', - eventSourceARN: 'arn:aws:sqs:region:account-id:queue-name', - awsRegion: 'region', - }, - ], - }; - - const response = await updateContact(event); - expect(response.statusCode).toBe(200); - }); -}); diff --git a/packages/active-campaign-client/src/__tests__/handlers/createList.test.ts b/packages/active-campaign-client/src/__tests__/helpers/createList.test.ts similarity index 95% rename from packages/active-campaign-client/src/__tests__/handlers/createList.test.ts rename to packages/active-campaign-client/src/__tests__/helpers/createList.test.ts index 1c8d722ace..c4d3e1b1b0 100644 --- a/packages/active-campaign-client/src/__tests__/handlers/createList.test.ts +++ b/packages/active-campaign-client/src/__tests__/helpers/createList.test.ts @@ -1,4 +1,4 @@ -import { createList } from '../../handlers/createList'; +import { createList } from '../../helpers/createList'; import { SQSEvent } from 'aws-lambda'; describe.skip('createList handler', () => { diff --git a/packages/active-campaign-client/src/__tests__/handlers/deleteList.test.ts b/packages/active-campaign-client/src/__tests__/helpers/deleteList.test.ts similarity index 93% rename from packages/active-campaign-client/src/__tests__/handlers/deleteList.test.ts rename to packages/active-campaign-client/src/__tests__/helpers/deleteList.test.ts index 90ffd8ce87..78e4a5f702 100644 --- a/packages/active-campaign-client/src/__tests__/handlers/deleteList.test.ts +++ b/packages/active-campaign-client/src/__tests__/helpers/deleteList.test.ts @@ -1,4 +1,4 @@ -import { deleteList } from '../../handlers/deleteList'; +import { deleteList } from '../../helpers/deleteList'; import { SQSEvent } from 'aws-lambda'; describe.skip('deleteList handler', () => { diff --git a/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts b/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts new file mode 100644 index 0000000000..a2ab058139 --- /dev/null +++ b/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts @@ -0,0 +1,82 @@ +import { ListUsersCommandOutput } from '@aws-sdk/client-cognito-identity-provider'; +import { listUsersCommandOutputToUser } from '../../helpers/listUsersCommandOutputToUser'; +import { User } from '../../types/user'; + +const listUsersCommandOutput: ListUsersCommandOutput = { + $metadata: { + httpStatusCode: 200, + requestId: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + attempts: 1, + totalRetryDelay: 0, + }, + Users: [ + { + Attributes: [ + { + Name: 'email', + Value: 'test@mail.com', + }, + { + Name: 'email_verified', + Value: 'true', + }, + { + Name: 'family_name', + Value: 'Doe', + }, + { + Name: 'given_name', + Value: 'Giovanni', + }, + { + Name: 'custom:mailinglist_accepted', + Value: 'true', + }, + { + Name: 'custom:user_preferences', + Value: + '{"subscribedWebinarSlugs":["comunicazioni-a-valore-legale","nuove-api-io","live","cooming-soon","test","always-live","PagoPA-multe"]}', + }, + { + Name: 'custom:company_type', + Value: 'gestore-di-pubblico-servizio', + }, + { + Name: 'custom:job_role', + Value: 'Developer', + }, + { + Name: 'custom:privacy_accepted', + Value: 'true', + }, + { + Name: 'sub', + Value: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + }, + ], + Enabled: true, + UserStatus: 'CONFIRMED', + Username: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + }, + ], +}; + +describe('addContact handler', () => { + it('should properly convert ListUsersCommandOutput to User', async () => { + const user = listUsersCommandOutputToUser(listUsersCommandOutput); + const expectedUser: User = { + username: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + email: 'test@mail.com', + given_name: 'Giovanni', + family_name: 'Doe', + 'custom:mailinglist_accepted': 'true', + 'custom:company_type': 'gestore-di-pubblico-servizio', + 'custom:job_role': 'Developer', + }; + expect(user).toBeDefined(); + Object.keys(expectedUser).forEach((value) => { + const key = value as keyof User; + expect(user![key]).toBe(expectedUser[key]); + }); + }); +}); diff --git a/packages/active-campaign-client/src/utils/activeCampaignClient.ts b/packages/active-campaign-client/src/clients/activeCampaignClient.ts similarity index 93% rename from packages/active-campaign-client/src/utils/activeCampaignClient.ts rename to packages/active-campaign-client/src/clients/activeCampaignClient.ts index 53cd3ccaa5..ed3beb1301 100644 --- a/packages/active-campaign-client/src/utils/activeCampaignClient.ts +++ b/packages/active-campaign-client/src/clients/activeCampaignClient.ts @@ -22,7 +22,7 @@ export class ActiveCampaignClient { private async makeRequest( method: string, path: string, - data?: any, + data?: ContactPayload | ListPayload, params?: Record ): Promise { return new Promise((resolve, reject) => { @@ -114,8 +114,6 @@ export class ActiveCampaignClient { } export const acClient = new ActiveCampaignClient( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - process.env.AC_BASE_URL!, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - process.env.AC_API_KEY! + process.env.AC_BASE_URL || '', + process.env.AC_API_KEY || '' ); diff --git a/packages/active-campaign-client/src/clients/cognitoClient.ts b/packages/active-campaign-client/src/clients/cognitoClient.ts new file mode 100644 index 0000000000..9d9a2ccadf --- /dev/null +++ b/packages/active-campaign-client/src/clients/cognitoClient.ts @@ -0,0 +1,5 @@ +import { CognitoIdentityProviderClient } from '@aws-sdk/client-cognito-identity-provider'; + +export const cognitoClient = new CognitoIdentityProviderClient({ + region: process.env.AWS_REGION, +}); diff --git a/packages/active-campaign-client/src/handlers/addContact.ts b/packages/active-campaign-client/src/handlers/addContact.ts deleted file mode 100644 index e6bdadb7ca..0000000000 --- a/packages/active-campaign-client/src/handlers/addContact.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { acClient } from '../utils/activeCampaignClient'; -import { SignUpUserData } from 'nextjs-website/src/lib/types/sign-up'; -import { ContactPayload } from '../types/contactPayload'; - -export async function addContact(event: { - readonly Records: SQSEvent['Records']; -}): Promise { - try { - const firstMessage = event.Records[0] ?? { body: '{}' }; - // Parse request body - const userData: SignUpUserData & { readonly cognitoId: string } = - JSON.parse(firstMessage.body); - - // Transform to AC payload - const acPayload: ContactPayload = { - contact: { - email: userData.username, - firstName: userData.firstName, - lastName: userData.lastName, - phone: `cognito:${userData.cognitoId}`, - fieldValues: [ - { - field: '2', - value: userData.company, - }, - { - field: '1', - value: userData.role, - }, - { - field: '3', - value: userData.mailinglistAccepted ? 'TRUE' : 'FALSE', - }, - ], - }, - }; - - const response = await acClient.createContact(acPayload); - - return { - statusCode: 200, - body: JSON.stringify(response), - }; - } catch (error) { - console.error('Error:', error); - return { - statusCode: 500, - body: JSON.stringify({ message: 'Internal server error' }), - }; - } -} diff --git a/packages/active-campaign-client/src/handlers/updateContact.ts b/packages/active-campaign-client/src/handlers/updateContact.ts deleted file mode 100644 index dff29e4bd5..0000000000 --- a/packages/active-campaign-client/src/handlers/updateContact.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { acClient } from '../utils/activeCampaignClient'; -import { ContactPayload } from '../types/contactPayload'; - -export async function updateContact(event: { - readonly Records: SQSEvent['Records']; -}): Promise { - try { - const firstMessage = event.Records[0] ?? { body: '{}' }; - // Parse request body - const userData = JSON.parse(firstMessage.body); - - if (!userData.username) { - return { - statusCode: 400, - body: JSON.stringify({ message: 'Missing email' }), - }; - } - - const contactId = await acClient.getContactByCognitoId(userData.cognitoId); - - if (!contactId) { - return { - statusCode: 404, - body: JSON.stringify({ message: 'Contact not found' }), - }; - } - - const acPayload: ContactPayload = { - contact: { - email: userData.username, - firstName: userData.firstName, - lastName: userData.lastName, - fieldValues: [ - { - field: '2', - value: userData.company, - }, - { - field: '1', - value: userData.role, - }, - { - field: '3', - value: userData.mailinglistAccepted ? 'TRUE' : 'FALSE', - }, - ], - }, - }; - - const response = await acClient.updateContact(contactId, acPayload); - - return { - statusCode: 200, - body: JSON.stringify(response), - }; - } catch (error) { - console.error('Error:', error); - return { - statusCode: 500, - body: JSON.stringify({ message: 'Internal server error' }), - }; - } -} diff --git a/packages/active-campaign-client/src/helpers/addContact.ts b/packages/active-campaign-client/src/helpers/addContact.ts new file mode 100644 index 0000000000..1b5c843d9d --- /dev/null +++ b/packages/active-campaign-client/src/helpers/addContact.ts @@ -0,0 +1,46 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; +import { acClient } from '../clients/activeCampaignClient'; +import { ContactPayload } from '../types/contactPayload'; +import { User } from '../types/user'; + +export async function addContact(user: User): Promise { + try { + // Transform to AC payload + const acPayload: ContactPayload = { + contact: { + email: user.email, + firstName: user.given_name, + lastName: user.family_name, + phone: `cognito:${user.username}`, + fieldValues: [ + { + field: '2', + value: user['custom:company_type'], + }, + { + field: '1', + value: user['custom:job_role'], + }, + { + field: '3', + value: + user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', + }, + ], + }, + }; + + const response = await acClient.createContact(acPayload); + + return { + statusCode: 200, + body: JSON.stringify(response), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/handlers/createList.ts b/packages/active-campaign-client/src/helpers/createList.ts similarity index 94% rename from packages/active-campaign-client/src/handlers/createList.ts rename to packages/active-campaign-client/src/helpers/createList.ts index db5996dc5a..d614f1bd12 100644 --- a/packages/active-campaign-client/src/handlers/createList.ts +++ b/packages/active-campaign-client/src/helpers/createList.ts @@ -1,5 +1,5 @@ import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { acClient } from '../utils/activeCampaignClient'; +import { acClient } from '../clients/activeCampaignClient'; import { ListPayload } from '../types/listPayload'; import { WebinarPayload } from '../types/webinarPayload'; diff --git a/packages/active-campaign-client/src/handlers/deleteContact.ts b/packages/active-campaign-client/src/helpers/deleteContact.ts similarity index 58% rename from packages/active-campaign-client/src/handlers/deleteContact.ts rename to packages/active-campaign-client/src/helpers/deleteContact.ts index 1d72f6d691..085c6bc1a8 100644 --- a/packages/active-campaign-client/src/handlers/deleteContact.ts +++ b/packages/active-campaign-client/src/helpers/deleteContact.ts @@ -1,14 +1,10 @@ -import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { acClient } from '../utils/activeCampaignClient'; +import { APIGatewayProxyResult } from 'aws-lambda'; +import { acClient } from '../clients/activeCampaignClient'; -export async function deleteContact(event: { - readonly Records: SQSEvent['Records']; -}): Promise { +export async function deleteContact( + cognitoId: string +): Promise { try { - const firstMessage = event.Records[0] ?? { body: '{}' }; - // Parse request body - const { cognitoId } = JSON.parse(firstMessage.body); - const contactId = await acClient.getContactByCognitoId(cognitoId); if (!contactId) { diff --git a/packages/active-campaign-client/src/handlers/deleteList.ts b/packages/active-campaign-client/src/helpers/deleteList.ts similarity index 94% rename from packages/active-campaign-client/src/handlers/deleteList.ts rename to packages/active-campaign-client/src/helpers/deleteList.ts index 22ea9ac9c5..1d19d32689 100644 --- a/packages/active-campaign-client/src/handlers/deleteList.ts +++ b/packages/active-campaign-client/src/helpers/deleteList.ts @@ -1,5 +1,5 @@ import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { acClient } from '../utils/activeCampaignClient'; +import { acClient } from '../clients/activeCampaignClient'; export async function deleteList(event: { readonly Records: SQSEvent['Records']; diff --git a/packages/active-campaign-client/src/helpers/getUserFromCognito.ts b/packages/active-campaign-client/src/helpers/getUserFromCognito.ts new file mode 100644 index 0000000000..41d02e7c7b --- /dev/null +++ b/packages/active-campaign-client/src/helpers/getUserFromCognito.ts @@ -0,0 +1,19 @@ +import { ListUsersCommand } from '@aws-sdk/client-cognito-identity-provider'; +import { cognitoClient } from '../clients/cognitoClient'; +import { QueueEvent } from '../types/queueEvent'; +import { listUsersCommandOutputToUser } from './listUsersCommandOutputToUser'; + +export async function getUserFromCognito(queueEvent: QueueEvent) { + const command = new ListUsersCommand({ + UserPoolId: process.env.COGNITO_USER_POOL_ID, + Filter: `username = "${queueEvent.detail.additionalEventData.sub}"`, + }); + const listUsersCommandOutput = await cognitoClient.send(command); + const user = listUsersCommandOutputToUser(listUsersCommandOutput); + if (!user) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('User not found'); + } + console.log('User:', JSON.stringify(user, null, 2)); // TODO: Remove after testing + return user; +} diff --git a/packages/active-campaign-client/src/helpers/listUsersCommandOutputToUser.ts b/packages/active-campaign-client/src/helpers/listUsersCommandOutputToUser.ts new file mode 100644 index 0000000000..773149c355 --- /dev/null +++ b/packages/active-campaign-client/src/helpers/listUsersCommandOutputToUser.ts @@ -0,0 +1,21 @@ +import { ListUsersCommandOutput } from '@aws-sdk/client-cognito-identity-provider'; +import { User } from '../types/user'; + +export function listUsersCommandOutputToUser( + listUsersCommandOutput: ListUsersCommandOutput +) { + const userData = listUsersCommandOutput.Users?.[0]; + if (!userData) { + return undefined; + } + return { + username: userData.Username, + ...userData.Attributes?.reduce((acc, attr) => { + if (!attr.Name || !attr.Value) { + return acc; + } + acc[attr.Name] = attr.Value || ''; + return acc; + }, {} as Record), + } as User; +} diff --git a/packages/active-campaign-client/src/helpers/updateContact.ts b/packages/active-campaign-client/src/helpers/updateContact.ts new file mode 100644 index 0000000000..469b7b138d --- /dev/null +++ b/packages/active-campaign-client/src/helpers/updateContact.ts @@ -0,0 +1,54 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; +import { acClient } from '../clients/activeCampaignClient'; +import { ContactPayload } from '../types/contactPayload'; +import { User } from '../types/user'; + +export async function updateContact( + user: User +): Promise { + try { + const acPayload: ContactPayload = { + contact: { + email: user.email, + firstName: user.given_name, + lastName: user.family_name, + phone: `cognito:${user.username}`, + fieldValues: [ + { + field: '2', + value: user['custom:company_type'], + }, + { + field: '1', + value: user['custom:job_role'], + }, + { + field: '3', + value: + user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', + }, + ], + }, + }; + const contactId = await acClient.getContactByCognitoId(user.username); + if (!contactId) { + return { + statusCode: 404, + body: JSON.stringify({ message: 'Contact not found' }), + }; + } + + const response = await acClient.updateContact(contactId, acPayload); + + return { + statusCode: 200, + body: JSON.stringify(response), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/index.ts b/packages/active-campaign-client/src/index.ts index 87b5a2fdae..a3d2e6fa5e 100644 --- a/packages/active-campaign-client/src/index.ts +++ b/packages/active-campaign-client/src/index.ts @@ -1,12 +1,38 @@ import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { addContact } from './handlers/addContact'; +import { getUserFromCognito } from './helpers/getUserFromCognito'; +import { QueueEvent } from './types/queueEvent'; +import { addContact } from './helpers/addContact'; +import { updateContact } from './helpers/updateContact'; +import { deleteContact } from './helpers/deleteContact'; export async function handler(event: { readonly Records: SQSEvent['Records']; }): Promise { - console.log('Event:', event); - return { - statusCode: 200, - body: JSON.stringify(event), - }; + try { + console.log('Event:', event); // TODO: Remove after testing + const queueEvent = JSON.parse( + event.Records[0].body + ) as unknown as QueueEvent; + switch (queueEvent.detail.eventName) { + case 'ConfirmSignUp': + return await addContact(await getUserFromCognito(queueEvent)); + case 'UpdateUserAttributes': + return await updateContact(await getUserFromCognito(queueEvent)); + case 'DeleteUser': + return await deleteContact(queueEvent.detail.additionalEventData.sub); + default: + console.log('Unknown event:', queueEvent.detail.eventName); + break; + } + return { + statusCode: 200, + body: JSON.stringify(event), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } } diff --git a/packages/active-campaign-client/src/types/queueEvent.ts b/packages/active-campaign-client/src/types/queueEvent.ts new file mode 100644 index 0000000000..aee4519189 --- /dev/null +++ b/packages/active-campaign-client/src/types/queueEvent.ts @@ -0,0 +1,13 @@ +export type QueueEventType = + | 'UpdateUserAttributes' + | 'DeleteUser' + | 'ConfirmSignUp'; + +export type QueueEvent = { + readonly detail: { + readonly eventName: QueueEventType; + readonly additionalEventData: { + readonly sub: string; + }; + }; +}; diff --git a/packages/active-campaign-client/src/types/user.ts b/packages/active-campaign-client/src/types/user.ts new file mode 100644 index 0000000000..b293734dec --- /dev/null +++ b/packages/active-campaign-client/src/types/user.ts @@ -0,0 +1,9 @@ +export type User = { + readonly username: string; + readonly email: string; + readonly given_name: string; + readonly family_name: string; + readonly 'custom:mailinglist_accepted': string; + readonly 'custom:company_type': string; + readonly 'custom:job_role': string; +}; From e1f67d6def98d4b8470185d88c76e6227c5767b3 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Fri, 29 Nov 2024 13:58:02 +0100 Subject: [PATCH 02/24] [DEV-2044][DEV-2041][DEV-2028] Setup active campaign syncer infra (#1258) * feat: started implementation * feat: active campaign sync infrastructure * chore: added changeset * feat: add active campaign base url ssm parameter * feat: deploy ac sync lambda workflow implemented --- .changeset/silly-geese-shop.md | 5 + .github/workflows/deploy_ac_sync_lambda.yaml | 75 +++++++++++++++ .gitignore | 3 + apps/infrastructure/src/main.tf | 10 ++ .../src/modules/active_campaign/data.tf | 1 + .../modules/active_campaign/eventbridge.tf | 67 +++++++++++++ .../active_campaign/functions/index.js | 4 + .../src/modules/active_campaign/iam.tf | 95 +++++++++++++++++++ .../src/modules/active_campaign/lambda.tf | 63 ++++++++++++ .../src/modules/active_campaign/locals.tf | 5 + .../src/modules/active_campaign/sqs.tf | 63 ++++++++++++ .../src/modules/active_campaign/variables.tf | 45 +++++++++ .../src/modules/website/dynamodb.tf | 3 + .../src/modules/website/outputs.tf | 4 + 14 files changed, 443 insertions(+) create mode 100644 .changeset/silly-geese-shop.md create mode 100644 .github/workflows/deploy_ac_sync_lambda.yaml create mode 100644 apps/infrastructure/src/modules/active_campaign/data.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/eventbridge.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/functions/index.js create mode 100644 apps/infrastructure/src/modules/active_campaign/iam.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/lambda.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/locals.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/sqs.tf create mode 100644 apps/infrastructure/src/modules/active_campaign/variables.tf diff --git a/.changeset/silly-geese-shop.md b/.changeset/silly-geese-shop.md new file mode 100644 index 0000000000..a257302d65 --- /dev/null +++ b/.changeset/silly-geese-shop.md @@ -0,0 +1,5 @@ +--- +"infrastructure": minor +--- + +Implemented active campaign syncer infrastructure diff --git a/.github/workflows/deploy_ac_sync_lambda.yaml b/.github/workflows/deploy_ac_sync_lambda.yaml new file mode 100644 index 0000000000..9c1c3fa779 --- /dev/null +++ b/.github/workflows/deploy_ac_sync_lambda.yaml @@ -0,0 +1,75 @@ +name: Deploy Lambda Active Campaign Syncer + +on: + push: + branches: + - "main" + paths: + - "packages/active-campaign-client/**" + - ".github/workflows/deploy_ac_sync_lambda.yaml" + workflow_dispatch: + inputs: + environment: + description: 'Choose environment' + type: choice + required: true + default: dev + options: + - dev + - prod + +jobs: + build: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: '20.x' + + - name: Build + working-directory: packages/active-campaign-client + run: npm run build + + - name: Package + working-directory: packages/active-campaign-client/dist + run: zip -r function.zip . + + - name: Archive build artifacts + uses: actions/upload-artifact@v3 + with: + name: active-campaign-client + path: packages/active-campaign-client/dist/function.zip + + deploy: + name: Deploy Lambda Active Campaign Syncer + runs-on: ubuntu-22.04 + needs: build + + environment: ${{ github.event.inputs.environment || 'dev' }} + permissions: + id-token: write + contents: read + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v3 + with: + name: active-campaign-client + path: ./packages/active-campaign-client/target + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: ${{ secrets.DEPLOY_IAM_ROLE }} + aws-region: eu-south-1 + + - name: Deploy Lambda function (${{ github.event.inputs.environment || 'dev' }}) + run: | + aws lambda update-function-code \ + --function-name ac-${{ github.event.inputs.environment || 'dev' }}-sync-lambda \ + --zip-file fileb://packages/active-campaign-client/target/function.zip \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5a11476e5f..398b8ada23 100644 --- a/.gitignore +++ b/.gitignore @@ -409,5 +409,8 @@ apps/chatbot/empty_htmls.json /results +# terraform +apps/infrastructure/src/builds + ## Python ## __pycache__/ diff --git a/apps/infrastructure/src/main.tf b/apps/infrastructure/src/main.tf index f14227059b..b1534ee827 100644 --- a/apps/infrastructure/src/main.tf +++ b/apps/infrastructure/src/main.tf @@ -145,3 +145,13 @@ module "cicd" { website_bucket = module.website.website_bucket website_cdn = module.website.website_cdn } + +module "active_campaign" { + source = "./modules/active_campaign" + + environment = var.environment + tags = var.tags + + cognito_user_pool = module.website.cognito_user_pool + webinar_subscriptions_ddb_stream_arn = module.website.webinar_subscriptions_ddb_stream_arn +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/active_campaign/data.tf b/apps/infrastructure/src/modules/active_campaign/data.tf new file mode 100644 index 0000000000..8fc4b38cc5 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/data.tf @@ -0,0 +1 @@ +data "aws_caller_identity" "current" {} diff --git a/apps/infrastructure/src/modules/active_campaign/eventbridge.tf b/apps/infrastructure/src/modules/active_campaign/eventbridge.tf new file mode 100644 index 0000000000..c584d96e38 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/eventbridge.tf @@ -0,0 +1,67 @@ +# EventBridge Pipe for DynamoDB Stream -> SQS FIFO +resource "aws_pipes_pipe" "dynamodb_to_sqs" { + name = "${local.prefix}-webinar-subscriptions-pipe" + source = var.webinar_subscriptions_ddb_stream_arn + target = aws_sqs_queue.fifo_queue.arn + role_arn = aws_iam_role.pipes_role.arn + + log_configuration { + include_execution_data = ["ALL"] + level = "ERROR" + cloudwatch_logs_log_destination { + log_group_arn = aws_cloudwatch_log_group.pipe.arn + } + } + + source_parameters { + dynamodb_stream_parameters { + batch_size = 1 + starting_position = "LATEST" + } + } + + target_parameters { + input_template = <", + "additionalEventData": { + "sub": "<$.dynamodb.Keys.username.S>" + } + }, + "webinarId": "<$.dynamodb.Keys.webinarId.S>" +} +EOF + sqs_queue_parameters { + message_group_id = local.sqs_message_group_id + } + } +} + +resource "aws_cloudwatch_log_group" "pipe" { + name = "${local.prefix}-webinar-subscriptions-pipe" + retention_in_days = 30 +} + +# EventBridge Rule to Capture Cognito Events +resource "aws_cloudwatch_event_rule" "cognito_events" { + name = "${local.prefix}-cognito-events-rule" + event_pattern = jsonencode({ + source = ["aws.cognito-idp"] + detail-type = ["AWS API Call via CloudTrail"], + detail = { + eventSource = ["cognito-idp.amazonaws.com"], + eventName = ["UpdateUserAttributes", "DeleteUser", "ConfirmSignUp"] + } + }) +} + +resource "aws_cloudwatch_event_target" "cognito_events_sqs" { + target_id = aws_sqs_queue.fifo_queue.name + rule = aws_cloudwatch_event_rule.cognito_events.name + arn = aws_sqs_queue.fifo_queue.arn + + sqs_target { + message_group_id = local.sqs_message_group_id + } +} diff --git a/apps/infrastructure/src/modules/active_campaign/functions/index.js b/apps/infrastructure/src/modules/active_campaign/functions/index.js new file mode 100644 index 0000000000..73796e9a95 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/functions/index.js @@ -0,0 +1,4 @@ +module.exports.handler = async (event, context) => { + console.log("EVENT: \n" + JSON.stringify(event, null, 2)); + return context.logStreamName; +}; diff --git a/apps/infrastructure/src/modules/active_campaign/iam.tf b/apps/infrastructure/src/modules/active_campaign/iam.tf new file mode 100644 index 0000000000..6dc67e8858 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/iam.tf @@ -0,0 +1,95 @@ +resource "aws_iam_role" "pipes_role" { + name = "${local.prefix}-webinar-subscriptions-pipe-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "pipes.amazonaws.com" + } + } + ] + }) +} + +resource "aws_iam_policy" "pipes" { + name = "${local.prefix}-webinar-subscriptions-pipe-policy" + description = "Policy to allow webinar subscriptions pipe to deploy website" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = [ + "dynamodb:DescribeStream", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:ListStreams" + ] + Effect = "Allow" + Resource = [ + var.webinar_subscriptions_ddb_stream_arn + ] + }, + { + Action = [ + "sqs:SendMessage" + ] + Effect = "Allow" + Resource = [ + aws_sqs_queue.fifo_queue.arn + ] + }, + { + Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"], + Effect = "Allow", + Resource = aws_cloudwatch_log_group.pipe.arn + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "pipes" { + role = aws_iam_role.pipes_role.name + policy_arn = aws_iam_policy.pipes.arn +} + +# Lambda function +resource "aws_iam_policy" "lambda_policy" { + name = "${local.prefix}-sync-lambda-policy" + description = "Lambda policy for accessing SQS and logging" + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Action = ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"], + Effect = "Allow", + Resource = [aws_sqs_queue.fifo_queue.arn, aws_sqs_queue.fifo_dlq_queue.arn] + }, + { + Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"], + Effect = "Allow", + Resource = "arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:log-group:*${local.prefix}*" + }, + { + Action = ["ssm:GetParameter", "ssm:GetParameters"] + Effect = "Allow" + Resource = ["arn:aws:ssm:${var.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/ac/*"] + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "lambda_policy_attach" { + role = module.lambda_sync.lambda_role_name + policy_arn = aws_iam_policy.lambda_policy.arn +} + +resource "aws_iam_role_policy_attachment" "lambda_cognito_policy_attach" { + role = module.lambda_sync.lambda_role_name + policy_arn = "arn:aws:iam::aws:policy/AmazonCognitoReadOnly" +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/active_campaign/lambda.tf b/apps/infrastructure/src/modules/active_campaign/lambda.tf new file mode 100644 index 0000000000..dbcaeb6bbc --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/lambda.tf @@ -0,0 +1,63 @@ +# Lambda Function for SQS FIFO +module "lambda_sync" { + source = "git::github.com/terraform-aws-modules/terraform-aws-lambda.git?ref=9633abb6b6d275d3a28604dbfa755098470420d4" # v6.5.0 + + function_name = "${local.prefix}-sync-lambda" + description = "Lambda function that syncs Active Campaign" + + environment_variables = { + AC_API_KEY_PARAM = module.active_campaign_api_key.ssm_parameter_name + AC_BASE_URL_PARAM = module.active_campaign_base_url.ssm_parameter_name + COGNITO_USER_POOL_ID = var.cognito_user_pool.id + } + + runtime = "nodejs20.x" + architectures = ["x86_64"] + + handler = "index.handler" + source_path = "${path.module}/functions" + ignore_source_code_hash = true + create_current_version_allowed_triggers = false + + timeout = 15 + memory_size = 256 + + event_source_mapping = { + sqs = { + event_source_arn = aws_sqs_queue.fifo_queue.arn + batch_size = 1 + scaling_config = { + maximum_concurrency = 2 + } + } + } + + allowed_triggers = { + sqs = { + principal = "sqs.amazonaws.com" + source_arn = aws_sqs_queue.fifo_queue.arn + } + } + + tags = var.tags +} + +module "active_campaign_api_key" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/ac/api_key" + value = "Substitute with real api key from the console" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +module "active_campaign_base_url" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/ac/base_url" + value = "Substitute with real api key from the console" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} diff --git a/apps/infrastructure/src/modules/active_campaign/locals.tf b/apps/infrastructure/src/modules/active_campaign/locals.tf new file mode 100644 index 0000000000..4f2f172cbf --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/locals.tf @@ -0,0 +1,5 @@ +locals { + prefix = "${var.module}-${var.environment}" + + sqs_message_group_id = "userEvents" +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/active_campaign/sqs.tf b/apps/infrastructure/src/modules/active_campaign/sqs.tf new file mode 100644 index 0000000000..e3784d1925 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/sqs.tf @@ -0,0 +1,63 @@ +# SQS FIFO Queue +resource "aws_sqs_queue" "fifo_queue" { + name = "${local.prefix}-events.fifo" + fifo_queue = true + content_based_deduplication = true + deduplication_scope = "messageGroup" + fifo_throughput_limit = "perMessageGroupId" + + redrive_policy = jsonencode({ + deadLetterTargetArn = aws_sqs_queue.fifo_dlq_queue.arn + maxReceiveCount = 1 + }) + + policy = jsonencode({ + "Version" : "2008-10-17", + "Id" : "__default_policy_ID", + "Statement" : [ + { + "Sid" : "__owner_statement", + "Effect" : "Allow", + "Principal" : { + "AWS" : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" + }, + "Action" : "SQS:*", + "Resource" : "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${local.prefix}-events.fifo" + }, + { + "Sid" : "AllowFromEventBridge", + "Effect" : "Allow", + "Principal" : { + "Service" : "events.amazonaws.com" + }, + "Action" : "sqs:SendMessage", + "Resource" : "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${local.prefix}-events.fifo", + "Condition" : { + "ArnEquals" : { + "aws:SourceArn" : aws_cloudwatch_event_rule.cognito_events.arn + } + } + }, + { + "Sid" : "AllowFromEventPipes", + "Effect" : "Allow", + "Principal" : { + "Service" : "pipes.amazonaws.com" + }, + "Action" : "sqs:SendMessage", + "Resource" : "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${local.prefix}-events.fifo", + "Condition" : { + "ArnEquals" : { + "aws:SourceArn" : "arn:aws:pipes:${var.aws_region}:${data.aws_caller_identity.current.account_id}:pipe/${local.prefix}-webinar-subscriptions-pipe" + } + } + } + ] + }) +} + +# Dead Letter Queue (DLQ) +resource "aws_sqs_queue" "fifo_dlq_queue" { + name = "${local.prefix}-events-dlq.fifo" + fifo_queue = true +} diff --git a/apps/infrastructure/src/modules/active_campaign/variables.tf b/apps/infrastructure/src/modules/active_campaign/variables.tf new file mode 100644 index 0000000000..5e3aaf7411 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/variables.tf @@ -0,0 +1,45 @@ +variable "aws_region" { + type = string + description = "AWS region to create resources. Default Milan" + default = "eu-south-1" +} + +variable "environment" { + type = string + description = "Environment" +} + +variable "tags" { + type = map(any) + default = { + CreatedBy = "Terraform", + Wbs = "BD110 - PORTALS E TOOLS" + CostCenter = "BD110 - PORTALS E TOOLS" + Owner = "CloudGaaP-AI" + ManagementTeam = "team_cloudgaap_ai" + } +} + +variable "module" { + type = string + description = "Prefix for resources" + default = "ac" +} + +variable "cognito_user_pool" { + type = object({ + id = string + arn = string + domain = string + region = string + client_id = string + endpoint = string + }) + sensitive = true + description = "The cognito user pool used to authenticate api calls" +} + +variable "webinar_subscriptions_ddb_stream_arn" { + type = string + description = "The ARN of the webinar subscriptions ddb stream" +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/website/dynamodb.tf b/apps/infrastructure/src/modules/website/dynamodb.tf index eaffd28f85..6475dd7447 100644 --- a/apps/infrastructure/src/modules/website/dynamodb.tf +++ b/apps/infrastructure/src/modules/website/dynamodb.tf @@ -36,6 +36,9 @@ module "dynamodb_webinar_subscriptions" { range_key = "webinarId" server_side_encryption_enabled = true + stream_enabled = true + stream_view_type = "KEYS_ONLY" + attributes = [ { name = "username" diff --git a/apps/infrastructure/src/modules/website/outputs.tf b/apps/infrastructure/src/modules/website/outputs.tf index ee73c332d7..a791b5b83a 100644 --- a/apps/infrastructure/src/modules/website/outputs.tf +++ b/apps/infrastructure/src/modules/website/outputs.tf @@ -23,3 +23,7 @@ output "cognito_user_pool" { sensitive = true } + +output "webinar_subscriptions_ddb_stream_arn" { + value = module.dynamodb_webinar_subscriptions.dynamodb_table_stream_arn +} \ No newline at end of file From e623940ed94783118382ab8c3a9b9d743d2ec61b Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Mon, 2 Dec 2024 12:26:11 +0100 Subject: [PATCH 03/24] [CAI-214] Implement langfuse infrastructure (#1261) * feat: implement langfuse infrastructure * chore: changeset added * fix: reduce aurora acus * chore: removed unused LANGFUSE_TAG env variable to ecs --- .changeset/soft-socks-build.md | 5 + apps/infrastructure/src/main.tf | 1 + .../infrastructure/src/modules/chatbot/acm.tf | 16 +- .../infrastructure/src/modules/chatbot/alb.tf | 178 +++++++++++++++++ .../src/modules/chatbot/cognito_user.tf | 187 ++++++++++++++++++ .../src/modules/chatbot/data.tf | 12 ++ .../infrastructure/src/modules/chatbot/ecr.tf | 2 +- .../infrastructure/src/modules/chatbot/ecs.tf | 178 +++++++++++++++++ .../infrastructure/src/modules/chatbot/iam.tf | 46 +++++ .../src/modules/chatbot/lambda_chatbot.tf | 4 +- .../src/modules/chatbot/locals.tf | 5 + .../src/modules/chatbot/rds_aurora.tf | 76 +++++++ .../src/modules/chatbot/route53.tf | 34 +++- .../task-definitions/langfuse.json.tpl | 111 +++++++++++ .../src/modules/chatbot/variables.tf | 27 ++- .../infrastructure/src/modules/cms/outputs.tf | 13 +- apps/infrastructure/src/variables.tf | 21 ++ 17 files changed, 900 insertions(+), 16 deletions(-) create mode 100644 .changeset/soft-socks-build.md create mode 100644 apps/infrastructure/src/modules/chatbot/alb.tf create mode 100644 apps/infrastructure/src/modules/chatbot/cognito_user.tf create mode 100644 apps/infrastructure/src/modules/chatbot/rds_aurora.tf create mode 100644 apps/infrastructure/src/modules/chatbot/task-definitions/langfuse.json.tpl diff --git a/.changeset/soft-socks-build.md b/.changeset/soft-socks-build.md new file mode 100644 index 0000000000..ee002d02e0 --- /dev/null +++ b/.changeset/soft-socks-build.md @@ -0,0 +1,5 @@ +--- +"infrastructure": minor +--- + +Langfuse infrastructure implemented diff --git a/apps/infrastructure/src/main.tf b/apps/infrastructure/src/main.tf index b1534ee827..b8ffb44dfe 100644 --- a/apps/infrastructure/src/main.tf +++ b/apps/infrastructure/src/main.tf @@ -128,6 +128,7 @@ module "chatbot" { security_groups = module.cms.security_groups dns_domain_name = var.dns_domain_name ecs_redis = var.chatbot_ecs_redis + ecs_monitoring = var.chatbot_ecs_monitoring } module "cicd" { diff --git a/apps/infrastructure/src/modules/chatbot/acm.tf b/apps/infrastructure/src/modules/chatbot/acm.tf index 5b151226c6..35c59fbcb4 100644 --- a/apps/infrastructure/src/modules/chatbot/acm.tf +++ b/apps/infrastructure/src/modules/chatbot/acm.tf @@ -28,4 +28,18 @@ module "ssl_certificate_us_east_1" { wait_for_validation = false # https://github.com/terraform-aws-modules/terraform-aws-acm/blob/8d0b22f1f242a1b36e29b8cb38aaeac9b887500d/README.md?plain=1#L174 validation_method = "DNS" dns_ttl = 3600 -} \ No newline at end of file +} + +module "internal_ssl_certificate" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-acm.git?ref=8d0b22f1f242a1b36e29b8cb38aaeac9b887500d" # v5.0.0 + domain_name = "dummy.${aws_route53_zone.chatbot_internal.name}" + zone_id = var.dns_chatbot_hosted_zone.id + + subject_alternative_names = [ + "*.${aws_route53_zone.chatbot_internal.name}" + ] + + wait_for_validation = false # https://github.com/terraform-aws-modules/terraform-aws-acm/blob/8d0b22f1f242a1b36e29b8cb38aaeac9b887500d/README.md?plain=1#L174 + validation_method = "DNS" + dns_ttl = 3600 +} diff --git a/apps/infrastructure/src/modules/chatbot/alb.tf b/apps/infrastructure/src/modules/chatbot/alb.tf new file mode 100644 index 0000000000..3551003333 --- /dev/null +++ b/apps/infrastructure/src/modules/chatbot/alb.tf @@ -0,0 +1,178 @@ +## Application Load Balancer for Chatbot Monitoring tool +module "monitoring_load_balancer" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-alb.git?ref=3e9c6cbaf4c1d858c3bbee6f086f0c8ef17522ab" # v9.6.0 + + name = "${local.prefix}-monitoring-alb" + vpc_id = var.vpc.id + subnets = var.vpc.public_subnets + security_groups = [aws_security_group.monitoring_lb.id] + internal = false + create_security_group = false + load_balancer_type = "application" + + listeners = { + front_end_http = { + port = 80 + protocol = "HTTP" + redirect = { + port = "443" + protocol = "HTTPS" + status_code = "HTTP_301" + } + } + front_end_https = { + port = 443 + protocol = "HTTPS" + certificate_arn = module.ssl_certificate.acm_certificate_arn + forward = { + target_group_key = "monitoring-target-group" + } + } + } + + target_groups = { + monitoring-target-group = { + name = "monitoring-target-group" + protocol = "HTTP" + port = var.ecs_monitoring.port + target_type = "ip" + vpc_id = var.vpc.id + + health_check = { + healthy_threshold = "3" + interval = "30" + protocol = "HTTP" + matcher = "200" + timeout = "3" + path = "/api/public/ready" + unhealthy_threshold = "2" + } + create_attachment = false + } + } +} + +### AWS Security Group ### +# Traffic to the DB should only come from ECS +# Traffic to the ECS cluster should only come from the ALB + +resource "aws_security_group" "monitoring_lb" { + name = "${local.prefix}-monitoring-lb" + description = "Ingress - Load Balancer" + vpc_id = var.vpc.id + + ingress { + protocol = "tcp" + from_port = 80 + to_port = 80 + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + protocol = "tcp" + from_port = 443 + to_port = 443 + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + # https://registry.terraform.io/providers/hashicorp/aws/5.35.0/docs/resources/security_group#recreating-a-security-group + lifecycle { + create_before_destroy = true + } +} + +## Application Load Balancer for Chatbot Monitoring tool internally +module "internal_monitoring_load_balancer" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-alb.git?ref=3e9c6cbaf4c1d858c3bbee6f086f0c8ef17522ab" # v9.6.0 + + name = "${local.prefix}-int-monitoring-alb" + vpc_id = var.vpc.id + subnets = var.vpc.private_subnets + security_groups = [aws_security_group.monitoring_lb.id] + internal = true + create_security_group = false + load_balancer_type = "application" + + listeners = { + front_end_http = { + port = 80 + protocol = "HTTP" + redirect = { + port = "443" + protocol = "HTTPS" + status_code = "HTTP_301" + } + } + front_end_https = { + port = 443 + protocol = "HTTPS" + certificate_arn = module.internal_ssl_certificate.acm_certificate_arn + forward = { + target_group_key = "internal-monitoring-target-group" + } + } + } + + target_groups = { + internal-monitoring-target-group = { + name = "internal-monitoring-target-group" + protocol = "HTTP" + port = var.ecs_monitoring.port + target_type = "ip" + vpc_id = var.vpc.id + + health_check = { + healthy_threshold = "3" + interval = "30" + protocol = "HTTP" + matcher = "200" + timeout = "3" + path = "/api/public/ready" + unhealthy_threshold = "2" + } + create_attachment = false + } + } +} + +### AWS Security Group ### +# Traffic to Langfuse comes only from the chatbot lambda + +resource "aws_security_group" "internal_monitoring_lb" { + name = "${local.prefix}-internal-monitoring-lb" + description = "Ingress - Load Balancer" + vpc_id = var.vpc.id + + ingress { + protocol = "tcp" + from_port = 80 + to_port = 80 + security_groups = [aws_security_group.lambda.id] + } + + ingress { + protocol = "tcp" + from_port = 443 + to_port = 443 + security_groups = [aws_security_group.lambda.id] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + # https://registry.terraform.io/providers/hashicorp/aws/5.35.0/docs/resources/security_group#recreating-a-security-group + lifecycle { + create_before_destroy = true + } +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/chatbot/cognito_user.tf b/apps/infrastructure/src/modules/chatbot/cognito_user.tf new file mode 100644 index 0000000000..797f39629f --- /dev/null +++ b/apps/infrastructure/src/modules/chatbot/cognito_user.tf @@ -0,0 +1,187 @@ +locals { + from_email_address = format("PagoPA DevPortal ", var.dns_domain_name) +} + +resource "aws_cognito_user_pool" "monitoring" { + lifecycle { + prevent_destroy = true + } + + name = "${local.prefix}-monitoring-user-pool" + deletion_protection = "ACTIVE" + + user_pool_add_ons { + advanced_security_mode = "OFF" + } + + username_attributes = ["email"] + auto_verified_attributes = ["email"] + + user_attribute_update_settings { + attributes_require_verification_before_update = ["email"] + } + + account_recovery_setting { + recovery_mechanism { + name = "verified_email" + priority = 1 + } + } + + admin_create_user_config { + # allow user to create via signup page + allow_admin_create_user_only = true + } + + password_policy { + minimum_length = 8 + require_lowercase = true + require_numbers = true + require_uppercase = true + require_symbols = true + temporary_password_validity_days = 7 + } + + # Custom attributes cannot be required. + # Terraform cannot update or delete an attribute. + # Terraform can add a new attribute as update in-place. + # https://github.com/hashicorp/terraform-provider-aws/issues/24844 + schema { + name = "email" + attribute_data_type = "String" + developer_only_attribute = false + mutable = true + required = true + + string_attribute_constraints { + min_length = 1 + # https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.1 + max_length = 512 + } + } + + schema { + name = "given_name" + attribute_data_type = "String" + developer_only_attribute = false + mutable = true + required = true + string_attribute_constraints { + min_length = 1 + max_length = 256 + } + } + + schema { + name = "family_name" + attribute_data_type = "String" + developer_only_attribute = false + mutable = true + required = true + string_attribute_constraints { + min_length = 1 + max_length = 256 + } + } +} + +resource "aws_cognito_user_pool_client" "langfuse" { + name = "${local.prefix}-monitoring-langfuse" + + user_pool_id = aws_cognito_user_pool.monitoring.id + generate_secret = true + prevent_user_existence_errors = "ENABLED" + + callback_urls = (var.environment == "dev" ? + [ + "http://localhost:3001/api/auth/callback/cognito", + "https://${local.monitoring_host}/api/auth/callback/cognito" + ] : + [ + "https://${local.monitoring_host}/api/auth/callback/cognito" + ] + ) + + allowed_oauth_flows_user_pool_client = true + allowed_oauth_flows = ["code"] + allowed_oauth_scopes = ["openid"] + supported_identity_providers = ["COGNITO"] + explicit_auth_flows = ["ALLOW_USER_PASSWORD_AUTH", "ALLOW_REFRESH_TOKEN_AUTH", "ALLOW_USER_SRP_AUTH"] + auth_session_validity = 3 + + refresh_token_validity = 30 + access_token_validity = 1 + id_token_validity = 1 + + token_validity_units { + refresh_token = "days" + access_token = "hours" + id_token = "hours" + } +} + +resource "aws_cognito_user_pool_domain" "monitoring" { + domain = "monitoring" + user_pool_id = aws_cognito_user_pool.monitoring.id +} + +resource "random_password" "master" { + length = 16 + special = true + min_upper = 1 + min_special = 1 + min_lower = 1 + override_special = "!?" +} + +resource "aws_cognito_user" "master" { + user_pool_id = aws_cognito_user_pool.monitoring.id + username = local.langfuse_master_email + password = random_password.master.result + message_action = "SUPPRESS" + attributes = { + email = local.langfuse_master_email + email_verified = true + given_name = "Master" + family_name = "User" + } +} + +module "master_user_password" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/master_user_password" + value = random_password.master.result + type = "SecureString" + secure_type = true +} + +module "user_pool_client_id" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/user_pool_client_id" + value = aws_cognito_user_pool_client.langfuse.id + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +module "user_pool_client_secret" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/user_pool_client_secret" + value = aws_cognito_user_pool_client.langfuse.client_secret + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +module "user_pool_issuer" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/user_pool_issuer" + value = "https://${aws_cognito_user_pool.monitoring.endpoint}" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} diff --git a/apps/infrastructure/src/modules/chatbot/data.tf b/apps/infrastructure/src/modules/chatbot/data.tf index 3e20bd5788..a895dd6a5d 100644 --- a/apps/infrastructure/src/modules/chatbot/data.tf +++ b/apps/infrastructure/src/modules/chatbot/data.tf @@ -130,4 +130,16 @@ data "aws_iam_policy_document" "bedrock_logging" { "${module.bedrock_log_group[0].cloudwatch_log_group_arn}:log-stream:aws/bedrock/modelinvocations" ] } +} + +data "aws_iam_policy_document" "ecs_monitoring_ssm_policy" { + statement { + sid = "AllowSSMOperations" + effect = "Allow" + actions = [ + "ssm:GetParameter", + "ssm:GetParameters" + ] + resources = ["arn:aws:ssm:${var.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/chatbot/monitoring/*"] + } } \ No newline at end of file diff --git a/apps/infrastructure/src/modules/chatbot/ecr.tf b/apps/infrastructure/src/modules/chatbot/ecr.tf index e2958d3e21..d51224b185 100644 --- a/apps/infrastructure/src/modules/chatbot/ecr.tf +++ b/apps/infrastructure/src/modules/chatbot/ecr.tf @@ -1,4 +1,4 @@ -## ECR Container Registry for CMS Strapi +## ECR Container Registry for Chatbot module "ecr" { source = "git::https://github.com/terraform-aws-modules/terraform-aws-ecr.git?ref=9f4b587846551110b0db199ea5599f016570fefe" # v1.6.0 diff --git a/apps/infrastructure/src/modules/chatbot/ecs.tf b/apps/infrastructure/src/modules/chatbot/ecs.tf index 4258568785..399f078740 100644 --- a/apps/infrastructure/src/modules/chatbot/ecs.tf +++ b/apps/infrastructure/src/modules/chatbot/ecs.tf @@ -110,3 +110,181 @@ resource "aws_security_group_rule" "nlb_ingress" { security_group_id = aws_security_group.redis.id source_security_group_id = aws_security_group.nlb.id } + +##### Monitoring (Langfuse) +resource "aws_ecs_task_definition" "monitoring_task_def" { + family = "langfuse-task-def" + execution_role_arn = module.iam_role_ecs_monitoring_task_execution.iam_role_arn + task_role_arn = module.ecs_monitoring_task_iam_role.iam_role_arn + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = var.ecs_monitoring.cpu + memory = var.ecs_monitoring.memory + container_definitions = templatefile( + "${path.module}/task-definitions/langfuse.json.tpl", + { + image = var.ecs_monitoring.image_uri + fargate_cpu = var.ecs_monitoring.cpu + fargate_memory = var.ecs_monitoring.memory + container_port = var.ecs_monitoring.port + container_name = "langfuse" + aws_region = var.aws_region + log_group = module.ecs_log_group.cloudwatch_log_group_name + + postgres_url = module.postgres_url.ssm_parameter_arn + base_url = "https://${local.monitoring_host}" + client_id = module.user_pool_client_id.ssm_parameter_arn + client_secret = module.user_pool_client_secret.ssm_parameter_arn + issuer = module.user_pool_issuer.ssm_parameter_arn + master_user_email = local.langfuse_master_email + master_user_name = "master" + master_user_password = module.master_user_password.ssm_parameter_arn + encryption_key = module.encryption_key.ssm_parameter_arn + salt = module.salt.ssm_parameter_arn + nextauth_secret = module.nextauth_secret.ssm_parameter_arn + langfuse_public_key = module.langfuse_public_key.ssm_parameter_arn + langfuse_secret_key = module.langfuse_secret_key.ssm_parameter_arn + }) +} + +module "monitoring_ecs_service" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ecs.git//modules/service?ref=8b97783def49997d18a6fcb00dc21ce1edc0f538" # v5.9.0 + + name = "langfuse-ecs" + cluster_arn = module.ecs_cluster.arn + desired_count = 1 + create_task_definition = false + create_iam_role = false + create_task_exec_iam_role = false + create_security_group = false + launch_type = "FARGATE" + force_new_deployment = true + enable_execute_command = true + task_definition_arn = aws_ecs_task_definition.monitoring_task_def.arn + tasks_iam_role_arn = module.ecs_monitoring_task_iam_role.iam_role_arn + task_exec_iam_role_arn = module.iam_role_ecs_task_execution.iam_role_arn + ignore_task_definition_changes = false + + security_group_ids = [aws_security_group.monitoring_ecs.id] + subnet_ids = var.vpc.private_subnets + assign_public_ip = false + + load_balancer = { + monitoring-target-group = { + target_group_arn = module.monitoring_load_balancer.target_groups["monitoring-target-group"].arn + container_name = "langfuse" + container_port = var.ecs_monitoring.port + } + + internal-monitoring-target-group = { + target_group_arn = module.internal_monitoring_load_balancer.target_groups["internal-monitoring-target-group"].arn + container_name = "langfuse" + container_port = var.ecs_monitoring.port + } + } +} + +resource "aws_security_group" "monitoring_ecs" { + name = "${local.prefix}-monitoring-ecs" + description = "Monitoring ECS" + vpc_id = var.vpc.id + + # https://registry.terraform.io/providers/hashicorp/aws/5.35.0/docs/resources/security_group#recreating-a-security-group + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "monitoring_ecs_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = aws_security_group.monitoring_ecs.id +} + +resource "aws_security_group_rule" "alb_ingress" { + type = "ingress" + from_port = var.ecs_monitoring.port + to_port = var.ecs_monitoring.port + protocol = "tcp" + security_group_id = aws_security_group.monitoring_ecs.id + source_security_group_id = aws_security_group.monitoring_lb.id +} + +resource "aws_security_group_rule" "internal_alb_ingress" { + type = "ingress" + from_port = var.ecs_monitoring.port + to_port = var.ecs_monitoring.port + protocol = "tcp" + security_group_id = aws_security_group.monitoring_ecs.id + source_security_group_id = aws_security_group.internal_monitoring_lb.id +} + +resource "random_password" "encryption_key" { + length = 64 # 32 bytes in hexadecimal = 64 characters + special = false # Disable special characters + override_special = "" # Ensure no special characters are added +} + +module "encryption_key" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/encryption_key" + value = random_password.encryption_key.result + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +resource "random_id" "salt" { + byte_length = 32 # Generate 32 random bytes +} + +module "salt" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/salt" + value = base64encode(random_id.salt.b64_std) + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +resource "random_id" "nextauth_secret" { + byte_length = 32 # Generate 32 random bytes +} + +module "nextauth_secret" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/nextauth_secret" + value = base64encode(random_id.nextauth_secret.b64_std) + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +resource "random_uuid" "public_key_uuid" {} +resource "random_uuid" "secret_key_uuid" {} + +module "langfuse_public_key" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/langfuse_public_key" + value = "pk-lf-${random_uuid.public_key_uuid.result}" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} + +module "langfuse_secret_key" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/langfuse_secret_key" + value = "sk-lf-${random_uuid.secret_key_uuid.result}" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} diff --git a/apps/infrastructure/src/modules/chatbot/iam.tf b/apps/infrastructure/src/modules/chatbot/iam.tf index aef7ef2dec..4159ef1692 100644 --- a/apps/infrastructure/src/modules/chatbot/iam.tf +++ b/apps/infrastructure/src/modules/chatbot/iam.tf @@ -90,4 +90,50 @@ module "iam_role_bedrock_logging" { "bedrock.amazonaws.com" ] role_requires_mfa = false +} + +############################################################################### +# IAM Role used by Monitoring ECS # +############################################################################### +module "ecs_monitoring_task_iam_role" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-iam.git//modules/iam-assumable-role?ref=f37809108f86d8fbdf17f735df734bf4abe69315" # v5.34.0 + + create_role = true + role_name = "${local.prefix}-monitoring-ecs-task-role" + + custom_role_policy_arns = [ + "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role", + module.iam_policy_ecs_task_role_ssm.arn, + ] + number_of_custom_role_policy_arns = 2 + trusted_role_services = [ + "ecs-tasks.amazonaws.com" + ] + role_requires_mfa = false +} + +module "iam_role_ecs_monitoring_task_execution" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-iam.git//modules/iam-assumable-role?ref=f37809108f86d8fbdf17f735df734bf4abe69315" # v5.34.0 + + create_role = true + role_name = "${local.prefix}-ecs-monitoring-task-execution-role" + + custom_role_policy_arns = [ + "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", + "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", + module.iam_policy_ecs_monitoring_task_role_ssm.arn + ] + number_of_custom_role_policy_arns = 3 + trusted_role_services = [ + "ecs-tasks.amazonaws.com" + ] + role_requires_mfa = false +} + +module "iam_policy_ecs_monitoring_task_role_ssm" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-iam.git//modules/iam-policy?ref=f37809108f86d8fbdf17f735df734bf4abe69315" # v5.34.0 + + name = "ECSMonitoringTaskRolePoliciesSSM" + path = "/" + policy = data.aws_iam_policy_document.ecs_monitoring_ssm_policy.json } \ No newline at end of file diff --git a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf index 452bef0838..5a7331ede0 100644 --- a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf +++ b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf @@ -11,7 +11,9 @@ locals { LOG_LEVEL = "INFO" LLAMA_INDEX_CACHE_DIR = "/tmp" NLTK_DATA = "_static/nltk_cache/" - + CHB_LANGFUSE_HOST = "https://${local.priv_monitoring_host}" + CHB_LANGFUSE_PUBLIC_KEY = module.langfuse_public_key.ssm_parameter_name + CHB_LANGFUSE_SECRET_KEY = module.langfuse_secret_key.ssm_parameter_name # Be extremely careful when changing the provider # both the generation and the embedding models would be changed # embeddings size change would break the application and requires reindexing diff --git a/apps/infrastructure/src/modules/chatbot/locals.tf b/apps/infrastructure/src/modules/chatbot/locals.tf index a7d32eac97..1dde3aad92 100644 --- a/apps/infrastructure/src/modules/chatbot/locals.tf +++ b/apps/infrastructure/src/modules/chatbot/locals.tf @@ -5,4 +5,9 @@ locals { redis_container_name = "redis-stack" lambda_timeout = 180 + + monitoring_host = aws_route53_record.monitoring.fqdn + priv_monitoring_host = aws_route53_record.internal_monitoring.fqdn + monitoring_database_name = "monitoring" + langfuse_master_email = "devportal@pagopa.it" } \ No newline at end of file diff --git a/apps/infrastructure/src/modules/chatbot/rds_aurora.tf b/apps/infrastructure/src/modules/chatbot/rds_aurora.tf new file mode 100644 index 0000000000..2319806d35 --- /dev/null +++ b/apps/infrastructure/src/modules/chatbot/rds_aurora.tf @@ -0,0 +1,76 @@ +# RDS Aurora PostgreSQL Serverless for Chatbot Monitoring tool +resource "random_password" "monitoring_database_password" { + length = 16 + special = true + override_special = "!#$%&*()-_=+[]{}<>:?" +} + + +module "rds" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-rds-aurora.git?ref=7bf5933100eb355b13854232e5d63c62ea7cad35" # v9.0.0 + + name = "${local.prefix}-monitoring-database" + engine = "aurora-postgresql" + engine_mode = "provisioned" + engine_version = "14" + auto_minor_version_upgrade = true + database_name = local.monitoring_database_name + master_username = "postgres" + master_password = random_password.monitoring_database_password.result + vpc_id = var.vpc.id + db_subnet_group_name = var.vpc.database_subnet_group_name + vpc_security_group_ids = [aws_security_group.monitoring_database.id] + apply_immediately = true + skip_final_snapshot = true + manage_master_user_password = false + backup_retention_period = 3 + + serverlessv2_scaling_configuration = { + min_capacity = 0.5 + max_capacity = 1 + } + + instance_class = "db.serverless" + instances = { + one = {} + } +} + +### AWS RDS Security Group ### +# Traffic to the DB should only come from ECS +resource "aws_security_group" "monitoring_database" { + name = "${local.prefix}-monitoring-database-sg" + description = "Ingress - RDS instance" + vpc_id = var.vpc.id + + ingress { + protocol = "tcp" + from_port = 5432 + to_port = 5432 + security_groups = [ + aws_security_group.monitoring_ecs.id + ] + } + + egress { + protocol = "-1" + from_port = 0 + to_port = 0 + cidr_blocks = ["0.0.0.0/0"] + } + + # https://registry.terraform.io/providers/hashicorp/aws/5.35.0/docs/resources/security_group#recreating-a-security-group + lifecycle { + create_before_destroy = true + } +} + +module "postgres_url" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-ssm-parameter.git?ref=77d2c139784197febbc8f8e18a33d23eb4736879" # v1.1.0 + + name = "/chatbot/monitoring/postgres_url" + value = "postgresql://${module.rds.cluster_master_username}:${module.rds.cluster_master_password}@${module.rds.cluster_endpoint}:${module.rds.cluster_port}/${local.monitoring_database_name}" + type = "SecureString" + secure_type = true + ignore_value_changes = true +} diff --git a/apps/infrastructure/src/modules/chatbot/route53.tf b/apps/infrastructure/src/modules/chatbot/route53.tf index a84111200b..616a2b92a9 100644 --- a/apps/infrastructure/src/modules/chatbot/route53.tf +++ b/apps/infrastructure/src/modules/chatbot/route53.tf @@ -8,4 +8,36 @@ resource "aws_route53_record" "apigw" { name = aws_api_gateway_domain_name.domain_name.regional_domain_name zone_id = aws_api_gateway_domain_name.domain_name.regional_zone_id } -} \ No newline at end of file +} + +resource "aws_route53_record" "monitoring" { + name = "mon" + type = "A" + zone_id = var.dns_chatbot_hosted_zone.id + + alias { + name = module.monitoring_load_balancer.dns_name + zone_id = module.monitoring_load_balancer.zone_id + evaluate_target_health = true + } +} + + +resource "aws_route53_zone" "chatbot_internal" { + name = "internal.${var.dns_chatbot_hosted_zone.name}" + vpc { + vpc_id = var.vpc.id + } +} + +resource "aws_route53_record" "internal_monitoring" { + name = "mon" + type = "A" + zone_id = aws_route53_zone.chatbot_internal.zone_id + + alias { + name = module.internal_monitoring_load_balancer.dns_name + zone_id = module.internal_monitoring_load_balancer.zone_id + evaluate_target_health = true + } +} diff --git a/apps/infrastructure/src/modules/chatbot/task-definitions/langfuse.json.tpl b/apps/infrastructure/src/modules/chatbot/task-definitions/langfuse.json.tpl new file mode 100644 index 0000000000..250e381bbf --- /dev/null +++ b/apps/infrastructure/src/modules/chatbot/task-definitions/langfuse.json.tpl @@ -0,0 +1,111 @@ +[ + { + "name": "${container_name}", + "image": "${image}", + "portMappings": [ + { + "containerPort": ${container_port} + } + ], + "linuxParameters": { + "initProcessEnabled": true + }, + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "${log_group}", + "awslogs-region": "${aws_region}", + "awslogs-stream-prefix": "${container_name}" + }, + "secretOptions": [] + }, + "environment": [ + { + "name": "NEXTAUTH_URL", + "value": "${base_url}" + }, + { + "name": "AUTH_COGNITO_ALLOW_ACCOUNT_LINKING", + "value": "true" + }, + { + "name": "LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES", + "value": "false" + }, + { + "name": "LANGFUSE_INIT_ORG_ID", + "value": "pagopa" + }, + { + "name": "LANGFUSE_INIT_ORG_NAME", + "value": "PagoPA" + }, + { + "name": "LANGFUSE_INIT_PROJECT_ID", + "value": "cloudgaapai-discovery" + }, + { + "name": "LANGFUSE_INIT_PROJECT_NAME", + "value": "CloudGaapAI - Discovery" + }, + { + "name": "AUTH_DISABLE_USERNAME_PASSWORD", + "value": "true" + }, + { + "name": "AUTH_DISABLE_SIGNUP", + "value": "false" + }, + { + "name": "LANGFUSE_INIT_USER_EMAIL", + "value": "${master_user_email}" + }, + { + "name": "LANGFUSE_INIT_USER_NAME", + "value": "${master_user_name}" + } + ], + "secrets": [ + { + "name": "DATABASE_URL", + "valueFrom": "${postgres_url}" + }, + { + "name" : "AUTH_COGNITO_CLIENT_ID", + "valueFrom" : "${client_id}" + }, + { + "name" : "AUTH_COGNITO_CLIENT_SECRET", + "valueFrom" : "${client_secret}" + }, + { + "name" : "AUTH_COGNITO_ISSUER", + "valueFrom" : "${issuer}" + }, + { + "name" : "LANGFUSE_INIT_USER_PASSWORD", + "valueFrom" : "${master_user_password}" + }, + { + "name": "ENCRYPTION_KEY", + "valueFrom": "${encryption_key}" + }, + { + "name": "SALT", + "valueFrom": "${salt}" + }, + { + "name": "NEXTAUTH_SECRET", + "valueFrom": "${nextauth_secret}" + }, + { + "name": "LANGFUSE_INIT_PROJECT_PUBLIC_KEY", + "valueFrom": "${langfuse_public_key}" + }, + { + "name": "LANGFUSE_INIT_PROJECT_SECRET_KEY", + "valueFrom": "${langfuse_secret_key}" + } + ] + } +] diff --git a/apps/infrastructure/src/modules/chatbot/variables.tf b/apps/infrastructure/src/modules/chatbot/variables.tf index 2c07b97647..3420e987b5 100644 --- a/apps/infrastructure/src/modules/chatbot/variables.tf +++ b/apps/infrastructure/src/modules/chatbot/variables.tf @@ -59,12 +59,13 @@ variable "cognito_user_pool" { variable "vpc" { type = object({ - id = string - cidr_block = string - public_subnets = list(string) - database_subnets = list(string) - private_subnets = list(string) - elasticache_subnets = list(string) + id = string + cidr_block = string + public_subnets = list(string) + database_subnets = list(string) + private_subnets = list(string) + elasticache_subnets = list(string) + database_subnet_group_name = string }) description = "The VPC used to deploy the resources" @@ -106,4 +107,18 @@ variable "api_gateway" { default = { integration_timeout_sec = 60 } +} + +################################################################################ +# ECS - Monitoring +################################################################################ + +variable "ecs_monitoring" { + type = object({ + cpu = number + memory = number + image_uri = string + port = number + }) + description = "Langfuse configuration for the AI chatbot" } \ No newline at end of file diff --git a/apps/infrastructure/src/modules/cms/outputs.tf b/apps/infrastructure/src/modules/cms/outputs.tf index a13df4bb21..ae43046083 100644 --- a/apps/infrastructure/src/modules/cms/outputs.tf +++ b/apps/infrastructure/src/modules/cms/outputs.tf @@ -1,11 +1,12 @@ output "vpc" { value = { - id = module.vpc.vpc_id - cidr_block = module.vpc.vpc_cidr_block - public_subnets = module.vpc.public_subnets - database_subnets = module.vpc.database_subnets - private_subnets = module.vpc.private_subnets - elasticache_subnets = module.vpc.elasticache_subnets + id = module.vpc.vpc_id + cidr_block = module.vpc.vpc_cidr_block + public_subnets = module.vpc.public_subnets + database_subnets = module.vpc.database_subnets + private_subnets = module.vpc.private_subnets + elasticache_subnets = module.vpc.elasticache_subnets + database_subnet_group_name = module.vpc.database_subnet_group_name } } diff --git a/apps/infrastructure/src/variables.tf b/apps/infrastructure/src/variables.tf index d4951495f6..15c03bceb7 100644 --- a/apps/infrastructure/src/variables.tf +++ b/apps/infrastructure/src/variables.tf @@ -118,3 +118,24 @@ variable "chatbot_ecs_redis" { port = 6379 } } + +################################################################################ +# ECS - Chatbot Monitoring +################################################################################ + +variable "chatbot_ecs_monitoring" { + type = object({ + cpu = optional(number, 2048) + memory = optional(number, 4096) + image_uri = optional(string, "ghcr.io/langfuse/langfuse:sha-9375250") + port = optional(number, 3000) + }) + description = "Redis configuration for the AI chatbot" + + default = { + cpu = 2048 + memory = 4096 + image_uri = "ghcr.io/langfuse/langfuse:sha-9375250" + port = 3000 + } +} \ No newline at end of file From 455614999231457e614844eae04b3338539f5873 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Mon, 2 Dec 2024 14:35:59 +0100 Subject: [PATCH 04/24] fix: add npm install on deploy ac sync lambda workflow --- .github/workflows/deploy_ac_sync_lambda.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/deploy_ac_sync_lambda.yaml b/.github/workflows/deploy_ac_sync_lambda.yaml index 9c1c3fa779..c89085b421 100644 --- a/.github/workflows/deploy_ac_sync_lambda.yaml +++ b/.github/workflows/deploy_ac_sync_lambda.yaml @@ -30,6 +30,10 @@ jobs: uses: actions/setup-node@v3 with: node-version: '20.x' + + - name: Install dependencies + shell: bash + run: npm install - name: Build working-directory: packages/active-campaign-client From 94f52b476771374aa9e189898a7248befad6fbea Mon Sep 17 00:00:00 2001 From: Devis Battisti Date: Mon, 2 Dec 2024 16:14:47 +0100 Subject: [PATCH 05/24] chore: disable chatbot test (#1262) --- apps/chatbot/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/chatbot/package.json b/apps/chatbot/package.json index 1c6e630358..339c4484ea 100644 --- a/apps/chatbot/package.json +++ b/apps/chatbot/package.json @@ -3,6 +3,5 @@ "version": "4.0.0", "private": true, "scripts": { - "test": "./docker/docker-compose-run-tests.sh" } } From bbe33fcd6f8f2273824a32dad3cdfc810f57b016 Mon Sep 17 00:00:00 2001 From: marcobottaro <39835990+marcobottaro@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:53:56 +0100 Subject: [PATCH 06/24] [DEV-2046] Fix img_src CSP directive to see also in Dev the images inserted using production's CMS (#1256) * Fix img_src CSP rule to see in Dev the images inserted using production's CMS * Fix changeset --------- Co-authored-by: christian-calabrese --- .changeset/six-yaks-obey.md | 5 +++++ apps/infrastructure/src/modules/website/cloudfront.tf | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/six-yaks-obey.md diff --git a/.changeset/six-yaks-obey.md b/.changeset/six-yaks-obey.md new file mode 100644 index 0000000000..8d7db22d60 --- /dev/null +++ b/.changeset/six-yaks-obey.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Fix img_src CSP directive to see also in Dev the images inserted using production's CMS diff --git a/apps/infrastructure/src/modules/website/cloudfront.tf b/apps/infrastructure/src/modules/website/cloudfront.tf index 24a97e996b..270df5b294 100644 --- a/apps/infrastructure/src/modules/website/cloudfront.tf +++ b/apps/infrastructure/src/modules/website/cloudfront.tf @@ -6,7 +6,7 @@ locals { form_action = "'self'" font_src = "data: 'self' https://privacyportalde-cdn.onetrust.com/privacy-notice-scripts/icons/" connect_src = "'self' https://cognito-identity.eu-south-1.amazonaws.com/ https://dynamodb.eu-south-1.amazonaws.com/ https://cognito-idp.eu-south-1.amazonaws.com/ https://raw.githubusercontent.com/pagopa/ https://raw.githubusercontent.com/teamdigitale/ https://*.cookielaw.org https://*.onetrust.com https://www.google-analytics.com https://api.io.italia.it *.google-analytics.com https://pagopa.matomo.cloud/ https://*.${var.dns_domain_name}" - img_src = "data: 'self' https://i.vimeocdn.com/ https://io.italia.it/assets/ https://raw.githubusercontent.com/pagopa/ https://www.pagopa.gov.it/assets/ https://*.cookielaw.org/logos/ recaptcha.net https://*.googleusercontent.com https://*.${var.dns_domain_name}" + img_src = "data: 'self' https://i.vimeocdn.com/ https://io.italia.it/assets/ https://raw.githubusercontent.com/pagopa/ https://www.pagopa.gov.it/assets/ https://*.cookielaw.org/logos/ recaptcha.net https://*.googleusercontent.com https://*.dev.developer.pagopa.it https://*.developer.pagopa.it" frame_src = "https://player.vimeo.com/ https://vimeo.com/ https://demo.arcade.software/ https://www.google.com https://recaptcha.net https://www.youtube.com https://pagopa.applytojob.com https://www.figma.com/ https://codepen.io/" } @@ -110,4 +110,4 @@ resource "aws_cloudfront_distribution" "website" { acm_certificate_arn = var.use_custom_certificate ? aws_acm_certificate.website.arn : null ssl_support_method = var.use_custom_certificate ? "sni-only" : null } -} \ No newline at end of file +} From 94ca22c30461caa5a9578a3cc854e8b53cdc6e17 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Tue, 3 Dec 2024 15:18:54 +0100 Subject: [PATCH 07/24] fix: npm install and add permissions to gh actions role (#1263) * fix: npm install and add permissions to gh actions role * chore: added changeset * revert: using working-directory in npm install --- .changeset/smooth-laws-do.md | 5 +++++ .github/workflows/deploy_ac_sync_lambda.yaml | 1 - apps/infrastructure/src/modules/website/iam_policy.tf | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/smooth-laws-do.md diff --git a/.changeset/smooth-laws-do.md b/.changeset/smooth-laws-do.md new file mode 100644 index 0000000000..df459d6565 --- /dev/null +++ b/.changeset/smooth-laws-do.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Added permissions to deploy the ac sync lambdas via GH actions diff --git a/.github/workflows/deploy_ac_sync_lambda.yaml b/.github/workflows/deploy_ac_sync_lambda.yaml index c89085b421..ca70c278b8 100644 --- a/.github/workflows/deploy_ac_sync_lambda.yaml +++ b/.github/workflows/deploy_ac_sync_lambda.yaml @@ -32,7 +32,6 @@ jobs: node-version: '20.x' - name: Install dependencies - shell: bash run: npm install - name: Build diff --git a/apps/infrastructure/src/modules/website/iam_policy.tf b/apps/infrastructure/src/modules/website/iam_policy.tf index 234703992e..7e6882f040 100644 --- a/apps/infrastructure/src/modules/website/iam_policy.tf +++ b/apps/infrastructure/src/modules/website/iam_policy.tf @@ -65,6 +65,15 @@ resource "aws_iam_policy" "deploy_website" { Resource = [ aws_cloudfront_distribution.website.arn ] + }, + { + Action = [ + "lambda:UpdateFunctionCode" + ] + Effect = "Allow" + Resource = [ + "arn:aws:lambda:${var.aws_region}:${data.aws_caller_identity.current.account_id}:function:ac-${var.environment}-*" + ] } ] }) From 7ac487f9195a0a508b563b0b8f89bb1284c5ddba Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Wed, 4 Dec 2024 16:44:37 +0100 Subject: [PATCH 08/24] [DEV-2054] Fix webinar codec (#1265) * Fix webinar codec * Add changeset * Update package lock --- .changeset/big-zebras-eat.md | 5 ++ .../src/app/[productSlug]/overview/page.tsx | 2 +- apps/nextjs-website/src/app/page.tsx | 2 +- .../lib/strapi/codecs/RelatedLinksCodec.ts | 3 +- apps/nextjs-website/src/lib/types/webinar.ts | 2 +- package-lock.json | 74 ++++++++++++++++++- 6 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 .changeset/big-zebras-eat.md diff --git a/.changeset/big-zebras-eat.md b/.changeset/big-zebras-eat.md new file mode 100644 index 0000000000..4244d795f7 --- /dev/null +++ b/.changeset/big-zebras-eat.md @@ -0,0 +1,5 @@ +--- +"nextjs-website": minor +--- + +Fix related links and webinar codec diff --git a/apps/nextjs-website/src/app/[productSlug]/overview/page.tsx b/apps/nextjs-website/src/app/[productSlug]/overview/page.tsx index 900fac6fc5..08a05eba41 100644 --- a/apps/nextjs-website/src/app/[productSlug]/overview/page.tsx +++ b/apps/nextjs-website/src/app/[productSlug]/overview/page.tsx @@ -90,7 +90,7 @@ export type OverviewPageProps = { }[]; }; readonly relatedLinks?: { - readonly title: string; + readonly title?: string; readonly links: { text: string; href: string; diff --git a/apps/nextjs-website/src/app/page.tsx b/apps/nextjs-website/src/app/page.tsx index 8ba2f9d854..8f5506c0c2 100644 --- a/apps/nextjs-website/src/app/page.tsx +++ b/apps/nextjs-website/src/app/page.tsx @@ -56,7 +56,7 @@ type EcosystemProps = { }; type ComingSoonDocumentationProps = { - readonly title: string; + readonly title?: string; readonly links: readonly { readonly text: string; readonly href: string; diff --git a/apps/nextjs-website/src/lib/strapi/codecs/RelatedLinksCodec.ts b/apps/nextjs-website/src/lib/strapi/codecs/RelatedLinksCodec.ts index 53fa9ffd4a..4bc222ccc9 100644 --- a/apps/nextjs-website/src/lib/strapi/codecs/RelatedLinksCodec.ts +++ b/apps/nextjs-website/src/lib/strapi/codecs/RelatedLinksCodec.ts @@ -1,7 +1,8 @@ import * as t from 'io-ts/lib'; import { LinkCodec } from './LinkCodec'; +import { NullToUndefinedCodec } from './NullToUndefinedCodec'; export const RelatedLinksCodec = t.type({ - title: t.string, + title: t.union([NullToUndefinedCodec, t.string]), links: t.array(LinkCodec), }); diff --git a/apps/nextjs-website/src/lib/types/webinar.ts b/apps/nextjs-website/src/lib/types/webinar.ts index b0ae646619..7d7dc145ad 100644 --- a/apps/nextjs-website/src/lib/types/webinar.ts +++ b/apps/nextjs-website/src/lib/types/webinar.ts @@ -35,7 +35,7 @@ export type Webinar = { }[]; }; readonly relatedLinks?: { - readonly title: string; + readonly title?: string; readonly links: readonly { readonly text: string; readonly href: string; diff --git a/package-lock.json b/package-lock.json index 3b410b8de4..a0a960bbc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1794,6 +1794,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.696.0.tgz", "integrity": "sha512-hC31OhTlchMkIVExJTLtisay9BgWkHkV1qW/OZhaLiUeiM3FlDi+80ZGaiSg1hoFgOUR5SQL1kEf177/6PWJgg==", + "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -1845,6 +1846,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", @@ -1859,6 +1861,7 @@ "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==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -1870,6 +1873,7 @@ "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==", + "dev": true, "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -1882,6 +1886,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -1894,6 +1899,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -1907,6 +1913,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, "dependencies": { "tslib": "^2.6.2" } @@ -1915,6 +1922,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", @@ -1925,6 +1933,7 @@ "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==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -1936,6 +1945,7 @@ "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==", + "dev": true, "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -1948,6 +1958,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -1960,6 +1971,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2008,6 +2020,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.696.0.tgz", "integrity": "sha512-ikxQ3mo86d1mAq5zTaQAh8rLBERwL+I4MUYu/IVYW2hhl9J2SDsl0SgnKeXQG6S8zWuHcBO587zsZaRta1MQ/g==", + "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2060,6 +2073,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.696.0.tgz", "integrity": "sha512-eJOxR8/UyI7kGSRyE751Ea7MKEzllQs7eNveDJy9OP4t/jsN/P19HJ1YHeA1np40JRTUBfqa6WLAAiIXsk8rkg==", + "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2110,6 +2124,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/core": "^2.5.3", @@ -2131,6 +2146,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2146,6 +2162,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2166,6 +2183,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.696.0.tgz", "integrity": "sha512-9WsZZofjPjNAAZhIh7c7FOhLK8CR3RnGgUm1tdZzV6ZSM1BuS2m6rdwIilRxAh3fxxKDkmW/r/aYmmCYwA+AYA==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/credential-provider-env": "3.696.0", @@ -2191,6 +2209,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.696.0.tgz", "integrity": "sha512-8F6y5FcfRuMJouC5s207Ko1mcVvOXReBOlJmhIwE4QH1CnO/CliIyepnAZrRQ659mo5wIuquz6gXnpYbitEVMg==", + "dev": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.696.0", "@aws-sdk/credential-provider-http": "3.696.0", @@ -2213,6 +2232,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2229,6 +2249,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.696.0.tgz", "integrity": "sha512-4SSZ9Nk08JSu4/rX1a+dEac/Ims1HCXfV7YLUe5LGdtRLSKRoQQUy+hkFaGYoSugP/p1UfUPl3BuTO9Vv8z1pA==", + "dev": true, "dependencies": { "@aws-sdk/client-sso": "3.696.0", "@aws-sdk/core": "3.696.0", @@ -2247,6 +2268,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2265,6 +2287,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/protocol-http": "^4.1.7", @@ -2279,6 +2302,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2292,6 +2316,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/protocol-http": "^4.1.7", @@ -2306,6 +2331,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2323,6 +2349,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/node-config-provider": "^3.1.11", @@ -2339,6 +2366,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.696.0.tgz", "integrity": "sha512-fvTcMADrkwRdNwVmJXi2pSPf1iizmUqczrR1KusH4XehI/KybS4U6ViskRT0v07vpxwL7x+iaD/8fR0PUu5L/g==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/property-provider": "^3.1.9", @@ -2357,6 +2385,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2369,6 +2398,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2383,6 +2413,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2394,6 +2425,7 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "dev": true, "dependencies": { "@aws-sdk/middleware-user-agent": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2417,6 +2449,7 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2429,6 +2462,7 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", + "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/types": "^3.7.1", @@ -2444,6 +2478,7 @@ "version": "2.5.3", "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz", "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==", + "dev": true, "dependencies": { "@smithy/middleware-serde": "^3.0.10", "@smithy/protocol-http": "^4.1.7", @@ -2462,6 +2497,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", + "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/property-provider": "^3.1.10", @@ -2477,6 +2513,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dev": true, "dependencies": { "@smithy/protocol-http": "^4.1.7", "@smithy/querystring-builder": "^3.0.10", @@ -2489,6 +2526,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "@smithy/util-buffer-from": "^3.0.0", @@ -2503,6 +2541,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2512,6 +2551,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2523,6 +2563,7 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", + "dev": true, "dependencies": { "@smithy/protocol-http": "^4.1.7", "@smithy/types": "^3.7.1", @@ -2536,6 +2577,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz", "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==", + "dev": true, "dependencies": { "@smithy/core": "^2.5.3", "@smithy/middleware-serde": "^3.0.10", @@ -2554,6 +2596,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz", "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==", + "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/protocol-http": "^4.1.7", @@ -2573,6 +2616,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2585,6 +2629,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2597,6 +2642,7 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", + "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.10", "@smithy/shared-ini-file-loader": "^3.1.11", @@ -2611,6 +2657,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", + "dev": true, "dependencies": { "@smithy/abort-controller": "^3.1.8", "@smithy/protocol-http": "^4.1.7", @@ -2626,6 +2673,7 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2638,6 +2686,7 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2650,6 +2699,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "@smithy/util-uri-escape": "^3.0.0", @@ -2663,6 +2713,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2675,6 +2726,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1" }, @@ -2686,6 +2738,7 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2698,6 +2751,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", + "dev": true, "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.7", @@ -2716,6 +2770,7 @@ "version": "3.4.4", "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz", "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==", + "dev": true, "dependencies": { "@smithy/core": "^2.5.3", "@smithy/middleware-endpoint": "^3.2.3", @@ -2733,6 +2788,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2744,6 +2800,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", + "dev": true, "dependencies": { "@smithy/querystring-parser": "^3.0.10", "@smithy/types": "^3.7.1", @@ -2754,6 +2811,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "dev": true, "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", @@ -2767,6 +2825,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "dev": true, "dependencies": { "tslib": "^2.6.2" } @@ -2775,6 +2834,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2786,6 +2846,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "dev": true, "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" @@ -2798,6 +2859,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2809,6 +2871,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz", "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==", + "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.10", "@smithy/smithy-client": "^3.4.4", @@ -2824,6 +2887,7 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz", "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==", + "dev": true, "dependencies": { "@smithy/config-resolver": "^3.0.12", "@smithy/credential-provider-imds": "^3.2.7", @@ -2841,6 +2905,7 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", + "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/types": "^3.7.1", @@ -2854,6 +2919,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2865,6 +2931,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", + "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2877,6 +2944,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", + "dev": true, "dependencies": { "@smithy/service-error-classification": "^3.0.10", "@smithy/types": "^3.7.1", @@ -2890,6 +2958,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", + "dev": true, "dependencies": { "@smithy/fetch-http-handler": "^4.1.1", "@smithy/node-http-handler": "^3.3.1", @@ -2908,6 +2977,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2919,6 +2989,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dev": true, "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" @@ -2931,6 +3002,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -52942,7 +53014,6 @@ "packages/active-campaign-client": { "version": "0.1.1", "dependencies": { - "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@types/aws-lambda": "^8.10.126", "@types/jest": "^29.5.1", "aws-lambda": "^1.0.7", @@ -52951,6 +53022,7 @@ "typescript": "^5.0.2" }, "devDependencies": { + "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "^8.57.1", "dotenv": "16.4.5", From 67d15f1d1025e896b5766f7fe4a67198477ce396 Mon Sep 17 00:00:00 2001 From: devportal-portalsandtools-github-bot Date: Wed, 4 Dec 2024 16:52:58 +0100 Subject: [PATCH 09/24] Update CHANGELOG and prepare next release (#1247) --- .changeset/big-zebras-eat.md | 5 ----- .changeset/dry-papayas-switch.md | 5 ----- .changeset/flat-walls-cough.md | 5 ----- .changeset/hungry-eels-stare.md | 5 ----- .changeset/many-pens-grab.md | 5 ----- .changeset/silly-geese-shop.md | 5 ----- .changeset/six-yaks-obey.md | 5 ----- .changeset/smooth-laws-do.md | 5 ----- .changeset/soft-socks-build.md | 5 ----- .changeset/stale-wombats-cover.md | 5 ----- .changeset/ten-trains-grin.md | 5 ----- apps/infrastructure/CHANGELOG.md | 12 ++++++++++++ apps/infrastructure/package.json | 2 +- apps/nextjs-website/CHANGELOG.md | 7 +++++++ apps/nextjs-website/package.json | 2 +- package-lock.json | 6 +++--- packages/active-campaign-client/CHANGELOG.md | 13 +++++++++++++ packages/active-campaign-client/package.json | 2 +- 18 files changed, 38 insertions(+), 61 deletions(-) delete mode 100644 .changeset/big-zebras-eat.md delete mode 100644 .changeset/dry-papayas-switch.md delete mode 100644 .changeset/flat-walls-cough.md delete mode 100644 .changeset/hungry-eels-stare.md delete mode 100644 .changeset/many-pens-grab.md delete mode 100644 .changeset/silly-geese-shop.md delete mode 100644 .changeset/six-yaks-obey.md delete mode 100644 .changeset/smooth-laws-do.md delete mode 100644 .changeset/soft-socks-build.md delete mode 100644 .changeset/stale-wombats-cover.md delete mode 100644 .changeset/ten-trains-grin.md diff --git a/.changeset/big-zebras-eat.md b/.changeset/big-zebras-eat.md deleted file mode 100644 index 4244d795f7..0000000000 --- a/.changeset/big-zebras-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nextjs-website": minor ---- - -Fix related links and webinar codec diff --git a/.changeset/dry-papayas-switch.md b/.changeset/dry-papayas-switch.md deleted file mode 100644 index e52832ac15..0000000000 --- a/.changeset/dry-papayas-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": minor ---- - -Add handler for updating and deleting contact diff --git a/.changeset/flat-walls-cough.md b/.changeset/flat-walls-cough.md deleted file mode 100644 index e35e9653fe..0000000000 --- a/.changeset/flat-walls-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": minor ---- - -Add package setup and the lambda function to add user to Active Campaign diff --git a/.changeset/hungry-eels-stare.md b/.changeset/hungry-eels-stare.md deleted file mode 100644 index 885647f4fb..0000000000 --- a/.changeset/hungry-eels-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nextjs-website": minor ---- - -Add history to send query endpoint diff --git a/.changeset/many-pens-grab.md b/.changeset/many-pens-grab.md deleted file mode 100644 index cbc0f7d35a..0000000000 --- a/.changeset/many-pens-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": minor ---- - -Add handlers for create list and delete list on Active Campaign diff --git a/.changeset/silly-geese-shop.md b/.changeset/silly-geese-shop.md deleted file mode 100644 index a257302d65..0000000000 --- a/.changeset/silly-geese-shop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"infrastructure": minor ---- - -Implemented active campaign syncer infrastructure diff --git a/.changeset/six-yaks-obey.md b/.changeset/six-yaks-obey.md deleted file mode 100644 index 8d7db22d60..0000000000 --- a/.changeset/six-yaks-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"infrastructure": patch ---- - -Fix img_src CSP directive to see also in Dev the images inserted using production's CMS diff --git a/.changeset/smooth-laws-do.md b/.changeset/smooth-laws-do.md deleted file mode 100644 index df459d6565..0000000000 --- a/.changeset/smooth-laws-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"infrastructure": patch ---- - -Added permissions to deploy the ac sync lambdas via GH actions diff --git a/.changeset/soft-socks-build.md b/.changeset/soft-socks-build.md deleted file mode 100644 index ee002d02e0..0000000000 --- a/.changeset/soft-socks-build.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"infrastructure": minor ---- - -Langfuse infrastructure implemented diff --git a/.changeset/stale-wombats-cover.md b/.changeset/stale-wombats-cover.md deleted file mode 100644 index bd6172cb1b..0000000000 --- a/.changeset/stale-wombats-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": minor ---- - -Refactor active campaign pacakge and create index file diff --git a/.changeset/ten-trains-grin.md b/.changeset/ten-trains-grin.md deleted file mode 100644 index 1951726bf8..0000000000 --- a/.changeset/ten-trains-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": patch ---- - -Removed axios, removed .env except than for the test, create new main handler to execute function in aws lambda diff --git a/apps/infrastructure/CHANGELOG.md b/apps/infrastructure/CHANGELOG.md index 278b5cf783..a34f895e62 100644 --- a/apps/infrastructure/CHANGELOG.md +++ b/apps/infrastructure/CHANGELOG.md @@ -1,5 +1,17 @@ # infrastructure +## 1.4.0 + +### Minor Changes + +- e1f67d6: Implemented active campaign syncer infrastructure +- e623940: Langfuse infrastructure implemented + +### Patch Changes + +- bbe33fc: Fix img_src CSP directive to see also in Dev the images inserted using production's CMS +- 94ca22c: Added permissions to deploy the ac sync lambdas via GH actions + ## 1.3.0 ### Minor Changes diff --git a/apps/infrastructure/package.json b/apps/infrastructure/package.json index 23c0fbb057..47276be978 100644 --- a/apps/infrastructure/package.json +++ b/apps/infrastructure/package.json @@ -1,5 +1,5 @@ { "name": "infrastructure", - "version": "1.3.0", + "version": "1.4.0", "private": true } diff --git a/apps/nextjs-website/CHANGELOG.md b/apps/nextjs-website/CHANGELOG.md index b4e15e6da9..b4cb6bad65 100644 --- a/apps/nextjs-website/CHANGELOG.md +++ b/apps/nextjs-website/CHANGELOG.md @@ -1,5 +1,12 @@ # nextjs-website +## 4.13.0 + +### Minor Changes + +- 7ac487f: Fix related links and webinar codec +- fe61351: Add history to send query endpoint + ## 4.12.0 ### Minor Changes diff --git a/apps/nextjs-website/package.json b/apps/nextjs-website/package.json index 75ca40b1c6..56c45d9b2a 100644 --- a/apps/nextjs-website/package.json +++ b/apps/nextjs-website/package.json @@ -1,6 +1,6 @@ { "name": "nextjs-website", - "version": "4.12.0", + "version": "4.13.0", "private": true, "scripts": { "download-docs": "./scripts/fetch-docs.sh docs/from-gitbook", diff --git a/package-lock.json b/package-lock.json index a0a960bbc6..d520543f04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,10 +58,10 @@ } }, "apps/infrastructure": { - "version": "1.3.0" + "version": "1.4.0" }, "apps/nextjs-website": { - "version": "4.12.0", + "version": "4.13.0", "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", "@aws-amplify/auth": "^5.6.6", @@ -53012,7 +53012,7 @@ } }, "packages/active-campaign-client": { - "version": "0.1.1", + "version": "0.2.0", "dependencies": { "@types/aws-lambda": "^8.10.126", "@types/jest": "^29.5.1", diff --git a/packages/active-campaign-client/CHANGELOG.md b/packages/active-campaign-client/CHANGELOG.md index e3ef97d23b..a46830c935 100644 --- a/packages/active-campaign-client/CHANGELOG.md +++ b/packages/active-campaign-client/CHANGELOG.md @@ -1,5 +1,18 @@ # active-campaign-client +## 0.2.0 + +### Minor Changes + +- 3239223: Add handler for updating and deleting contact +- 07703f2: Add package setup and the lambda function to add user to Active Campaign +- 3197206: Add handlers for create list and delete list on Active Campaign +- c6a3f41: Refactor active campaign pacakge and create index file + +### Patch Changes + +- e725bb1: Removed axios, removed .env except than for the test, create new main handler to execute function in aws lambda + ## 0.1.1 ### Patch Changes diff --git a/packages/active-campaign-client/package.json b/packages/active-campaign-client/package.json index 385348bc3f..308850df00 100644 --- a/packages/active-campaign-client/package.json +++ b/packages/active-campaign-client/package.json @@ -1,6 +1,6 @@ { "name": "active-campaign-client", - "version": "0.1.1", + "version": "0.2.0", "description": "Implements ActiveCampaign API to add, update and delete Accounts and to add and update lists", "scripts": { "lint": "eslint src", From d1dae75e7aba1564cdb23efa68e971ff07589752 Mon Sep 17 00:00:00 2001 From: tommaso1 Date: Thu, 5 Dec 2024 09:26:43 +0100 Subject: [PATCH 10/24] [DEV-1983][DEV-1986] Add function to subscribe and unsubscribe contact from active campaign list (#1257) * Add function to subscribe and upsubscribe contact from active campaign list * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/.env.example Co-authored-by: Marco Ponchia * pr comments --------- Co-authored-by: t Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> Co-authored-by: Marco Ponchia --- .changeset/plenty-parrots-attend.md | 5 ++ packages/active-campaign-client/.env.example | 2 + .../helpers/manageListSubscription.test.ts | 21 +++++++ .../src/clients/activeCampaignClient.ts | 23 ++++++- .../src/helpers/manageListSubscription.ts | 60 +++++++++++++++++++ .../src/types/listStatusPayload.ts | 4 +- 6 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 .changeset/plenty-parrots-attend.md create mode 100644 packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts create mode 100644 packages/active-campaign-client/src/helpers/manageListSubscription.ts diff --git a/.changeset/plenty-parrots-attend.md b/.changeset/plenty-parrots-attend.md new file mode 100644 index 0000000000..2dca24136d --- /dev/null +++ b/.changeset/plenty-parrots-attend.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": minor +--- + +Add function to subscribe and upsubscribe contact from active campaign list diff --git a/packages/active-campaign-client/.env.example b/packages/active-campaign-client/.env.example index eca72b4959..9127f4a182 100644 --- a/packages/active-campaign-client/.env.example +++ b/packages/active-campaign-client/.env.example @@ -3,3 +3,5 @@ AC_API_KEY=your_api_key SENDER_URL=localhost:3000 AWS_REGION="region" AWS_USER_POOL_ID="region_DFWF81fRa" +COGNITO_USER_ID=66ae52a0-f051-7080-04a1-465b3a4f44cc +LIST_NAME=test-webinar-1732097286071 \ No newline at end of file diff --git a/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts b/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts new file mode 100644 index 0000000000..a49abb0dd2 --- /dev/null +++ b/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts @@ -0,0 +1,21 @@ +// remove .skip to run the test, be aware it does real API calls +import { + addContactToList, + removeContactToList, +} from '../../helpers/manageListSubscription'; + +describe.skip('manage list subscription', () => { + const cognitoUserId = process.env.COGNITO_USER_ID || ''; + const listName = process.env.LIST_NAME || ''; + + it('should subscribe the contact to the list', async () => { + const result = await addContactToList(cognitoUserId, listName); + + expect(result.statusCode).toBe(200); + }); + + it('should unsubscribe the contact from the list', async () => { + const result = await removeContactToList(cognitoUserId, listName); + expect(result.statusCode).toBe(200); + }); +}); diff --git a/packages/active-campaign-client/src/clients/activeCampaignClient.ts b/packages/active-campaign-client/src/clients/activeCampaignClient.ts index ed3beb1301..b49aab7c46 100644 --- a/packages/active-campaign-client/src/clients/activeCampaignClient.ts +++ b/packages/active-campaign-client/src/clients/activeCampaignClient.ts @@ -1,6 +1,7 @@ import * as https from 'https'; import { ContactPayload } from '../types/contactPayload'; import { ListPayload } from '../types/listPayload'; +import { ListStatusPayload } from '../types/listStatusPayload'; export class ActiveCampaignClient { private readonly baseUrl: string; @@ -22,7 +23,7 @@ export class ActiveCampaignClient { private async makeRequest( method: string, path: string, - data?: ContactPayload | ListPayload, + data?: ContactPayload | ListPayload | ListStatusPayload, params?: Record ): Promise { return new Promise((resolve, reject) => { @@ -111,6 +112,26 @@ export class ActiveCampaignClient { async deleteList(id: number) { return this.makeRequest('DELETE', `/api/3/lists/${id}`); } + + async addContactToList(contactId: string, listId: number) { + return this.makeRequest('POST', `/api/3/contactLists`, { + contactList: { + contact: contactId, + list: listId, + status: 1, // subscribe + }, + }); + } + + async removeContactFromList(contactId: string, listId: number) { + return this.makeRequest('POST', `/api/3/contactLists`, { + contactList: { + contact: contactId, + list: listId, + status: 2, // unsubscrbe + }, + }); + } } export const acClient = new ActiveCampaignClient( diff --git a/packages/active-campaign-client/src/helpers/manageListSubscription.ts b/packages/active-campaign-client/src/helpers/manageListSubscription.ts new file mode 100644 index 0000000000..fe610f656b --- /dev/null +++ b/packages/active-campaign-client/src/helpers/manageListSubscription.ts @@ -0,0 +1,60 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; +import { acClient } from '../clients/activeCampaignClient'; + +export async function addContactToList( + cognitoId: string, + listName: string +): Promise { + try { + const contactId = await acClient.getContactByCognitoId(cognitoId); + if (!contactId) { + return { + statusCode: 404, + body: JSON.stringify({ message: 'Contact not found' }), + }; + } + + const listId = await acClient.getListIdByName(listName); + + const response = await acClient.addContactToList(contactId, listId); + return { + statusCode: 200, + body: JSON.stringify(response), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} + +export async function removeContactToList( + cognitoId: string, + listName: string +): Promise { + try { + const contactId = await acClient.getContactByCognitoId(cognitoId); + if (!contactId) { + return { + statusCode: 404, + body: JSON.stringify({ message: 'Contact not found' }), + }; + } + + const listId = await acClient.getListIdByName(listName); + + const response = await acClient.removeContactFromList(contactId, listId); + return { + statusCode: 200, + body: JSON.stringify(response), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/types/listStatusPayload.ts b/packages/active-campaign-client/src/types/listStatusPayload.ts index 84b34131b8..009119b9ae 100644 --- a/packages/active-campaign-client/src/types/listStatusPayload.ts +++ b/packages/active-campaign-client/src/types/listStatusPayload.ts @@ -1,7 +1,7 @@ export type ListStatusPayload = { readonly contactList: { - readonly list: string; + readonly list: number; readonly contact: string; - readonly status: string; + readonly status: number; }; }; From b9003b60182a27dd558c0098a157cecdccedf4be Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Thu, 5 Dec 2024 09:48:17 +0100 Subject: [PATCH 11/24] [DEV-2045] Refactor index and add queue event parser helper (#1259) * Add function to subscribe and upsubscribe contact from active campaign list * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Refactor index and add queue event parser helper * Update packages/active-campaign-client/.env.example Co-authored-by: Marco Ponchia * pr comments * Connect webinar events to active campaign endpoint * Fix console log --------- Co-authored-by: t Co-authored-by: tommaso1 Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .../listUsersCommandOutputToUser.test.ts | 2 +- .../helpers/queueEventParser.test.ts | 216 ++++++++++++++++++ .../src/handlers/sqsQueueHandler.ts | 46 ++++ .../src/helpers/queueEventParser.ts | 33 +++ packages/active-campaign-client/src/index.ts | 40 +--- .../src/types/queueEvent.ts | 5 +- 6 files changed, 305 insertions(+), 37 deletions(-) create mode 100644 packages/active-campaign-client/src/__tests__/helpers/queueEventParser.test.ts create mode 100644 packages/active-campaign-client/src/handlers/sqsQueueHandler.ts create mode 100644 packages/active-campaign-client/src/helpers/queueEventParser.ts diff --git a/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts b/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts index a2ab058139..d52071522e 100644 --- a/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts +++ b/packages/active-campaign-client/src/__tests__/helpers/listUsersCommandOutputToUser.test.ts @@ -61,7 +61,7 @@ const listUsersCommandOutput: ListUsersCommandOutput = { ], }; -describe('addContact handler', () => { +describe('Helpers: listUsersCommandOutputToUser', () => { it('should properly convert ListUsersCommandOutput to User', async () => { const user = listUsersCommandOutputToUser(listUsersCommandOutput); const expectedUser: User = { diff --git a/packages/active-campaign-client/src/__tests__/helpers/queueEventParser.test.ts b/packages/active-campaign-client/src/__tests__/helpers/queueEventParser.test.ts new file mode 100644 index 0000000000..37db2c381d --- /dev/null +++ b/packages/active-campaign-client/src/__tests__/helpers/queueEventParser.test.ts @@ -0,0 +1,216 @@ +import { queueEventParser } from '../../helpers/queueEventParser'; +import { QueueEvent, QueueEventType } from '../../types/queueEvent'; + +const MOCK_WEBINAR_ID = 'webinar-id'; +const MOCK_COGNITO_ID = 'c67ec280-799a-40d6-b398-2a2b31aefbbd'; + +const generateMockBody = (eventName?: QueueEventType, webinarId?: string) => { + const webinarData = webinarId ? { webinarId } : {}; + return { + ...webinarData, + version: '0', + id: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + 'detail-type': 'AWS API Call via CloudTrail', + source: 'aws.cognito-idp', + account: '99999999999', + time: '2024-11-25T13:34:12Z', + region: 'region', + resources: [], + detail: { + eventVersion: '1.08', + userIdentity: { + type: 'Unknown', + principalId: 'Anonymous', + }, + eventTime: '2024-11-25T13:34:12Z', + eventSource: 'cognito-idp.amazonaws.com', + eventName: `${eventName || 'Unknown'}`, + awsRegion: 'region', + sourceIPAddress: '1.1.1.1', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + requestParameters: { + userAttributes: 'HIDDEN_DUE_TO_SECURITY_REASONS', + accessToken: 'HIDDEN_DUE_TO_SECURITY_REASONS', + }, + responseElements: null, + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + requestID: 'c67ec280-799a-40d6-b398-2a2b31aefbbd', + eventID: '1b231015-853a-4042-a157-4127a9ec5530', + readOnly: false, + eventType: 'AwsApiCall', + managementEvent: true, + recipientAccountId: '999999999', + eventCategory: 'Management', + tlsDetails: { + tlsVersion: 'TLSv1.3', + cipherSuite: 'TLS_AES_128_GCM_SHA256', + clientProvidedHostHeader: 'clientProvidedHostHeader', + }, + }, + }; +}; + +const generateSQSMockEvent = (params?: { + readonly eventType?: QueueEventType; + readonly webinarId?: string; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + readonly customBody?: Record; +}) => ({ + Records: [ + { + messageId: '983ad1cf-e06a-4393-8382-e51af60c4f58', + receiptHandle: 'receiptHandle', + body: JSON.stringify( + params?.customBody || + generateMockBody(params?.eventType, params?.webinarId) + ), + attributes: { + ApproximateReceiveCount: '1', + SentTimestamp: '99999999', + SequenceNumber: '1245', + MessageGroupId: 'userEvents', + SenderId: 'SenderId', + MessageDeduplicationId: 'MessageDeduplicationId', + ApproximateFirstReceiveTimestamp: '99999999', + }, + messageAttributes: {}, + md5OfBody: 'sdf1df457fg71d5sf1dfsd7', + eventSource: 'aws:sqs', + eventSourceARN: 'eventSourceARN', + awsRegion: 'awsRegion', + }, + ], +}); + +describe('Helpers: queueEventParser', () => { + it('should rise an error if event is different from QueueEventType', async () => { + const sqsEvent = generateSQSMockEvent(); + expect(() => { + queueEventParser(sqsEvent); + }).toThrow('Event missing required fields'); + }); + + it('should rise an error if body is not a valid JSON', async () => { + const sqsEvent = generateSQSMockEvent(); + expect(() => { + queueEventParser(sqsEvent); + }).toThrow('Event missing required fields'); + }); + + it('should properly convert UpdateUserAttributes event', async () => { + const sqsEvent = generateSQSMockEvent({ + eventType: 'UpdateUserAttributes', + }); + const parsedQueueEvent = queueEventParser(sqsEvent); + const queueEvent: QueueEvent = { + detail: { + eventName: 'UpdateUserAttributes', + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + }, + }; + expect(parsedQueueEvent.detail.eventName).toEqual( + queueEvent.detail.eventName + ); + expect(parsedQueueEvent.detail.additionalEventData.sub).toEqual( + queueEvent.detail.additionalEventData.sub + ); + }); + + it('should properly convert DeleteUser event', async () => { + const sqsEvent = generateSQSMockEvent({ eventType: 'DeleteUser' }); + const parsedQueueEvent = queueEventParser(sqsEvent); + const queueEvent: QueueEvent = { + detail: { + eventName: 'DeleteUser', + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + }, + }; + expect(parsedQueueEvent.detail.eventName).toEqual( + queueEvent.detail.eventName + ); + expect(parsedQueueEvent.detail.additionalEventData.sub).toEqual( + queueEvent.detail.additionalEventData.sub + ); + }); + + it('should properly convert ConfirmSignUp event', async () => { + const sqsEvent = generateSQSMockEvent({ eventType: 'ConfirmSignUp' }); + const parsedQueueEvent = queueEventParser(sqsEvent); + const queueEvent: QueueEvent = { + detail: { + eventName: 'ConfirmSignUp', + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + }, + }; + expect(parsedQueueEvent.detail.eventName).toEqual( + queueEvent.detail.eventName + ); + expect(parsedQueueEvent.detail.additionalEventData.sub).toEqual( + queueEvent.detail.additionalEventData.sub + ); + }); + + it('should properly convert DynamoINSERT event', async () => { + const sqsEvent = generateSQSMockEvent({ + eventType: 'DynamoINSERT', + webinarId: MOCK_WEBINAR_ID, + }); + const parsedQueueEvent = queueEventParser(sqsEvent); + const queueEvent: QueueEvent = { + detail: { + eventName: 'DynamoINSERT', + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + }, + webinarId: MOCK_WEBINAR_ID, + }; + expect(parsedQueueEvent.detail.eventName).toEqual( + queueEvent.detail.eventName + ); + expect(parsedQueueEvent.detail.additionalEventData.sub).toEqual( + queueEvent.detail.additionalEventData.sub + ); + expect(parsedQueueEvent.webinarId).toEqual(queueEvent.webinarId); + }); + + it('should properly convert DynamoREMOVE event', async () => { + const sqsEvent = generateSQSMockEvent({ + eventType: 'DynamoREMOVE', + webinarId: MOCK_WEBINAR_ID, + }); + const parsedQueueEvent = queueEventParser(sqsEvent); + const queueEvent: QueueEvent = { + detail: { + eventName: 'DynamoREMOVE', + additionalEventData: { + sub: MOCK_COGNITO_ID, + }, + }, + webinarId: MOCK_WEBINAR_ID, + }; + expect(parsedQueueEvent.detail.eventName).toEqual( + queueEvent.detail.eventName + ); + expect(parsedQueueEvent.detail.additionalEventData.sub).toEqual( + queueEvent.detail.additionalEventData.sub + ); + expect(parsedQueueEvent.webinarId).toEqual(queueEvent.webinarId); + }); + + it('should rise an error if webinar id is missing for Dynamo event', async () => { + const sqsEvent = generateSQSMockEvent({ eventType: 'DynamoREMOVE' }); + expect(() => { + queueEventParser(sqsEvent); + }).toThrow('Event missing required fields'); + }); +}); diff --git a/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts b/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts new file mode 100644 index 0000000000..3522ef77fb --- /dev/null +++ b/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts @@ -0,0 +1,46 @@ +import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; +import { getUserFromCognito } from '../helpers/getUserFromCognito'; +import { addContact } from '../helpers/addContact'; +import { updateContact } from '../helpers/updateContact'; +import { deleteContact } from '../helpers/deleteContact'; +import { queueEventParser } from '../helpers/queueEventParser'; +import { + addContactToList, + removeContactToList, +} from '../helpers/manageListSubscription'; + +export async function sqsQueueHandler(event: { + readonly Records: SQSEvent['Records']; +}): Promise { + try { + console.log('Event:', event); // TODO: Remove after testing + const queueEvent = queueEventParser(event); + switch (queueEvent.detail.eventName) { + case 'ConfirmSignUp': + return await addContact(await getUserFromCognito(queueEvent)); + case 'UpdateUserAttributes': + return await updateContact(await getUserFromCognito(queueEvent)); + case 'DeleteUser': + return await deleteContact(queueEvent.detail.additionalEventData.sub); + case 'DynamoINSERT': + return await addContactToList( + queueEvent.detail.additionalEventData.sub, + queueEvent.webinarId || '' + ); + case 'DynamoREMOVE': + return await removeContactToList( + queueEvent.detail.additionalEventData.sub, + queueEvent.webinarId || '' + ); + default: + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Unknown event'); + } + } catch (error) { + console.error('Error:', error); // TODO: Remove after testing + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/helpers/queueEventParser.ts b/packages/active-campaign-client/src/helpers/queueEventParser.ts new file mode 100644 index 0000000000..0b9ae8b8cb --- /dev/null +++ b/packages/active-campaign-client/src/helpers/queueEventParser.ts @@ -0,0 +1,33 @@ +import { SQSEvent } from 'aws-lambda'; +import { QueueEvent, QueueEventType } from '../types/queueEvent'; + +const queueEvents: readonly QueueEventType[] = [ + 'ConfirmSignUp', + 'UpdateUserAttributes', + 'DeleteUser', + 'DynamoINSERT', + 'DynamoREMOVE', +]; + +const dynamoEvents: readonly QueueEventType[] = [ + 'DynamoINSERT', + 'DynamoREMOVE', +]; + +export function queueEventParser(event: { + readonly Records: SQSEvent['Records']; +}): QueueEvent { + const queueEvent = JSON.parse(event.Records[0].body) as unknown as QueueEvent; + + if ( + !queueEvents.includes(queueEvent.detail.eventName) || + !queueEvent.detail.additionalEventData.sub || + (dynamoEvents.includes(queueEvent.detail.eventName) && + !queueEvent.webinarId) + ) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Event missing required fields'); + } + + return queueEvent; +} diff --git a/packages/active-campaign-client/src/index.ts b/packages/active-campaign-client/src/index.ts index a3d2e6fa5e..0d1edb3b65 100644 --- a/packages/active-campaign-client/src/index.ts +++ b/packages/active-campaign-client/src/index.ts @@ -1,38 +1,8 @@ -import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { getUserFromCognito } from './helpers/getUserFromCognito'; -import { QueueEvent } from './types/queueEvent'; -import { addContact } from './helpers/addContact'; -import { updateContact } from './helpers/updateContact'; -import { deleteContact } from './helpers/deleteContact'; +import { SQSEvent } from 'aws-lambda'; +import { sqsQueueHandler } from './handlers/sqsQueueHandler'; -export async function handler(event: { +export async function sqsQueue(event: { readonly Records: SQSEvent['Records']; -}): Promise { - try { - console.log('Event:', event); // TODO: Remove after testing - const queueEvent = JSON.parse( - event.Records[0].body - ) as unknown as QueueEvent; - switch (queueEvent.detail.eventName) { - case 'ConfirmSignUp': - return await addContact(await getUserFromCognito(queueEvent)); - case 'UpdateUserAttributes': - return await updateContact(await getUserFromCognito(queueEvent)); - case 'DeleteUser': - return await deleteContact(queueEvent.detail.additionalEventData.sub); - default: - console.log('Unknown event:', queueEvent.detail.eventName); - break; - } - return { - statusCode: 200, - body: JSON.stringify(event), - }; - } catch (error) { - console.error('Error:', error); - return { - statusCode: 500, - body: JSON.stringify({ message: 'Internal server error' }), - }; - } +}) { + return await sqsQueueHandler(event); } diff --git a/packages/active-campaign-client/src/types/queueEvent.ts b/packages/active-campaign-client/src/types/queueEvent.ts index aee4519189..df216bc813 100644 --- a/packages/active-campaign-client/src/types/queueEvent.ts +++ b/packages/active-campaign-client/src/types/queueEvent.ts @@ -1,7 +1,9 @@ export type QueueEventType = | 'UpdateUserAttributes' | 'DeleteUser' - | 'ConfirmSignUp'; + | 'ConfirmSignUp' + | 'DynamoINSERT' + | 'DynamoREMOVE'; export type QueueEvent = { readonly detail: { @@ -10,4 +12,5 @@ export type QueueEvent = { readonly sub: string; }; }; + readonly webinarId?: string; }; From a7e0508f1ba641c72b06e6d8cbf949bb0ad88bc6 Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Thu, 5 Dec 2024 15:02:51 +0100 Subject: [PATCH 12/24] [DEV-2055] Add ssm to ac client (#1264) * Add function to subscribe and upsubscribe contact from active campaign list * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/__tests__/handlers/manageListSubscription.test.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Refactor index and add queue event parser helper * Update packages/active-campaign-client/.env.example Co-authored-by: Marco Ponchia * pr comments * Connect webinar events to active campaign endpoint * Fix console log * Add ssm client * Fix package lock --------- Co-authored-by: t Co-authored-by: tommaso1 Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/modern-hairs-train.md | 5 + .changeset/plenty-parrots-attend.md | 5 - package-lock.json | 1827 +++++++++++++---- packages/active-campaign-client/.env.example | 4 +- packages/active-campaign-client/package.json | 3 +- .../src/clients/activeCampaignClient.ts | 50 +- 6 files changed, 1507 insertions(+), 387 deletions(-) create mode 100644 .changeset/modern-hairs-train.md delete mode 100644 .changeset/plenty-parrots-attend.md diff --git a/.changeset/modern-hairs-train.md b/.changeset/modern-hairs-train.md new file mode 100644 index 0000000000..84a3789b1c --- /dev/null +++ b/.changeset/modern-hairs-train.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": minor +--- + +Add SSM client to mange secrets diff --git a/.changeset/plenty-parrots-attend.md b/.changeset/plenty-parrots-attend.md deleted file mode 100644 index 2dca24136d..0000000000 --- a/.changeset/plenty-parrots-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"active-campaign-client": minor ---- - -Add function to subscribe and upsubscribe contact from active campaign list diff --git a/package-lock.json b/package-lock.json index d520543f04..5ef4494002 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1794,7 +1794,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.696.0.tgz", "integrity": "sha512-hC31OhTlchMkIVExJTLtisay9BgWkHkV1qW/OZhaLiUeiM3FlDi+80ZGaiSg1hoFgOUR5SQL1kEf177/6PWJgg==", - "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -1846,7 +1845,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "dev": true, "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", @@ -1861,7 +1859,6 @@ "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==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -1873,7 +1870,6 @@ "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==", - "dev": true, "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -1886,7 +1882,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dev": true, "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -1899,7 +1894,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "dev": true, "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -1913,7 +1907,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "dev": true, "dependencies": { "tslib": "^2.6.2" } @@ -1922,7 +1915,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "dev": true, "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", @@ -1933,7 +1925,6 @@ "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==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -1945,7 +1936,6 @@ "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==", - "dev": true, "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -1958,7 +1948,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dev": true, "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -1971,7 +1960,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", - "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2020,7 +2008,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.696.0.tgz", "integrity": "sha512-ikxQ3mo86d1mAq5zTaQAh8rLBERwL+I4MUYu/IVYW2hhl9J2SDsl0SgnKeXQG6S8zWuHcBO587zsZaRta1MQ/g==", - "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2073,7 +2060,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.696.0.tgz", "integrity": "sha512-eJOxR8/UyI7kGSRyE751Ea7MKEzllQs7eNveDJy9OP4t/jsN/P19HJ1YHeA1np40JRTUBfqa6WLAAiIXsk8rkg==", - "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2124,7 +2110,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/core": "^2.5.3", @@ -2146,7 +2131,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2162,7 +2146,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2183,7 +2166,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.696.0.tgz", "integrity": "sha512-9WsZZofjPjNAAZhIh7c7FOhLK8CR3RnGgUm1tdZzV6ZSM1BuS2m6rdwIilRxAh3fxxKDkmW/r/aYmmCYwA+AYA==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/credential-provider-env": "3.696.0", @@ -2209,7 +2191,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.696.0.tgz", "integrity": "sha512-8F6y5FcfRuMJouC5s207Ko1mcVvOXReBOlJmhIwE4QH1CnO/CliIyepnAZrRQ659mo5wIuquz6gXnpYbitEVMg==", - "dev": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.696.0", "@aws-sdk/credential-provider-http": "3.696.0", @@ -2232,7 +2213,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2249,7 +2229,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.696.0.tgz", "integrity": "sha512-4SSZ9Nk08JSu4/rX1a+dEac/Ims1HCXfV7YLUe5LGdtRLSKRoQQUy+hkFaGYoSugP/p1UfUPl3BuTO9Vv8z1pA==", - "dev": true, "dependencies": { "@aws-sdk/client-sso": "3.696.0", "@aws-sdk/core": "3.696.0", @@ -2268,7 +2247,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2287,7 +2265,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/protocol-http": "^4.1.7", @@ -2302,7 +2279,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2316,7 +2292,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/protocol-http": "^4.1.7", @@ -2331,7 +2306,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", - "dev": true, "dependencies": { "@aws-sdk/core": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2349,7 +2323,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/node-config-provider": "^3.1.11", @@ -2366,7 +2339,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.696.0.tgz", "integrity": "sha512-fvTcMADrkwRdNwVmJXi2pSPf1iizmUqczrR1KusH4XehI/KybS4U6ViskRT0v07vpxwL7x+iaD/8fR0PUu5L/g==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/property-provider": "^3.1.9", @@ -2385,7 +2357,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2398,7 +2369,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2413,7 +2383,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", - "dev": true, "dependencies": { "@aws-sdk/types": "3.696.0", "@smithy/types": "^3.7.1", @@ -2425,7 +2394,6 @@ "version": "3.696.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", - "dev": true, "dependencies": { "@aws-sdk/middleware-user-agent": "3.696.0", "@aws-sdk/types": "3.696.0", @@ -2449,7 +2417,6 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2462,7 +2429,6 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", - "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/types": "^3.7.1", @@ -2478,7 +2444,6 @@ "version": "2.5.3", "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz", "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==", - "dev": true, "dependencies": { "@smithy/middleware-serde": "^3.0.10", "@smithy/protocol-http": "^4.1.7", @@ -2497,7 +2462,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", - "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/property-provider": "^3.1.10", @@ -2513,7 +2477,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", - "dev": true, "dependencies": { "@smithy/protocol-http": "^4.1.7", "@smithy/querystring-builder": "^3.0.10", @@ -2526,7 +2489,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "@smithy/util-buffer-from": "^3.0.0", @@ -2541,7 +2503,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2551,7 +2512,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2563,7 +2523,6 @@ "version": "3.0.12", "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", - "dev": true, "dependencies": { "@smithy/protocol-http": "^4.1.7", "@smithy/types": "^3.7.1", @@ -2577,7 +2536,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz", "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==", - "dev": true, "dependencies": { "@smithy/core": "^2.5.3", "@smithy/middleware-serde": "^3.0.10", @@ -2596,7 +2554,6 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz", "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==", - "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/protocol-http": "^4.1.7", @@ -2616,7 +2573,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2629,7 +2585,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2642,7 +2597,6 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", - "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.10", "@smithy/shared-ini-file-loader": "^3.1.11", @@ -2657,7 +2611,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", - "dev": true, "dependencies": { "@smithy/abort-controller": "^3.1.8", "@smithy/protocol-http": "^4.1.7", @@ -2673,7 +2626,6 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2686,7 +2638,6 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2699,7 +2650,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "@smithy/util-uri-escape": "^3.0.0", @@ -2713,7 +2663,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2726,7 +2675,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1" }, @@ -2738,7 +2686,6 @@ "version": "3.1.11", "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2751,7 +2698,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", - "dev": true, "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.7", @@ -2770,7 +2716,6 @@ "version": "3.4.4", "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz", "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==", - "dev": true, "dependencies": { "@smithy/core": "^2.5.3", "@smithy/middleware-endpoint": "^3.2.3", @@ -2788,7 +2733,6 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2800,7 +2744,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", - "dev": true, "dependencies": { "@smithy/querystring-parser": "^3.0.10", "@smithy/types": "^3.7.1", @@ -2811,7 +2754,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "dev": true, "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", @@ -2825,7 +2767,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "dev": true, "dependencies": { "tslib": "^2.6.2" } @@ -2834,7 +2775,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2846,7 +2786,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "dev": true, "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" @@ -2859,7 +2798,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2871,7 +2809,6 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz", "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==", - "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.10", "@smithy/smithy-client": "^3.4.4", @@ -2887,7 +2824,6 @@ "version": "3.0.27", "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz", "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==", - "dev": true, "dependencies": { "@smithy/config-resolver": "^3.0.12", "@smithy/credential-provider-imds": "^3.2.7", @@ -2905,7 +2841,6 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", - "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.11", "@smithy/types": "^3.7.1", @@ -2919,7 +2854,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2931,7 +2865,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", - "dev": true, "dependencies": { "@smithy/types": "^3.7.1", "tslib": "^2.6.2" @@ -2944,7 +2877,6 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", - "dev": true, "dependencies": { "@smithy/service-error-classification": "^3.0.10", "@smithy/types": "^3.7.1", @@ -2958,7 +2890,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", - "dev": true, "dependencies": { "@smithy/fetch-http-handler": "^4.1.1", "@smithy/node-http-handler": "^3.3.1", @@ -2977,7 +2908,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "dev": true, "dependencies": { "tslib": "^2.6.2" }, @@ -2989,7 +2919,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "dev": true, "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" @@ -3002,7 +2931,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -6644,405 +6572,1570 @@ "tslib": "^2.5.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/util": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/client-sso": { + "version": "3.441.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.441.0", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.438.0", + "@aws-sdk/region-config-resolver": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.438.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.437.0", + "@smithy/config-resolver": "^2.0.16", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-endpoints": "^1.0.2", + "@smithy/util-retry": "^2.0.5", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/client-sts": { + "version": "3.441.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.441.0", + "@aws-sdk/credential-provider-node": "3.441.0", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-sdk-sts": "3.433.0", + "@aws-sdk/middleware-signing": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.438.0", + "@aws-sdk/region-config-resolver": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.438.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.437.0", + "@smithy/config-resolver": "^2.0.16", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-endpoints": "^1.0.2", + "@smithy/util-retry": "^2.0.5", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.441.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.433.0", + "@aws-sdk/credential-provider-process": "3.433.0", + "@aws-sdk/credential-provider-sso": "3.441.0", + "@aws-sdk/credential-provider-web-identity": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.441.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.433.0", + "@aws-sdk/credential-provider-ini": "3.441.0", + "@aws-sdk/credential-provider-process": "3.433.0", + "@aws-sdk/credential-provider-sso": "3.441.0", + "@aws-sdk/credential-provider-web-identity": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.441.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.441.0", + "@aws-sdk/token-providers": "3.438.0", + "@aws-sdk/types": "3.433.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-logger": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-signing": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-signing": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/signature-v4": "^2.0.0", + "@smithy/types": "^2.4.0", + "@smithy/util-middleware": "^2.0.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.438.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.438.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/types": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.433.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.437.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/types": "^2.4.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-ses/node_modules/fast-xml-parser": { + "version": "4.2.5", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/@aws-sdk/client-ssm": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.699.0.tgz", + "integrity": "sha512-ROynEZI8RZC+NkQP/BBcdkhGHuk+RJkinemxmsTt8FGYqHlK/7hcOjWitziAGpmjWfPm4a6UAtqeNg/AX7nvlw==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.9", + "@types/uuid": "^9.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "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.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "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.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "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.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/client-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", + "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz", + "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/client-sts": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz", + "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/core": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", + "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", + "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", + "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz", + "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz", + "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.699.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", + "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz", + "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==", + "dependencies": { + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/token-providers": "3.699.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", + "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", + "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/middleware-logger": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", + "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", + "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", + "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", + "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/token-providers": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz", + "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/types": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", + "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/util-endpoints": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", + "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "@smithy/util-endpoints": "^2.1.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", + "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", + "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/abort-controller": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/config-resolver": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", + "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/core": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.4.tgz", + "integrity": "sha512-iFh2Ymn2sCziBRLPuOOxRPkuCx/2gBdXtBGuCUFLUe6bWYjKnhHyIPqGeNkLZ5Aco/5GjebRTBFiWID3sDbrKw==", + "dependencies": { + "@smithy/middleware-serde": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-stream": "^3.3.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/credential-provider-imds": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", + "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/hash-node": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", + "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", + "dependencies": { + "@smithy/types": "^3.7.1", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/invalid-dependency": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", + "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/middleware-content-length": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", + "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/middleware-endpoint": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.4.tgz", + "integrity": "sha512-TybiW2LA3kYVd3e+lWhINVu1o26KJbBwOpADnf0L4x/35vLVica77XVR5hvV9+kWeTGeSJ3IHTcYxbRxlbwhsg==", + "dependencies": { + "@smithy/core": "^2.5.4", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/middleware-retry": { + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.28.tgz", + "integrity": "sha512-vK2eDfvIXG1U64FEUhYxoZ1JSj4XFbYWkK36iz02i3pFwWiDz1Q7jKhGTBCwx/7KqJNk4VS7d7cDLXFOvP7M+g==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.7", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/middleware-serde": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", + "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/middleware-stack": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", + "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/node-config-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", "dependencies": { - "tslib": "^1.11.1" + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-browser": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/node-http-handler": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", + "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/abort-controller": "^3.1.8", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-js": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/property-provider": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/supports-web-crypto": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/protocol-http": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", + "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", "dependencies": { - "tslib": "^1.11.1" + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/util": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/querystring-builder": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", + "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/types": "^3.7.1", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/querystring-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", + "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/client-sso": { - "version": "3.441.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/service-error-classification": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", + "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.441.0", - "@aws-sdk/middleware-host-header": "3.433.0", - "@aws-sdk/middleware-logger": "3.433.0", - "@aws-sdk/middleware-recursion-detection": "3.433.0", - "@aws-sdk/middleware-user-agent": "3.438.0", - "@aws-sdk/region-config-resolver": "3.433.0", - "@aws-sdk/types": "3.433.0", - "@aws-sdk/util-endpoints": "3.438.0", - "@aws-sdk/util-user-agent-browser": "3.433.0", - "@aws-sdk/util-user-agent-node": "3.437.0", - "@smithy/config-resolver": "^2.0.16", - "@smithy/fetch-http-handler": "^2.2.4", - "@smithy/hash-node": "^2.0.12", - "@smithy/invalid-dependency": "^2.0.12", - "@smithy/middleware-content-length": "^2.0.14", - "@smithy/middleware-endpoint": "^2.1.3", - "@smithy/middleware-retry": "^2.0.18", - "@smithy/middleware-serde": "^2.0.12", - "@smithy/middleware-stack": "^2.0.6", - "@smithy/node-config-provider": "^2.1.3", - "@smithy/node-http-handler": "^2.1.8", - "@smithy/protocol-http": "^3.0.8", - "@smithy/smithy-client": "^2.1.12", - "@smithy/types": "^2.4.0", - "@smithy/url-parser": "^2.0.12", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.16", - "@smithy/util-defaults-mode-node": "^2.0.21", - "@smithy/util-endpoints": "^1.0.2", - "@smithy/util-retry": "^2.0.5", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/client-sts": { - "version": "3.441.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.441.0", - "@aws-sdk/credential-provider-node": "3.441.0", - "@aws-sdk/middleware-host-header": "3.433.0", - "@aws-sdk/middleware-logger": "3.433.0", - "@aws-sdk/middleware-recursion-detection": "3.433.0", - "@aws-sdk/middleware-sdk-sts": "3.433.0", - "@aws-sdk/middleware-signing": "3.433.0", - "@aws-sdk/middleware-user-agent": "3.438.0", - "@aws-sdk/region-config-resolver": "3.433.0", - "@aws-sdk/types": "3.433.0", - "@aws-sdk/util-endpoints": "3.438.0", - "@aws-sdk/util-user-agent-browser": "3.433.0", - "@aws-sdk/util-user-agent-node": "3.437.0", - "@smithy/config-resolver": "^2.0.16", - "@smithy/fetch-http-handler": "^2.2.4", - "@smithy/hash-node": "^2.0.12", - "@smithy/invalid-dependency": "^2.0.12", - "@smithy/middleware-content-length": "^2.0.14", - "@smithy/middleware-endpoint": "^2.1.3", - "@smithy/middleware-retry": "^2.0.18", - "@smithy/middleware-serde": "^2.0.12", - "@smithy/middleware-stack": "^2.0.6", - "@smithy/node-config-provider": "^2.1.3", - "@smithy/node-http-handler": "^2.1.8", - "@smithy/protocol-http": "^3.0.8", - "@smithy/smithy-client": "^2.1.12", - "@smithy/types": "^2.4.0", - "@smithy/url-parser": "^2.0.12", - "@smithy/util-base64": "^2.0.0", - "@smithy/util-body-length-browser": "^2.0.0", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.16", - "@smithy/util-defaults-mode-node": "^2.0.21", - "@smithy/util-endpoints": "^1.0.2", - "@smithy/util-retry": "^2.0.5", - "@smithy/util-utf8": "^2.0.0", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/signature-v4": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", + "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.441.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/smithy-client": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.5.tgz", + "integrity": "sha512-k0sybYT9zlP79sIKd1XGm4TmK0AS1nA2bzDHXx7m0nGi3RQ8dxxQUs4CPkSmQTKAo+KF9aINU3KzpGIpV7UoMw==", "dependencies": { - "@aws-sdk/credential-provider-env": "3.433.0", - "@aws-sdk/credential-provider-process": "3.433.0", - "@aws-sdk/credential-provider-sso": "3.441.0", - "@aws-sdk/credential-provider-web-identity": "3.433.0", - "@aws-sdk/types": "3.433.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/core": "^2.5.4", + "@smithy/middleware-endpoint": "^3.2.4", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.441.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/types": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dependencies": { - "@aws-sdk/credential-provider-env": "3.433.0", - "@aws-sdk/credential-provider-ini": "3.441.0", - "@aws-sdk/credential-provider-process": "3.433.0", - "@aws-sdk/credential-provider-sso": "3.441.0", - "@aws-sdk/credential-provider-web-identity": "3.433.0", - "@aws-sdk/types": "3.433.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/url-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", + "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/querystring-parser": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.441.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", "dependencies": { - "@aws-sdk/client-sso": "3.441.0", - "@aws-sdk/token-providers": "3.438.0", - "@aws-sdk/types": "3.433.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dependencies": { + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/protocol-http": "^3.0.8", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-logger": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-defaults-mode-browser": { + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.28.tgz", + "integrity": "sha512-6bzwAbZpHRFVJsOztmov5PGDmJYsbNSoIEfHSJJyFLzfBGCCChiO3od9k7E/TLgrCsIifdAbB9nqbVbyE7wRUw==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.28.tgz", + "integrity": "sha512-78ENJDorV1CjOQselGmm3+z7Yqjj5HWCbjzh0Ixuq736dh1oEnD9sAttSBNSLlpZsX8VQnmERqA2fEFlmqWn8w==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/protocol-http": "^3.0.8", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/config-resolver": "^3.0.12", + "@smithy/credential-provider-imds": "^3.2.7", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-endpoints": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", + "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", "dependencies": { - "@aws-sdk/middleware-signing": "3.433.0", - "@aws-sdk/types": "3.433.0", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-signing": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^3.0.8", - "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.4.0", - "@smithy/util-middleware": "^2.0.5", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.438.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-middleware": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@aws-sdk/util-endpoints": "3.438.0", - "@smithy/protocol-http": "^3.0.8", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/types": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-retry": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", + "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", "dependencies": { - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "@smithy/service-error-classification": "^3.0.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.433.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-stream": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", + "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/types": "^2.4.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.437.0", - "license": "Apache-2.0", + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", "dependencies": { - "@aws-sdk/types": "3.433.0", - "@smithy/node-config-provider": "^2.1.3", - "@smithy/types": "^2.4.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "aws-crt": ">=1.0.0" + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm/node_modules/@smithy/util-waiter": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.9.tgz", + "integrity": "sha512-/aMXPANhMOlMPjfPtSrDfPeVP8l56SJlz93xeiLmhLe5xvlXA5T3abZ2ilEsDEPeY9T/wnN/vNGn9wa1SbufWA==", + "dependencies": { + "@smithy/abort-controller": "^3.1.8", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/client-ses/node_modules/fast-xml-parser": { - "version": "4.2.5", + "node_modules/@aws-sdk/client-ssm/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" ], - "license": "MIT", - "dependencies": { - "strnum": "^1.0.5" - }, "bin": { - "fxparser": "src/cli/cli.js" + "uuid": "dist/bin/uuid" } }, "node_modules/@aws-sdk/client-sso": { @@ -26869,7 +27962,6 @@ }, "node_modules/@types/uuid": { "version": "9.0.8", - "dev": true, "license": "MIT" }, "node_modules/@types/ws": { @@ -53014,6 +54106,8 @@ "packages/active-campaign-client": { "version": "0.2.0", "dependencies": { + "@aws-sdk/client-cognito-identity-provider": "^3.696.0", + "@aws-sdk/client-ssm": "^3.699.0", "@types/aws-lambda": "^8.10.126", "@types/jest": "^29.5.1", "aws-lambda": "^1.0.7", @@ -53022,7 +54116,6 @@ "typescript": "^5.0.2" }, "devDependencies": { - "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "^8.57.1", "dotenv": "16.4.5", diff --git a/packages/active-campaign-client/.env.example b/packages/active-campaign-client/.env.example index 9127f4a182..c9ffddf5e6 100644 --- a/packages/active-campaign-client/.env.example +++ b/packages/active-campaign-client/.env.example @@ -4,4 +4,6 @@ SENDER_URL=localhost:3000 AWS_REGION="region" AWS_USER_POOL_ID="region_DFWF81fRa" COGNITO_USER_ID=66ae52a0-f051-7080-04a1-465b3a4f44cc -LIST_NAME=test-webinar-1732097286071 \ No newline at end of file +LIST_NAME=test-webinar-1732097286071 +AC_BASE_URL_PARAM='/ac/base_url' +AC_API_KEY_PARAM='/ac/api_key' diff --git a/packages/active-campaign-client/package.json b/packages/active-campaign-client/package.json index 308850df00..4b0b81bca5 100644 --- a/packages/active-campaign-client/package.json +++ b/packages/active-campaign-client/package.json @@ -8,7 +8,6 @@ "build": "tsc" }, "devDependencies": { - "@aws-sdk/client-cognito-identity-provider": "^3.696.0", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "^8.57.1", "dotenv": "16.4.5", @@ -16,6 +15,8 @@ "eslint-config-custom": "^0.1.0" }, "dependencies": { + "@aws-sdk/client-cognito-identity-provider": "^3.696.0", + "@aws-sdk/client-ssm": "^3.699.0", "@types/aws-lambda": "^8.10.126", "@types/jest": "^29.5.1", "aws-lambda": "^1.0.7", diff --git a/packages/active-campaign-client/src/clients/activeCampaignClient.ts b/packages/active-campaign-client/src/clients/activeCampaignClient.ts index b49aab7c46..7b3c12492f 100644 --- a/packages/active-campaign-client/src/clients/activeCampaignClient.ts +++ b/packages/active-campaign-client/src/clients/activeCampaignClient.ts @@ -1,21 +1,41 @@ import * as https from 'https'; +import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'; import { ContactPayload } from '../types/contactPayload'; import { ListPayload } from '../types/listPayload'; import { ListStatusPayload } from '../types/listStatusPayload'; +async function getParameter( + paramName: string, + ssmClient: SSMClient, + fallbackValue?: string +) { + // TODO: remove fallbackValue only for testing purposes should be substituted by a mock function + if (fallbackValue) { + return fallbackValue; + } + const command = new GetParameterCommand({ + Name: paramName, + WithDecryption: true, // Use this if the parameter is encrypted + }); + const response = await ssmClient.send(command); + + return response.Parameter?.Value; +} + export class ActiveCampaignClient { - private readonly baseUrl: string; - private readonly apiKey: string; + private readonly baseUrlParam: string; + private readonly apiKeyParam: string; + + private readonly ssm = new SSMClient(); - constructor(baseUrl: string, apiKey: string) { - // Remove any trailing slashes from the baseUrl - this.baseUrl = baseUrl.replace(/\/$/, ''); - this.apiKey = apiKey; + constructor(baseUrlParam?: string, apiKeyParam?: string) { + this.baseUrlParam = baseUrlParam || ''; + this.apiKeyParam = apiKeyParam || ''; } - private getHeaders() { + private getHeaders(apiKey: string) { return { - 'Api-Token': this.apiKey, + 'Api-Token': apiKey, 'Content-Type': 'application/json', }; } @@ -26,9 +46,13 @@ export class ActiveCampaignClient { data?: ContactPayload | ListPayload | ListStatusPayload, params?: Record ): Promise { + const [apiKey, baseUrl] = await Promise.all([ + getParameter(this.apiKeyParam, this.ssm, process.env.AC_API_KEY), + getParameter(this.baseUrlParam, this.ssm, process.env.AC_BASE_URL), + ]); return new Promise((resolve, reject) => { - // Parse the base URL to get hostname and path - const url = new URL(path, this.baseUrl); + // Parse the base URL to get hostname and path and remove any trailing slashes from the baseUrl + const url = new URL(path, baseUrl?.replace(/\/$/, '')); // Add query parameters if they exist if (params) { @@ -41,7 +65,7 @@ export class ActiveCampaignClient { method, hostname: url.hostname, path: `${url.pathname}${url.search}`, - headers: this.getHeaders(), + headers: this.getHeaders(apiKey || ''), }; const req = https.request(options, (res) => { @@ -135,6 +159,6 @@ export class ActiveCampaignClient { } export const acClient = new ActiveCampaignClient( - process.env.AC_BASE_URL || '', - process.env.AC_API_KEY || '' + process.env.AC_BASE_URL_PARAM, + process.env.AC_API_KEY_PARAM ); From 22aea81ac2322be58a247bb33f9b296fcdf61f76 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Thu, 5 Dec 2024 16:48:00 +0100 Subject: [PATCH 13/24] fix: handler in ac sync lambda (#1267) --- .changeset/eighty-seals-worry.md | 5 +++++ apps/infrastructure/src/modules/active_campaign/lambda.tf | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/eighty-seals-worry.md diff --git a/.changeset/eighty-seals-worry.md b/.changeset/eighty-seals-worry.md new file mode 100644 index 0000000000..c8ce6b94b8 --- /dev/null +++ b/.changeset/eighty-seals-worry.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Change ac sync lambda handler to index.sqsQueue diff --git a/apps/infrastructure/src/modules/active_campaign/lambda.tf b/apps/infrastructure/src/modules/active_campaign/lambda.tf index dbcaeb6bbc..1eb481488f 100644 --- a/apps/infrastructure/src/modules/active_campaign/lambda.tf +++ b/apps/infrastructure/src/modules/active_campaign/lambda.tf @@ -14,7 +14,7 @@ module "lambda_sync" { runtime = "nodejs20.x" architectures = ["x86_64"] - handler = "index.handler" + handler = "index.sqsQueue" source_path = "${path.module}/functions" ignore_source_code_hash = true create_current_version_allowed_triggers = false From 82b7d4b1c8c082fe0a6b8bb55b2d01c9c5fbd570 Mon Sep 17 00:00:00 2001 From: marcobottaro <39835990+marcobottaro@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:00:54 +0100 Subject: [PATCH 14/24] [DEV-2047] Add Active Campaign integration to create and delete lists when creating and deleting webinars (#1260) * Add Active Campaign integration to create and delete lists when creating and deleting webinars * Fix naming and refactor error handling * update lifecycle env var retrive --------- Co-authored-by: Marco Ponchia Co-authored-by: Marco Ponchia --- .changeset/weak-monkeys-grab.md | 5 + apps/strapi-cms/.env.default | 6 + apps/strapi-cms/package.json | 1 + .../content-types/webinar/lifecycles.ts | 163 +++++++++++++++++- package-lock.json | 12 ++ 5 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 .changeset/weak-monkeys-grab.md diff --git a/.changeset/weak-monkeys-grab.md b/.changeset/weak-monkeys-grab.md new file mode 100644 index 0000000000..2989ca349d --- /dev/null +++ b/.changeset/weak-monkeys-grab.md @@ -0,0 +1,5 @@ +--- +"strapi-cms": minor +--- + +Add Active Campaign integration to create and delete lists when creating and deleting webinars diff --git a/apps/strapi-cms/.env.default b/apps/strapi-cms/.env.default index 9c70738f7f..f513d49b2b 100644 --- a/apps/strapi-cms/.env.default +++ b/apps/strapi-cms/.env.default @@ -55,3 +55,9 @@ GOOGLE_OAUTH_CLIENT_ID= GOOGLE_OAUTH_CLIENT_SECRET= GOOGLE_OAUTH_REDIRECT_URI= GOOGLE_GSUITE_HD= + +# ACTIVE CAMPAIGN +ACTIVE_CAMPAIGN_INTEGRATION_IS_ENABLED=True +AC_BASE_URL=https://.activehosted.com +AC_API_KEY=your_api_key +SENDER_URL=your_server_url diff --git a/apps/strapi-cms/package.json b/apps/strapi-cms/package.json index cbbce99ac5..792c028112 100644 --- a/apps/strapi-cms/package.json +++ b/apps/strapi-cms/package.json @@ -20,6 +20,7 @@ "@strapi/plugin-users-permissions": "4.24.2", "@strapi/provider-upload-aws-s3": "^4.24.2", "@strapi/strapi": "4.24.2", + "axios": "^1.7.8", "better-sqlite3": "8.6.0", "pg": "^8.11.5", "react": "^18.2.0", diff --git a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts index 26f5bad5ed..cc0af4ca3e 100644 --- a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts +++ b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts @@ -1,10 +1,37 @@ -import { errors } from '@strapi/utils'; +import { errors, env } from '@strapi/utils'; +import axios from 'axios'; + +interface IActiveCampaignListPayload { + readonly list: { + readonly name: string; + readonly stringid: string; + readonly sender_url: string; + readonly sender_reminder: string; + readonly subscription_notify?: string; + readonly unsubscription_notify?: string; + }; +} + +const activeCampaignIntegrationIsEnabled = + env('ACTIVE_CAMPAIGN_INTEGRATION_IS_ENABLED', 'False') === 'True'; + +function getHeaders() { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'Api-Token': env('AC_API_KEY', ''), + // eslint-disable-next-line @typescript-eslint/naming-convention + 'Content-Type': 'application/json', + }; +} interface IWebinar { + readonly id?: string; readonly slug?: string; + readonly title?: string; readonly locale?: string; readonly startDatetime?: string; readonly endDatetime?: string; + readonly publishedAt?: string; } interface IWebinarEvent { @@ -14,6 +41,7 @@ interface IWebinarEvent { readonly id?: string; }; }; + readonly result: IWebinar; } const validateDates = (event: IWebinarEvent): boolean => { @@ -36,11 +64,142 @@ const validateDates = (event: IWebinarEvent): boolean => { return true; }; +const validateSlug = async (event: IWebinarEvent): Promise => { + const { id } = event.params.data; + if (!id) { + throw new errors.ApplicationError('Webinar id not found'); + } + const previousWebinar = await strapi.db + .query('api::webinar.webinar') + .findOne({ + select: ['slug'], + where: { id }, + }); + if (previousWebinar && previousWebinar.slug !== event.params.data.slug) { + throw new errors.ApplicationError( + 'The slug of a webinar cannot be changed' + ); + } + return true; +}; + +const activeCampaignError = (message: string) => { + throw new errors.ApplicationError( + `Something went wrong during Active Campaign ${message}` + ); +}; + +const createActiveCampaignList = async ( + event: IWebinarEvent +): Promise => { + if ( + !activeCampaignIntegrationIsEnabled || + !event.result?.slug || + !event.result?.title + ) { + return true; + } + + const { slug: name, title: stringid } = event.result; + + const payload: IActiveCampaignListPayload = { + list: { + name, + sender_reminder: '', + sender_url: `${env( + 'SENDER_URL', + 'http://localhost:3000/' + )}/webinars/${name}`, + stringid, + subscription_notify: '', + unsubscription_notify: '', + }, + }; + + const response = await axios + .post(`${env('AC_BASE_URL')}/api/3/lists`, payload, { + headers: getHeaders(), + }) + .catch((_) => { + activeCampaignError('list creation'); + }); + + if (response?.status !== 201) { + activeCampaignError('list creation'); + } + + return response?.status === 201; +}; + +const getListIdByName = async (name: string): Promise => { + const response = await axios.get<{ + readonly lists: ReadonlyArray<{ readonly id: number }>; + }>( + `${env('AC_BASE_URL')}/api/3/lists`, + // eslint-disable-next-line @typescript-eslint/naming-convention + { headers: getHeaders(), params: { 'filters[name][eq]': name } } + ); + return response?.data.lists[0]?.id; +}; + +const deleteActiveCampaignList = async ( + event: IWebinarEvent +): Promise => { + if ( + !activeCampaignIntegrationIsEnabled || + !event?.params.where || + !event.params.where.id + ) { + return true; + } + const webinar = await strapi.db + .query('api::webinar.webinar') + .findOne({ where: { id: event.params.where.id } }); + + if (!webinar?.slug) { + activeCampaignError('list deletion: webinar slug is missing'); + } + // Get list ID using the slug (name) + const listId = await getListIdByName(webinar.slug); + + if (!listId) { + return false; + } + + const response = await axios + .delete(`${env('AC_BASE_URL')}/api/3/lists/${listId}`, { + headers: getHeaders(), + }) + .catch((_) => { + activeCampaignError('list deletion'); + }); + + if (response?.status !== 200) { + activeCampaignError('list deletion'); + } + + return response?.status === 200; +}; + module.exports = { + async afterCreate(event: IWebinarEvent) { + await createActiveCampaignList(event); + }, beforeCreate(event: IWebinarEvent) { validateDates(event); }, - beforeUpdate(event: IWebinarEvent) { + async beforeDelete(event: IWebinarEvent) { + await deleteActiveCampaignList(event); + }, + beforeDeleteMany() { + if (activeCampaignIntegrationIsEnabled) { + throw new errors.ApplicationError( + 'Bulk deletion is not allowed for webinars if Active Campaign integration is enabled' + ); + } + }, + async beforeUpdate(event: IWebinarEvent) { validateDates(event); + await validateSlug(event); }, }; diff --git a/package-lock.json b/package-lock.json index 5ef4494002..5e054c02bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -423,6 +423,7 @@ "@strapi/plugin-users-permissions": "4.24.2", "@strapi/provider-upload-aws-s3": "^4.24.2", "@strapi/strapi": "4.24.2", + "axios": "^1.7.8", "better-sqlite3": "8.6.0", "pg": "^8.11.5", "react": "^18.2.0", @@ -443,6 +444,17 @@ "npm": ">=6.0.0" } }, + "apps/strapi-cms/node_modules/axios": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "apps/strapi-cms/node_modules/eslint": { "version": "8.50.0", "dev": true, From 38fc70b0505a97e3d24210e13f49b9f23ea7f034 Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Mon, 9 Dec 2024 15:50:07 +0100 Subject: [PATCH 15/24] [DEV-2058] Fix webinar slug validation (#1271) * Fix webinar validateSlug * add changeset --- .changeset/pretty-gorillas-bow.md | 5 +++++ .../src/api/webinar/content-types/webinar/lifecycles.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/pretty-gorillas-bow.md diff --git a/.changeset/pretty-gorillas-bow.md b/.changeset/pretty-gorillas-bow.md new file mode 100644 index 0000000000..750a34a160 --- /dev/null +++ b/.changeset/pretty-gorillas-bow.md @@ -0,0 +1,5 @@ +--- +"strapi-cms": minor +--- + +Fix webinar validateSlug on update diff --git a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts index cc0af4ca3e..39085e59e4 100644 --- a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts +++ b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts @@ -65,7 +65,11 @@ const validateDates = (event: IWebinarEvent): boolean => { }; const validateSlug = async (event: IWebinarEvent): Promise => { - const { id } = event.params.data; + if (!event.params.data.slug || !activeCampaignIntegrationIsEnabled) { + return true; + } + + const id = event.params.where?.id; if (!id) { throw new errors.ApplicationError('Webinar id not found'); } From fbd9da8f1b324e1f30acb45b0c0572a757bf8fe8 Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Tue, 10 Dec 2024 10:26:04 +0100 Subject: [PATCH 16/24] Move env variable in function (#1272) * Refactor active campaign enable to a getter function * Add change set --- .changeset/cyan-dolls-reply.md | 5 +++++ .../api/webinar/content-types/webinar/lifecycles.ts | 13 +++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 .changeset/cyan-dolls-reply.md diff --git a/.changeset/cyan-dolls-reply.md b/.changeset/cyan-dolls-reply.md new file mode 100644 index 0000000000..297cf6ee85 --- /dev/null +++ b/.changeset/cyan-dolls-reply.md @@ -0,0 +1,5 @@ +--- +"strapi-cms": patch +--- + +Refactor move ACTIVE_CAMPAIGN_INTEGRATION_ENABLED env var in getter function diff --git a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts index 39085e59e4..5bfe1df738 100644 --- a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts +++ b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts @@ -12,8 +12,9 @@ interface IActiveCampaignListPayload { }; } -const activeCampaignIntegrationIsEnabled = - env('ACTIVE_CAMPAIGN_INTEGRATION_IS_ENABLED', 'False') === 'True'; +function getActiveCampaignIntegrationIsEnabled() { + return env('ACTIVE_CAMPAIGN_INTEGRATION_ENABLED', 'false') === 'true'; +} function getHeaders() { return { @@ -65,7 +66,7 @@ const validateDates = (event: IWebinarEvent): boolean => { }; const validateSlug = async (event: IWebinarEvent): Promise => { - if (!event.params.data.slug || !activeCampaignIntegrationIsEnabled) { + if (!event.params.data.slug || !getActiveCampaignIntegrationIsEnabled()) { return true; } @@ -97,7 +98,7 @@ const createActiveCampaignList = async ( event: IWebinarEvent ): Promise => { if ( - !activeCampaignIntegrationIsEnabled || + !getActiveCampaignIntegrationIsEnabled() || !event.result?.slug || !event.result?.title ) { @@ -150,7 +151,7 @@ const deleteActiveCampaignList = async ( event: IWebinarEvent ): Promise => { if ( - !activeCampaignIntegrationIsEnabled || + !getActiveCampaignIntegrationIsEnabled() || !event?.params.where || !event.params.where.id ) { @@ -196,7 +197,7 @@ module.exports = { await deleteActiveCampaignList(event); }, beforeDeleteMany() { - if (activeCampaignIntegrationIsEnabled) { + if (getActiveCampaignIntegrationIsEnabled()) { throw new errors.ApplicationError( 'Bulk deletion is not allowed for webinars if Active Campaign integration is enabled' ); From 8f7d007ac01c93dfaa3a7afecf6e246f0b6fc8d1 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Tue, 10 Dec 2024 10:59:41 +0100 Subject: [PATCH 17/24] [DEV-2049] Add ac env vars to strapi container (#1268) * feat: add ecs variables for active campaign * fix: add outputs and variables needed to integrate active campaign with strapi * chore: ran pre-commit * fix: added iam permissions to ecs * fix: adding https protocol in front of ac_sender_url * fix: making ac variables in cms module optional * chore: remove moved block for active campaign module --- .changeset/plenty-buses-hope.md | 5 +++++ .../src/env/dev/terraform.tfvars | 3 ++- .../src/env/prod/terraform.tfvars | 3 ++- apps/infrastructure/src/main.tf | 12 ++++++++---- .../src/modules/active_campaign/lambda.tf | 5 +++-- .../src/modules/active_campaign/output.tf | 7 +++++++ apps/infrastructure/src/modules/cms/ecs.tf | 4 ++++ .../src/modules/cms/iam_policy.tf | 6 ++++-- .../cms/task-definitions/cms_app.json.tpl | 18 +++++++++++++++++- .../src/modules/cms/variables.tf | 19 +++++++++++++++++++ apps/infrastructure/src/variables.tf | 9 +++++++++ 11 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 .changeset/plenty-buses-hope.md create mode 100644 apps/infrastructure/src/modules/active_campaign/output.tf diff --git a/.changeset/plenty-buses-hope.md b/.changeset/plenty-buses-hope.md new file mode 100644 index 0000000000..aea2df4cbc --- /dev/null +++ b/.changeset/plenty-buses-hope.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Added environment variables that allow strapi to integrate with active campaign diff --git a/apps/infrastructure/src/env/dev/terraform.tfvars b/apps/infrastructure/src/env/dev/terraform.tfvars index b01f1d9408..9ab307ea25 100644 --- a/apps/infrastructure/src/env/dev/terraform.tfvars +++ b/apps/infrastructure/src/env/dev/terraform.tfvars @@ -29,4 +29,5 @@ dns_domain_name_cms = { } } -create_chatbot = true \ No newline at end of file +create_chatbot = true +ac_integration_is_enabled = true \ No newline at end of file diff --git a/apps/infrastructure/src/env/prod/terraform.tfvars b/apps/infrastructure/src/env/prod/terraform.tfvars index 82bf7a303b..aeb66a0cb0 100644 --- a/apps/infrastructure/src/env/prod/terraform.tfvars +++ b/apps/infrastructure/src/env/prod/terraform.tfvars @@ -32,4 +32,5 @@ dns_domain_name_cms = { } } -create_chatbot = true \ No newline at end of file +create_chatbot = true +ac_integration_is_enabled = false \ No newline at end of file diff --git a/apps/infrastructure/src/main.tf b/apps/infrastructure/src/main.tf index b8ffb44dfe..18196ce232 100644 --- a/apps/infrastructure/src/main.tf +++ b/apps/infrastructure/src/main.tf @@ -101,9 +101,12 @@ module "cms" { github_repository = var.github_repository tags = var.tags - dns_domain_name = var.dns_domain_name - dns_domain_name_cms = var.dns_domain_name_cms - hosted_zone_id = module.core.hosted_zone_id + dns_domain_name = var.dns_domain_name + dns_domain_name_cms = var.dns_domain_name_cms + hosted_zone_id = module.core.hosted_zone_id + ac_integration_is_enabled = var.ac_integration_is_enabled + ac_base_url_param = var.ac_integration_is_enabled ? module.active_campaign[0].base_url_param : null + ac_api_key_param = var.ac_integration_is_enabled ? module.active_campaign[0].api_key_param : null } module "chatbot" { @@ -148,6 +151,7 @@ module "cicd" { } module "active_campaign" { + count = var.ac_integration_is_enabled ? 1 : 0 source = "./modules/active_campaign" environment = var.environment @@ -155,4 +159,4 @@ module "active_campaign" { cognito_user_pool = module.website.cognito_user_pool webinar_subscriptions_ddb_stream_arn = module.website.webinar_subscriptions_ddb_stream_arn -} \ No newline at end of file +} diff --git a/apps/infrastructure/src/modules/active_campaign/lambda.tf b/apps/infrastructure/src/modules/active_campaign/lambda.tf index 1eb481488f..3834d82e7e 100644 --- a/apps/infrastructure/src/modules/active_campaign/lambda.tf +++ b/apps/infrastructure/src/modules/active_campaign/lambda.tf @@ -19,8 +19,9 @@ module "lambda_sync" { ignore_source_code_hash = true create_current_version_allowed_triggers = false - timeout = 15 - memory_size = 256 + timeout = 15 + memory_size = 256 + maximum_retry_attempts = 0 event_source_mapping = { sqs = { diff --git a/apps/infrastructure/src/modules/active_campaign/output.tf b/apps/infrastructure/src/modules/active_campaign/output.tf new file mode 100644 index 0000000000..626343b7a3 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/output.tf @@ -0,0 +1,7 @@ +output "base_url_param" { + value = module.active_campaign_base_url.ssm_parameter_arn +} + +output "api_key_param" { + value = module.active_campaign_api_key.ssm_parameter_arn +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/cms/ecs.tf b/apps/infrastructure/src/modules/cms/ecs.tf index 6bfababb9c..93a9df10a4 100644 --- a/apps/infrastructure/src/modules/cms/ecs.tf +++ b/apps/infrastructure/src/modules/cms/ecs.tf @@ -47,6 +47,10 @@ resource "aws_ecs_task_definition" "cms_task_def" { google_oauth_client_id = module.secret_cms_google_oauth_client_id.ssm_parameter_arn google_oauth_client_secret = module.secret_cms_google_oauth_client_secret.ssm_parameter_arn google_oauth_redirect_uri = format("https://cms.%s/strapi-plugin-sso/google/callback", var.dns_domain_name) + ac_integration_is_enabled = var.ac_integration_is_enabled + ac_base_url = var.ac_integration_is_enabled ? var.ac_base_url_param : module.secret_cms_transfer_token_salt.ssm_parameter_arn + ac_api_key = var.ac_integration_is_enabled ? var.ac_api_key_param : module.secret_cms_transfer_token_salt.ssm_parameter_arn + ac_sender_url = "https://${var.dns_domain_name}" }) } diff --git a/apps/infrastructure/src/modules/cms/iam_policy.tf b/apps/infrastructure/src/modules/cms/iam_policy.tf index 9f3a652d47..01f5b2e1ba 100644 --- a/apps/infrastructure/src/modules/cms/iam_policy.tf +++ b/apps/infrastructure/src/modules/cms/iam_policy.tf @@ -82,7 +82,7 @@ data "aws_iam_policy_document" "ecs_task_execution" { actions = [ "ssm:GetParameters" ] - resources = [ + resources = concat([ module.secret_cms_database_password.ssm_parameter_arn, module.secret_cms_admin_jwt_secret.ssm_parameter_arn, module.secret_cms_app_keys.ssm_parameter_arn, @@ -95,7 +95,9 @@ data "aws_iam_policy_document" "ecs_task_execution" { module.secret_cms_google_gsuite_hd.ssm_parameter_arn, module.secret_cms_google_oauth_client_id.ssm_parameter_arn, module.secret_cms_google_oauth_client_secret.ssm_parameter_arn, - ] + ], + (var.ac_integration_is_enabled ? [var.ac_base_url_param, var.ac_api_key_param] : []) + ) } statement { diff --git a/apps/infrastructure/src/modules/cms/task-definitions/cms_app.json.tpl b/apps/infrastructure/src/modules/cms/task-definitions/cms_app.json.tpl index eaca9b9045..d90bd0e4d7 100644 --- a/apps/infrastructure/src/modules/cms/task-definitions/cms_app.json.tpl +++ b/apps/infrastructure/src/modules/cms/task-definitions/cms_app.json.tpl @@ -91,6 +91,14 @@ { "name": "DEPLOY_WEBSITE_TARGET_BRANCH", "value": "${target_branch}" + }, + { + "name": "ACTIVE_CAMPAIGN_INTEGRATION_IS_ENABLED", + "value": "${ac_integration_is_enabled}" + }, + { + "name": "SENDER_URL", + "value": "${ac_sender_url}" } ], "secrets" : [ @@ -141,7 +149,15 @@ { "name": "GOOGLE_OAUTH_CLIENT_SECRET", "valueFrom": "${google_oauth_client_secret}" - } + }, + { + "name": "AC_BASE_URL", + "valueFrom": "${ac_base_url}" + }, + { + "name": "AC_API_KEY", + "valueFrom": "${ac_api_key}" + } ] } ] diff --git a/apps/infrastructure/src/modules/cms/variables.tf b/apps/infrastructure/src/modules/cms/variables.tf index cb6442fe15..4f624c8943 100644 --- a/apps/infrastructure/src/modules/cms/variables.tf +++ b/apps/infrastructure/src/modules/cms/variables.tf @@ -54,4 +54,23 @@ variable "dns_domain_name_cms" { variable "hosted_zone_id" { type = string description = "The ID of the hosted zone to create the public DNS records in" +} + +## Active Campaign configuration for Strapi +variable "ac_integration_is_enabled" { + type = bool + description = "Enable Active Campaign integration for Strapi" + default = false +} + +variable "ac_base_url_param" { + type = string + description = "Active Campaign base URL SSM parameter ARN" + default = null +} + +variable "ac_api_key_param" { + type = string + description = "Active Campaign API key SSM parameter ARN" + default = null } \ No newline at end of file diff --git a/apps/infrastructure/src/variables.tf b/apps/infrastructure/src/variables.tf index 15c03bceb7..b20094e9b2 100644 --- a/apps/infrastructure/src/variables.tf +++ b/apps/infrastructure/src/variables.tf @@ -138,4 +138,13 @@ variable "chatbot_ecs_monitoring" { image_uri = "ghcr.io/langfuse/langfuse:sha-9375250" port = 3000 } +} + +################################################################################ +# Active Campaign integration +################################################################################ +variable "ac_integration_is_enabled" { + type = bool + description = "Defines if Active Campaign integration should be enabled" + default = false } \ No newline at end of file From 63c19a7b7a8456a69676a0fc393ff2b09636548f Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Tue, 10 Dec 2024 16:46:27 +0100 Subject: [PATCH 18/24] [DEV-2049] Fix ac env vars in strapi container (#1274) * feat: add ecs variables for active campaign * chore: ran pre-commit * fix: ac_integration_is_enabled has capital letter --- apps/infrastructure/src/modules/cms/ecs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/infrastructure/src/modules/cms/ecs.tf b/apps/infrastructure/src/modules/cms/ecs.tf index 93a9df10a4..dd32b3f48a 100644 --- a/apps/infrastructure/src/modules/cms/ecs.tf +++ b/apps/infrastructure/src/modules/cms/ecs.tf @@ -47,7 +47,7 @@ resource "aws_ecs_task_definition" "cms_task_def" { google_oauth_client_id = module.secret_cms_google_oauth_client_id.ssm_parameter_arn google_oauth_client_secret = module.secret_cms_google_oauth_client_secret.ssm_parameter_arn google_oauth_redirect_uri = format("https://cms.%s/strapi-plugin-sso/google/callback", var.dns_domain_name) - ac_integration_is_enabled = var.ac_integration_is_enabled + ac_integration_is_enabled = var.ac_integration_is_enabled ? "True" : "False" ac_base_url = var.ac_integration_is_enabled ? var.ac_base_url_param : module.secret_cms_transfer_token_salt.ssm_parameter_arn ac_api_key = var.ac_integration_is_enabled ? var.ac_api_key_param : module.secret_cms_transfer_token_salt.ssm_parameter_arn ac_sender_url = "https://${var.dns_domain_name}" From 5e861a03088ae33a75876c109431aa2bbaa57b95 Mon Sep 17 00:00:00 2001 From: tommaso1 Date: Wed, 18 Dec 2024 10:30:50 +0100 Subject: [PATCH 19/24] [DEV-2017] Resync user on active campaign (#1269) * sync user wip * sync user * changeset * Update .changeset/cuddly-cats-retire.md Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/helpers/resyncUser.ts Co-authored-by: Marco Ponchia * pr comments * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * pr changes * pr changes --------- Co-authored-by: t Co-authored-by: Marco Ponchia Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/cuddly-cats-retire.md | 5 ++ .../src/handlers/resyncUserHandler.ts | 82 +++++++++++++++++++ .../src/helpers/getSubscribedWebinars.ts | 30 +++++++ .../src/helpers/getUserFromCognito.ts | 16 ++-- packages/active-campaign-client/src/index.ts | 7 ++ 5 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 .changeset/cuddly-cats-retire.md create mode 100644 packages/active-campaign-client/src/handlers/resyncUserHandler.ts create mode 100644 packages/active-campaign-client/src/helpers/getSubscribedWebinars.ts diff --git a/.changeset/cuddly-cats-retire.md b/.changeset/cuddly-cats-retire.md new file mode 100644 index 0000000000..ef17a074d8 --- /dev/null +++ b/.changeset/cuddly-cats-retire.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": minor +--- + +Add resync user handler diff --git a/packages/active-campaign-client/src/handlers/resyncUserHandler.ts b/packages/active-campaign-client/src/handlers/resyncUserHandler.ts new file mode 100644 index 0000000000..a9edc97d5d --- /dev/null +++ b/packages/active-campaign-client/src/handlers/resyncUserHandler.ts @@ -0,0 +1,82 @@ +import { deleteContact } from '../helpers/deleteContact'; +import { getUserFromCognitoUsername } from '../helpers/getUserFromCognito'; +import { getSubscribedWebinars } from '../helpers/getSubscribedWebinars'; +import { addContact } from '../helpers/addContact'; +import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; +import { addContactToList } from '../helpers/manageListSubscription'; +import { queueEventParser } from '../helpers/queueEventParser'; + +export async function resyncUserHandler(event: { + readonly Records: SQSEvent['Records']; +}): Promise { + try { + const queueEvent = queueEventParser(event); + const cognitoUsername = queueEvent.detail.additionalEventData.sub; + const deletionResult = await deleteContact(cognitoUsername); + if ( + deletionResult.statusCode !== 200 && + deletionResult.statusCode !== 404 + ) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Error adding contact'); + } + + const user = await getUserFromCognitoUsername(cognitoUsername); + + if (!user) { + console.log( + `User: ${cognitoUsername} not present on Cognito, sync done.` + ); + return { + statusCode: 200, + body: JSON.stringify({ + message: 'User not present on Cognito, sync done.', + }), + }; + } + + const userWebinarsSubscriptions = await getSubscribedWebinars( + cognitoUsername + ); + + const webinarIds = JSON.parse(userWebinarsSubscriptions.body) + .map( + (webinar: { readonly webinarId: { readonly S: string } }) => + webinar?.webinarId?.S + ) + .filter(Boolean); + + const res = await addContact(user); + if (res.statusCode !== 200) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Error adding contact'); + } + + await webinarIds.reduce( + async ( + prevPromise: Promise, + webinarId: string + ) => { + await prevPromise; + try { + const result = await addContactToList(cognitoUsername, webinarId); + console.log('Add contact to list result:', result, webinarId); // TODO: Remove after testing + await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 sec to avoid rate limiting + } catch (e) { + console.error('Error adding contact to list', e); // TODO: Remove after testing + } + }, + Promise.resolve() + ); + + return { + statusCode: 200, + body: JSON.stringify({ message: 'User resynced' }), + }; + } catch (error) { + return { + statusCode: 500, + body: JSON.stringify({ message: error }), + }; + } +} diff --git a/packages/active-campaign-client/src/helpers/getSubscribedWebinars.ts b/packages/active-campaign-client/src/helpers/getSubscribedWebinars.ts new file mode 100644 index 0000000000..1d6d757381 --- /dev/null +++ b/packages/active-campaign-client/src/helpers/getSubscribedWebinars.ts @@ -0,0 +1,30 @@ +import { DynamoDBClient, QueryCommand } from '@aws-sdk/client-dynamodb'; +import { APIGatewayProxyResult } from 'aws-lambda'; + +export async function getSubscribedWebinars( + username: string +): Promise { + try { + const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION }); + const command = new QueryCommand({ + TableName: process.env.DYNAMO_WEBINARS_TABLE_NAME, + KeyConditionExpression: 'username = :username', + ExpressionAttributeValues: { + ':username': { S: username }, + }, + }); + + const response = await dynamoClient.send(command); + console.log('getWebinarSubscriptions', response); + return { + statusCode: 200, + body: JSON.stringify(response.Items), + }; + } catch (error) { + console.error('Error querying items by username:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/helpers/getUserFromCognito.ts b/packages/active-campaign-client/src/helpers/getUserFromCognito.ts index 41d02e7c7b..c3630ad897 100644 --- a/packages/active-campaign-client/src/helpers/getUserFromCognito.ts +++ b/packages/active-campaign-client/src/helpers/getUserFromCognito.ts @@ -4,16 +4,22 @@ import { QueueEvent } from '../types/queueEvent'; import { listUsersCommandOutputToUser } from './listUsersCommandOutputToUser'; export async function getUserFromCognito(queueEvent: QueueEvent) { + const username = queueEvent.detail.additionalEventData.sub; + const user = await getUserFromCognitoUsername(username); + if (!user) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('User not found'); + } + return user; +} + +export async function getUserFromCognitoUsername(username: string) { const command = new ListUsersCommand({ UserPoolId: process.env.COGNITO_USER_POOL_ID, - Filter: `username = "${queueEvent.detail.additionalEventData.sub}"`, + Filter: `username = "${username}"`, }); const listUsersCommandOutput = await cognitoClient.send(command); const user = listUsersCommandOutputToUser(listUsersCommandOutput); - if (!user) { - // eslint-disable-next-line functional/no-throw-statements - throw new Error('User not found'); - } console.log('User:', JSON.stringify(user, null, 2)); // TODO: Remove after testing return user; } diff --git a/packages/active-campaign-client/src/index.ts b/packages/active-campaign-client/src/index.ts index 0d1edb3b65..cab74a8145 100644 --- a/packages/active-campaign-client/src/index.ts +++ b/packages/active-campaign-client/src/index.ts @@ -1,8 +1,15 @@ import { SQSEvent } from 'aws-lambda'; import { sqsQueueHandler } from './handlers/sqsQueueHandler'; +import { resyncUserHandler } from './handlers/resyncUserHandler'; export async function sqsQueue(event: { readonly Records: SQSEvent['Records']; }) { return await sqsQueueHandler(event); } + +export async function resyncQueue(event: { + readonly Records: SQSEvent['Records']; +}) { + return await resyncUserHandler(event); +} From 86642955510897775de3b0cf00b04bb8c1972719 Mon Sep 17 00:00:00 2001 From: christian-calabrese Date: Wed, 18 Dec 2024 14:07:33 +0100 Subject: [PATCH 20/24] [DEV-2072] Use the ddb streams event id as SQS message group id (#1282) * feat: add ecs variables for active campaign * fix: use ddb stream as sqs fifo dedup id * fix: conflict on cms ecs * chore: changeset added * feat: added alarms * chore: ran terraform fmt * fix: alarms thresholds --- .changeset/gorgeous-ghosts-float.md | 5 ++ .../cloudwatch_metrics_alarms.tf | 66 +++++++++++++++++++ .../modules/active_campaign/eventbridge.tf | 5 +- .../src/modules/active_campaign/sqs.tf | 4 +- 4 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 .changeset/gorgeous-ghosts-float.md create mode 100644 apps/infrastructure/src/modules/active_campaign/cloudwatch_metrics_alarms.tf diff --git a/.changeset/gorgeous-ghosts-float.md b/.changeset/gorgeous-ghosts-float.md new file mode 100644 index 0000000000..1e7fcf4403 --- /dev/null +++ b/.changeset/gorgeous-ghosts-float.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Use the ddb stream event id as message group id in sqs diff --git a/apps/infrastructure/src/modules/active_campaign/cloudwatch_metrics_alarms.tf b/apps/infrastructure/src/modules/active_campaign/cloudwatch_metrics_alarms.tf new file mode 100644 index 0000000000..d0452a3b96 --- /dev/null +++ b/apps/infrastructure/src/modules/active_campaign/cloudwatch_metrics_alarms.tf @@ -0,0 +1,66 @@ +# CloudWatch Metrics and Alarms for Active Campaign Sync Resources + +resource "aws_cloudwatch_metric_alarm" "pipe_failed" { + alarm_name = "${local.prefix}-webinar-subs-pipe-errors" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = 1 + period = 60 + statistic = "Sum" + threshold = 1 + metric_name = "ExecutionFailed" + namespace = "AWS/EventBridge/Pipes" + dimensions = { + PipeName = aws_pipes_pipe.dynamodb_to_sqs.name + } + alarm_description = "This metric monitors the webinar subscriptions eventbridge pipe failures" + insufficient_data_actions = [] + alarm_actions = [aws_sns_topic.alerts.arn] +} + +resource "aws_cloudwatch_metric_alarm" "dlq" { + alarm_name = "${local.prefix}-sqs-messages-in-dlq" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = 1 + period = 60 + statistic = "Sum" + threshold = 1 + metric_name = "ApproximateNumberOfMessagesVisible" + namespace = "AWS/SQS" + dimensions = { + QueueName = aws_sqs_queue.fifo_dlq_queue.name + } + alarm_description = "This metric monitors messages put in the dead letter queue" + insufficient_data_actions = [] + alarm_actions = [aws_sns_topic.alerts.arn] +} + +# SNS Topic for Alarms +resource "aws_sns_topic" "alerts" { + name = "${local.prefix}-cloudwatch-alarms" +} + +resource "aws_sns_topic_policy" "alerts" { + arn = aws_sns_topic.alerts.arn + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "AllowCloudWatchAlarms" + Effect = "Allow" + Principal = { + Service = "cloudwatch.amazonaws.com" + } + Action = "sns:Publish" + Resource = aws_sns_topic.alerts.arn + Condition = { + ArnLike = { + "aws:SourceArn" = "arn:aws:cloudwatch:${var.aws_region}:${data.aws_caller_identity.current.account_id}:alarm:*" + } + StringEquals = { + "aws:SourceAccount" = data.aws_caller_identity.current.account_id + } + } + } + ] + }) +} \ No newline at end of file diff --git a/apps/infrastructure/src/modules/active_campaign/eventbridge.tf b/apps/infrastructure/src/modules/active_campaign/eventbridge.tf index c584d96e38..8386b7a3b9 100644 --- a/apps/infrastructure/src/modules/active_campaign/eventbridge.tf +++ b/apps/infrastructure/src/modules/active_campaign/eventbridge.tf @@ -29,11 +29,12 @@ resource "aws_pipes_pipe" "dynamodb_to_sqs" { "sub": "<$.dynamodb.Keys.username.S>" } }, - "webinarId": "<$.dynamodb.Keys.webinarId.S>" + "webinarId": "<$.dynamodb.Keys.webinarId.S>", + "eventID": "<$.eventID>" } EOF sqs_queue_parameters { - message_group_id = local.sqs_message_group_id + message_group_id = "$.eventID" } } } diff --git a/apps/infrastructure/src/modules/active_campaign/sqs.tf b/apps/infrastructure/src/modules/active_campaign/sqs.tf index e3784d1925..b5746ce958 100644 --- a/apps/infrastructure/src/modules/active_campaign/sqs.tf +++ b/apps/infrastructure/src/modules/active_campaign/sqs.tf @@ -3,8 +3,8 @@ resource "aws_sqs_queue" "fifo_queue" { name = "${local.prefix}-events.fifo" fifo_queue = true content_based_deduplication = true - deduplication_scope = "messageGroup" - fifo_throughput_limit = "perMessageGroupId" + deduplication_scope = "queue" + fifo_throughput_limit = "perQueue" redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.fifo_dlq_queue.arn From 2345af938a2ac719ba4e0738257e8b421e71a097 Mon Sep 17 00:00:00 2001 From: Marco Domenico Cirillo <59966344+mdciri@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:23:16 +0100 Subject: [PATCH 21/24] [CAI-271] - Monitoring with Langfuse (#1254) * Update scripts to accept langfuse * Update app api.md * Update modules * Update docker compose yaml file with langfuse * Update modules * Update modules * Update modules * Update chatbot that masks string to send to langfuse server * Update src.modules * Update params * Update env example * Update src.modules * Update config.prompts * Update poetry * Update local Dockerfile * Update app/main.py * Remove generate method from chatbot and tests * Add langfuse connection test * Add langfuse connection test * Reinstate app/main.py * Merged branch with main * Update authors in pyproject * Update docker compose test * chore: out dir for tests * Update src.modules * Update src.app.main * Update docker * Restore pre-push * Update poetry * Update src.app.main * Update docker * chore: use port 3001 for Langfuse because 3000 is used by frontend * Remove gradio and webapp * Update src.modules * Update docker compose.yaml * chore: redis data persistence, frontend build * chore: langfuse host * chore: readme * Update README * chore: scripts * fix: create index command * Update main.py * Update fe package-lock.json * Update retrieve langfuse api key through SSM * Update retrieve langfuse api key through SSM * Update add and remove tag for langfuse * Update add and remove tag for langfuse * Update chat_generate method * Update trace id langfuse equal to dynamodb id * chore: .env.example order * chore: langfuse env.example * chore: env.example fix * chore: langfuse env vars * feat: salts table * feat(chatbot): salt for user id hash * fix(chatbot): salts query * Update scripts for langfuse * Update prompts * Update pytest * Update chatbot * chatbot: langfuse score * Update modules.chatbot * Update embedding model * Update feedback * feat: add missing infra parts * chore: add changeset --------- Co-authored-by: Devis Battisti Co-authored-by: christian-calabrese --- .changeset/nice-coins-mix.md | 6 + .gitmodules | 2 +- apps/chatbot/.dockerignore | 1 + apps/chatbot/.env.example | 75 +- apps/chatbot/README.md | 44 +- apps/chatbot/TESTBOOK.md | 17 + apps/chatbot/config/params.yaml | 8 +- apps/chatbot/config/prompts.yaml | 24 +- apps/chatbot/docker/app.local.Dockerfile | 10 +- apps/chatbot/docker/compose.test.yaml | 8 +- apps/chatbot/docker/compose.yaml | 43 +- .../docker/docker-compose-build-local.sh | 2 +- .../docker/docker-compose-run-create_index.sh | 2 +- .../files/dynamodb_schemas/queries.json | 2 +- .../docker/files/dynamodb_schemas/salts.json | 21 + .../files/dynamodb_schemas/sessions.json | 2 +- .../files/nextjs-website/generated/404.html | 1 + .../case-histories/tari-cagliari.html | 1 + .../case-histories/tari-cagliari.txt | 23 + .../generated/case-histories/test-case.html | 1 + .../generated/case-histories/test-case.txt | 23 + .../files/nextjs-website/generated/index.html | 1 + .../generated/privacy-policy.html | 1 + .../nextjs-website/generated/solutions.html | 1 + .../generated/terms-of-service.html | 1 + .../nextjs-website/generated/webinars.html | 1 + apps/chatbot/poetry.lock | 1634 +++++++---------- apps/chatbot/pyproject.toml | 4 +- .../dynamodb-create-table-queries-local.sh | 33 - .../dynamodb-create-table-sessions-local.sh | 33 - apps/chatbot/scripts/dynamodb-init.sh | 11 +- apps/chatbot/scripts/run.local.sh | 4 +- apps/chatbot/src/app/api.md | 137 +- apps/chatbot/src/app/main.py | 60 +- apps/chatbot/src/modules/chatbot.py | 305 ++- .../src/modules/create_vector_index.py | 5 +- apps/chatbot/src/modules/engine.py | 61 +- apps/chatbot/src/modules/evaluation.py | 18 +- apps/chatbot/src/modules/handlers.py | 259 +++ apps/chatbot/src/modules/models.py | 38 +- apps/chatbot/src/modules/presidio.py | 14 +- apps/chatbot/src/modules/test_chatbot.py | 88 +- apps/chatbot/src/modules/utils.py | 16 +- apps/chatbot/src/modules/vector_database.py | 26 +- apps/chatbot/src/webapp/app.py | 82 - apps/chatbot/src/webapp/chatbot.png | Bin 22002 -> 0 bytes apps/chatbot/src/webapp/user.png | Bin 13491 -> 0 bytes .../src/modules/chatbot/cognito_user.tf | 2 +- .../src/modules/chatbot/data.tf | 4 +- .../src/modules/chatbot/dynamodb.tf | 18 + .../src/modules/chatbot/lambda_chatbot.tf | 19 +- apps/nextjs-website/.tmp-docs | 1 + package-lock.json | 105 ++ 53 files changed, 1839 insertions(+), 1459 deletions(-) create mode 100644 .changeset/nice-coins-mix.md create mode 100644 apps/chatbot/TESTBOOK.md create mode 100644 apps/chatbot/docker/files/dynamodb_schemas/salts.json create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/404.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.txt create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.txt create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/index.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/privacy-policy.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/solutions.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/terms-of-service.html create mode 100644 apps/chatbot/docker/files/nextjs-website/generated/webinars.html delete mode 100755 apps/chatbot/scripts/dynamodb-create-table-queries-local.sh delete mode 100755 apps/chatbot/scripts/dynamodb-create-table-sessions-local.sh create mode 100644 apps/chatbot/src/modules/handlers.py delete mode 100644 apps/chatbot/src/webapp/app.py delete mode 100644 apps/chatbot/src/webapp/chatbot.png delete mode 100644 apps/chatbot/src/webapp/user.png create mode 160000 apps/nextjs-website/.tmp-docs diff --git a/.changeset/nice-coins-mix.md b/.changeset/nice-coins-mix.md new file mode 100644 index 0000000000..b84112ca18 --- /dev/null +++ b/.changeset/nice-coins-mix.md @@ -0,0 +1,6 @@ +--- +"infrastructure": minor +"chatbot": minor +--- + +Implemented llm monitoring with LangFuse diff --git a/.gitmodules b/.gitmodules index 871ef6b87b..3e82eeea1e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "apps/nextjs-website/.tmp-docs"] path = apps/nextjs-website/.tmp-docs - url = https://github.com/pagopa/devportal-docs.git \ No newline at end of file + url = https://github.com/pagopa/devportal-docs.git diff --git a/apps/chatbot/.dockerignore b/apps/chatbot/.dockerignore index c694205073..efb4c09adc 100644 --- a/apps/chatbot/.dockerignore +++ b/apps/chatbot/.dockerignore @@ -2,3 +2,4 @@ build-devp .pytest_cache load-test +*.ipynb \ No newline at end of file diff --git a/apps/chatbot/.env.example b/apps/chatbot/.env.example index 7006ba44f8..2ca70aad6c 100644 --- a/apps/chatbot/.env.example +++ b/apps/chatbot/.env.example @@ -1,31 +1,66 @@ -environment=local -CORS_DOMAINS=["*"] -PYTHONPATH=app-path -LOG_LEVEL=DEBUG +AUTH_COGNITO_ALLOW_ACCOUNT_LINKING=true +AUTH_COGNITO_CLIENT_ID=... +AUTH_COGNITO_CLIENT_SECRET= +AUTH_COGNITO_ISSUER=https://cognito-idp.eu-south-1.amazonaws.com/eu-south-1_xxxxxxxx +AUTH_DISABLE_SIGNUP=false +AUTH_DISABLE_USERNAME_PASSWORD=true CHB_AWS_ACCESS_KEY_ID=... -CHB_AWS_SECRET_ACCESS_KEY=... +CHB_AWS_BEDROCK_EMBED_REGION=eu-central-1 +CHB_AWS_BEDROCK_LLM_REGION=eu-west-3 CHB_AWS_DEFAULT_REGION=eu-south-1 -CHB_AWS_BEDROCK_REGION=eu-west-3 CHB_AWS_GUARDRAIL_ID=... CHB_AWS_GUARDRAIL_VERSION=... -CHB_REDIS_URL=... -CHB_WEBSITE_URL=... -CHB_REDIS_INDEX_NAME=... -CHB_LLAMAINDEX_INDEX_ID=... +CHB_AWS_SECRET_ACCESS_KEY=... CHB_DOCUMENTATION_DIR=... -CHB_USE_PRESIDIO=... -CHB_GOOGLE_API_KEY=... -CHB_PROVIDER=... -CHB_MODEL_ID=... -CHB_MODEL_TEMPERATURE=... -CHB_MODEL_MAXTOKENS=... +CHB_DYNAMODB_URL=http://locahost:8080 CHB_EMBED_MODEL_ID=... -CHB_ENGINE_SIMILARITY_TOPK=... CHB_ENGINE_SIMILARITY_CUTOFF=... +CHB_ENGINE_SIMILARITY_TOPK=... CHB_ENGINE_USE_ASYNC=True CHB_ENGINE_USE_STREAMING=... -CHB_ENGINE_USE_CHAT_ENGINE=... +CHB_GOOGLE_API_KEY=... +CHB_LANGFUSE_HOST=http://localhost:3000 +CHB_LANGFUSE_PUBLIC_KEY=/nonexistent/ssmpath +CHB_LANGFUSE_SECRET_KEY=/nonexistent/ssmpath +CHB_LLAMAINDEX_INDEX_ID=... +CHB_MODEL_ID=... +CHB_MODEL_MAXTOKENS=... +CHB_MODEL_TEMPERATURE=... +CHB_PROVIDER=... CHB_QUERY_TABLE_PREFIX=chatbot-local -CHB_DYNAMODB_URL=http://locahost:8080 -CHB_USE_PRESIDIO=True +CHB_REDIS_INDEX_NAME=... +CHB_REDIS_URL=... CHB_SESSION_MAX_DURATION_DAYS=1 +CHB_USE_CHAT_ENGINE=True +CHB_USE_PRESIDIO=True +CHB_WEBSITE_URL=... +CORS_DOMAINS=["*"] +ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000 +environment=local +LAMBDA_TASK_ROOT=app-dir +LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=false +LANGFUSE_INIT_ORG_ID=... +LANGFUSE_INIT_ORG_NAME=... +LANGFUSE_INIT_PROJECT_ID=monitor-123 +LANGFUSE_INIT_PROJECT_NAME=Monitor +LANGFUSE_INIT_PROJECT_PUBLIC_KEY=pk-xxx +LANGFUSE_INIT_PROJECT_SECRET_KEY=sk-xxx +LANGFUSE_INIT_USER_EMAIL=... +LANGFUSE_INIT_USER_NAME=... +LANGFUSE_INIT_USER_PASSWORD=... +LANGFUSE_TAG=development +LANGFUSE_USER_EMAIL=user@example.com +LANGFUSE_USER_NAME=User +LANGFUSE_USER_PASSWORD=... +LOG_LEVEL=DEBUG +NEXTAUTH_SECRET=mysecret +NEXTAUTH_URL=http://localhost:3001 +POSTGRES_DB=postgres +POSTGRES_HOST=localhost +POSTGRES_PASSWORD=postgres +POSTGRES_PORT=5432 +POSTGRES_USER=postgres +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} +PYTHONPATH=app-path +SALT=mysalt +TELEMETRY_ENABLED=true diff --git a/apps/chatbot/README.md b/apps/chatbot/README.md index 27e5b40194..1d212ccb90 100644 --- a/apps/chatbot/README.md +++ b/apps/chatbot/README.md @@ -7,10 +7,16 @@ Even though the provider is the Google one, we stored its API key in AWS. So, be The Retrieval-Augmented Generation (RAG) was implemented using [llama-index](https://docs.llamaindex.ai/en/stable/). All the parameters and prompts used are stored in `config`. +The monitoring is done using [Langfuse](https://langfuse.com/) deployed on AWS. + ## Environment Variables Create a `.env` file inside this folder and store the environment variables listed in `.env.example`. +cp .env.example .env + +Note that the envirables inside `.env` file should be pointing to the AWS infrastructure.s + ## Virtual environment Before creating your virtual environment, install [Miniconda](https://docs.anaconda.com/miniconda/#quick-command-line-install) and [Poetry](https://python-poetry.org/docs/main#installation) on your device. @@ -36,30 +42,44 @@ In this way, `PYTHONPATH` points to where the Python packages and modules are, n To reach the remote redis instance, it is necessary to open a tunnel: -``` ./scripts/redis-tunnel.sh -``` Verify that the HTML files that compose the Developer Portal documentation exist in a directory. Otherwise create the documentation. Once you have the documentation directory ready, put its path in `params` and, in the end, create the vector index doing: -``` python src/modules/create_vector_index.py --params config/params.yaml -``` This script reads the documentation, split it into chucks with gerarchical organization, and stores it on Redis. Check out the params in order to store your vector index accordingly. -## test +## Test + +In order to test the chatbot and its APIs, run: + + pytest + +For more details, read [TESTBOOK.md](https://github.com/pagopa/developer-portal/blob/main/apps/chatbot/TESTBOOK.md). + +## Docker + +In order to run the chatbot locally for the first time, you need to: + +- install [Docker Compose](https://docs.docker.com/compose/install/), +- create `.env.local` file running: + + cp .env.example .env.local + + and fill it in, + +- run the following bash scripts: -``` -pytest -``` + ./docker/docker-compose-build-local.sh + ./docker/docker-compose-run-create_index.sh -## Web App +In this way, the docker images are built and the vector index is stored in Redis. - python src/webapp/app.py +Now you can start the API running: -This scripts uses [Gradio](https://www.gradio.app/) framework to lunch a web application at the [default link](http://127.0.0.1:7860) where the user can interact with the chatbot. + ./docker/docker-compose-up-api.sh -Both [`user icon`](https://www.flaticon.com/free-icon/user_1077012) and [`chatbot icon`](https://www.flaticon.com/free-icon/chatbot_8943377) are made by [Freepick](https://www.freepik.com/) and they were downloaded from [Flaticon](https://www.flaticon.com/). +Note that the `docker/compose.yaml` needs `.env.local` file with the correct environment variables. diff --git a/apps/chatbot/TESTBOOK.md b/apps/chatbot/TESTBOOK.md new file mode 100644 index 0000000000..93aeb3f730 --- /dev/null +++ b/apps/chatbot/TESTBOOK.md @@ -0,0 +1,17 @@ +# Testbook + +In order to test the chatbot functions and its APIs, run: + + pytest + +the command test the function explained in the table below. + +| Function | Requirements | Masked Inputs | Description | +| :------------------------------: | :-----------------------: | :---------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| `test_connection_redis()` | Redis client | None | Check the connection with Redis is up | +| `test_connection_langfuse()` | Langfuse client | None | Check the connection with Langfuse is up | +| `test_cloud_connection()` | AWS or Gemini credentials | LLM and Embedding model ID | Check the models' loading | +| `test_prompt_templates()` | Llama-index | `prompts.yaml` | Check the prompts have the same variables of the prompts templates | +| `test_pii_mask()` | Presidio | a string to mask | Check that Presidio works as expected | +| `test_messages_to_chathistory()` | Llama-index | chat history from the local storage | Check the write functioning of creating a chat history in Llama-index | +| `test_chat_generation()` | Llama-index | two queries | Check the chatbot generation given a query, then checks again its functioning generating a new answer usinng a second query and the previous interaction as chat history | diff --git a/apps/chatbot/config/params.yaml b/apps/chatbot/config/params.yaml index 656ed28107..58f14b2f1d 100644 --- a/apps/chatbot/config/params.yaml +++ b/apps/chatbot/config/params.yaml @@ -52,6 +52,8 @@ config_presidio: allow_list: - Discovery - discovery + - rispondo + - Rispondo - Rif - SEND - send @@ -61,8 +63,12 @@ config_presidio: - Gpd - STATO - stato - - PagoPA + - PagoPA - pagoPA + - Devportal + - devPortal + - DevPortal + - devportal - pagopa - Pagopa - Firma con IO diff --git a/apps/chatbot/config/prompts.yaml b/apps/chatbot/config/prompts.yaml index 4f51b2043d..57b12c3c10 100644 --- a/apps/chatbot/config/prompts.yaml +++ b/apps/chatbot/config/prompts.yaml @@ -36,12 +36,14 @@ qa_prompt_str: | Task: Given the query: {query_str} Reply according to the `Chatbot Policy` listed above. + If the query is a thank, transform it into a polite and contextually appropriate answer. Answer: refine_prompt_str: | - Given the original answer: {existing_answer}, we have the opportunity to refine it (only if needed) with some more context here below: + Given the original answer: {existing_answer}, + we have the opportunity to refine it (only if needed) with some more context here below: -------------------- {context_msg} -------------------- @@ -53,15 +55,15 @@ refine_prompt_str: | Answer: condense_prompt_str: | - Given a conversation (between Human and Assistant) and a follow up message from Human, rewrite the message to be a standalone question that captures all relevant context from the conversation. - - The standalone question must be in Italian. - - + Given the following chat history between a user and an AI assistant: {chat_history} - - + -------------------- + and a follow up question from user: {question} - - - + -------------------- + Task: + Rephrase the follow up question to be a standalone question. + If the follow up question is a thank, transform it into a polite and contextually appropriate standalone response. + The standalone question or response must be in Italian. + + Standalone question or response: diff --git a/apps/chatbot/docker/app.local.Dockerfile b/apps/chatbot/docker/app.local.Dockerfile index ba490b2572..b2d61ac35e 100644 --- a/apps/chatbot/docker/app.local.Dockerfile +++ b/apps/chatbot/docker/app.local.Dockerfile @@ -19,11 +19,13 @@ RUN pip install --upgrade pip \ && pip install poetry awscli WORKDIR /app -COPY pyproject.toml . -COPY poetry.lock . +COPY ./pyproject.toml . +COPY ./poetry.lock . +COPY ./src ./src +COPY ./config ./config +COPY ./scripts ./scripts + RUN poetry config virtualenvs.create false RUN poetry install -COPY . . - CMD ["fastapi", "dev", "src/app/main.py", "--port", "8080", "--host", "0.0.0.0"] diff --git a/apps/chatbot/docker/compose.test.yaml b/apps/chatbot/docker/compose.test.yaml index b696d9e324..40c242b930 100644 --- a/apps/chatbot/docker/compose.test.yaml +++ b/apps/chatbot/docker/compose.test.yaml @@ -26,13 +26,17 @@ services: - AWS_SECRET_ACCESS_KEY=dummy - AWS_DEFAULT_REGION=local healthcheck: - test: ["CMD-SHELL", '[ "$(curl -s -o /dev/null -I -w ''%{http_code}'' http://localhost:8000)" == "400" ]'] + test: + [ + "CMD-SHELL", + '[ "$(curl -s -o /dev/null -I -w ''%{http_code}'' http://localhost:8000)" == "400" ]', + ] interval: 10s timeout: 10s retries: 10 networks: - ntw - + redis: image: redis/redis-stack:7.2.0-v13 networks: diff --git a/apps/chatbot/docker/compose.yaml b/apps/chatbot/docker/compose.yaml index 7f83597df1..5fdec24110 100644 --- a/apps/chatbot/docker/compose.yaml +++ b/apps/chatbot/docker/compose.yaml @@ -1,9 +1,9 @@ +--- services: api: build: context: .. dockerfile: docker/app.local.Dockerfile - env_file: ../.env.local command: "./scripts/run.local.sh" ports: - "8080:8080" @@ -16,6 +16,25 @@ services: condition: service_started dynamodb: condition: service_started + langfuse: + condition: service_started + env_file: ../.env.local + networks: + - ntw + + postgres: + image: postgres:17.2-alpine + restart: always + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 3s + timeout: 3s + retries: 10 + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + env_file: ../.env.local networks: - ntw @@ -35,6 +54,8 @@ services: ports: - "6379:6379" - "8001:8001" + volumes: + - redis_data:/data networks: - ntw @@ -42,18 +63,36 @@ services: build: context: .. dockerfile: docker/app.local.Dockerfile + command: "python src/modules/create_vector_index.py --params config/params.yaml" ports: - "8080:8080" volumes: - ..:/app - ../../nextjs-website/out:/app/build-devp/out - command: "python src/modules/create_vector_index.py --params config/params.yaml" tty: true depends_on: redis: condition: service_started + env_file: ../.env.local + networks: + - ntw + + langfuse: + image: langfuse/langfuse:2 + depends_on: + postgres: + condition: service_healthy + ports: + - "3001:3000" + env_file: ../.env.local networks: - ntw +volumes: + postgres_data: + driver: local + redis_data: + driver: local + networks: ntw: diff --git a/apps/chatbot/docker/docker-compose-build-local.sh b/apps/chatbot/docker/docker-compose-build-local.sh index 563590505f..ac1c475f1e 100755 --- a/apps/chatbot/docker/docker-compose-build-local.sh +++ b/apps/chatbot/docker/docker-compose-build-local.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker compose --env-file .env -f docker/compose.yaml -p chatbot build \ No newline at end of file +docker compose -f docker/compose.yaml -p chatbot build diff --git a/apps/chatbot/docker/docker-compose-run-create_index.sh b/apps/chatbot/docker/docker-compose-run-create_index.sh index 3e03f4f306..841345d5bc 100755 --- a/apps/chatbot/docker/docker-compose-run-create_index.sh +++ b/apps/chatbot/docker/docker-compose-run-create_index.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker compose --env-file .env -f docker/compose.yaml -p chatbot run create_index +docker compose -f docker/compose.yaml -p chatbot run create_index diff --git a/apps/chatbot/docker/files/dynamodb_schemas/queries.json b/apps/chatbot/docker/files/dynamodb_schemas/queries.json index 77d652c1f6..a6674d5aa7 100644 --- a/apps/chatbot/docker/files/dynamodb_schemas/queries.json +++ b/apps/chatbot/docker/files/dynamodb_schemas/queries.json @@ -47,5 +47,5 @@ "WriteCapacityUnits": 5 }, "TableClass": "STANDARD", - "DeletionProtectionEnabled": true + "DeletionProtectionEnabled": false } diff --git a/apps/chatbot/docker/files/dynamodb_schemas/salts.json b/apps/chatbot/docker/files/dynamodb_schemas/salts.json new file mode 100644 index 0000000000..4223747933 --- /dev/null +++ b/apps/chatbot/docker/files/dynamodb_schemas/salts.json @@ -0,0 +1,21 @@ +{ + "TableName": "chatbot-local-salts", + "KeySchema": [ + { + "AttributeName": "sessionId", + "KeyType": "HASH" + } + ], + "AttributeDefinitions": [ + { + "AttributeName": "sessionId", + "AttributeType": "S" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableClass": "STANDARD", + "DeletionProtectionEnabled": false +} diff --git a/apps/chatbot/docker/files/dynamodb_schemas/sessions.json b/apps/chatbot/docker/files/dynamodb_schemas/sessions.json index 71404bbeeb..bd0f90277b 100644 --- a/apps/chatbot/docker/files/dynamodb_schemas/sessions.json +++ b/apps/chatbot/docker/files/dynamodb_schemas/sessions.json @@ -47,5 +47,5 @@ "WriteCapacityUnits": 5 }, "TableClass": "STANDARD", - "DeletionProtectionEnabled": true + "DeletionProtectionEnabled": false } diff --git a/apps/chatbot/docker/files/nextjs-website/generated/404.html b/apps/chatbot/docker/files/nextjs-website/generated/404.html new file mode 100644 index 0000000000..e0b59ef3ac --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/404.html @@ -0,0 +1 @@ +
404

Pagina non trovata

La pagina che stai cercando non esiste


\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.html b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.html new file mode 100644 index 0000000000..0da1794de1 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.html @@ -0,0 +1 @@ +PagoPA DevPortal | Il processo di riscossione della TARI del Comune di Cagliari

Il processo di riscossione della TARI del Comune di Cagliari

Il racconto dell'esperienza del Comune di Cagliari, uno dei primi Comuni d'Italia a integrare SEND per gestire le notifiche a valore legale relative agli accertamenti Tari.

Lo scenario

Il Comune di Cagliari, che già da tempo è attivo sulla piattaforma pagoPA, è stato uno dei primi comuni a salire a bordo di SEND per gestire le notifiche a valore legale relative agli accertamenti Tari. Abbiamo incontrato Sabrina Contu e Paola Cuccureddu, rispettivamente funzionaria IMU/Tasi e funzionaria TARI del Comune di Cagliari, e abbiamo chiesto loro di raccontarci l’esperienza di onboarding e integrazione di SEND.

“Quando nel 2022 è stata pubblicata la Misura 1.4.5 Piattaforma Notifiche Digitali che consentiva alle amministrazioni di poter ricevere un finanziamento, nell’ambito del PNRR, per l'adesione a SEND” ci spiega Sabrina Contu, “abbiamo studiato il regolamento di attuazione della normativa e, prima di procedere, abbiamo fatto un'analisi degli invii di atti a valore legale effettuati nell’ultimo triennio verso società e professionisti. Questa analisi del business case è stata fondamentale perchè ci ha consentito di quantificare il valore di quegli avvisi e, nell'analisi costi / benefici, di renderci immediatamente conto degli evidenti vantaggi per l’Amministrazione nell’adesione a SEND, sia dal punto di vista economico che dal punto di vista della sicurezza dell’incasso a fronte di una maggiore probabilità di reperibilità del destinatario.

Onboarding e integrazione

“Una volta deciso di procedere con l’adesione, il passo successivo è stato la scelta del fornitore tecnologico per l’integrazione alla Piattaforma. Nel nostro caso, la software house che già gestiva l'applicativo dei tributi era anche già pronta per partire con SEND. Ci siamo quindi interfacciati con i referenti di PagoPA che ci hanno dato tutte le indicazioni utili per l’adesione: dall’accesso all'area riservata alla firma dell’accordo.

Dal canto nostro, abbiamo istituito l’apposito capitolo di spesa ed effettuato su questo l’apposito impegno di spesa per la prestazione del servizio.

Naturalmente questa nuova modalità di invio impone il rispetto di una serie di criteri e parametri: ad esempio, l’atto è nativo digitale e richiede quindi - per la versione stampata - di seguire delle specifiche precise, che ci sono state fornite e spiegate dal team di PagoPA e ci hanno consentito di procedere alla digitalizzazione degli atti con grande facilità.”

“Siamo pienamente soddisfatti di quanto fatto già lo scorso anno con SEND: abbiamo rilevato un significativo snellimento dei processi e abbiamo sperimentato i vantaggi legati al ritorno della notifica che viene automaticamente caricata in procedura.” conclude Sabrina Contu.

La risposta dei cittadini

“Abbiamo cercato di fare una comunicazione sul territorio in modo che i cittadini fossero informati di questa nuova possibilità, per accompagnarli in questo percorso di transizione digitale e consentire loro di percepire il cambio di passo del Comune come un vantaggio reale.” racconta Paola Cuccureddu. “Sappiamo bene all'interno di un comune quanto siano rilevanti - e purtroppo limitate - sia il fattore tempo che le risorse umane e tecniche disponibili. Con SEND abbiamo potuto ridurre i costi e ottimizzare al meglio le risorse disponibili, creando un servizio maggiormente di valore e impiegando quelle risorse per riuscire a fare una maggiore lotta all'evasione. Per il 2024 vogliamo continuare a notificare con SEND, forti anche dell’esperienza dello scorso anno, e contiamo di gestire circa 40.000 notifiche legate agli accertamenti TARI.”

Siamo pienamente soddisfatti di quanto fatto già lo scorso anno con SEND: abbiamo rilevato un significativo snellimento dei processi e abbiamo sperimentato i vantaggi legati al ritorno della notifica che viene automaticamente caricata in procedura.
Siamo pienamente soddisfatti di quanto fatto già lo scorso anno con SEND: abbiamo rilevato un significativo snellimento dei processi e abbiamo sperimentato i vantaggi legati al ritorno della notifica che viene automaticamente caricata in procedura.

Come integrarsi? Inizia da qui

IO, l’app dei servizi pubblici

Raccogli tutti i servizi digitali del tuo ente in un’unica piattaforma e interagisci in modo semplice e sicuro con i cittadini.

Piattaforma pagoPA

Gestisci gli incassi in modo centralizzato e con immediata riconciliazione delle posizioni debitorie.

SEND - Servizio Notifiche Digitali

Invia comunicazioni a valore legale con un processo di notificazione gestito interamente dalla piattaforma.


\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.txt b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.txt new file mode 100644 index 0000000000..878bba4eb5 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/tari-cagliari.txt @@ -0,0 +1,23 @@ +1:HL["/_next/static/media/28fac4a6e903645b-s.p.woff2",{"as":"font","type":"font/woff2"}] +2:HL["/_next/static/media/2bb25458ea2620e9-s.p.woff2",{"as":"font","type":"font/woff2"}] +3:HL["/_next/static/media/f378bd2abf9e0d48-s.p.woff2",{"as":"font","type":"font/woff2"}] +4:HL["/_next/static/css/c1a3c2f6d783e471.css",{"as":"style"}] +0:["dgB9Zym4WNhjMAim9VsHX",[[["",{"children":["case-histories",{"children":[["caseHistorySlug","tari-cagliari","d"],{"children":["__PAGE__?{\"caseHistorySlug\":\"tari-cagliari\"}",{}]}]}]},"$undefined","$undefined",true],"$L5",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c1a3c2f6d783e471.css","precedence":"next"}]],"$L6"]]]] +7:HL["/_next/static/css/918940977e95543e.css",{"as":"style"}] +5:[null,"$L8",null] +9:I{"id":44631,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +a:I{"id":36738,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +b:I{"id":93038,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +c:I{"id":8392,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +d:I{"id":10099,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +e:I{"id":15337,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +f:I{"id":13249,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +10:I{"id":92842,"chunks":["2272:static/chunks/webpack-d4fd03056baeac5f.js","1293:static/chunks/1dd3208c-3c1077ed7a7ffc38.js","3575:static/chunks/3575-63f451fe7624e01e.js"],"name":"default","async":false} +11:I{"id":41316,"chunks":["2272:static/chunks/webpack-d4fd03056baeac5f.js","1293:static/chunks/1dd3208c-3c1077ed7a7ffc38.js","3575:static/chunks/3575-63f451fe7624e01e.js"],"name":"default","async":false} +12:I{"id":80741,"chunks":["7950:static/chunks/7950-2339fabfd6a7629e.js","3093:static/chunks/3093-9dff2f7303959b74.js","2352:static/chunks/2352-337e28b99911d4e6.js","9160:static/chunks/app/not-found-b6e4c33c40a04c85.js"],"name":"Abstract","async":false} +15:I{"id":61151,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +8:["$","html",null,{"lang":"it","className":"__variable_c1363f","children":[["$","head",null,{"children":false}],["$","$L9",null,{"options":{"key":"mui"},"children":["$","$La",null,{"locale":"it","messages":{"devPortal":{"company":"PagoPA","siteHeader":{"label":"Menu","products":"Prodotti","profile":"Profilo","webinars":"Webinar","solutions":"Soluzioni"},"title":"DevPortal"},"profile":{"title":"Profilo","agreements":{"newsletter":{"description":"Inviami email relative alle risorse e agli aggiornamenti sui prodotti. Se questa opzione è attiva, PagoPA ti invierà di tanto in tanto delle email utili e pertinenti.","error":{"subscribe":"C'è stato un errore nell'iscrizione, riprova più tardi o contatta l'assistenza tecnica.","unsubscribe":"C'è stato un errore nella cancellazione, riprova più tardi o contatta l'assistenza tecnica."},"subscribe":"Iscriviti","title":"Iscrizione alla newsletter","unsubscribe":"Annulla iscrizione"},"privacy":{"basicData":"PagoPA raccoglie dati personali di base che ti permettono di creare e utilizzare il tuo account su DevPortal. Questi dati sono raccolti durante la registrazione e l'aggiornamento del tuo profilo. PagoPA garantisce che i tuoi dati vengano gestiti in modo sicuro e ne giustifica l’utilizzo secondo l’informativa Privacy di PagoPA. I tuoi dati personali di base verranno conservati fino a quando avrai un account attivo su PagoPA DevPortal.","title":"Privacy","statement":{"text":"La nostra $labelOfLinkToReplace$ fornisce informazioni dettagliate sui tuoi diritti in materia di privacy.","labelOfLinkToReplace":"Informativa Privacy"}},"title":"Consensi e privacy"},"personalData":{"save":"Conferma","cancel":"Annulla","title":"Su di te","dataSection":"I tuoi dati","accountSection":"Il tuo account","deleteAccountSection":"Eliminazione Account","deleteAccount":{"sectionLabel":"Puoi decidere di eliminare il tuo account su PagoPA DevPortal in qualsiasi momento. I tuoi dati verranno cancellati dai nostri sistemi.","buttonLabel":"Elimina account","modalTitle":"Confermi di voler eliminare il tuo account?","modalText":"Se elimini il tuo account PagoPA DevPortal tutte le tue preferenze e i tuoi dati verranno cancellati dai nostri sistemi. Questa azione non è reversibile."},"deleteAccountButton":"Elimina account","addField":"Inserisci","fields":{"name":"Nome","surname":"Cognome","role":"Ruolo","company":"Tipologia di ente o azienda","sector":"Settore","products":"Prodotti di interesse","email":"Indirizzo email","password":"Password"}},"changePassword":{"title":"Cambia password","currentPassword":"Password attuale","newPassword":"Nuova password","confirmPassword":"Conferma password","wrongPassword":"La password inserita non risulta corretta","requiredCurrentPassword":"È necessario inserire la password attuale","passwordsNotMatch":"Le password non corrispondono","passwordPolicy":"Non rispetta i requisiti. Minimo 8 caratteri, almeno un numero, almeno una lettera maiuscola e almeno un carattere speciale","cancel":"Annulla","save":"Conferma","dialog":{"title":"La password è stata modificata correttamente","text":"Effettua l’accesso utilizzando la nuova password. Se sono presenti altre finestre del browser con accesso al tuo account tramite la vecchia password, assicurati di chiuderle.","confirmLabel":"Vai al login"}},"changeEmail":{"cancel":"Annulla","save":"Conferma","title":"Modifica l'indirizzo email","notAuthorizedException":"L'indirizzo email inserito non è valido","wrongEmail":"L'indirizzo email inserito non risulta corretto","dialog":{"title":"Verifica il nuovo indirizzo email","text":"Abbiamo inviato una email all’indirizzo che hai inserito.\nClicca sul link contenuto al suo interno per verificarlo e associarlo al tuo account PagoPA DevPortal.","confirmLabel":"Chiudi"}},"insert":"Inserisci"},"webinar":{"liveWebinar":"Webinar in corso","subscriptionError":"Limite di iscrizioni raggiunto","genericSubscriptionError":"Qualcosa è andato storto, riprova più tardi","goToWebinar":"Vai al webinar","whyParticipate":"Perché partecipare?","speakers":"Ospiti","subscribe":"Iscriviti","speakersTitle":"Ospiti","questionList":{"title":{"highlightedQuestions":"Domande scelte","questions":"Domande"},"hiddenByMe":"Hai nascosto questa domanda","highlightedBy":"Scelta da"},"questionsForm":{"title":"Scrivi qui domande e commenti per la discussione finale (al massimo {maxLength} caratteri)","question":"Domanda","submit":"Invia","submitted":"Inviato","error":"Errore nell'invio, riprova più tardi."},"warnings":{"email":"Il giorno prima dell'evento riceverai una email con i dettagli.","goTo":"Collegati alla pagina del webinar all'orario di inizio dell'evento.","refresh":"Collegati a questa pagina all'orario di inizio dell'evento."},"webinarsSection":{"description":"","noWebinars":"Stiamo preparando i prossimi eventi, controlla più avanti.","title":{"dontLoseNext":"Non perderti il prossimo webinar","dontLoseNextPlural":"Non perderti i prossimi webinar","next":"I prossimi appuntamenti","our":"I nostri webinar","participateTo":"Partecipa ai nostri webinar","dedicatedWebinar":"Guarda il webinar dedicato"},"solutionDescription":"I webinar PagoPA LAB sono incontri formativi in cui gli specialisti del nostro team illustrano tutti i passaggi del processo di gestione di un servizio pubblico digitale, approfondendo i benefici di un approccio integrato delle piattaforme gestite da PagoPA.","questionsAndAnswers":{"title":"Le risposte alle vostre domande","showMore":"Mostra più domande","showLess":"Mostra meno domande"},"relatedResources":{"title":"Risorse correlate"}},"view":"Visualizza","pastWebinars":{"title":"Esplora tutti i webinar","description":"Approfondisci argomenti legati all'integrazione con i nostri prodotti attraverso la guida e i consigli esperti dei professionisti PagoPA.","cta":"Vedi tutti"}},"webinars":{"title":"Partecipa agli eventi live e guarda i webinar passati ","subtitle":"Con i webinar di PagoPA DevPortal hai l'opportunità di approfondire argomenti legati all'integrazione con i nostri prodotti, attraverso la guida e i consigli esperti del nostro team.","nextWebinars":"I prossimi appuntamenti","pastWebinars":"Webinar passati"},"auth":{"logout":"Esci","login":{"action":"Accedi","loginToYourAccount":"Accedi al tuo account DevPortal","rememberMe":"Ricordami","forgotPassword":"Hai dimenticato la password?","noAccount":"Non hai un account?","noAccountError":"Nome utente o password non corretti.","accountAlreadyConfirmed":{"yourAccountIsAlreadyConfirmed":"Hai già validato questo indirizzo email","goToLogin":"Vai al Login"}},"confirmation":{"title":"Verifica la tua identità","body":"Abbiamo inviato un codice di verifica a {email}
Il codice scade tra 15 minuti.","code":"Codice di verifica","checkJunkMail":"Non hai ricevuto alcuna email? Controlla la posta indesiderata oppure","continue":"Continua","ctaLabel":"Reinvia email","resendEmail":"Reinvia email"},"resendEmail":{"label":"Reinvia email"},"signUp":{"action":"Iscriviti","createYourAccount":"Crea il tuo account","passwordMismatchError":"Le password non combaciano","confirmComunications":"Inviami email relative alle risorse e agli aggiornamenti sui prodotti. Se questa casella è selezionata, PagoPA ti invierà di tanto in tanto delle email utili e pertinenti. Puoi annullare l'iscrizione in qualsiasi momento.","acceptPolicy":"Cliccando su iscriviti dichiari di aver preso visione della nostra informativa privacy e dei nostri termini e condizioni d'uso.","alreadyHaveAnAccount":"Hai già un account?","whyCreateAccount":"Perché iscriversi a PagoPA DevPortal","passwordError":"Non rispetta i requisiti.","passwordPolicy":"Minimo 8 caratteri, almeno un numero, almeno una lettera maiuscola e almeno un carattere speciale","emailSent":"Email inviata a {email}","advantages":{"exclusive_contents":{"title":"Accedi a contenuti esclusivi","text":"Assisti ai webinar di PagoPA e interagisci con noi sugli argomenti del momento.","isComingSoon":"false"},"product_updates":{"title":"Ricevi aggiornamenti sui nostri prodotti","text":"Non perdere neanche un nuovo contenuto, guida o tutorial. Puoi scegliere di ricevere via email le novità sui prodotti PagoPA e sull'integrazione tecnologica. ","isComingSoon":"false"},"api_keys":{"title":"Genera, gestisci e utilizza api Key","text":"Sblocca tutto il potenziale del DevPortal con API Key, Mocker, SDK ed altro ancora.","isComingSoon":"true"},"support":{"title":"Richiedi assistenza tramite un form dedicato","text":"Avvicinati con facilità alle soluzioni di cui hai bisogno e risolvi le difficoltà con il nostro aiuto.","isComingSoon":"true"}},"companyRoles":{"ente-pubblico":"Ente pubblico","partner-tecnologico":"Partner tecnologico","psp":"PSP","gestore-di-pubblico-servizio":"Gestore di pubblico servizio","azienda-privata":"Azienda privata","altro":"Altro"}},"confirmSignUp":{"title":"Confermaci che sei tu","emailSent":"Abbiamo inviato una email a ","clickToConfirm":"Clicca sul pulsante contenuto al suo interno per verificarla.","didntReceiveEmail":"Non hai ricevuto l'email? Controlla la posta indesiderata oppure","resendEmail":"Invia nuovamente l'email","wrongEmail":"L'indirizzo email è errato?"},"confirmLogin":{"title":"Verifica la tua identità","code":"Codice di verifica","confirmationCodeSent":"Abbiamo inviato un codice di verifica a ","confirmationCodeExpires":"Il codice scade tra 15 minuti.","checkJunkMail":"Non hai ricevuto alcuna email? Controlla la posta indesiderata oppure","continue":"Continua","resendEmail":"Reinvia email","invalidCode":"Il codice inserito non è corretto","emptyCode":"Il codice è obbligatorio"},"accountActivated":{"goToLogin":"Vai al login","welcomeMessage":"Ti diamo il benvenuto su PagoPA DevPortal.","yourAccountIsActive":"Il tuo account è attivo"},"resetPassword":{"body":"Inserisci il tuo indirizzo email e ti invieremo le istruzioni per impostare una nuova password.","checkEmailEnd":"riceverai una email con un link per impostare una nuova password.","checkEmailStart":"Se esiste un account associato a ","checkEmailTitle":"Controlla l'email","emailFieldError":"L’indirizzo email non è valido","goToLogin":"Torna al login","invalidLinkError":"Il link non è valido","newPassword":"Imposta una nuova password","passwordSet":"Password impostata correttamente","rememberPassword":"Ricordi la tua password?","resendEmail":"Reinvia email","resendEmailPrompt":"Non hai ricevuto l'email? Controlla nella posta indesiderata oppure","send":"Invia","title":"Recupera password","wrongEmail":"L'indirizzo email è errato?"},"expiredCode":{"expiredLink":"Il link che hai usato è scaduto","goToProfile":"Vai al profilo"}},"shared":{"comingSoon":"In Arrivo","readTutorial":"Leggi il tutorial","readStory":"Leggi la storia","moreInfo":"Scopri di più","version":"Versione","copiedTooltip":"Copiato","siteTitle":"PagoPA DevPortal","emailAddress":"Indirizzo email","password":"Password","goBack":"Torna indietro","requiredFields":"* Campi obbligatori","firstName":"Nome","lastName":"Cognome","confirmPassword":"Conferma password","company":"Tipologia Ente o Azienda","role":"Ruolo","requiredFieldError":"Questo campo non può essere vuoto","emailFieldError":"Inserisci un indirizzo email valido","emailAlreadyTaken":"Esiste già un account per questo indirizzo email","goToModel":"Vai al modello","edit":"Modifica","cancel":"Annulla","yourData":"Profilo","subscribeButton":{"subscribeLabel":{"default":"Iscriviti","takePart":"Partecipa","view":"Visualizza"},"subscribedLabel":"Iscrizione confermata","unsubscribeLabel":"Annulla iscrizione"},"relatedLinks":"Link utili","downloadableDocuments":"Materiali scaricabili","download":"Scarica"},"pageNotFound":{"overline":"404","title":"Pagina non trovata","description":"La pagina che stai cercando non esiste"},"productGuidePage":{"onThisPage":"In questa pagina","tableOfContents":"Tabella dei contenuti"},"homepage":{"news":{"title":"In evidenza","list":{"0":{"title":"Usa il validatore di SEND per fare una verifica sull’integrazione","href":{"label":"Vai al validatore","title":"Vai al validatore"},"image":{"url":"/images/homepage-validatore.png","alt":"Immagine: Usa il validatore di SEND per fare una verifica sull’integrazione"}},"1":{"title":"Scopri i nuovi tutorial di Firma con IO","href":{"label":"Vai ai tutorial","title":"Vai ai tutorial"},"image":{"url":"/images/homepage-io-sign.png","alt":"Immagine: Scopri i nuovi tutorial di Firma con IO"}},"2":{"title":"Scopri la Quick Start di piattaforma pagoPA: l’integrazione in pochi semplici step","href":{"label":"Vai alla guida","title":"Vai alla guida"},"image":{"url":"/images/homepage-pago-pa.png","alt":"Immagine: Scopri la Quick Start di piattaforma pagoPA: l’integrazione in pochi semplici step"}}}},"webinarBannerButtonContent":"Scopri","productsShowcaseTitle":"Scopri il nostro ecosistema","heroItems":{"0":{"title":"Tutto ciò che serve per integrarsi con i prodotti PagoPA"},"1":{"title":"Invia comunicazioni a valore legale con piattaforma notifiche","ctaLabel":"Vai a SEND"},"2":{"title":"Richiedi una firma su documenti e contratti","ctaLabel":"Vai a Firma con IO"}},"webinarsSection":{"description":"","title":"Partecipa ai nostri webinar","link":{"href":"#","label":"Vedi tutti i webinar"}},"comingsoonDocumentation":{"title":"Documentazione in arrivo","links":{"0":{"text":"Interoperabilità. Scambia informazioni con altri enti in tutta sicurezza."},"1":{"text":"Check IBAN. Utilizza un sistema per la gestione degli incassi centralizzato e immediato."}}}},"quickStartGuide":{"content":{"apiPhases":{"request":{"cta":{"label":"Invia la richiesta"},"title":"Chiamata API"},"response":{"cta":{"icon":"Replay","label":"Ripristina la chiamata"},"title":"Risposta del server"}},"next":"Prossimo contenuto","previous":"Contenuto precedente"}},"overview":{"startInfo":{"title":"Si comincia da qui"},"tutorial":{"title":"Esplora i tutorial","ctaLabel":"Vedi tutti i tutorial"},"postIntegration":{"title":"Dopo l'integrazione"},"relatedLinks":{"title":"LINK UTILI"}},"footer":{"companyLink":{"ariaLabel":"Link: vai al sito di PagoPA S.p.A."},"languages":{"it":"Italiano"},"legalInfo":"PagoPA S.p.A. - Società per azioni con socio unico - Capitale sociale di euro 1,000,000 interamente versato - Sede legale in Roma, Piazza Colonna 370,

CAP 00187 - N. di iscrizione a Registro Imprese di Roma, CF e P.IVA 15376371009","followUs":{"links":{"accessibility":{"ariaLabel":"Vai al link: Accessibilità","label":"Accessibilità"}},"title":"Seguici su"},"aboutUs":{"title":"","links":{"whoWeAre":{"ariaLabel":"Vai al link: Chi siamo","label":"Chi siamo"},"pnrr":{"ariaLabel":"Vai al link: PNRR","label":"PNRR"},"media":{"ariaLabel":"Vai al link: Media","label":"Media"},"workWithUs":{"ariaLabel":"Vai al link: Lavora con noi","label":"Lavora con noi"}}},"resources":{"title":"Risorse","links":{"privacyPolicy":{"ariaLabel":"Vai al link: Informativa Privacy","label":"Informativa Privacy"},"termsOfService":{"ariaLabel":"Vai al link: Termini e Condizioni","label":"Termini e Condizioni"},"societaTrasparente":{"ariaLabel":"Vai al link: Società trasparente","label":"Società trasparente"},"disclosurePolicy":{"ariaLabel":"Vai al link: Responsible Disclosure Policy","label":"Responsible Disclosure Policy"},"model231":{"ariaLabel":"Vai al link: Modello 231","label":"Modello 231"}}},"services":{"title":"PRODOTTI E SERVIZI","links":{"appIO":{"ariaLabel":"Vai al link: App IO","label":"App IO"},"pagoPA":{"ariaLabel":"Vai al link: Piattaforma pagoPA","label":"Piattaforma pagoPA"},"centroStella":{"ariaLabel":"Vai al link: Centro stella","label":"Centro stella"},"checkIBAN":{"ariaLabel":"Vai al link: Check IBAN","label":"Check IBAN"},"send":{"ariaLabel":"Vai al link: SEND - Servizio Notifiche Digitali","label":"SEND - Servizio Notifiche Digitali"},"pdnd":{"ariaLabel":"Vai al link: Piattaforma Digitale Nazionale Dati - Interoperabilità","label":"Piattaforma Digitale Nazionale Dati - Interoperabilità"}}},"cookiePreferences":{"ariaLabel":"Preferenza Cookie","label":"Preferenza Cookie"}},"errors":{"CodeDeliveryFailureException":"Impossibile inviare il codice di verifica.","ForbiddenException":"La tua richiesta non è stata consentita dal sistema di autenticazione.","InternalErrorException":"Si è verificato un errore interno al sistema di autenticazione.","InvalidEmailRoleAccessPolicyException":"Il sistema di autenticazione non è autorizzato a utilizzare la tua identità email.","InvalidLambdaResponseException":"Il sistema di autenticazione ha riscontrato una risposta non valida.","InvalidParameterException":"Il servizio di autenticazione ha riscontrato un parametro non valido.","InvalidPasswordException":"Password non valida.","ResourceNotFoundException":"Il servizio di autenticazione non trova la risorsa richiesta.","TooManyRequestsException":"Troppe richieste di autenticazione.","UnexpectedLambdaException":"É stata riscontrata un'eccezione imprevista con il sistema di autenticazione.","UserLambdaValidationException":"Il servizio di autenticazione ha riscontrato un'eccezione di convalida utente.","UsernameExistsException":"Username già registrato.","UserNotFoundException":"Utente non registrato.","NotAuthorizedException":"Operazione non autorizzata.","PasswordResetRequiredException":"É stato richiesto un reset della password.","UserNotConfirmedException":"Utente non confermato, controlla nella email e apri il link di conferma.","CodeMismatchException":"Codice non valido.","ExpiredCodeException":"Codice scaduto.","TooManyFailedAttemptsException":"Troppi tentativi errati.","LimitExceededException":"Limiti di autenticazione superati."},"swagger":{"errorCard":{"header":"Oops, manca qualcosa.","message":"Non siamo riusciti a trovare la fonte originale per visualizzare questo contenuto."},"parameters":{"header":"Parametri","empty":"Nessun parametro"},"requestBody":{"header":"Corpo"},"responses":{"header":"Risposte"},"example":"Esempio","schema":"Modello","emptyOperations":{"header":"Nessuna operazione","message":"Non ci sono operazioni disponibili per questo endpoint."}},"breadcrumbs":{"home":"DevPortal","webinars":"Webinar","solutions":"Soluzioni"},"solution":{"steps":{"platforms":"Piattaforme Abilitanti"},"ctaDetailLabel":"Leggi la guida completa"},"caseHistory":{"productShowcaseLabel":"Come integrarsi? Inizia da qui"},"apiDataListPage":{"explore":"Esplora le API"},"chatBot":{"title":"Chatbot","writeNewMessagePlaceholder":"Scrivi un nuovo messaggio","chatHistory":"Cronologia chat","delete":"Elimina"}},"timeZone":"Europe/Rome","children":["$","$Lb",null,{"children":[["$","$Lc",null,{"cookieDomainScript":"$undefined"}],["$","$Ld",null,{"children":["$","$Le",null,{"isChatbotVisible":false,"children":[["$","$Lf",null,{"products":[{"name":"IO, l’app dei servizi pubblici","shortName":"IO","description":"Raccogli tutti i servizi digitali del tuo ente in un’unica piattaforma e interagisci in modo semplice e sicuro con i cittadini.","slug":"app-io","path":"/app-io","logo":{"alternativeText":"IO, l’app dei servizi pubblici","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/appIo.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/app-io/overview"},"quickStart":{"name":"Quick start","path":"/app-io/quick-start"},"api":{"name":"API","path":"/app-io/api/app-io-main"},"tutorials":{"name":"Tutorial","path":"/app-io/tutorials"},"guides":{"name":"Guide e manuali","path":"/app-io/guides"}}},{"name":"Firma con IO","shortName":"Firma con IO","description":"Richiedi la Firma Elettronica Certificata su contratti e documenti. Le cittadine e i cittadini possono firmare direttamente sull’app IO.","slug":"firma-con-io","path":"/firma-con-io","logo":{"alternativeText":"Firma con IO","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/appIo.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/firma-con-io/overview"},"quickStart":{"name":"Quick start","path":"/firma-con-io/quick-start"},"api":{"name":"API","path":"/firma-con-io/api/firma-con-io-main"},"tutorials":{"name":"Tutorial","path":"/firma-con-io/tutorials"},"guides":{"name":"Guide e manuali","path":"/firma-con-io/guides"}}},{"name":"SEND - Servizio Notifiche Digitali","shortName":"SEND","description":"Invia comunicazioni a valore legale con un processo di notificazione gestito interamente dalla piattaforma.","slug":"send","path":"/send","logo":{"alternativeText":"SEND - Servizio Notifiche Digitali","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/send.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/send/overview"},"quickStart":{"name":"Quick start","path":"/send/quick-start"},"api":{"name":"API","path":"/send/api/send-main"},"tutorials":{"name":"Tutorial","path":"/send/tutorials"},"guides":{"name":"Guide e manuali","path":"/send/guides"}}},{"name":"Piattaforma pagoPA","shortName":"pagoPA","description":"Gestisci gli incassi in modo centralizzato e con immediata riconciliazione delle posizioni debitorie.","path":"/pago-pa","slug":"pago-pa","logo":{"alternativeText":"Piattaforma pagoPA","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/pagoPa.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/pago-pa/overview"},"quickStart":{"name":"Quick start","path":"/pago-pa/quick-start"},"api":{"name":"API","path":"/pago-pa/api"},"tutorials":{"name":"Tutorial","path":"/pago-pa/tutorials"},"guides":{"name":"Guide e manuali","path":"/pago-pa/guides"}}}]}],["$","main",null,{"children":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":["$","$L12",null,{"layout":"center","overline":"404","title":"Pagina non trovata","description":"La pagina che stai cercando non esiste"}],"notFoundStyles":[],"childProp":{"current":[null,["$","div",null,{"id":"chatbot-page-content","children":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children","case-histories","children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children","case-histories","children",["caseHistorySlug","tari-cagliari","d"],"children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$L13","$L14",null],"segment":"__PAGE__?{\"caseHistorySlug\":\"tari-cagliari\"}"},"styles":[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/918940977e95543e.css","precedence":"next"}]]}],"segment":["caseHistorySlug","tari-cagliari","d"]},"styles":[]}]}],null],"segment":"case-histories"},"styles":[]}]}],["$","$L15",null,{}]]}]}]]}]}]}]]}] +16:I{"id":54316,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","3495:static/chunks/f5890c91-7948379131fd4dd8.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","1189:static/chunks/1189-2b1aa7c0348b14f6.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","6686:static/chunks/6686-9bc47ab2e6abbf5b.js","1878:static/chunks/1878-a3a68810eafbc18e.js","2536:static/chunks/2536-70a61cc5dfb9f7da.js","2373:static/chunks/app/case-histories/[caseHistorySlug]/page-bb9f62747b123bc3.js"],"name":"","async":false} +14:["$","$L16",null,{"slug":"tari-cagliari","title":"Il processo di riscossione della TARI del Comune di Cagliari","description":"Il racconto dell'esperienza del Comune di Cagliari, uno dei primi Comuni d'Italia a integrare SEND per gestire le notifiche a valore legale relative agli accertamenti Tari.","publishedAt":"$D2024-07-24T06:58:54.121Z","image":{"name":"tari.png","alternativeText":"$undefined","caption":"$undefined","width":364,"height":208,"ext":".png","mime":"image/png","size":16.7,"url":"https://cdn.dev.developer.pagopa.it/tari_71964937e2.png"},"parts":[{"component":"blockRenderer","html":[{"type":"heading","level":5,"children":[{"text":"Lo scenario","type":"text"}]},{"type":"paragraph","children":[{"text":"Il Comune di Cagliari, che già da tempo è attivo sulla piattaforma pagoPA, è stato uno dei primi comuni a salire a bordo di SEND per gestire le notifiche a valore legale relative agli accertamenti Tari. Abbiamo incontrato Sabrina Contu e Paola Cuccureddu, rispettivamente funzionaria IMU/Tasi e funzionaria TARI del Comune di Cagliari, e abbiamo chiesto loro di raccontarci l’esperienza di onboarding e integrazione di SEND.","type":"text"}]},{"type":"paragraph","children":[{"text":"“Quando nel 2022 è stata pubblicata la Misura 1.4.5 Piattaforma Notifiche Digitali che consentiva alle amministrazioni di poter ricevere un finanziamento, nell’ambito del PNRR, per l'adesione a SEND” ci spiega Sabrina Contu, “abbiamo studiato il regolamento di attuazione della normativa e, prima di procedere, abbiamo fatto un'analisi degli invii di atti a valore legale effettuati nell’ultimo triennio verso società e professionisti. Questa analisi del business case è stata fondamentale perchè ci ha consentito di quantificare il valore di quegli avvisi e, nell'analisi costi / benefici, di renderci immediatamente conto degli evidenti vantaggi per l’Amministrazione nell’adesione a SEND, sia dal punto di vista economico che dal punto di vista della sicurezza dell’incasso a fronte di una maggiore probabilità di reperibilità del destinatario.","type":"text"}]},{"type":"heading","level":5,"children":[{"text":"Onboarding e integrazione","type":"text"}]},{"type":"paragraph","children":[{"text":"“Una volta deciso di procedere con l’adesione, il passo successivo è stato la scelta del fornitore tecnologico per l’integrazione alla Piattaforma. Nel nostro caso, la software house che già gestiva l'applicativo dei tributi era anche già pronta per partire con SEND. Ci siamo quindi interfacciati con i referenti di PagoPA che ci hanno dato tutte le indicazioni utili per l’adesione: dall’accesso all'area riservata alla firma dell’accordo. ","type":"text"}]},{"type":"paragraph","children":[{"text":"Dal canto nostro, abbiamo istituito l’apposito capitolo di spesa ed effettuato su questo l’apposito impegno di spesa per la prestazione del servizio.","type":"text"}]},{"type":"paragraph","children":[{"text":"Naturalmente questa nuova modalità di invio impone il rispetto di una serie di criteri e parametri: ad esempio, l’atto è nativo digitale e richiede quindi - per la versione stampata - di seguire delle specifiche precise, che ci sono state fornite e spiegate dal team di PagoPA e ci hanno consentito di procedere alla digitalizzazione degli atti con grande facilità.”","type":"text"}]},{"type":"paragraph","children":[{"text":"“Siamo pienamente soddisfatti di quanto fatto già lo scorso anno con SEND: abbiamo rilevato un significativo snellimento dei processi e abbiamo sperimentato i vantaggi legati al ritorno della notifica che viene automaticamente caricata in procedura.” conclude Sabrina Contu. ","type":"text"}]},{"type":"heading","level":5,"children":[{"text":"La risposta dei cittadini","type":"text"}]},{"type":"paragraph","children":[{"text":"“Abbiamo cercato di fare una comunicazione sul territorio in modo che i cittadini fossero informati di questa nuova possibilità, per accompagnarli in questo percorso di transizione digitale e consentire loro di percepire il cambio di passo del Comune come un vantaggio reale.” racconta Paola Cuccureddu. “Sappiamo bene all'interno di un comune quanto siano rilevanti - e purtroppo limitate - sia il fattore tempo che le risorse umane e tecniche disponibili. Con SEND abbiamo potuto ridurre i costi e ottimizzare al meglio le risorse disponibili, creando un servizio maggiormente di valore e impiegando quelle risorse per riuscire a fare una maggiore lotta all'evasione. Per il 2024 vogliamo continuare a notificare con SEND, forti anche dell’esperienza dello scorso anno, e contiamo di gestire circa 40.000 notifiche legate agli accertamenti TARI.”","type":"text"}]}],"id":8,"__component":"parts.html"},{"component":"quote","quote":"Siamo pienamente soddisfatti di quanto fatto già lo scorso anno con SEND: abbiamo rilevato un significativo snellimento dei processi e abbiamo sperimentato i vantaggi legati al ritorno della notifica che viene automaticamente caricata in procedura.","backgroundImage":{"name":"43575a126f32092f1a455b95e4192aca.jpg","alternativeText":"$undefined","caption":"$undefined","width":2880,"height":1120,"ext":".jpg","mime":"image/jpeg","size":596.04,"url":"https://cdn.dev.developer.pagopa.it/43575a126f32092f1a455b95e4192aca_9932ad76b1.jpg"}}],"products":[{"name":"IO, l’app dei servizi pubblici","description":"Raccogli tutti i servizi digitali del tuo ente in un’unica piattaforma e interagisci in modo semplice e sicuro con i cittadini.","slug":"app-io","shortName":"IO","logo":{"name":"appIo.svg","alternativeText":"$undefined","caption":"$undefined","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","size":1.9,"url":"https://cdn.dev.developer.pagopa.it/app_Io_d9bffd556b.svg"}},{"name":"Piattaforma pagoPA","description":"Gestisci gli incassi in modo centralizzato e con immediata riconciliazione delle posizioni debitorie.","slug":"pago-pa","shortName":"pagoPA","logo":{"name":"pagoPa.svg","alternativeText":"$undefined","caption":"$undefined","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","size":2.28,"url":"https://cdn.dev.developer.pagopa.it/pago_Pa_ce808e88c2.svg"}},{"name":"SEND - Servizio Notifiche Digitali","description":"Invia comunicazioni a valore legale con un processo di notificazione gestito interamente dalla piattaforma.","slug":"send","shortName":"SEND","logo":{"name":"send.svg","alternativeText":"$undefined","caption":"$undefined","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","size":1.56,"url":"https://cdn.dev.developer.pagopa.it/send_9dd94aaf2a.svg"}}]}] +6:[["$","meta","0",{"charSet":"utf-8"}],["$","title","1",{"children":"PagoPA DevPortal | Il processo di riscossione della TARI del Comune di Cagliari"}],["$","meta","2",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","3",{"property":"og:title","content":"PagoPA DevPortal | Il processo di riscossione della TARI del Comune di Cagliari"}],["$","meta","4",{"property":"og:locale","content":"it_IT"}],["$","meta","5",{"property":"og:image","content":"https://dev.developer.pagopa.it/images/dev-portal-home.jpg"}],["$","meta","6",{"property":"og:type","content":"website"}],["$","meta","7",{"name":"twitter:card","content":"summary"}],["$","meta","8",{"name":"twitter:site","content":"@pagopa"}],["$","meta","9",{"name":"twitter:creator","content":"@pagopa"}],["$","meta","10",{"name":"twitter:title","content":"PagoPA DevPortal | Il processo di riscossione della TARI del Comune di Cagliari"}],["$","meta","11",{"name":"twitter:image","content":"https://dev.developer.pagopa.it/images/dev-portal-home.jpg"}],["$","link","12",{"rel":"icon","href":"/icon.svg?f2ac316c8a418774","type":"image/svg+xml","sizes":"any"}],["$","meta","13",{"name":"next-size-adjust"}]] +13:null diff --git a/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.html b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.html new file mode 100644 index 0000000000..d5d87eee48 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.html @@ -0,0 +1 @@ +PagoPA DevPortal | test case

test case

h1

h2

h3

h4

h5

\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.txt b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.txt new file mode 100644 index 0000000000..80f29fda36 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/case-histories/test-case.txt @@ -0,0 +1,23 @@ +1:HL["/_next/static/media/28fac4a6e903645b-s.p.woff2",{"as":"font","type":"font/woff2"}] +2:HL["/_next/static/media/2bb25458ea2620e9-s.p.woff2",{"as":"font","type":"font/woff2"}] +3:HL["/_next/static/media/f378bd2abf9e0d48-s.p.woff2",{"as":"font","type":"font/woff2"}] +4:HL["/_next/static/css/c1a3c2f6d783e471.css",{"as":"style"}] +0:["dgB9Zym4WNhjMAim9VsHX",[[["",{"children":["case-histories",{"children":[["caseHistorySlug","test-case","d"],{"children":["__PAGE__?{\"caseHistorySlug\":\"test-case\"}",{}]}]}]},"$undefined","$undefined",true],"$L5",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c1a3c2f6d783e471.css","precedence":"next"}]],"$L6"]]]] +7:HL["/_next/static/css/918940977e95543e.css",{"as":"style"}] +5:[null,"$L8",null] +9:I{"id":44631,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +a:I{"id":36738,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +b:I{"id":93038,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +c:I{"id":8392,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +d:I{"id":10099,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +e:I{"id":15337,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +f:I{"id":13249,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +10:I{"id":92842,"chunks":["2272:static/chunks/webpack-d4fd03056baeac5f.js","1293:static/chunks/1dd3208c-3c1077ed7a7ffc38.js","3575:static/chunks/3575-63f451fe7624e01e.js"],"name":"default","async":false} +11:I{"id":41316,"chunks":["2272:static/chunks/webpack-d4fd03056baeac5f.js","1293:static/chunks/1dd3208c-3c1077ed7a7ffc38.js","3575:static/chunks/3575-63f451fe7624e01e.js"],"name":"default","async":false} +12:I{"id":80741,"chunks":["7950:static/chunks/7950-2339fabfd6a7629e.js","3093:static/chunks/3093-9dff2f7303959b74.js","2352:static/chunks/2352-337e28b99911d4e6.js","9160:static/chunks/app/not-found-b6e4c33c40a04c85.js"],"name":"Abstract","async":false} +15:I{"id":61151,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","793:static/chunks/793-77ca7af0bb11a65e.js","9324:static/chunks/9324-d505475479bc0041.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","3185:static/chunks/app/layout-c2a6e31b15c439fb.js"],"name":"","async":false} +8:["$","html",null,{"lang":"it","className":"__variable_c1363f","children":[["$","head",null,{"children":false}],["$","$L9",null,{"options":{"key":"mui"},"children":["$","$La",null,{"locale":"it","messages":{"devPortal":{"company":"PagoPA","siteHeader":{"label":"Menu","products":"Prodotti","profile":"Profilo","webinars":"Webinar","solutions":"Soluzioni"},"title":"DevPortal"},"profile":{"title":"Profilo","agreements":{"newsletter":{"description":"Inviami email relative alle risorse e agli aggiornamenti sui prodotti. Se questa opzione è attiva, PagoPA ti invierà di tanto in tanto delle email utili e pertinenti.","error":{"subscribe":"C'è stato un errore nell'iscrizione, riprova più tardi o contatta l'assistenza tecnica.","unsubscribe":"C'è stato un errore nella cancellazione, riprova più tardi o contatta l'assistenza tecnica."},"subscribe":"Iscriviti","title":"Iscrizione alla newsletter","unsubscribe":"Annulla iscrizione"},"privacy":{"basicData":"PagoPA raccoglie dati personali di base che ti permettono di creare e utilizzare il tuo account su DevPortal. Questi dati sono raccolti durante la registrazione e l'aggiornamento del tuo profilo. PagoPA garantisce che i tuoi dati vengano gestiti in modo sicuro e ne giustifica l’utilizzo secondo l’informativa Privacy di PagoPA. I tuoi dati personali di base verranno conservati fino a quando avrai un account attivo su PagoPA DevPortal.","title":"Privacy","statement":{"text":"La nostra $labelOfLinkToReplace$ fornisce informazioni dettagliate sui tuoi diritti in materia di privacy.","labelOfLinkToReplace":"Informativa Privacy"}},"title":"Consensi e privacy"},"personalData":{"save":"Conferma","cancel":"Annulla","title":"Su di te","dataSection":"I tuoi dati","accountSection":"Il tuo account","deleteAccountSection":"Eliminazione Account","deleteAccount":{"sectionLabel":"Puoi decidere di eliminare il tuo account su PagoPA DevPortal in qualsiasi momento. I tuoi dati verranno cancellati dai nostri sistemi.","buttonLabel":"Elimina account","modalTitle":"Confermi di voler eliminare il tuo account?","modalText":"Se elimini il tuo account PagoPA DevPortal tutte le tue preferenze e i tuoi dati verranno cancellati dai nostri sistemi. Questa azione non è reversibile."},"deleteAccountButton":"Elimina account","addField":"Inserisci","fields":{"name":"Nome","surname":"Cognome","role":"Ruolo","company":"Tipologia di ente o azienda","sector":"Settore","products":"Prodotti di interesse","email":"Indirizzo email","password":"Password"}},"changePassword":{"title":"Cambia password","currentPassword":"Password attuale","newPassword":"Nuova password","confirmPassword":"Conferma password","wrongPassword":"La password inserita non risulta corretta","requiredCurrentPassword":"È necessario inserire la password attuale","passwordsNotMatch":"Le password non corrispondono","passwordPolicy":"Non rispetta i requisiti. Minimo 8 caratteri, almeno un numero, almeno una lettera maiuscola e almeno un carattere speciale","cancel":"Annulla","save":"Conferma","dialog":{"title":"La password è stata modificata correttamente","text":"Effettua l’accesso utilizzando la nuova password. Se sono presenti altre finestre del browser con accesso al tuo account tramite la vecchia password, assicurati di chiuderle.","confirmLabel":"Vai al login"}},"changeEmail":{"cancel":"Annulla","save":"Conferma","title":"Modifica l'indirizzo email","notAuthorizedException":"L'indirizzo email inserito non è valido","wrongEmail":"L'indirizzo email inserito non risulta corretto","dialog":{"title":"Verifica il nuovo indirizzo email","text":"Abbiamo inviato una email all’indirizzo che hai inserito.\nClicca sul link contenuto al suo interno per verificarlo e associarlo al tuo account PagoPA DevPortal.","confirmLabel":"Chiudi"}},"insert":"Inserisci"},"webinar":{"liveWebinar":"Webinar in corso","subscriptionError":"Limite di iscrizioni raggiunto","genericSubscriptionError":"Qualcosa è andato storto, riprova più tardi","goToWebinar":"Vai al webinar","whyParticipate":"Perché partecipare?","speakers":"Ospiti","subscribe":"Iscriviti","speakersTitle":"Ospiti","questionList":{"title":{"highlightedQuestions":"Domande scelte","questions":"Domande"},"hiddenByMe":"Hai nascosto questa domanda","highlightedBy":"Scelta da"},"questionsForm":{"title":"Scrivi qui domande e commenti per la discussione finale (al massimo {maxLength} caratteri)","question":"Domanda","submit":"Invia","submitted":"Inviato","error":"Errore nell'invio, riprova più tardi."},"warnings":{"email":"Il giorno prima dell'evento riceverai una email con i dettagli.","goTo":"Collegati alla pagina del webinar all'orario di inizio dell'evento.","refresh":"Collegati a questa pagina all'orario di inizio dell'evento."},"webinarsSection":{"description":"","noWebinars":"Stiamo preparando i prossimi eventi, controlla più avanti.","title":{"dontLoseNext":"Non perderti il prossimo webinar","dontLoseNextPlural":"Non perderti i prossimi webinar","next":"I prossimi appuntamenti","our":"I nostri webinar","participateTo":"Partecipa ai nostri webinar","dedicatedWebinar":"Guarda il webinar dedicato"},"solutionDescription":"I webinar PagoPA LAB sono incontri formativi in cui gli specialisti del nostro team illustrano tutti i passaggi del processo di gestione di un servizio pubblico digitale, approfondendo i benefici di un approccio integrato delle piattaforme gestite da PagoPA.","questionsAndAnswers":{"title":"Le risposte alle vostre domande","showMore":"Mostra più domande","showLess":"Mostra meno domande"},"relatedResources":{"title":"Risorse correlate"}},"view":"Visualizza","pastWebinars":{"title":"Esplora tutti i webinar","description":"Approfondisci argomenti legati all'integrazione con i nostri prodotti attraverso la guida e i consigli esperti dei professionisti PagoPA.","cta":"Vedi tutti"}},"webinars":{"title":"Partecipa agli eventi live e guarda i webinar passati ","subtitle":"Con i webinar di PagoPA DevPortal hai l'opportunità di approfondire argomenti legati all'integrazione con i nostri prodotti, attraverso la guida e i consigli esperti del nostro team.","nextWebinars":"I prossimi appuntamenti","pastWebinars":"Webinar passati"},"auth":{"logout":"Esci","login":{"action":"Accedi","loginToYourAccount":"Accedi al tuo account DevPortal","rememberMe":"Ricordami","forgotPassword":"Hai dimenticato la password?","noAccount":"Non hai un account?","noAccountError":"Nome utente o password non corretti.","accountAlreadyConfirmed":{"yourAccountIsAlreadyConfirmed":"Hai già validato questo indirizzo email","goToLogin":"Vai al Login"}},"confirmation":{"title":"Verifica la tua identità","body":"Abbiamo inviato un codice di verifica a {email}
Il codice scade tra 15 minuti.","code":"Codice di verifica","checkJunkMail":"Non hai ricevuto alcuna email? Controlla la posta indesiderata oppure","continue":"Continua","ctaLabel":"Reinvia email","resendEmail":"Reinvia email"},"resendEmail":{"label":"Reinvia email"},"signUp":{"action":"Iscriviti","createYourAccount":"Crea il tuo account","passwordMismatchError":"Le password non combaciano","confirmComunications":"Inviami email relative alle risorse e agli aggiornamenti sui prodotti. Se questa casella è selezionata, PagoPA ti invierà di tanto in tanto delle email utili e pertinenti. Puoi annullare l'iscrizione in qualsiasi momento.","acceptPolicy":"Cliccando su iscriviti dichiari di aver preso visione della nostra informativa privacy e dei nostri termini e condizioni d'uso.","alreadyHaveAnAccount":"Hai già un account?","whyCreateAccount":"Perché iscriversi a PagoPA DevPortal","passwordError":"Non rispetta i requisiti.","passwordPolicy":"Minimo 8 caratteri, almeno un numero, almeno una lettera maiuscola e almeno un carattere speciale","emailSent":"Email inviata a {email}","advantages":{"exclusive_contents":{"title":"Accedi a contenuti esclusivi","text":"Assisti ai webinar di PagoPA e interagisci con noi sugli argomenti del momento.","isComingSoon":"false"},"product_updates":{"title":"Ricevi aggiornamenti sui nostri prodotti","text":"Non perdere neanche un nuovo contenuto, guida o tutorial. Puoi scegliere di ricevere via email le novità sui prodotti PagoPA e sull'integrazione tecnologica. ","isComingSoon":"false"},"api_keys":{"title":"Genera, gestisci e utilizza api Key","text":"Sblocca tutto il potenziale del DevPortal con API Key, Mocker, SDK ed altro ancora.","isComingSoon":"true"},"support":{"title":"Richiedi assistenza tramite un form dedicato","text":"Avvicinati con facilità alle soluzioni di cui hai bisogno e risolvi le difficoltà con il nostro aiuto.","isComingSoon":"true"}},"companyRoles":{"ente-pubblico":"Ente pubblico","partner-tecnologico":"Partner tecnologico","psp":"PSP","gestore-di-pubblico-servizio":"Gestore di pubblico servizio","azienda-privata":"Azienda privata","altro":"Altro"}},"confirmSignUp":{"title":"Confermaci che sei tu","emailSent":"Abbiamo inviato una email a ","clickToConfirm":"Clicca sul pulsante contenuto al suo interno per verificarla.","didntReceiveEmail":"Non hai ricevuto l'email? Controlla la posta indesiderata oppure","resendEmail":"Invia nuovamente l'email","wrongEmail":"L'indirizzo email è errato?"},"confirmLogin":{"title":"Verifica la tua identità","code":"Codice di verifica","confirmationCodeSent":"Abbiamo inviato un codice di verifica a ","confirmationCodeExpires":"Il codice scade tra 15 minuti.","checkJunkMail":"Non hai ricevuto alcuna email? Controlla la posta indesiderata oppure","continue":"Continua","resendEmail":"Reinvia email","invalidCode":"Il codice inserito non è corretto","emptyCode":"Il codice è obbligatorio"},"accountActivated":{"goToLogin":"Vai al login","welcomeMessage":"Ti diamo il benvenuto su PagoPA DevPortal.","yourAccountIsActive":"Il tuo account è attivo"},"resetPassword":{"body":"Inserisci il tuo indirizzo email e ti invieremo le istruzioni per impostare una nuova password.","checkEmailEnd":"riceverai una email con un link per impostare una nuova password.","checkEmailStart":"Se esiste un account associato a ","checkEmailTitle":"Controlla l'email","emailFieldError":"L’indirizzo email non è valido","goToLogin":"Torna al login","invalidLinkError":"Il link non è valido","newPassword":"Imposta una nuova password","passwordSet":"Password impostata correttamente","rememberPassword":"Ricordi la tua password?","resendEmail":"Reinvia email","resendEmailPrompt":"Non hai ricevuto l'email? Controlla nella posta indesiderata oppure","send":"Invia","title":"Recupera password","wrongEmail":"L'indirizzo email è errato?"},"expiredCode":{"expiredLink":"Il link che hai usato è scaduto","goToProfile":"Vai al profilo"}},"shared":{"comingSoon":"In Arrivo","readTutorial":"Leggi il tutorial","readStory":"Leggi la storia","moreInfo":"Scopri di più","version":"Versione","copiedTooltip":"Copiato","siteTitle":"PagoPA DevPortal","emailAddress":"Indirizzo email","password":"Password","goBack":"Torna indietro","requiredFields":"* Campi obbligatori","firstName":"Nome","lastName":"Cognome","confirmPassword":"Conferma password","company":"Tipologia Ente o Azienda","role":"Ruolo","requiredFieldError":"Questo campo non può essere vuoto","emailFieldError":"Inserisci un indirizzo email valido","emailAlreadyTaken":"Esiste già un account per questo indirizzo email","goToModel":"Vai al modello","edit":"Modifica","cancel":"Annulla","yourData":"Profilo","subscribeButton":{"subscribeLabel":{"default":"Iscriviti","takePart":"Partecipa","view":"Visualizza"},"subscribedLabel":"Iscrizione confermata","unsubscribeLabel":"Annulla iscrizione"},"relatedLinks":"Link utili","downloadableDocuments":"Materiali scaricabili","download":"Scarica"},"pageNotFound":{"overline":"404","title":"Pagina non trovata","description":"La pagina che stai cercando non esiste"},"productGuidePage":{"onThisPage":"In questa pagina","tableOfContents":"Tabella dei contenuti"},"homepage":{"news":{"title":"In evidenza","list":{"0":{"title":"Usa il validatore di SEND per fare una verifica sull’integrazione","href":{"label":"Vai al validatore","title":"Vai al validatore"},"image":{"url":"/images/homepage-validatore.png","alt":"Immagine: Usa il validatore di SEND per fare una verifica sull’integrazione"}},"1":{"title":"Scopri i nuovi tutorial di Firma con IO","href":{"label":"Vai ai tutorial","title":"Vai ai tutorial"},"image":{"url":"/images/homepage-io-sign.png","alt":"Immagine: Scopri i nuovi tutorial di Firma con IO"}},"2":{"title":"Scopri la Quick Start di piattaforma pagoPA: l’integrazione in pochi semplici step","href":{"label":"Vai alla guida","title":"Vai alla guida"},"image":{"url":"/images/homepage-pago-pa.png","alt":"Immagine: Scopri la Quick Start di piattaforma pagoPA: l’integrazione in pochi semplici step"}}}},"webinarBannerButtonContent":"Scopri","productsShowcaseTitle":"Scopri il nostro ecosistema","heroItems":{"0":{"title":"Tutto ciò che serve per integrarsi con i prodotti PagoPA"},"1":{"title":"Invia comunicazioni a valore legale con piattaforma notifiche","ctaLabel":"Vai a SEND"},"2":{"title":"Richiedi una firma su documenti e contratti","ctaLabel":"Vai a Firma con IO"}},"webinarsSection":{"description":"","title":"Partecipa ai nostri webinar","link":{"href":"#","label":"Vedi tutti i webinar"}},"comingsoonDocumentation":{"title":"Documentazione in arrivo","links":{"0":{"text":"Interoperabilità. Scambia informazioni con altri enti in tutta sicurezza."},"1":{"text":"Check IBAN. Utilizza un sistema per la gestione degli incassi centralizzato e immediato."}}}},"quickStartGuide":{"content":{"apiPhases":{"request":{"cta":{"label":"Invia la richiesta"},"title":"Chiamata API"},"response":{"cta":{"icon":"Replay","label":"Ripristina la chiamata"},"title":"Risposta del server"}},"next":"Prossimo contenuto","previous":"Contenuto precedente"}},"overview":{"startInfo":{"title":"Si comincia da qui"},"tutorial":{"title":"Esplora i tutorial","ctaLabel":"Vedi tutti i tutorial"},"postIntegration":{"title":"Dopo l'integrazione"},"relatedLinks":{"title":"LINK UTILI"}},"footer":{"companyLink":{"ariaLabel":"Link: vai al sito di PagoPA S.p.A."},"languages":{"it":"Italiano"},"legalInfo":"PagoPA S.p.A. - Società per azioni con socio unico - Capitale sociale di euro 1,000,000 interamente versato - Sede legale in Roma, Piazza Colonna 370,

CAP 00187 - N. di iscrizione a Registro Imprese di Roma, CF e P.IVA 15376371009","followUs":{"links":{"accessibility":{"ariaLabel":"Vai al link: Accessibilità","label":"Accessibilità"}},"title":"Seguici su"},"aboutUs":{"title":"","links":{"whoWeAre":{"ariaLabel":"Vai al link: Chi siamo","label":"Chi siamo"},"pnrr":{"ariaLabel":"Vai al link: PNRR","label":"PNRR"},"media":{"ariaLabel":"Vai al link: Media","label":"Media"},"workWithUs":{"ariaLabel":"Vai al link: Lavora con noi","label":"Lavora con noi"}}},"resources":{"title":"Risorse","links":{"privacyPolicy":{"ariaLabel":"Vai al link: Informativa Privacy","label":"Informativa Privacy"},"termsOfService":{"ariaLabel":"Vai al link: Termini e Condizioni","label":"Termini e Condizioni"},"societaTrasparente":{"ariaLabel":"Vai al link: Società trasparente","label":"Società trasparente"},"disclosurePolicy":{"ariaLabel":"Vai al link: Responsible Disclosure Policy","label":"Responsible Disclosure Policy"},"model231":{"ariaLabel":"Vai al link: Modello 231","label":"Modello 231"}}},"services":{"title":"PRODOTTI E SERVIZI","links":{"appIO":{"ariaLabel":"Vai al link: App IO","label":"App IO"},"pagoPA":{"ariaLabel":"Vai al link: Piattaforma pagoPA","label":"Piattaforma pagoPA"},"centroStella":{"ariaLabel":"Vai al link: Centro stella","label":"Centro stella"},"checkIBAN":{"ariaLabel":"Vai al link: Check IBAN","label":"Check IBAN"},"send":{"ariaLabel":"Vai al link: SEND - Servizio Notifiche Digitali","label":"SEND - Servizio Notifiche Digitali"},"pdnd":{"ariaLabel":"Vai al link: Piattaforma Digitale Nazionale Dati - Interoperabilità","label":"Piattaforma Digitale Nazionale Dati - Interoperabilità"}}},"cookiePreferences":{"ariaLabel":"Preferenza Cookie","label":"Preferenza Cookie"}},"errors":{"CodeDeliveryFailureException":"Impossibile inviare il codice di verifica.","ForbiddenException":"La tua richiesta non è stata consentita dal sistema di autenticazione.","InternalErrorException":"Si è verificato un errore interno al sistema di autenticazione.","InvalidEmailRoleAccessPolicyException":"Il sistema di autenticazione non è autorizzato a utilizzare la tua identità email.","InvalidLambdaResponseException":"Il sistema di autenticazione ha riscontrato una risposta non valida.","InvalidParameterException":"Il servizio di autenticazione ha riscontrato un parametro non valido.","InvalidPasswordException":"Password non valida.","ResourceNotFoundException":"Il servizio di autenticazione non trova la risorsa richiesta.","TooManyRequestsException":"Troppe richieste di autenticazione.","UnexpectedLambdaException":"É stata riscontrata un'eccezione imprevista con il sistema di autenticazione.","UserLambdaValidationException":"Il servizio di autenticazione ha riscontrato un'eccezione di convalida utente.","UsernameExistsException":"Username già registrato.","UserNotFoundException":"Utente non registrato.","NotAuthorizedException":"Operazione non autorizzata.","PasswordResetRequiredException":"É stato richiesto un reset della password.","UserNotConfirmedException":"Utente non confermato, controlla nella email e apri il link di conferma.","CodeMismatchException":"Codice non valido.","ExpiredCodeException":"Codice scaduto.","TooManyFailedAttemptsException":"Troppi tentativi errati.","LimitExceededException":"Limiti di autenticazione superati."},"swagger":{"errorCard":{"header":"Oops, manca qualcosa.","message":"Non siamo riusciti a trovare la fonte originale per visualizzare questo contenuto."},"parameters":{"header":"Parametri","empty":"Nessun parametro"},"requestBody":{"header":"Corpo"},"responses":{"header":"Risposte"},"example":"Esempio","schema":"Modello","emptyOperations":{"header":"Nessuna operazione","message":"Non ci sono operazioni disponibili per questo endpoint."}},"breadcrumbs":{"home":"DevPortal","webinars":"Webinar","solutions":"Soluzioni"},"solution":{"steps":{"platforms":"Piattaforme Abilitanti"},"ctaDetailLabel":"Leggi la guida completa"},"caseHistory":{"productShowcaseLabel":"Come integrarsi? Inizia da qui"},"apiDataListPage":{"explore":"Esplora le API"},"chatBot":{"title":"Chatbot","writeNewMessagePlaceholder":"Scrivi un nuovo messaggio","chatHistory":"Cronologia chat","delete":"Elimina"}},"timeZone":"Europe/Rome","children":["$","$Lb",null,{"children":[["$","$Lc",null,{"cookieDomainScript":"$undefined"}],["$","$Ld",null,{"children":["$","$Le",null,{"isChatbotVisible":false,"children":[["$","$Lf",null,{"products":[{"name":"IO, l’app dei servizi pubblici","shortName":"IO","description":"Raccogli tutti i servizi digitali del tuo ente in un’unica piattaforma e interagisci in modo semplice e sicuro con i cittadini.","slug":"app-io","path":"/app-io","logo":{"alternativeText":"IO, l’app dei servizi pubblici","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/appIo.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/app-io/overview"},"quickStart":{"name":"Quick start","path":"/app-io/quick-start"},"api":{"name":"API","path":"/app-io/api/app-io-main"},"tutorials":{"name":"Tutorial","path":"/app-io/tutorials"},"guides":{"name":"Guide e manuali","path":"/app-io/guides"}}},{"name":"Firma con IO","shortName":"Firma con IO","description":"Richiedi la Firma Elettronica Certificata su contratti e documenti. Le cittadine e i cittadini possono firmare direttamente sull’app IO.","slug":"firma-con-io","path":"/firma-con-io","logo":{"alternativeText":"Firma con IO","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/appIo.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/firma-con-io/overview"},"quickStart":{"name":"Quick start","path":"/firma-con-io/quick-start"},"api":{"name":"API","path":"/firma-con-io/api/firma-con-io-main"},"tutorials":{"name":"Tutorial","path":"/firma-con-io/tutorials"},"guides":{"name":"Guide e manuali","path":"/firma-con-io/guides"}}},{"name":"SEND - Servizio Notifiche Digitali","shortName":"SEND","description":"Invia comunicazioni a valore legale con un processo di notificazione gestito interamente dalla piattaforma.","slug":"send","path":"/send","logo":{"alternativeText":"SEND - Servizio Notifiche Digitali","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/send.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/send/overview"},"quickStart":{"name":"Quick start","path":"/send/quick-start"},"api":{"name":"API","path":"/send/api/send-main"},"tutorials":{"name":"Tutorial","path":"/send/tutorials"},"guides":{"name":"Guide e manuali","path":"/send/guides"}}},{"name":"Piattaforma pagoPA","shortName":"pagoPA","description":"Gestisci gli incassi in modo centralizzato e con immediata riconciliazione delle posizioni debitorie.","path":"/pago-pa","slug":"pago-pa","logo":{"alternativeText":"Piattaforma pagoPA","caption":"$undefined","size":10,"name":"","width":60,"height":61,"ext":".svg","mime":"image/svg+xml","url":"/icons/pagoPa.svg"},"subpaths":{"overview":{"name":"Panoramica","path":"/pago-pa/overview"},"quickStart":{"name":"Quick start","path":"/pago-pa/quick-start"},"api":{"name":"API","path":"/pago-pa/api"},"tutorials":{"name":"Tutorial","path":"/pago-pa/tutorials"},"guides":{"name":"Guide e manuali","path":"/pago-pa/guides"}}}]}],["$","main",null,{"children":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":["$","$L12",null,{"layout":"center","overline":"404","title":"Pagina non trovata","description":"La pagina che stai cercando non esiste"}],"notFoundStyles":[],"childProp":{"current":[null,["$","div",null,{"id":"chatbot-page-content","children":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children","case-histories","children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$","$L10",null,{"parallelRouterKey":"children","segmentPath":["children","case-histories","children",["caseHistorySlug","test-case","d"],"children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L11",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$L13","$L14",null],"segment":"__PAGE__?{\"caseHistorySlug\":\"test-case\"}"},"styles":[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/918940977e95543e.css","precedence":"next"}]]}],"segment":["caseHistorySlug","test-case","d"]},"styles":[]}]}],null],"segment":"case-histories"},"styles":[]}]}],["$","$L15",null,{}]]}]}]]}]}]}]]}] +16:I{"id":54316,"chunks":["2978:static/chunks/e871d0c9-75a84d7b32d4bfcc.js","3495:static/chunks/f5890c91-7948379131fd4dd8.js","7950:static/chunks/7950-2339fabfd6a7629e.js","2645:static/chunks/2645-e818d1ef9d77508b.js","3093:static/chunks/3093-9dff2f7303959b74.js","1607:static/chunks/1607-bd6a7b286c720918.js","3401:static/chunks/3401-95a9b8907071a549.js","2352:static/chunks/2352-337e28b99911d4e6.js","9962:static/chunks/9962-d802b3a5617cee9a.js","1464:static/chunks/1464-708bd411d4e8fbe2.js","8541:static/chunks/8541-575bce64f7a8e39b.js","9889:static/chunks/9889-574b6d473be64fdb.js","6751:static/chunks/6751-e35273ed6785c759.js","3864:static/chunks/3864-8d73cd0bdcf76e4e.js","2056:static/chunks/2056-b2663ceea2894c1f.js","2377:static/chunks/2377-3873cc84882ec78b.js","7640:static/chunks/7640-ca747730c54eac58.js","4263:static/chunks/4263-662bc88b72cc5d29.js","4047:static/chunks/4047-f8e10a6b37bf2b34.js","1189:static/chunks/1189-2b1aa7c0348b14f6.js","2367:static/chunks/2367-df6623c4eb9dd6b0.js","6686:static/chunks/6686-9bc47ab2e6abbf5b.js","1878:static/chunks/1878-a3a68810eafbc18e.js","2536:static/chunks/2536-70a61cc5dfb9f7da.js","2373:static/chunks/app/case-histories/[caseHistorySlug]/page-bb9f62747b123bc3.js"],"name":"","async":false} +14:["$","$L16",null,{"slug":"test-case","title":"test case","description":"$undefined","publishedAt":"$D2024-07-24T07:55:19.128Z","image":"$undefined","parts":[{"component":"blockRenderer","html":[{"type":"heading","level":1,"children":[{"text":"h1","type":"text"}]},{"type":"heading","level":2,"children":[{"text":"h2","type":"text"}]},{"type":"heading","level":3,"children":[{"text":"h3","type":"text"}]},{"type":"heading","level":4,"children":[{"text":"h4","type":"text"}]},{"type":"heading","level":5,"children":[{"text":"h5","type":"text"}]}],"id":10,"__component":"parts.html"}],"products":[]}] +6:[["$","meta","0",{"charSet":"utf-8"}],["$","title","1",{"children":"PagoPA DevPortal | test case"}],["$","meta","2",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","3",{"property":"og:title","content":"PagoPA DevPortal | test case"}],["$","meta","4",{"property":"og:locale","content":"it_IT"}],["$","meta","5",{"property":"og:image","content":"https://dev.developer.pagopa.it/images/dev-portal-home.jpg"}],["$","meta","6",{"property":"og:type","content":"website"}],["$","meta","7",{"name":"twitter:card","content":"summary"}],["$","meta","8",{"name":"twitter:site","content":"@pagopa"}],["$","meta","9",{"name":"twitter:creator","content":"@pagopa"}],["$","meta","10",{"name":"twitter:title","content":"PagoPA DevPortal | test case"}],["$","meta","11",{"name":"twitter:image","content":"https://dev.developer.pagopa.it/images/dev-portal-home.jpg"}],["$","link","12",{"rel":"icon","href":"/icon.svg?f2ac316c8a418774","type":"image/svg+xml","sizes":"any"}],["$","meta","13",{"name":"next-size-adjust"}]] +13:null diff --git a/apps/chatbot/docker/files/nextjs-website/generated/index.html b/apps/chatbot/docker/files/nextjs-website/generated/index.html new file mode 100644 index 0000000000..95c28d0ede --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/index.html @@ -0,0 +1 @@ +PagoPA DevPortal | PagoPA DevPortal

Tutto ciò che serve per integrarsi con i prodotti PagoPA

Tutto ciò che serve per integrarsi con i prodotti PagoPA

Invia comunicazioni a valore legale con SEND

Invia comunicazioni a valore legale con SEND

Richiedi una firma su documenti e contratti

Richiedi una firma su documenti e contratti

In evidenza

13 marzo 2024

Scopri la Quick Start di piattaforma pagoPA: l’integrazione in pochi semplici step

01 marzo 2024

Usa il validatore di SEND per fare una verifica sull’integrazione

01 marzo 2024

Scopri i nuovi tutorial di Firma con IO

Scopri il nostro ecosistema

IO, l’app dei servizi pubblici

Raccogli tutti i servizi digitali del tuo ente in un’unica piattaforma e interagisci in modo semplice e sicuro con i cittadini.

Firma con IO

Richiedi la Firma Elettronica Certificata su contratti e documenti. Le cittadine e i cittadini possono firmare direttamente sull’app IO.

Piattaforma pagoPA

Gestisci gli incassi in modo centralizzato e con immediata riconciliazione delle posizioni debitorie.

SEND - Servizio Notifiche Digitali

Invia comunicazioni a valore legale con un processo di notificazione gestito interamente dalla piattaforma.


\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/privacy-policy.html b/apps/chatbot/docker/files/nextjs-website/generated/privacy-policy.html new file mode 100644 index 0000000000..818281c7e2 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/privacy-policy.html @@ -0,0 +1 @@ +

\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/solutions.html b/apps/chatbot/docker/files/nextjs-website/generated/solutions.html new file mode 100644 index 0000000000..a2db58576c --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/solutions.html @@ -0,0 +1 @@ +

Le soluzioni PagoPA: una nuova esperienza di servizi pubblici

Scopri le soluzioni, guide pratiche realizzate per supportarti nella trasformazione digitale dei tuoi servizi attraverso l’utilizzo integrato delle piattaforme PagoPA.

Multe per violazioni al Codice della Strada

In questa guida trovi i consigli utili per erogare in maniera virtuosa il servizio di sanzioni per violazione al Codice della strada, con approfondimenti sulla gestione delle diverse fasi.

IO
pagoPA
SEND
Tassa sui rifiuti (TARI)

La soluzione dedicata alle buone pratiche per gestire al meglio la riscossione della Tassa sui rifiuti (TARI), tramite un approccio automatizzato e integrato che garantisca una maggiore efficienza in termini di tempi e costi.

IO
pagoPA
SEND

I benefici della trasformazione digitale dei servizi

Comunicazione tempestiva e trasparente
Comunicazione tempestiva e trasparente

I cittadini hanno un accesso più diretto e immediato alle informazioni importanti e ai servizi che possono utilizzare

Processi di erogazione ottimizzati
Processi di erogazione ottimizzati

L'automazione dei processi e la digitalizzazione dei servizi portano una riduzione dei costi operativi associati alle procedure manuali

Riduzione dei tempi  di incasso
Riduzione dei tempi di incasso

I pagamenti vengono elaborati in tempo reale, sono sempre tracciabili e possono essere facilmente aggiorati nel tempo.

Storie di successo

Le testimonianze di come gli enti hanno dato forma a servizi efficienti e accessibili, ottimizzando i processi grazie all’integrazione con le piattaforme PagoPA.

Il processo di riscossione della TARI del Comune di Cagliari

\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/terms-of-service.html b/apps/chatbot/docker/files/nextjs-website/generated/terms-of-service.html new file mode 100644 index 0000000000..fbb75907c9 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/terms-of-service.html @@ -0,0 +1 @@ +

\ No newline at end of file diff --git a/apps/chatbot/docker/files/nextjs-website/generated/webinars.html b/apps/chatbot/docker/files/nextjs-website/generated/webinars.html new file mode 100644 index 0000000000..e1c4ee7403 --- /dev/null +++ b/apps/chatbot/docker/files/nextjs-website/generated/webinars.html @@ -0,0 +1 @@ +PagoPA DevPortal | PagoPA DevPortal - Webinars

\ No newline at end of file diff --git a/apps/chatbot/poetry.lock b/apps/chatbot/poetry.lock index a1dad92b7d..7666daa55d 100644 --- a/apps/chatbot/poetry.lock +++ b/apps/chatbot/poetry.lock @@ -65,87 +65,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.6" +version = "3.11.7" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7510b3ca2275691875ddf072a5b6cd129278d11fe09301add7d292fc8d3432de"}, - {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfab0d2c3380c588fc925168533edb21d3448ad76c3eadc360ff963019161724"}, - {file = "aiohttp-3.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf02dba0f342f3a8228f43fae256aafc21c4bc85bffcf537ce4582e2b1565188"}, - {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92daedf7221392e7a7984915ca1b0481a94c71457c2f82548414a41d65555e70"}, - {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2274a7876e03429e3218589a6d3611a194bdce08c3f1e19962e23370b47c0313"}, - {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a2e1eae2d2f62f3660a1591e16e543b2498358593a73b193006fb89ee37abc6"}, - {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978ec3fb0a42efcd98aae608f58c6cfcececaf0a50b4e86ee3ea0d0a574ab73b"}, - {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51f87b27d9219ed4e202ed8d6f1bb96f829e5eeff18db0d52f592af6de6bdbf"}, - {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:04d1a02a669d26e833c8099992c17f557e3b2fdb7960a0c455d7b1cbcb05121d"}, - {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3679d5fcbc7f1ab518ab4993f12f80afb63933f6afb21b9b272793d398303b98"}, - {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a4b24e03d04893b5c8ec9cd5f2f11dc9c8695c4e2416d2ac2ce6c782e4e5ffa5"}, - {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d9abdfd35ecff1c95f270b7606819a0e2de9e06fa86b15d9080de26594cf4c23"}, - {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b5c3e7928a0ad80887a5eba1c1da1830512ddfe7394d805badda45c03db3109"}, - {file = "aiohttp-3.11.6-cp310-cp310-win32.whl", hash = "sha256:913dd9e9378f3c38aeb5c4fb2b8383d6490bc43f3b427ae79f2870651ae08f22"}, - {file = "aiohttp-3.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:4ac26d482c2000c3a59bf757a77adc972828c9d4177b4bd432a46ba682ca7271"}, - {file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26ac4c960ea8debf557357a172b3ef201f2236a462aefa1bc17683a75483e518"}, - {file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8b1f13ebc99fb98c7c13057b748f05224ccc36d17dee18136c695ef23faaf4ff"}, - {file = "aiohttp-3.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4679f1a47516189fab1774f7e45a6c7cac916224c91f5f94676f18d0b64ab134"}, - {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74491fdb3d140ff561ea2128cb7af9ba0a360067ee91074af899c9614f88a18f"}, - {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f51e1a90412d387e62aa2d243998c5eddb71373b199d811e6ed862a9f34f9758"}, - {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72ab89510511c3bb703d0bb5504787b11e0ed8be928ed2a7cf1cda9280628430"}, - {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6681c9e046d99646e8059266688374a063da85b2e4c0ebfa078cda414905d080"}, - {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a17f8a6d3ab72cbbd137e494d1a23fbd3ea973db39587941f32901bb3c5c350"}, - {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:867affc7612a314b95f74d93aac550ce0909bc6f0b6c658cc856890f4d326542"}, - {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:00d894ebd609d5a423acef885bd61e7f6a972153f99c5b3ea45fc01fe909196c"}, - {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:614c87be9d0d64477d1e4b663bdc5d1534fc0a7ebd23fb08347ab9fd5fe20fd7"}, - {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:533ed46cf772f28f3bffae81c0573d916a64dee590b5dfaa3f3d11491da05b95"}, - {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:589884cfbc09813afb1454816b45677e983442e146183143f988f7f5a040791a"}, - {file = "aiohttp-3.11.6-cp311-cp311-win32.whl", hash = "sha256:1da63633ba921669eec3d7e080459d4ceb663752b3dafb2f31f18edd248d2170"}, - {file = "aiohttp-3.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:d778ddda09622e7d83095cc8051698a0084c155a1474bfee9bac27d8613dbc31"}, - {file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:943a952df105a5305257984e7a1f5c2d0fd8564ff33647693c4d07eb2315446d"}, - {file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d24ec28b7658970a1f1d98608d67f88376c7e503d9d45ff2ba1949c09f2b358c"}, - {file = "aiohttp-3.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6720e809a660fdb9bec7c168c582e11cfedce339af0a5ca847a5d5b588dce826"}, - {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4252d30da0ada6e6841b325869c7ef5104b488e8dd57ec439892abbb8d7b3615"}, - {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f65f43ff01b238aa0b5c47962c83830a49577efe31bd37c1400c3d11d8a32835"}, - {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc5933f6c9b26404444d36babb650664f984b8e5fa0694540e7b7315d11a4ff"}, - {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bf546ba0c029dfffc718c4b67748687fd4f341b07b7c8f1719d6a3a46164798"}, - {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c351d05bbeae30c088009c0bb3b17dda04fd854f91cc6196c448349cc98f71c3"}, - {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:10499079b063576fad1597898de3f9c0a2ce617c19cc7cd6b62fdcff6b408bf7"}, - {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:442ee82eda47dd59798d6866ce020fb8d02ea31ac9ac82b3d719ed349e6a9d52"}, - {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:86fce9127bc317119b34786d9e9ae8af4508a103158828a535f56d201da6ab19"}, - {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:973d26a5537ce5d050302eb3cd876457451745b1da0624cbb483217970e12567"}, - {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:532b8f038a4e001137d3600cea5d3439d1881df41bdf44d0f9651264d562fdf0"}, - {file = "aiohttp-3.11.6-cp312-cp312-win32.whl", hash = "sha256:4863c59f748dbe147da82b389931f2a676aebc9d3419813ed5ca32d057c9cb32"}, - {file = "aiohttp-3.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:5d7f481f82c18ac1f7986e31ba6eea9be8b2e2c86f1ef035b6866179b6c5dd68"}, - {file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:40f502350496ba4c6820816d3164f8a0297b9aa4e95d910da31beb189866a9df"}, - {file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9072669b0bffb40f1f6977d0b5e8a296edc964f9cefca3a18e68649c214d0ce3"}, - {file = "aiohttp-3.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:518160ecf4e6ffd61715bc9173da0925fcce44ae6c7ca3d3f098fe42585370fb"}, - {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f69cc1b45115ac44795b63529aa5caa9674be057f11271f65474127b24fc1ce6"}, - {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6be90a6beced41653bda34afc891617c6d9e8276eef9c183f029f851f0a3c3d"}, - {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00c22fe2486308770d22ef86242101d7b0f1e1093ce178f2358f860e5149a551"}, - {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2607ebb783e3aeefa017ec8f34b506a727e6b6ab2c4b037d65f0bc7151f4430a"}, - {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f761d6819870c2a8537f75f3e2fc610b163150cefa01f9f623945840f601b2c"}, - {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e44d1bc6c88f5234115011842219ba27698a5f2deee245c963b180080572aaa2"}, - {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7e0cb6a1b1f499cb2aa0bab1c9f2169ad6913c735b7447e058e0c29c9e51c0b5"}, - {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a76b4d4ca34254dca066acff2120811e2a8183997c135fcafa558280f2cc53f3"}, - {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69051c1e45fb18c0ae4d39a075532ff0b015982e7997f19eb5932eb4a3e05c17"}, - {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:aff2ed18274c0bfe0c1d772781c87d5ca97ae50f439729007cec9644ee9b15fe"}, - {file = "aiohttp-3.11.6-cp313-cp313-win32.whl", hash = "sha256:2fbea25f2d44df809a46414a8baafa5f179d9dda7e60717f07bded56300589b3"}, - {file = "aiohttp-3.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:f77bc29a465c0f9f6573d1abe656d385fa673e34efe615bd4acc50899280ee47"}, - {file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:de6123b298d17bca9e53581f50a275b36e10d98e8137eb743ce69ee766dbdfe9"}, - {file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a10200f705f4fff00e148b7f41e5d1d929c7cd4ac523c659171a0ea8284cd6fb"}, - {file = "aiohttp-3.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7776ef6901b54dd557128d96c71e412eec0c39ebc07567e405ac98737995aad"}, - {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e5c2a55583cd91936baf73d223807bb93ace6eb1fe54424782690f2707162ab"}, - {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b032bd6cf7422583bf44f233f4a1489fee53c6d35920123a208adc54e2aba41e"}, - {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fe2d99acbc5cf606f75d7347bf3a027c24c27bc052d470fb156f4cfcea5739"}, - {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a79c366375c2250934d1238abe5d5ea7754c823a1c7df0c52bf0a2bfded6a9"}, - {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33cbbe97dc94a34d1295a7bb68f82727bcbff2b284f73ae7e58ecc05903da97"}, - {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:19e4fb9ac727834b003338dcdd27dcfe0de4fb44082b01b34ed0ab67c3469fc9"}, - {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a97f6b2afbe1d27220c0c14ea978e09fb4868f462ef3d56d810d206bd2e057a2"}, - {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c3f7afeea03a9bc49be6053dfd30809cd442cc12627d6ca08babd1c1f9e04ccf"}, - {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0d10967600ce5bb69ddcb3e18d84b278efb5199d8b24c3c71a4959c2f08acfd0"}, - {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:60f2f631b9fe7aa321fa0f0ff3f5d8b9f7f9b72afd4eecef61c33cf1cfea5d58"}, - {file = "aiohttp-3.11.6-cp39-cp39-win32.whl", hash = "sha256:4d2b75333deb5c5f61bac5a48bba3dbc142eebbd3947d98788b6ef9cc48628ae"}, - {file = "aiohttp-3.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:8908c235421972a2e02abcef87d16084aabfe825d14cc9a1debd609b3cfffbea"}, - {file = "aiohttp-3.11.6.tar.gz", hash = "sha256:fd9f55c1b51ae1c20a1afe7216a64a88d38afee063baa23c7fce03757023c999"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, + {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, + {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, + {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, + {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, + {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, + {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, + {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, + {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, + {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, + {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, + {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, ] [package.dependencies] @@ -426,6 +426,17 @@ files = [ [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + [[package]] name = "beautifulsoup4" version = "4.12.3" @@ -1029,44 +1040,37 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "cymem" -version = "2.0.8" +version = "2.0.10" description = "Manage calls to calloc/free through Cython" optional = false python-versions = "*" files = [ - {file = "cymem-2.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77b5d3a73c41a394efd5913ab7e48512054cd2dabb9582d489535456641c7666"}, - {file = "cymem-2.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bd33da892fb560ba85ea14b1528c381ff474048e861accc3366c8b491035a378"}, - {file = "cymem-2.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29a551eda23eebd6d076b855f77a5ed14a1d1cae5946f7b3cb5de502e21b39b0"}, - {file = "cymem-2.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8260445652ae5ab19fff6851f32969a7b774f309162e83367dd0f69aac5dbf7"}, - {file = "cymem-2.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:a63a2bef4c7e0aec7c9908bca0a503bf91ac7ec18d41dd50dc7dff5d994e4387"}, - {file = "cymem-2.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6b84b780d52cb2db53d4494fe0083c4c5ee1f7b5380ceaea5b824569009ee5bd"}, - {file = "cymem-2.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d5f83dc3cb5a39f0e32653cceb7c8ce0183d82f1162ca418356f4a8ed9e203e"}, - {file = "cymem-2.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ac218cf8a43a761dc6b2f14ae8d183aca2bbb85b60fe316fd6613693b2a7914"}, - {file = "cymem-2.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42c993589d1811ec665d37437d5677b8757f53afadd927bf8516ac8ce2d3a50c"}, - {file = "cymem-2.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:ab3cf20e0eabee9b6025ceb0245dadd534a96710d43fb7a91a35e0b9e672ee44"}, - {file = "cymem-2.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cb51fddf1b920abb1f2742d1d385469bc7b4b8083e1cfa60255e19bc0900ccb5"}, - {file = "cymem-2.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9235957f8c6bc2574a6a506a1687164ad629d0b4451ded89d49ebfc61b52660c"}, - {file = "cymem-2.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2cc38930ff5409f8d61f69a01e39ecb185c175785a1c9bec13bcd3ac8a614ba"}, - {file = "cymem-2.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bf49e3ea2c441f7b7848d5c61b50803e8cbd49541a70bb41ad22fce76d87603"}, - {file = "cymem-2.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:ecd12e3bacf3eed5486e4cd8ede3c12da66ee0e0a9d0ae046962bc2bb503acef"}, - {file = "cymem-2.0.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:167d8019db3b40308aabf8183fd3fbbc256323b645e0cbf2035301058c439cd0"}, - {file = "cymem-2.0.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17cd2c2791c8f6b52f269a756ba7463f75bf7265785388a2592623b84bb02bf8"}, - {file = "cymem-2.0.8-cp36-cp36m-win_amd64.whl", hash = "sha256:6204f0a3307bf45d109bf698ba37997ce765f21e359284328e4306c7500fcde8"}, - {file = "cymem-2.0.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9c05db55ea338648f8e5f51dd596568c7f62c5ae32bf3fa5b1460117910ebae"}, - {file = "cymem-2.0.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ce641f7ba0489bd1b42a4335a36f38c8507daffc29a512681afaba94a0257d2"}, - {file = "cymem-2.0.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b83a5972a64f62796118da79dfeed71f4e1e770b2b7455e889c909504c2358"}, - {file = "cymem-2.0.8-cp37-cp37m-win_amd64.whl", hash = "sha256:ada6eb022e4a0f4f11e6356a5d804ceaa917174e6cf33c0b3e371dbea4dd2601"}, - {file = "cymem-2.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e593cd57e2e19eb50c7ddaf7e230b73c890227834425b9dadcd4a86834ef2ab"}, - {file = "cymem-2.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d513f0d5c6d76facdc605e42aa42c8d50bb7dedca3144ec2b47526381764deb0"}, - {file = "cymem-2.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e370dd54359101b125bfb191aca0542718077b4edb90ccccba1a28116640fed"}, - {file = "cymem-2.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f8c58cde71b8fc7024883031a4eec66c0a9a4d36b7850c3065493652695156"}, - {file = "cymem-2.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a6edddb30dd000a27987fcbc6f3c23b7fe1d74f539656952cb086288c0e4e29"}, - {file = "cymem-2.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b896c83c08dadafe8102a521f83b7369a9c5cc3e7768eca35875764f56703f4c"}, - {file = "cymem-2.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a4f8f2bfee34f6f38b206997727d29976666c89843c071a968add7d61a1e8024"}, - {file = "cymem-2.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7372e2820fa66fd47d3b135f3eb574ab015f90780c3a21cfd4809b54f23a4723"}, - {file = "cymem-2.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4e57bee56d35b90fc2cba93e75b2ce76feaca05251936e28a96cf812a1f5dda"}, - {file = "cymem-2.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ceeab3ce2a92c7f3b2d90854efb32cb203e78cb24c836a5a9a2cac221930303b"}, - {file = "cymem-2.0.8.tar.gz", hash = "sha256:8fb09d222e21dcf1c7e907dc85cf74501d4cea6c4ed4ac6c9e016f98fb59cbbf"}, + {file = "cymem-2.0.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:010f78804cf5e2fbd08abad210d2b78a828bea1a9f978737e28e1614f5a258b4"}, + {file = "cymem-2.0.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9688f691518859e76c24c37686314dc5163f2fae1b9df264714220fc087b09a5"}, + {file = "cymem-2.0.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61ce538c594f348b90037b03910da31ce7aacca090ea64063593688c55f6adad"}, + {file = "cymem-2.0.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d45b99c727dfc303db3bb9f136b86731a4d231fbf9c27ce5745ea4a527da0b5"}, + {file = "cymem-2.0.10-cp310-cp310-win_amd64.whl", hash = "sha256:a03abe0e2f8925707c3dee88060bea1a94b9a24afc7d07ee17f319022126bcb4"}, + {file = "cymem-2.0.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:18dc5a7b6a325d5fc0b2b40beb02673f36f64655ee086649c91e44ce092c7b36"}, + {file = "cymem-2.0.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d30ce83ff9009e5c5c8186845d9d583f867dace88113089bfc0ee1c348e45d5a"}, + {file = "cymem-2.0.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6cb07416c82633503974f331abde9e1514c90aae8b3240884e749c2a60adbc"}, + {file = "cymem-2.0.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34406e2bff8707719f3f4b262e50b04876369233d5277a7c2d0c2e73a8579b46"}, + {file = "cymem-2.0.10-cp311-cp311-win_amd64.whl", hash = "sha256:51218af9645541005a1313d6640bf6e86e7fb4b38a87268a5ea428d50ac3cec2"}, + {file = "cymem-2.0.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c6ed8b1ed448cd65e12405a02aa71b22a4094d8a623205625057c4c73ba4b133"}, + {file = "cymem-2.0.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5e57928d9e93c61265281ea01a1d24499d397625b2766a0c5735b99bceb3ba75"}, + {file = "cymem-2.0.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4932060a5d55648fa4a3960f1cad9905572ed5c6f02af42f849e869d2803d4"}, + {file = "cymem-2.0.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f4bc6c823b400d32cddcfeefb3f352d52a0cc911cb0b5c1ef64e3f9741fd56b9"}, + {file = "cymem-2.0.10-cp312-cp312-win_amd64.whl", hash = "sha256:6ae7f22af4bc4311f06c925df61c62219c11939dffc9c91d67caf89a7e1557a5"}, + {file = "cymem-2.0.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5698a515900dc697874444fa05d8d852bbad43543de2e7834ec3895156cc2aad"}, + {file = "cymem-2.0.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6580d657d0f208d675d62cc052fb908529d52d24282342e24a9843de85352b88"}, + {file = "cymem-2.0.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea72cf0e369f3cf1f10038d572143d88ce7c959222cf7d742acbeb45e00ac5c0"}, + {file = "cymem-2.0.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33d7f5014ad36af22995847fccd82ca0bd4b0394fb1d9dd9fef1e8cefdab2444"}, + {file = "cymem-2.0.10-cp313-cp313-win_amd64.whl", hash = "sha256:82f19a39052747309ced6b948b34aff62aa00c795c9d9d3d31a071e8c791efee"}, + {file = "cymem-2.0.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e644c3c48663d2c0580292e1d636e7eb8885bfe9df75f929d8ad0403621b75fe"}, + {file = "cymem-2.0.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0f2bc8c69a23e3243e3a0c0feca08c9d4454d3cb7934bb11f5e1b3333151d69d"}, + {file = "cymem-2.0.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5369f1974854102ee1751577f13acbbb6a13ba73f9fbb44580f8f3275dae0205"}, + {file = "cymem-2.0.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ffb6181d589e65c46c2d515d8326746a2e0bda31b67c8b1edfbf0663249f84fb"}, + {file = "cymem-2.0.10-cp39-cp39-win_amd64.whl", hash = "sha256:9805f7dbf078a0e2eb417b7e1166cedc590887b55e38a3f3ba5349649c93e6be"}, + {file = "cymem-2.0.10.tar.gz", hash = "sha256:f51700acfa1209b4a221dc892cca8030f4bc10d4c153dec098042f484c7f07a4"}, ] [[package]] @@ -1086,37 +1090,37 @@ typing-inspect = ">=0.4.0,<1" [[package]] name = "debugpy" -version = "1.8.8" +version = "1.8.9" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.8-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:e59b1607c51b71545cb3496876544f7186a7a27c00b436a62f285603cc68d1c6"}, - {file = "debugpy-1.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6531d952b565b7cb2fbd1ef5df3d333cf160b44f37547a4e7cf73666aca5d8d"}, - {file = "debugpy-1.8.8-cp310-cp310-win32.whl", hash = "sha256:b01f4a5e5c5fb1d34f4ccba99a20ed01eabc45a4684f4948b5db17a319dfb23f"}, - {file = "debugpy-1.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:535f4fb1c024ddca5913bb0eb17880c8f24ba28aa2c225059db145ee557035e9"}, - {file = "debugpy-1.8.8-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:c399023146e40ae373753a58d1be0a98bf6397fadc737b97ad612886b53df318"}, - {file = "debugpy-1.8.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09cc7b162586ea2171eea055985da2702b0723f6f907a423c9b2da5996ad67ba"}, - {file = "debugpy-1.8.8-cp311-cp311-win32.whl", hash = "sha256:eea8821d998ebeb02f0625dd0d76839ddde8cbf8152ebbe289dd7acf2cdc6b98"}, - {file = "debugpy-1.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:d4483836da2a533f4b1454dffc9f668096ac0433de855f0c22cdce8c9f7e10c4"}, - {file = "debugpy-1.8.8-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:0cc94186340be87b9ac5a707184ec8f36547fb66636d1029ff4f1cc020e53996"}, - {file = "debugpy-1.8.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64674e95916e53c2e9540a056e5f489e0ad4872645399d778f7c598eacb7b7f9"}, - {file = "debugpy-1.8.8-cp312-cp312-win32.whl", hash = "sha256:5c6e885dbf12015aed73770f29dec7023cb310d0dc2ba8bfbeb5c8e43f80edc9"}, - {file = "debugpy-1.8.8-cp312-cp312-win_amd64.whl", hash = "sha256:19ffbd84e757a6ca0113574d1bf5a2298b3947320a3e9d7d8dc3377f02d9f864"}, - {file = "debugpy-1.8.8-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:705cd123a773d184860ed8dae99becd879dfec361098edbefb5fc0d3683eb804"}, - {file = "debugpy-1.8.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890fd16803f50aa9cb1a9b9b25b5ec321656dd6b78157c74283de241993d086f"}, - {file = "debugpy-1.8.8-cp313-cp313-win32.whl", hash = "sha256:90244598214bbe704aa47556ec591d2f9869ff9e042e301a2859c57106649add"}, - {file = "debugpy-1.8.8-cp313-cp313-win_amd64.whl", hash = "sha256:4b93e4832fd4a759a0c465c967214ed0c8a6e8914bced63a28ddb0dd8c5f078b"}, - {file = "debugpy-1.8.8-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:143ef07940aeb8e7316de48f5ed9447644da5203726fca378f3a6952a50a9eae"}, - {file = "debugpy-1.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f95651bdcbfd3b27a408869a53fbefcc2bcae13b694daee5f1365b1b83a00113"}, - {file = "debugpy-1.8.8-cp38-cp38-win32.whl", hash = "sha256:26b461123a030e82602a750fb24d7801776aa81cd78404e54ab60e8b5fecdad5"}, - {file = "debugpy-1.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3cbf1833e644a3100eadb6120f25be8a532035e8245584c4f7532937edc652a"}, - {file = "debugpy-1.8.8-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:53709d4ec586b525724819dc6af1a7703502f7e06f34ded7157f7b1f963bb854"}, - {file = "debugpy-1.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a9c013077a3a0000e83d97cf9cc9328d2b0bbb31f56b0e99ea3662d29d7a6a2"}, - {file = "debugpy-1.8.8-cp39-cp39-win32.whl", hash = "sha256:ffe94dd5e9a6739a75f0b85316dc185560db3e97afa6b215628d1b6a17561cb2"}, - {file = "debugpy-1.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5c0e5a38c7f9b481bf31277d2f74d2109292179081f11108e668195ef926c0f9"}, - {file = "debugpy-1.8.8-py2.py3-none-any.whl", hash = "sha256:ec684553aba5b4066d4de510859922419febc710df7bba04fe9e7ef3de15d34f"}, - {file = "debugpy-1.8.8.zip", hash = "sha256:e6355385db85cbd666be703a96ab7351bc9e6c61d694893206f8001e22aee091"}, + {file = "debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e"}, + {file = "debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f"}, + {file = "debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037"}, + {file = "debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e"}, + {file = "debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040"}, + {file = "debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70"}, + {file = "debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66"}, + {file = "debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d"}, + {file = "debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2"}, + {file = "debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe"}, + {file = "debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11"}, + {file = "debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53"}, + {file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"}, + {file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"}, + {file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"}, + {file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"}, + {file = "debugpy-1.8.9-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:472a3994999fe6c0756945ffa359e9e7e2d690fb55d251639d07208dbc37caea"}, + {file = "debugpy-1.8.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365e556a4772d7d0d151d7eb0e77ec4db03bcd95f26b67b15742b88cacff88e9"}, + {file = "debugpy-1.8.9-cp38-cp38-win32.whl", hash = "sha256:54a7e6d3014c408eb37b0b06021366ee985f1539e12fe49ca2ee0d392d9ceca5"}, + {file = "debugpy-1.8.9-cp38-cp38-win_amd64.whl", hash = "sha256:8e99c0b1cc7bf86d83fb95d5ccdc4ad0586d4432d489d1f54e4055bcc795f693"}, + {file = "debugpy-1.8.9-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:7e8b079323a56f719977fde9d8115590cb5e7a1cba2fcee0986ef8817116e7c1"}, + {file = "debugpy-1.8.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6953b335b804a41f16a192fa2e7851bdcfd92173cbb2f9f777bb934f49baab65"}, + {file = "debugpy-1.8.9-cp39-cp39-win32.whl", hash = "sha256:7e646e62d4602bb8956db88b1e72fe63172148c1e25c041e03b103a25f36673c"}, + {file = "debugpy-1.8.9-cp39-cp39-win_amd64.whl", hash = "sha256:3d9755e77a2d680ce3d2c5394a444cf42be4a592caaf246dbfbdd100ffcf7ae5"}, + {file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"}, + {file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"}, ] [[package]] @@ -1315,17 +1319,6 @@ files = [ [package.dependencies] sgmllib3k = "*" -[[package]] -name = "ffmpy" -version = "0.4.0" -description = "A simple Python wrapper for FFmpeg" -optional = false -python-versions = "<4.0.0,>=3.8.1" -files = [ - {file = "ffmpy-0.4.0-py3-none-any.whl", hash = "sha256:39c0f20c5b465e7f8d29a5191f3a7d7675a8c546d9d985de8921151cd9b59e14"}, - {file = "ffmpy-0.4.0.tar.gz", hash = "sha256:131b57794e802ad555f579007497f7a3d0cab0583d37496c685b8acae4837b1d"}, -] - [[package]] name = "filelock" version = "3.16.1" @@ -1625,13 +1618,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-api-python-client" -version = "2.153.0" +version = "2.154.0" description = "Google API Client Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_python_client-2.153.0-py2.py3-none-any.whl", hash = "sha256:6ff13bbfa92a57972e33ec3808e18309e5981b8ca1300e5da23bf2b4d6947384"}, - {file = "google_api_python_client-2.153.0.tar.gz", hash = "sha256:35cce8647f9c163fc04fb4d811fc91aae51954a2bdd74918decbe0e65d791dd2"}, + {file = "google_api_python_client-2.154.0-py2.py3-none-any.whl", hash = "sha256:a521bbbb2ec0ba9d6f307cdd64ed6e21eeac372d1bd7493a4ab5022941f784ad"}, + {file = "google_api_python_client-2.154.0.tar.gz", hash = "sha256:1b420062e03bfcaa1c79e2e00a612d29a6a934151ceb3d272fe150a656dc8f17"}, ] [package.dependencies] @@ -1719,68 +1712,6 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] -[[package]] -name = "gradio" -version = "4.44.1" -description = "Python library for easily interacting with trained machine learning models" -optional = false -python-versions = ">=3.8" -files = [ - {file = "gradio-4.44.1-py3-none-any.whl", hash = "sha256:c908850c638e4a176b22f95a758ce6a63ffbc2a7a5a74b23186ceeeedc23f4d9"}, - {file = "gradio-4.44.1.tar.gz", hash = "sha256:a68a52498ac6b63f8864ef84bf7866a70e7d07ebe913edf921e1d2a3708ad5ae"}, -] - -[package.dependencies] -aiofiles = ">=22.0,<24.0" -anyio = ">=3.0,<5.0" -fastapi = "<1.0" -ffmpy = "*" -gradio-client = "1.3.0" -httpx = ">=0.24.1" -huggingface-hub = ">=0.19.3" -importlib-resources = ">=1.3,<7.0" -jinja2 = "<4.0" -markupsafe = ">=2.0,<3.0" -matplotlib = ">=3.0,<4.0" -numpy = ">=1.0,<3.0" -orjson = ">=3.0,<4.0" -packaging = "*" -pandas = ">=1.0,<3.0" -pillow = ">=8.0,<11.0" -pydantic = ">=2.0" -pydub = "*" -python-multipart = ">=0.0.9" -pyyaml = ">=5.0,<7.0" -ruff = {version = ">=0.2.2", markers = "sys_platform != \"emscripten\""} -semantic-version = ">=2.0,<3.0" -tomlkit = "0.12.0" -typer = {version = ">=0.12,<1.0", markers = "sys_platform != \"emscripten\""} -typing-extensions = ">=4.0,<5.0" -urllib3 = ">=2.0,<3.0" -uvicorn = {version = ">=0.14.0", markers = "sys_platform != \"emscripten\""} - -[package.extras] -oauth = ["authlib", "itsdangerous"] - -[[package]] -name = "gradio-client" -version = "1.3.0" -description = "Python library for easily interacting with trained machine learning models" -optional = false -python-versions = ">=3.8" -files = [ - {file = "gradio_client-1.3.0-py3-none-any.whl", hash = "sha256:20c40cb4d56e18de1a025ccf58079f08a304e4fb2dfbcf7c2352815b2cb31091"}, - {file = "gradio_client-1.3.0.tar.gz", hash = "sha256:d904afeae4f5682add0a6a263542c10e7669ff6c9de0a53a5c2fc9b719a24bb8"}, -] - -[package.dependencies] -fsspec = "*" -httpx = ">=0.24.1" -huggingface-hub = ">=0.19.3" -packaging = "*" -typing-extensions = ">=4.0,<5.0" -websockets = ">=10.0,<13.0" - [[package]] name = "greenlet" version = "3.1.1" @@ -2148,25 +2079,6 @@ files = [ [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] -[[package]] -name = "importlib-resources" -version = "6.4.5" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, - {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] -type = ["pytest-mypy"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -2330,84 +2242,86 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jiter" -version = "0.7.1" +version = "0.8.0" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" files = [ - {file = "jiter-0.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:262e96d06696b673fad6f257e6a0abb6e873dc22818ca0e0600f4a1189eb334f"}, - {file = "jiter-0.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be6de02939aac5be97eb437f45cfd279b1dc9de358b13ea6e040e63a3221c40d"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935f10b802bc1ce2b2f61843e498c7720aa7f4e4bb7797aa8121eab017293c3d"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9cd3cccccabf5064e4bb3099c87bf67db94f805c1e62d1aefd2b7476e90e0ee2"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4aa919ebfc5f7b027cc368fe3964c0015e1963b92e1db382419dadb098a05192"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ae2d01e82c94491ce4d6f461a837f63b6c4e6dd5bb082553a70c509034ff3d4"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f9568cd66dbbdab67ae1b4c99f3f7da1228c5682d65913e3f5f95586b3cb9a9"}, - {file = "jiter-0.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ecbf4e20ec2c26512736284dc1a3f8ed79b6ca7188e3b99032757ad48db97dc"}, - {file = "jiter-0.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1a0508fddc70ce00b872e463b387d49308ef02b0787992ca471c8d4ba1c0fa1"}, - {file = "jiter-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f84c9996664c460f24213ff1e5881530abd8fafd82058d39af3682d5fd2d6316"}, - {file = "jiter-0.7.1-cp310-none-win32.whl", hash = "sha256:c915e1a1960976ba4dfe06551ea87063b2d5b4d30759012210099e712a414d9f"}, - {file = "jiter-0.7.1-cp310-none-win_amd64.whl", hash = "sha256:75bf3b7fdc5c0faa6ffffcf8028a1f974d126bac86d96490d1b51b3210aa0f3f"}, - {file = "jiter-0.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ad04a23a91f3d10d69d6c87a5f4471b61c2c5cd6e112e85136594a02043f462c"}, - {file = "jiter-0.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e47a554de88dff701226bb5722b7f1b6bccd0b98f1748459b7e56acac2707a5"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e44fff69c814a2e96a20b4ecee3e2365e9b15cf5fe4e00869d18396daa91dab"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df0a1d05081541b45743c965436f8b5a1048d6fd726e4a030113a2699a6046ea"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f22cf8f236a645cb6d8ffe2a64edb5d2b66fb148bf7c75eea0cb36d17014a7bc"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8589f50b728ea4bf22e0632eefa125c8aa9c38ed202a5ee6ca371f05eeb3ff"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f20de711224f2ca2dbb166a8d512f6ff48c9c38cc06b51f796520eb4722cc2ce"}, - {file = "jiter-0.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a9803396032117b85ec8cbf008a54590644a062fedd0425cbdb95e4b2b60479"}, - {file = "jiter-0.7.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3d8bae77c82741032e9d89a4026479061aba6e646de3bf5f2fc1ae2bbd9d06e0"}, - {file = "jiter-0.7.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3dc9939e576bbc68c813fc82f6620353ed68c194c7bcf3d58dc822591ec12490"}, - {file = "jiter-0.7.1-cp311-none-win32.whl", hash = "sha256:f7605d24cd6fab156ec89e7924578e21604feee9c4f1e9da34d8b67f63e54892"}, - {file = "jiter-0.7.1-cp311-none-win_amd64.whl", hash = "sha256:f3ea649e7751a1a29ea5ecc03c4ada0a833846c59c6da75d747899f9b48b7282"}, - {file = "jiter-0.7.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ad36a1155cbd92e7a084a568f7dc6023497df781adf2390c345dd77a120905ca"}, - {file = "jiter-0.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7ba52e6aaed2dc5c81a3d9b5e4ab95b039c4592c66ac973879ba57c3506492bb"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b7de0b6f6728b678540c7927587e23f715284596724be203af952418acb8a2d"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9463b62bd53c2fb85529c700c6a3beb2ee54fde8bef714b150601616dcb184a6"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:627164ec01d28af56e1f549da84caf0fe06da3880ebc7b7ee1ca15df106ae172"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25d0e5bf64e368b0aa9e0a559c3ab2f9b67e35fe7269e8a0d81f48bbd10e8963"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c244261306f08f8008b3087059601997016549cb8bb23cf4317a4827f07b7d74"}, - {file = "jiter-0.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7ded4e4b75b68b843b7cea5cd7c55f738c20e1394c68c2cb10adb655526c5f1b"}, - {file = "jiter-0.7.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:80dae4f1889b9d09e5f4de6b58c490d9c8ce7730e35e0b8643ab62b1538f095c"}, - {file = "jiter-0.7.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5970cf8ec943b51bce7f4b98d2e1ed3ada170c2a789e2db3cb484486591a176a"}, - {file = "jiter-0.7.1-cp312-none-win32.whl", hash = "sha256:701d90220d6ecb3125d46853c8ca8a5bc158de8c49af60fd706475a49fee157e"}, - {file = "jiter-0.7.1-cp312-none-win_amd64.whl", hash = "sha256:7824c3ecf9ecf3321c37f4e4d4411aad49c666ee5bc2a937071bdd80917e4533"}, - {file = "jiter-0.7.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:097676a37778ba3c80cb53f34abd6943ceb0848263c21bf423ae98b090f6c6ba"}, - {file = "jiter-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3298af506d4271257c0a8f48668b0f47048d69351675dd8500f22420d4eec378"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12fd88cfe6067e2199964839c19bd2b422ca3fd792949b8f44bb8a4e7d21946a"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dacca921efcd21939123c8ea8883a54b9fa7f6545c8019ffcf4f762985b6d0c8"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de3674a5fe1f6713a746d25ad9c32cd32fadc824e64b9d6159b3b34fd9134143"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65df9dbae6d67e0788a05b4bad5706ad40f6f911e0137eb416b9eead6ba6f044"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ba9a358d59a0a55cccaa4957e6ae10b1a25ffdabda863c0343c51817610501d"}, - {file = "jiter-0.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:576eb0f0c6207e9ede2b11ec01d9c2182973986514f9c60bc3b3b5d5798c8f50"}, - {file = "jiter-0.7.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e550e29cdf3577d2c970a18f3959e6b8646fd60ef1b0507e5947dc73703b5627"}, - {file = "jiter-0.7.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:81d968dbf3ce0db2e0e4dec6b0a0d5d94f846ee84caf779b07cab49f5325ae43"}, - {file = "jiter-0.7.1-cp313-none-win32.whl", hash = "sha256:f892e547e6e79a1506eb571a676cf2f480a4533675f834e9ae98de84f9b941ac"}, - {file = "jiter-0.7.1-cp313-none-win_amd64.whl", hash = "sha256:0302f0940b1455b2a7fb0409b8d5b31183db70d2b07fd177906d83bf941385d1"}, - {file = "jiter-0.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c65a3ce72b679958b79d556473f192a4dfc5895e8cc1030c9f4e434690906076"}, - {file = "jiter-0.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e80052d3db39f9bb8eb86d207a1be3d9ecee5e05fdec31380817f9609ad38e60"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70a497859c4f3f7acd71c8bd89a6f9cf753ebacacf5e3e799138b8e1843084e3"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c1288bc22b9e36854a0536ba83666c3b1fb066b811019d7b682c9cf0269cdf9f"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b096ca72dd38ef35675e1d3b01785874315182243ef7aea9752cb62266ad516f"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8dbbd52c50b605af13dbee1a08373c520e6fcc6b5d32f17738875847fea4e2cd"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af29c5c6eb2517e71ffa15c7ae9509fa5e833ec2a99319ac88cc271eca865519"}, - {file = "jiter-0.7.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f114a4df1e40c03c0efbf974b376ed57756a1141eb27d04baee0680c5af3d424"}, - {file = "jiter-0.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:191fbaee7cf46a9dd9b817547bf556facde50f83199d07fc48ebeff4082f9df4"}, - {file = "jiter-0.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e2b445e5ee627fb4ee6bbceeb486251e60a0c881a8e12398dfdff47c56f0723"}, - {file = "jiter-0.7.1-cp38-none-win32.whl", hash = "sha256:47ac4c3cf8135c83e64755b7276339b26cd3c7ddadf9e67306ace4832b283edf"}, - {file = "jiter-0.7.1-cp38-none-win_amd64.whl", hash = "sha256:60b49c245cd90cde4794f5c30f123ee06ccf42fb8730a019a2870cd005653ebd"}, - {file = "jiter-0.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8f212eeacc7203256f526f550d105d8efa24605828382cd7d296b703181ff11d"}, - {file = "jiter-0.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9e247079d88c00e75e297e6cb3a18a039ebcd79fefc43be9ba4eb7fb43eb726"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0aacaa56360139c53dcf352992b0331f4057a0373bbffd43f64ba0c32d2d155"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc1b55314ca97dbb6c48d9144323896e9c1a25d41c65bcb9550b3e0c270ca560"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f281aae41b47e90deb70e7386558e877a8e62e1693e0086f37d015fa1c102289"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:93c20d2730a84d43f7c0b6fb2579dc54335db742a59cf9776d0b80e99d587382"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e81ccccd8069110e150613496deafa10da2f6ff322a707cbec2b0d52a87b9671"}, - {file = "jiter-0.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a7d5e85766eff4c9be481d77e2226b4c259999cb6862ccac5ef6621d3c8dcce"}, - {file = "jiter-0.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f52ce5799df5b6975439ecb16b1e879d7655e1685b6e3758c9b1b97696313bfb"}, - {file = "jiter-0.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0c91a0304373fdf97d56f88356a010bba442e6d995eb7773cbe32885b71cdd8"}, - {file = "jiter-0.7.1-cp39-none-win32.whl", hash = "sha256:5c08adf93e41ce2755970e8aa95262298afe2bf58897fb9653c47cd93c3c6cdc"}, - {file = "jiter-0.7.1-cp39-none-win_amd64.whl", hash = "sha256:6592f4067c74176e5f369228fb2995ed01400c9e8e1225fb73417183a5e635f0"}, - {file = "jiter-0.7.1.tar.gz", hash = "sha256:448cf4f74f7363c34cdef26214da527e8eeffd88ba06d0b80b485ad0667baf5d"}, + {file = "jiter-0.8.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:dee4eeb293ffcd2c3b31ebab684dbf7f7b71fe198f8eddcdf3a042cc6e10205a"}, + {file = "jiter-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aad1e6e9b01cf0304dcee14db03e92e0073287a6297caf5caf2e9dbfea16a924"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:504099fb7acdbe763e10690d560a25d4aee03d918d6a063f3a761d8a09fb833f"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2373487caad7fe39581f588ab5c9262fc1ade078d448626fec93f4ffba528858"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c341ecc3f9bccde952898b0c97c24f75b84b56a7e2f8bbc7c8e38cab0875a027"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e48e7a336529b9419d299b70c358d4ebf99b8f4b847ed3f1000ec9f320e8c0c"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5ee157a8afd2943be690db679f82fafb8d347a8342e8b9c34863de30c538d55"}, + {file = "jiter-0.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d7dceae3549b80087f913aad4acc2a7c1e0ab7cb983effd78bdc9c41cabdcf18"}, + {file = "jiter-0.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e29e9ecce53d396772590438214cac4ab89776f5e60bd30601f1050b34464019"}, + {file = "jiter-0.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fa1782f22d5f92c620153133f35a9a395d3f3823374bceddd3e7032e2fdfa0b1"}, + {file = "jiter-0.8.0-cp310-none-win32.whl", hash = "sha256:f754ef13b4e4f67a3bf59fe974ef4342523801c48bf422f720bd37a02a360584"}, + {file = "jiter-0.8.0-cp310-none-win_amd64.whl", hash = "sha256:796f750b65f5d605f5e7acaccc6b051675e60c41d7ac3eab40dbd7b5b81a290f"}, + {file = "jiter-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f6f4e645efd96b4690b9b6091dbd4e0fa2885ba5c57a0305c1916b75b4f30ff6"}, + {file = "jiter-0.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f61cf6d93c1ade9b8245c9f14b7900feadb0b7899dbe4aa8de268b705647df81"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0396bc5cb1309c6dab085e70bb3913cdd92218315e47b44afe9eace68ee8adaa"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62d0e42ec5dc772bd8554a304358220be5d97d721c4648b23f3a9c01ccc2cb26"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec4b711989860705733fc59fb8c41b2def97041cea656b37cf6c8ea8dee1c3f4"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:859cc35bf304ab066d88f10a44a3251a9cd057fb11ec23e00be22206db878f4f"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5000195921aa293b39b9b5bc959d7fa658e7f18f938c0e52732da8e3cc70a278"}, + {file = "jiter-0.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36050284c0abde57aba34964d3920f3d6228211b65df7187059bb7c7f143759a"}, + {file = "jiter-0.8.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a88f608e050cfe45c48d771e86ecdbf5258314c883c986d4217cc79e1fb5f689"}, + {file = "jiter-0.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:646cf4237665b2e13b4159d8f26d53f59bc9f2e6e135e3a508a2e5dd26d978c6"}, + {file = "jiter-0.8.0-cp311-none-win32.whl", hash = "sha256:21fe5b8345db1b3023052b2ade9bb4d369417827242892051244af8fae8ba231"}, + {file = "jiter-0.8.0-cp311-none-win_amd64.whl", hash = "sha256:30c2161c5493acf6b6c3c909973fb64ae863747def01cc7574f3954e0a15042c"}, + {file = "jiter-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d91a52d8f49ada2672a4b808a0c5c25d28f320a2c9ca690e30ebd561eb5a1002"}, + {file = "jiter-0.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c38cf25cf7862f61410b7a49684d34eb3b5bcbd7ddaf4773eea40e0bd43de706"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6189beb5c4b3117624be6b2e84545cff7611f5855d02de2d06ff68e316182be"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13fa849c0e30643554add089983caa82f027d69fad8f50acadcb21c462244ab"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d7765ca159d0a58e8e0f8ca972cd6d26a33bc97b4480d0d2309856763807cd28"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b0befe7c6e9fc867d5bed21bab0131dfe27d1fa5cd52ba2bced67da33730b7d"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7d6363d4c6f1052b1d8b494eb9a72667c3ef5f80ebacfe18712728e85327000"}, + {file = "jiter-0.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a873e57009863eeac3e3969e4653f07031d6270d037d6224415074ac17e5505c"}, + {file = "jiter-0.8.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2582912473c0d9940791479fe1bf2976a34f212eb8e0a82ee9e645ac275c5d16"}, + {file = "jiter-0.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:646163201af42f55393ee6e8f6136b8df488253a6533f4230a64242ecbfe6048"}, + {file = "jiter-0.8.0-cp312-none-win32.whl", hash = "sha256:96e75c9abfbf7387cba89a324d2356d86d8897ac58c956017d062ad510832dae"}, + {file = "jiter-0.8.0-cp312-none-win_amd64.whl", hash = "sha256:ed6074552b4a32e047b52dad5ab497223721efbd0e9efe68c67749f094a092f7"}, + {file = "jiter-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:dd5e351cb9b3e676ec3360a85ea96def515ad2b83c8ae3a251ce84985a2c9a6f"}, + {file = "jiter-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ba9f12b0f801ecd5ed0cec29041dc425d1050922b434314c592fc30d51022467"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7ba461c3681728d556392e8ae56fb44a550155a24905f01982317b367c21dd4"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a15ed47ab09576db560dbc5c2c5a64477535beb056cd7d997d5dd0f2798770e"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cef55042816d0737142b0ec056c0356a5f681fb8d6aa8499b158e87098f4c6f8"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:549f170215adeb5e866f10617c3d019d8eb4e6d4e3c6b724b3b8c056514a3487"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f867edeb279d22020877640d2ea728de5817378c60a51be8af731a8a8f525306"}, + {file = "jiter-0.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aef8845f463093799db4464cee2aa59d61aa8edcb3762aaa4aacbec3f478c929"}, + {file = "jiter-0.8.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:d0d6e22e4062c3d3c1bf3594baa2f67fc9dcdda8275abad99e468e0c6540bc54"}, + {file = "jiter-0.8.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:079e62e64696241ac3f408e337aaac09137ed760ccf2b72b1094b48745c13641"}, + {file = "jiter-0.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74d2b56ed3da5760544df53b5f5c39782e68efb64dc3aa0bba4cc08815e6fae8"}, + {file = "jiter-0.8.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:798dafe108cba58a7bb0a50d4d5971f98bb7f3c974e1373e750de6eb21c1a329"}, + {file = "jiter-0.8.0-cp313-none-win32.whl", hash = "sha256:ca6d3064dfc743eb0d3d7539d89d4ba886957c717567adc72744341c1e3573c9"}, + {file = "jiter-0.8.0-cp313-none-win_amd64.whl", hash = "sha256:38caedda64fe1f04b06d7011fc15e86b3b837ed5088657bf778656551e3cd8f9"}, + {file = "jiter-0.8.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:bb5c8a0a8d081c338db22e5b8d53a89a121790569cbb85f7d3cfb1fe0fbe9836"}, + {file = "jiter-0.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:202dbe8970bfb166fab950eaab8f829c505730a0b33cc5e1cfb0a1c9dd56b2f9"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9046812e5671fdcfb9ae02881fff1f6a14d484b7e8b3316179a372cdfa1e8026"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e6ac56425023e52d65150918ae25480d0a1ce2a6bf5ea2097f66a2cc50f6d692"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dfcf97210c6eab9d2a1c6af15dd39e1d5154b96a7145d0a97fa1df865b7b834"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4e3c8444d418686f78c9a547b9b90031faf72a0a1a46bfec7fb31edbd889c0d"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6507011a299b7f578559084256405a8428875540d8d13530e00b688e41b09493"}, + {file = "jiter-0.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0aae4738eafdd34f0f25c2d3668ce9e8fa0d7cb75a2efae543c9a69aebc37323"}, + {file = "jiter-0.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5d782e790396b13f2a7b36bdcaa3736a33293bdda80a4bf1a3ce0cd5ef9f15"}, + {file = "jiter-0.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cc7f993bc2c4e03015445adbb16790c303282fce2e8d9dc3a3905b1d40e50564"}, + {file = "jiter-0.8.0-cp38-none-win32.whl", hash = "sha256:d4a8a6eda018a991fa58ef707dd51524055d11f5acb2f516d70b1be1d15ab39c"}, + {file = "jiter-0.8.0-cp38-none-win_amd64.whl", hash = "sha256:4cca948a3eda8ea24ed98acb0ee19dc755b6ad2e570ec85e1527d5167f91ff67"}, + {file = "jiter-0.8.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ef89663678d8257063ce7c00d94638e05bd72f662c5e1eb0e07a172e6c1a9a9f"}, + {file = "jiter-0.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c402ddcba90b4cc71db3216e8330f4db36e0da2c78cf1d8a9c3ed8f272602a94"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a6dfe795b7a173a9f8ba7421cdd92193d60c1c973bbc50dc3758a9ad0fa5eb6"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ec29a31b9abd6be39453a2c45da067138a3005d65d2c0507c530e0f1fdcd9a4"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a488f8c54bddc3ddefaf3bfd6de4a52c97fc265d77bc2dcc6ee540c17e8c342"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aeb5561adf4d26ca0d01b5811b4d7b56a8986699a473d700757b4758ef787883"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ab961858d7ad13132328517d29f121ae1b2d94502191d6bcf96bddcc8bb5d1c"}, + {file = "jiter-0.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a207e718d114d23acf0850a2174d290f42763d955030d9924ffa4227dbd0018f"}, + {file = "jiter-0.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:733bc9dc8ff718a0ae4695239e9268eb93e88b73b367dfac3ec227d8ce2f1e77"}, + {file = "jiter-0.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1ec27299e22d05e13a06e460bf7f75f26f9aaa0e0fb7d060f40e88df1d81faa"}, + {file = "jiter-0.8.0-cp39-none-win32.whl", hash = "sha256:e8dbfcb46553e6661d3fc1f33831598fcddf73d0f67834bce9fc3e9ebfe5c439"}, + {file = "jiter-0.8.0-cp39-none-win_amd64.whl", hash = "sha256:af2ce2487b3a93747e2cb5150081d4ae1e5874fce5924fc1a12e9e768e489ad8"}, + {file = "jiter-0.8.0.tar.gz", hash = "sha256:86fee98b569d4cc511ff2e3ec131354fafebd9348a487549c31ad371ae730310"}, ] [[package]] @@ -2434,13 +2348,13 @@ files = [ [[package]] name = "json5" -version = "0.9.28" +version = "0.10.0" description = "A Python implementation of the JSON5 data format." optional = false python-versions = ">=3.8.0" files = [ - {file = "json5-0.9.28-py3-none-any.whl", hash = "sha256:29c56f1accdd8bc2e037321237662034a7e07921e2b7223281a5ce2c46f0c4df"}, - {file = "json5-0.9.28.tar.gz", hash = "sha256:1f82f36e615bc5b42f1bbd49dbc94b12563c56408c6ffa06414ea310890e9a6e"}, + {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"}, + {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"}, ] [package.extras] @@ -2914,6 +2828,31 @@ files = [ [package.dependencies] six = "*" +[[package]] +name = "langfuse" +version = "2.54.1" +description = "A client library for accessing langfuse" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langfuse-2.54.1-py3-none-any.whl", hash = "sha256:1f1261cf763886758c70e192133340ff296169cc0930cde725eee52d467eb661"}, + {file = "langfuse-2.54.1.tar.gz", hash = "sha256:7efc70799740ffa0ac7e04066e0596fb6433e8e501fc850c6a4e7967de6de8a7"}, +] + +[package.dependencies] +anyio = ">=4.4.0,<5.0.0" +backoff = ">=1.10.0" +httpx = ">=0.15.4,<1.0" +idna = ">=3.7,<4.0" +packaging = ">=23.2,<25.0" +pydantic = ">=1.10.7,<3.0" +wrapt = ">=1.14,<2.0" + +[package.extras] +langchain = ["langchain (>=0.0.309)"] +llama-index = ["llama-index (>=0.10.12,<2.0.0)"] +openai = ["openai (>=0.27.8)"] + [[package]] name = "language-data" version = "1.3.0" @@ -3402,18 +3341,19 @@ redisvl = ">=0.3.4,<0.4.0" [[package]] name = "llama-parse" -version = "0.5.14" +version = "0.5.15" description = "Parse files into RAG-Optimized formats." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_parse-0.5.14-py3-none-any.whl", hash = "sha256:64a46825598a239cd7066df7bd81f1f952ae7b3e26ad98f0e34aa9625ebcfd72"}, - {file = "llama_parse-0.5.14.tar.gz", hash = "sha256:b90510f58774d6ee73b6275fe4f1aa0ff3a306026df29959606e56073384248c"}, + {file = "llama_parse-0.5.15-py3-none-any.whl", hash = "sha256:7a3506c7d3ae5a8e68c70a457a7213d2698e26abcef1d7a989eb9771cd73ae60"}, + {file = "llama_parse-0.5.15.tar.gz", hash = "sha256:ecb009f71c8b4c657085ca81808a922c80785810e38b10f3b46f03cfd29ba92a"}, ] [package.dependencies] click = ">=8.1.7,<9.0.0" llama-index-core = ">=0.11.0" +pydantic = "!=2.10" [[package]] name = "lxml" @@ -4020,44 +3960,37 @@ files = [ [[package]] name = "murmurhash" -version = "1.0.10" +version = "1.0.11" description = "Cython bindings for MurmurHash" optional = false python-versions = ">=3.6" files = [ - {file = "murmurhash-1.0.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3e90eef568adca5e17a91f96975e9a782ace3a617bbb3f8c8c2d917096e9bfeb"}, - {file = "murmurhash-1.0.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f8ecb00cc1ab57e4b065f9fb3ea923b55160c402d959c69a0b6dbbe8bc73efc3"}, - {file = "murmurhash-1.0.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3310101004d9e2e0530c2fed30174448d998ffd1b50dcbfb7677e95db101aa4b"}, - {file = "murmurhash-1.0.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65401a6f1778676253cbf89c1f45a8a7feb7d73038e483925df7d5943c08ed9"}, - {file = "murmurhash-1.0.10-cp310-cp310-win_amd64.whl", hash = "sha256:f23f2dfc7174de2cdc5007c0771ab8376a2a3f48247f32cac4a5563e40c6adcc"}, - {file = "murmurhash-1.0.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90ed37ee2cace9381b83d56068334f77e3e30bc521169a1f886a2a2800e965d6"}, - {file = "murmurhash-1.0.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:22e9926fdbec9d24ced9b0a42f0fee68c730438be3cfb00c2499fd495caec226"}, - {file = "murmurhash-1.0.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54bfbfd68baa99717239b8844600db627f336a08b1caf4df89762999f681cdd1"}, - {file = "murmurhash-1.0.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b9d200a09d48ef67f6840b77c14f151f2b6c48fd69661eb75c7276ebdb146c"}, - {file = "murmurhash-1.0.10-cp311-cp311-win_amd64.whl", hash = "sha256:e5d7cfe392c0a28129226271008e61e77bf307afc24abf34f386771daa7b28b0"}, - {file = "murmurhash-1.0.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:96f0a070344d4802ea76a160e0d4c88b7dc10454d2426f48814482ba60b38b9e"}, - {file = "murmurhash-1.0.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9f61862060d677c84556610ac0300a0776cb13cb3155f5075ed97e80f86e55d9"}, - {file = "murmurhash-1.0.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3b6d2d877d8881a08be66d906856d05944be0faf22b9a0390338bcf45299989"}, - {file = "murmurhash-1.0.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f54b0031d8696fed17ed6e9628f339cdea0ba2367ca051e18ff59193f52687"}, - {file = "murmurhash-1.0.10-cp312-cp312-win_amd64.whl", hash = "sha256:97e09d675de2359e586f09de1d0de1ab39f9911edffc65c9255fb5e04f7c1f85"}, - {file = "murmurhash-1.0.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b64e5332932993fef598e78d633b1ba664789ab73032ed511f3dc615a631a1a"}, - {file = "murmurhash-1.0.10-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2a38437a8497e082408aa015c6d90554b9e00c2c221fdfa79728a2d99a739e"}, - {file = "murmurhash-1.0.10-cp36-cp36m-win_amd64.whl", hash = "sha256:55f4e4f9291a53c36070330950b472d72ba7d331e4ce3ce1ab349a4f458f7bc4"}, - {file = "murmurhash-1.0.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:16ef9f0855952493fe08929d23865425906a8c0c40607ac8a949a378652ba6a9"}, - {file = "murmurhash-1.0.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cc3351ae92b89c2fcdc6e41ac6f17176dbd9b3554c96109fd0713695d8663e7"}, - {file = "murmurhash-1.0.10-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6559fef7c2e7349a42a63549067709b656d6d1580752bd76be1541d8b2d65718"}, - {file = "murmurhash-1.0.10-cp37-cp37m-win_amd64.whl", hash = "sha256:8bf49e3bb33febb7057ae3a5d284ef81243a1e55eaa62bdcd79007cddbdc0461"}, - {file = "murmurhash-1.0.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f1605fde07030516eb63d77a598dd164fb9bf217fd937dbac588fe7e47a28c40"}, - {file = "murmurhash-1.0.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4904f7e68674a64eb2b08823c72015a5e14653e0b4b109ea00c652a005a59bad"}, - {file = "murmurhash-1.0.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0438f0cb44cf1cd26251f72c1428213c4197d40a4e3f48b1efc3aea12ce18517"}, - {file = "murmurhash-1.0.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db1171a3f9a10571931764cdbfaa5371f4cf5c23c680639762125cb075b833a5"}, - {file = "murmurhash-1.0.10-cp38-cp38-win_amd64.whl", hash = "sha256:1c9fbcd7646ad8ba67b895f71d361d232c6765754370ecea473dd97d77afe99f"}, - {file = "murmurhash-1.0.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7024ab3498434f22f8e642ae31448322ad8228c65c8d9e5dc2d563d57c14c9b8"}, - {file = "murmurhash-1.0.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a99dedfb7f0cc5a4cd76eb409ee98d3d50eba024f934e705914f6f4d765aef2c"}, - {file = "murmurhash-1.0.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b580b8503647de5dd7972746b7613ea586270f17ac92a44872a9b1b52c36d68"}, - {file = "murmurhash-1.0.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75840212bf75eb1352c946c3cf1622dacddd6d6bdda34368237d1eb3568f23a"}, - {file = "murmurhash-1.0.10-cp39-cp39-win_amd64.whl", hash = "sha256:a4209962b9f85de397c3203ea4b3a554da01ae9fd220fdab38757d4e9eba8d1a"}, - {file = "murmurhash-1.0.10.tar.gz", hash = "sha256:5282aab1317804c6ebd6dd7f69f15ba9075aee671c44a34be2bde0f1b11ef88a"}, + {file = "murmurhash-1.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a73cf9f55c8218d5aa47b3b6dac28fa2e1730bbca0874e7eabe5e1a6024780c5"}, + {file = "murmurhash-1.0.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48716859a12596024d9adecf399e356c3c5c38ba2eb0d8270bd6655c05a0af28"}, + {file = "murmurhash-1.0.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1967ccc893c80798a420c5c3829ea9755d0b4a4972b0bf6e5c34d1117f5d0222"}, + {file = "murmurhash-1.0.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:904c4d6550c640e0f640b6357ecaa13406e6d925e55fbb4ac9e1f27ff25bee3c"}, + {file = "murmurhash-1.0.11-cp310-cp310-win_amd64.whl", hash = "sha256:4c24f1c96e8ce720ac85058c37e6e775be6017f0966abff2863733d91368e03e"}, + {file = "murmurhash-1.0.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53ed86ce0bef2475af9314f732ca66456e7b00abb1d1a6c29c432e5f0f49bad5"}, + {file = "murmurhash-1.0.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51e7c61f59e0ee1c465c841f530ef6373a98dc028059048fc0c857dfd5d57b1c"}, + {file = "murmurhash-1.0.11-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b9a5109e29d43c79bfdca8dbad9bee7190846a88ec6d4135754727fb49a64e5"}, + {file = "murmurhash-1.0.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:12845ad43a2e54734b52f58e8d228eacd03803d368b689b3868a0bdec4c10da1"}, + {file = "murmurhash-1.0.11-cp311-cp311-win_amd64.whl", hash = "sha256:e3d0bdbffd82924725cd6549b03ee11997a2c58253f0fdda571a5fedacc894a1"}, + {file = "murmurhash-1.0.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:185b2cd20b81fa876eaa2249faafd0b7b3d0c54ef04714e38135d9f482cf6ce9"}, + {file = "murmurhash-1.0.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fd3083c6d977c2bc1e2f35ff999c39de43de09fd588f780243ec78debb316406"}, + {file = "murmurhash-1.0.11-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49a3cf4d26f7213d0f4a6c2c49496cbe9f78b30d56b1c3b17fbc74676372ea3f"}, + {file = "murmurhash-1.0.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a1bdb3c3fe32d93f7c461f11e6b2f7bbe64b3d70f56e48052490435853ed5c91"}, + {file = "murmurhash-1.0.11-cp312-cp312-win_amd64.whl", hash = "sha256:0b507dd8ea10f3e5204b397ea9917a3a5f11756859d91406a8f485f18a411bdf"}, + {file = "murmurhash-1.0.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:036aea55d160d65698888a903fd2a19c4258be711f7bf2ab1b6cebdf41e09e09"}, + {file = "murmurhash-1.0.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f4b991b5bd88f5d57550a6328f8adb2f16656781e9eade9c16e55b41f6fab7"}, + {file = "murmurhash-1.0.11-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5527ec305236a2ef404a38e0e57b1dc886a431e2032acf4c7ce3b17382c49ef"}, + {file = "murmurhash-1.0.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b26cf1be87c13fb242b9c252f11a25da71056c8fb5f22623e455129cce99592a"}, + {file = "murmurhash-1.0.11-cp313-cp313-win_amd64.whl", hash = "sha256:24aba80a793bf371de70fffffc1f16c06810e4d8b90125b5bb762aabda3174d1"}, + {file = "murmurhash-1.0.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:234cc9719a5df1bffe174664b84b8381f66016a1f094d43db3fb8ffca1d72207"}, + {file = "murmurhash-1.0.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faf1db780cfca0a021ce32542ac750d24b9b3e81e2a4a6fcb78efcc8ec611813"}, + {file = "murmurhash-1.0.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1f7f7c8bce5fa1c50c6214421af27eb0bbb07cc55c4a35efa5735ceaf1a6a1c"}, + {file = "murmurhash-1.0.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b8d8fad28cf7d9661486f8e3d48e4215db69f5f9b091e78edcccf2c46459846a"}, + {file = "murmurhash-1.0.11-cp39-cp39-win_amd64.whl", hash = "sha256:6ae5fc4f59be8eebcb8d24ffee49f32ee4eccdc004060848834eb2540ee3a056"}, + {file = "murmurhash-1.0.11.tar.gz", hash = "sha256:87ff68a255e54e7648d0729ff4130f43f7f38f03288a376e567934e16db93767"}, ] [[package]] @@ -4319,13 +4252,13 @@ files = [ [[package]] name = "openai" -version = "1.54.5" +version = "1.55.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" files = [ - {file = "openai-1.54.5-py3-none-any.whl", hash = "sha256:f55a4450f38501814b53e76311ed7845a6f7f35bab46d0fb2a3728035d7a72d8"}, - {file = "openai-1.54.5.tar.gz", hash = "sha256:2aab4f9755a3e1e04d8a45ac1f4ce7b6948bab76646020c6386256d7e5cbb7e0"}, + {file = "openai-1.55.1-py3-none-any.whl", hash = "sha256:d10d96a4f9dc5f05d38dea389119ec8dcd24bc9698293c8357253c601b4a77a5"}, + {file = "openai-1.55.1.tar.gz", hash = "sha256:471324321e7739214f16a544e801947a046d3c5d516fae8719a317234e4968d3"}, ] [package.dependencies] @@ -4341,73 +4274,6 @@ typing-extensions = ">=4.11,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -[[package]] -name = "orjson" -version = "3.10.11" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, - {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, - {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, - {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, - {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, - {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, - {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, - {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, - {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, - {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, - {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, - {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, - {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, - {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, - {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, - {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, - {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, - {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, - {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, - {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, - {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, - {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, - {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, - {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, - {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, - {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, - {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, - {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, - {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, - {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, - {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, - {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, - {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, - {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, - {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, - {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, - {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, - {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, - {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, - {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, - {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, - {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, - {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, - {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, - {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, - {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, - {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, - {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, -] - [[package]] name = "outcome" version = "1.3.0.post0" @@ -4692,18 +4558,18 @@ type = ["mypy (>=1.11.2)"] [[package]] name = "playwright" -version = "1.48.0" +version = "1.49.0" description = "A high-level API to automate web browsers" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "playwright-1.48.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:082bce2739f1078acc7d0734da8cc0e23eb91b7fae553f3316d733276f09a6b1"}, - {file = "playwright-1.48.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7da2eb51a19c7f3b523e9faa9d98e7af92e52eb983a099979ea79c9668e3cbf7"}, - {file = "playwright-1.48.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:115b988d1da322358b77bc3bf2d3cc90f8c881e691461538e7df91614c4833c9"}, - {file = "playwright-1.48.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:8dabb80e62f667fe2640a8b694e26a7b884c0b4803f7514a3954fc849126227b"}, - {file = "playwright-1.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ff8303409ebed76bed4c3d655340320b768817d900ba208b394fdd7d7939a5c"}, - {file = "playwright-1.48.0-py3-none-win32.whl", hash = "sha256:85598c360c590076d4f435525be991246d74a905b654ac19d26eab7ed9b98b2d"}, - {file = "playwright-1.48.0-py3-none-win_amd64.whl", hash = "sha256:e0e87b0c4dc8fce83c725dd851aec37bc4e882bb225ec8a96bd83cf32d4f1623"}, + {file = "playwright-1.49.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:704532a2d8ba580ec9e1895bfeafddce2e3d52320d4eb8aa38e80376acc5cbb0"}, + {file = "playwright-1.49.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e453f02c4e5cc2db7e9759c47e7425f32e50ac76c76b7eb17c69eed72f01c4d8"}, + {file = "playwright-1.49.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:37ae985309184472946a6eb1a237e5d93c9e58a781fa73b75c8751325002a5d4"}, + {file = "playwright-1.49.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:68d94beffb3c9213e3ceaafa66171affd9a5d9162e0c8a3eed1b1132c2e57598"}, + {file = "playwright-1.49.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f12d2aecdb41fc25a624cb15f3e8391c252ebd81985e3d5c1c261fe93779345"}, + {file = "playwright-1.49.0-py3-none-win32.whl", hash = "sha256:91103de52d470594ad375b512d7143fa95d6039111ae11a93eb4fe2f2b4a4858"}, + {file = "playwright-1.49.0-py3-none-win_amd64.whl", hash = "sha256:34d28a2c2d46403368610be4339898dc9c34eb9f7c578207b4715c49743a072a"}, ] [package.dependencies] @@ -5117,22 +4983,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, + {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, -] +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -5140,116 +5003,116 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" -[[package]] -name = "pydub" -version = "0.25.1" -description = "Manipulate audio with an simple and easy high level interface" -optional = false -python-versions = "*" -files = [ - {file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"}, - {file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"}, -] - [[package]] name = "pyee" version = "12.0.0" @@ -6014,42 +5877,15 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" -[[package]] -name = "ruff" -version = "0.7.4" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, - {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, - {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, - {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, - {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, - {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, - {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, -] - [[package]] name = "s3transfer" -version = "0.10.3" +version = "0.10.4" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, - {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, + {file = "s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e"}, + {file = "s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7"}, ] [package.dependencies] @@ -6060,13 +5896,13 @@ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] [[package]] name = "selenium" -version = "4.26.1" +version = "4.27.1" description = "Official Python bindings for Selenium WebDriver" optional = false python-versions = ">=3.8" files = [ - {file = "selenium-4.26.1-py3-none-any.whl", hash = "sha256:1db3f3a0cd5bb07624fa8a3905a6fdde1595a42185a0617077c361dc53d104fb"}, - {file = "selenium-4.26.1.tar.gz", hash = "sha256:7640f3f08ae7f4e450f895678e8a10a55eb4e4ca18311ed675ecc4684b96b683"}, + {file = "selenium-4.27.1-py3-none-any.whl", hash = "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18"}, + {file = "selenium-4.27.1.tar.gz", hash = "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2"}, ] [package.dependencies] @@ -6077,21 +5913,6 @@ typing_extensions = ">=4.9,<5.0" urllib3 = {version = ">=1.26,<3", extras = ["socks"]} websocket-client = ">=1.8,<2.0" -[[package]] -name = "semantic-version" -version = "2.10.0" -description = "A library implementing the 'SemVer' scheme." -optional = false -python-versions = ">=2.7" -files = [ - {file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"}, - {file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"}, -] - -[package.extras] -dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"] -doc = ["Sphinx", "sphinx-rtd-theme"] - [[package]] name = "send2trash" version = "1.8.3" @@ -6110,23 +5931,23 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "75.5.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.5.0-py3-none-any.whl", hash = "sha256:87cb777c3b96d638ca02031192d40390e0ad97737e27b6b4fa831bea86f2f829"}, - {file = "setuptools-75.5.0.tar.gz", hash = "sha256:5c4ccb41111392671f02bb5f8436dfc5a9a7185e80500531b133f5775c4163ef"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] -core = ["importlib-metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "sgmllib3k" @@ -6745,123 +6566,26 @@ testing = ["mypy", "pytest", "pytest-gitignore", "pytest-mock", "responses", "ru [[package]] name = "tokenizers" -version = "0.20.3" +version = "0.20.4" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "tokenizers-0.20.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:31ccab28dbb1a9fe539787210b0026e22debeab1662970f61c2d921f7557f7e4"}, - {file = "tokenizers-0.20.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6361191f762bda98c773da418cf511cbaa0cb8d0a1196f16f8c0119bde68ff8"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f128d5da1202b78fa0a10d8d938610472487da01b57098d48f7e944384362514"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79c4121a2e9433ad7ef0769b9ca1f7dd7fa4c0cd501763d0a030afcbc6384481"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7850fde24197fe5cd6556e2fdba53a6d3bae67c531ea33a3d7c420b90904141"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b357970c095dc134978a68c67d845a1e3803ab7c4fbb39195bde914e7e13cf8b"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a333d878c4970b72d6c07848b90c05f6b045cf9273fc2bc04a27211721ad6118"}, - {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd9fee817f655a8f50049f685e224828abfadd436b8ff67979fc1d054b435f1"}, - {file = "tokenizers-0.20.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e7816808b402129393a435ea2a509679b41246175d6e5e9f25b8692bfaa272b"}, - {file = "tokenizers-0.20.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba96367db9d8a730d3a1d5996b4b7babb846c3994b8ef14008cd8660f55db59d"}, - {file = "tokenizers-0.20.3-cp310-none-win32.whl", hash = "sha256:ee31ba9d7df6a98619426283e80c6359f167e2e9882d9ce1b0254937dbd32f3f"}, - {file = "tokenizers-0.20.3-cp310-none-win_amd64.whl", hash = "sha256:a845c08fdad554fe0871d1255df85772f91236e5fd6b9287ef8b64f5807dbd0c"}, - {file = "tokenizers-0.20.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:585b51e06ca1f4839ce7759941e66766d7b060dccfdc57c4ca1e5b9a33013a90"}, - {file = "tokenizers-0.20.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61cbf11954f3b481d08723ebd048ba4b11e582986f9be74d2c3bdd9293a4538d"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef820880d5e4e8484e2fa54ff8d297bb32519eaa7815694dc835ace9130a3eea"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:67ef4dcb8841a4988cd00dd288fb95dfc8e22ed021f01f37348fd51c2b055ba9"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff1ef8bd47a02b0dc191688ccb4da53600df5d4c9a05a4b68e1e3de4823e78eb"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:444d188186eab3148baf0615b522461b41b1f0cd58cd57b862ec94b6ac9780f1"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37c04c032c1442740b2c2d925f1857885c07619224a533123ac7ea71ca5713da"}, - {file = "tokenizers-0.20.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:453c7769d22231960ee0e883d1005c93c68015025a5e4ae56275406d94a3c907"}, - {file = "tokenizers-0.20.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4bb31f7b2847e439766aaa9cc7bccf7ac7088052deccdb2275c952d96f691c6a"}, - {file = "tokenizers-0.20.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:843729bf0f991b29655a069a2ff58a4c24375a553c70955e15e37a90dd4e045c"}, - {file = "tokenizers-0.20.3-cp311-none-win32.whl", hash = "sha256:efcce3a927b1e20ca694ba13f7a68c59b0bd859ef71e441db68ee42cf20c2442"}, - {file = "tokenizers-0.20.3-cp311-none-win_amd64.whl", hash = "sha256:88301aa0801f225725b6df5dea3d77c80365ff2362ca7e252583f2b4809c4cc0"}, - {file = "tokenizers-0.20.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:49d12a32e190fad0e79e5bdb788d05da2f20d8e006b13a70859ac47fecf6ab2f"}, - {file = "tokenizers-0.20.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:282848cacfb9c06d5e51489f38ec5aa0b3cd1e247a023061945f71f41d949d73"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abe4e08c7d0cd6154c795deb5bf81d2122f36daf075e0c12a8b050d824ef0a64"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca94fc1b73b3883c98f0c88c77700b13d55b49f1071dfd57df2b06f3ff7afd64"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef279c7e239f95c8bdd6ff319d9870f30f0d24915b04895f55b1adcf96d6c60d"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16384073973f6ccbde9852157a4fdfe632bb65208139c9d0c0bd0176a71fd67f"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:312d522caeb8a1a42ebdec87118d99b22667782b67898a76c963c058a7e41d4f"}, - {file = "tokenizers-0.20.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2b7cb962564785a83dafbba0144ecb7f579f1d57d8c406cdaa7f32fe32f18ad"}, - {file = "tokenizers-0.20.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:124c5882ebb88dadae1fc788a582299fcd3a8bd84fc3e260b9918cf28b8751f5"}, - {file = "tokenizers-0.20.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2b6e54e71f84c4202111a489879005cb14b92616a87417f6c102c833af961ea2"}, - {file = "tokenizers-0.20.3-cp312-none-win32.whl", hash = "sha256:83d9bfbe9af86f2d9df4833c22e94d94750f1d0cd9bfb22a7bb90a86f61cdb1c"}, - {file = "tokenizers-0.20.3-cp312-none-win_amd64.whl", hash = "sha256:44def74cee574d609a36e17c8914311d1b5dbcfe37c55fd29369d42591b91cf2"}, - {file = "tokenizers-0.20.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0b630e0b536ef0e3c8b42c685c1bc93bd19e98c0f1543db52911f8ede42cf84"}, - {file = "tokenizers-0.20.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a02d160d2b19bcbfdf28bd9a4bf11be4cb97d0499c000d95d4c4b1a4312740b6"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e3d80d89b068bc30034034b5319218c7c0a91b00af19679833f55f3becb6945"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:174a54910bed1b089226512b4458ea60d6d6fd93060254734d3bc3540953c51c"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:098b8a632b8656aa5802c46689462c5c48f02510f24029d71c208ec2c822e771"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78c8c143e3ae41e718588281eb3e212c2b31623c9d6d40410ec464d7d6221fb5"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b26b0aadb18cd8701077362ba359a06683662d5cafe3e8e8aba10eb05c037f1"}, - {file = "tokenizers-0.20.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07d7851a72717321022f3774e84aa9d595a041d643fafa2e87fbc9b18711dac0"}, - {file = "tokenizers-0.20.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bd44e48a430ada902c6266a8245f5036c4fe744fcb51f699999fbe82aa438797"}, - {file = "tokenizers-0.20.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a4c186bb006ccbe1f5cc4e0380d1ce7806f5955c244074fd96abc55e27b77f01"}, - {file = "tokenizers-0.20.3-cp313-none-win32.whl", hash = "sha256:6e19e0f1d854d6ab7ea0c743d06e764d1d9a546932be0a67f33087645f00fe13"}, - {file = "tokenizers-0.20.3-cp313-none-win_amd64.whl", hash = "sha256:d50ede425c7e60966a9680d41b58b3a0950afa1bb570488e2972fa61662c4273"}, - {file = "tokenizers-0.20.3-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:9adda1ff5fb9dcdf899ceca672a4e2ce9e797adb512a6467305ca3d8bfcfbdd0"}, - {file = "tokenizers-0.20.3-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:6dde2cae6004ba7a3badff4a11911cae03ebf23e97eebfc0e71fef2530e5074f"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4a7fd678b35614fca708579eb95b7587a5e8a6d328171bd2488fd9f27d82be4"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b80e3c7283a01a356bd2210f53d1a4a5d32b269c2024389ed0173137708d50e"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8cc0e8176b762973758a77f0d9c4467d310e33165fb74173418ca3734944da4"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5634b2e2f5f3d2b4439d2d74066e22eb4b1f04f3fea05cb2a3c12d89b5a3bcd"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b4ba635165bc1ea46f2da8e5d80b5f70f6ec42161e38d96dbef33bb39df73964"}, - {file = "tokenizers-0.20.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18e4c7c64172e7789bd8b07aa3087ea87c4c4de7e90937a2aa036b5d92332536"}, - {file = "tokenizers-0.20.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1f74909ef7675c26d4095a817ec3393d67f3158ca4836c233212e5613ef640c4"}, - {file = "tokenizers-0.20.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0e9b81321a1e05b16487d312b4264984513f8b4a7556229cafac6e88c2036b09"}, - {file = "tokenizers-0.20.3-cp37-none-win32.whl", hash = "sha256:ab48184cd58b4a03022a2ec75b54c9f600ffea9a733612c02325ed636f353729"}, - {file = "tokenizers-0.20.3-cp37-none-win_amd64.whl", hash = "sha256:60ac483cebee1c12c71878523e768df02fa17e4c54412966cb3ac862c91b36c1"}, - {file = "tokenizers-0.20.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3229ef103c89583d10b9378afa5d601b91e6337530a0988e17ca8d635329a996"}, - {file = "tokenizers-0.20.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6ac52cc24bad3de865c7e65b1c4e7b70d00938a8ae09a92a453b8f676e714ad5"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04627b7b502fa6a2a005e1bd446fa4247d89abcb1afaa1b81eb90e21aba9a60f"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c27ceb887f0e81a3c377eb4605dca7a95a81262761c0fba308d627b2abb98f2b"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65ab780194da4e1fcf5670523a2f377c4838ebf5249efe41fa1eddd2a84fb49d"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98d343134f47159e81f7f242264b0eb222e6b802f37173c8d7d7b64d5c9d1388"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2475bb004ab2009d29aff13b5047bfdb3d4b474f0aa9d4faa13a7f34dbbbb43"}, - {file = "tokenizers-0.20.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b6583a65c01db1197c1eb36857ceba8ec329d53afadd268b42a6b04f4965724"}, - {file = "tokenizers-0.20.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62d00ba208358c037eeab7bfc00a905adc67b2d31b68ab40ed09d75881e114ea"}, - {file = "tokenizers-0.20.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0fc7a39e5bedc817bda395a798dfe2d9c5f7c71153c90d381b5135a0328d9520"}, - {file = "tokenizers-0.20.3-cp38-none-win32.whl", hash = "sha256:84d40ee0f8550d64d3ea92dd7d24a8557a9172165bdb986c9fb2503b4fe4e3b6"}, - {file = "tokenizers-0.20.3-cp38-none-win_amd64.whl", hash = "sha256:205a45246ed7f1718cf3785cff88450ba603352412aaf220ace026384aa3f1c0"}, - {file = "tokenizers-0.20.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:93e37f0269a11dc3b1a953f1fca9707f0929ebf8b4063c591c71a0664219988e"}, - {file = "tokenizers-0.20.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f4cb0c614b0135e781de96c2af87e73da0389ac1458e2a97562ed26e29490d8d"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7eb2fb1c432f5746b22f8a7f09fc18c4156cb0031c77f53cb19379d82d43297a"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfa8d029bb156181b006643309d6b673615a24e4ed24cf03aa191d599b996f51"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f90549622de3bf476ad9f1dd6f3f952ec3ed6ab8615ae88ef060d0c5bfad55d"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d469c74eebf5c43fd61cd9b030e271d17198edd7bd45392e03a3c091d7d6d4"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bee8f53b2594749f4460d53253bae55d718f04e9b633efa0f5df8938bd98e4f0"}, - {file = "tokenizers-0.20.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:938441babf3e5720e4459e306ef2809fb267680df9d1ff2873458b22aef60248"}, - {file = "tokenizers-0.20.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7310ab23d7b0caebecc0e8be11a1146f320f5f07284000f6ea54793e83de1b75"}, - {file = "tokenizers-0.20.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:16121eb030a2b13094cfec936b0c12e8b4063c5f839591ea7d0212336d8f9921"}, - {file = "tokenizers-0.20.3-cp39-none-win32.whl", hash = "sha256:401cc21ef642ee235985d747f65e18f639464d377c70836c9003df208d582064"}, - {file = "tokenizers-0.20.3-cp39-none-win_amd64.whl", hash = "sha256:7498f3ea7746133335a6adb67a77cf77227a8b82c8483f644a2e5f86fea42b8d"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e919f2e3e68bb51dc31de4fcbbeff3bdf9c1cad489044c75e2b982a91059bd3c"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b8e9608f2773996cc272156e305bd79066163a66b0390fe21750aff62df1ac07"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39270a7050deaf50f7caff4c532c01b3c48f6608d42b3eacdebdc6795478c8df"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e005466632b1c5d2d2120f6de8aa768cc9d36cd1ab7d51d0c27a114c91a1e6ee"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a07962340b36189b6c8feda552ea1bfeee6cf067ff922a1d7760662c2ee229e5"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:55046ad3dd5f2b3c67501fcc8c9cbe3e901d8355f08a3b745e9b57894855f85b"}, - {file = "tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:efcf0eb939988b627558aaf2b9dc3e56d759cad2e0cfa04fcab378e4b48fc4fd"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f3558a7ae6a6d38a77dfce12172a1e2e1bf3e8871e744a1861cd7591ea9ebe24"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d53029fe44bc70c3ff14ef512460a0cf583495a0f8e2f4b70e26eb9438e38a9"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57a2a56397b2bec5a629b516b23f0f8a3e4f978c7488d4a299980f8375954b85"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e5bfaae740ef9ece000f8a07e78ac0e2b085c5ce9648f8593ddf0243c9f76d"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fbaf3ea28fedfb2283da60e710aff25492e795a7397cad8a50f1e079b65a5a70"}, - {file = "tokenizers-0.20.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c47c037116310dc976eb96b008e41b9cfaba002ed8005848d4d632ee0b7ba9ae"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c31751f0721f58f5e19bb27c1acc259aeff860d8629c4e1a900b26a1979ada8e"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c697cbd3be7a79ea250ea5f380d6f12e534c543cfb137d5c734966b3ee4f34cc"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b48971b88ef9130bf35b41b35fd857c3c4dae4a9cd7990ebc7fc03e59cc92438"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e615de179bbe060ab33773f0d98a8a8572b5883dd7dac66c1de8c056c7e748c"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da1ec842035ed9999c62e45fbe0ff14b7e8a7e02bb97688cc6313cf65e5cd755"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6ee4954c1dd23aadc27958dad759006e71659d497dcb0ef0c7c87ea992c16ebd"}, - {file = "tokenizers-0.20.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3eda46ca402751ec82553a321bf35a617b76bbed7586e768c02ccacbdda94d6d"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:de082392a85eb0055cc055c535bff2f0cc15d7a000bdc36fbf601a0f3cf8507a"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c3db46cc0647bfd88263afdb739b92017a02a87ee30945cb3e86c7e25c7c9917"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a292392f24ab9abac5cfa8197e5a6208f2e43723420217e1ceba0b4ec77816ac"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dcd91f4e60f62b20d83a87a84fe062035a1e3ff49a8c2bbdeb2d441c8e311f4"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:900991a2b8ee35961b1095db7e265342e0e42a84c1a594823d5ee9f8fb791958"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5a8d8261ca2133d4f98aa9627c748189502b3787537ba3d7e2beb4f7cfc5d627"}, - {file = "tokenizers-0.20.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c4fd4d71e6deb6ddf99d8d0eab87d1d16f635898906e631914a9bae8ae9f2cfb"}, - {file = "tokenizers-0.20.3.tar.gz", hash = "sha256:2278b34c5d0dd78e087e1ca7f9b1dcbf129d80211afa645f214bd6e051037539"}, + {file = "tokenizers-0.20.4-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:25f59ebc5b79e7bbafe86bfec62696468016627157d8a9ceba5092486796a156"}, + {file = "tokenizers-0.20.4-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:f41df992797ad0ff9472e8a2c7a3ef7178667935d984639b73da7d19b33ea4e2"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7786004e180fab72e6e873e982ccd18b3cfa31521d397b6c024cc19175abf91b"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:075635cd7e6936cc4b3a13901c1a05690d5b533ce3d0f035dee21117dd4f04ae"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa392bae7f0a36e4c97ad43100390ad84f2a1bfff6742604774210f7d7a4fa13"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eee647ccba9cbd36b5ec4e8e73d25dbd586ec06de7a43ff83a3dad9fec466a29"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:735ffc9bba65d20f8ab5f82dfbab262bb066afc7dee3684c5e5435e7a5da445d"}, + {file = "tokenizers-0.20.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05c2bab579c1f31292b48bb79b6334b5346c1ec87dac81089e6098b8a20b2fd4"}, + {file = "tokenizers-0.20.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3e960ad5c467a95e5665e518151ed9024e7aa111d2c54ff1938162cc7c2b8959"}, + {file = "tokenizers-0.20.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e59a405459ed31b73426b364752c2e7c73f4a94210a63fd7acd161a774af7bd2"}, + {file = "tokenizers-0.20.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:84bf8b4a7bbf1c6bb78775ae309a5c69d08dadf7b88125d6d19ccb4738a87350"}, + {file = "tokenizers-0.20.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a6d392a20ca70692aaba8a636677b57f6c67655879773ba2b6be8cb4a19ce6b8"}, + {file = "tokenizers-0.20.4-cp39-abi3-win32.whl", hash = "sha256:60ea37c885a9bb8efa53b7542ea83561cd00eb3ffb47a77f5ae622d9f7f66ffe"}, + {file = "tokenizers-0.20.4-cp39-abi3-win_amd64.whl", hash = "sha256:6cba92b87969ddf5a7e2f2293577c30129d8c22c6f68e8c626d3e76b8d52412c"}, + {file = "tokenizers-0.20.4.tar.gz", hash = "sha256:db50ac15e92981227f499268541306824f49e97dbeec05d118ebdc7c2d22322c"}, ] [package.dependencies] @@ -6883,53 +6607,42 @@ files = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -[[package]] -name = "tomlkit" -version = "0.12.0" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomlkit-0.12.0-py3-none-any.whl", hash = "sha256:926f1f37a1587c7a4f6c7484dae538f1345d96d793d9adab5d3675957b1d0766"}, - {file = "tomlkit-0.12.0.tar.gz", hash = "sha256:01f0477981119c7d8ee0f67ebe0297a7c95b14cf9f4b102b45486deb77018716"}, -] - [[package]] name = "tornado" -version = "6.4.1" +version = "6.4.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">=3.8" files = [ - {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, - {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, - {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, - {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, - {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1"}, + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c"}, + {file = "tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482"}, + {file = "tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38"}, + {file = "tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"}, ] [[package]] name = "tqdm" -version = "4.67.0" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be"}, - {file = "tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] @@ -7186,94 +6899,82 @@ colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\" and python [[package]] name = "watchfiles" -version = "0.24.0" +version = "1.0.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0"}, - {file = "watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a"}, - {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e"}, - {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c"}, - {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188"}, - {file = "watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735"}, - {file = "watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04"}, - {file = "watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428"}, - {file = "watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15"}, - {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823"}, - {file = "watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab"}, - {file = "watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec"}, - {file = "watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d"}, - {file = "watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c"}, - {file = "watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633"}, - {file = "watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a"}, - {file = "watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f"}, - {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234"}, - {file = "watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef"}, - {file = "watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968"}, - {file = "watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444"}, - {file = "watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896"}, - {file = "watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418"}, - {file = "watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48"}, - {file = "watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab"}, - {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f"}, - {file = "watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b"}, - {file = "watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18"}, - {file = "watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07"}, - {file = "watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366"}, - {file = "watchfiles-0.24.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318"}, - {file = "watchfiles-0.24.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b"}, - {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91"}, - {file = "watchfiles-0.24.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b"}, - {file = "watchfiles-0.24.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22"}, - {file = "watchfiles-0.24.0-cp38-none-win32.whl", hash = "sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1"}, - {file = "watchfiles-0.24.0-cp38-none-win_amd64.whl", hash = "sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1"}, - {file = "watchfiles-0.24.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886"}, - {file = "watchfiles-0.24.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a"}, - {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9"}, - {file = "watchfiles-0.24.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca"}, - {file = "watchfiles-0.24.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e"}, - {file = "watchfiles-0.24.0-cp39-none-win32.whl", hash = "sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da"}, - {file = "watchfiles-0.24.0-cp39-none-win_amd64.whl", hash = "sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f"}, - {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f"}, - {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b"}, - {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4"}, - {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a"}, - {file = "watchfiles-0.24.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be"}, - {file = "watchfiles-0.24.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5"}, - {file = "watchfiles-0.24.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777"}, - {file = "watchfiles-0.24.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e"}, - {file = "watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1"}, + {file = "watchfiles-1.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1d19df28f99d6a81730658fbeb3ade8565ff687f95acb59665f11502b441be5f"}, + {file = "watchfiles-1.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:28babb38cf2da8e170b706c4b84aa7e4528a6fa4f3ee55d7a0866456a1662041"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12ab123135b2f42517f04e720526d41448667ae8249e651385afb5cda31fedc0"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13a4f9ee0cd25682679eea5c14fc629e2eaa79aab74d963bc4e21f43b8ea1877"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e1d9284cc84de7855fcf83472e51d32daf6f6cecd094160192628bc3fee1b78"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ee5edc939f53466b329bbf2e58333a5461e6c7b50c980fa6117439e2c18b42d"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dccfc70480087567720e4e36ec381bba1ed68d7e5f368fe40c93b3b1eba0105"}, + {file = "watchfiles-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c83a6d33a9eda0af6a7470240d1af487807adc269704fe76a4972dd982d16236"}, + {file = "watchfiles-1.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:905f69aad276639eff3893759a07d44ea99560e67a1cf46ff389cd62f88872a2"}, + {file = "watchfiles-1.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09551237645d6bff3972592f2aa5424df9290e7a2e15d63c5f47c48cde585935"}, + {file = "watchfiles-1.0.0-cp310-none-win32.whl", hash = "sha256:d2b39aa8edd9e5f56f99a2a2740a251dc58515398e9ed5a4b3e5ff2827060755"}, + {file = "watchfiles-1.0.0-cp310-none-win_amd64.whl", hash = "sha256:2de52b499e1ab037f1a87cb8ebcb04a819bf087b1015a4cf6dcf8af3c2a2613e"}, + {file = "watchfiles-1.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:fbd0ab7a9943bbddb87cbc2bf2f09317e74c77dc55b1f5657f81d04666c25269"}, + {file = "watchfiles-1.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:774ef36b16b7198669ce655d4f75b4c3d370e7f1cbdfb997fb10ee98717e2058"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b4fb98100267e6a5ebaff6aaa5d20aea20240584647470be39fe4823012ac96"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0fc3bf0effa2d8075b70badfdd7fb839d7aa9cea650d17886982840d71fdeabf"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:648e2b6db53eca6ef31245805cd528a16f56fa4cc15aeec97795eaf713c11435"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa13d604fcb9417ae5f2e3de676e66aa97427d888e83662ad205bed35a313176"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:936f362e7ff28311b16f0b97ec51e8f2cc451763a3264640c6ed40fb252d1ee4"}, + {file = "watchfiles-1.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:245fab124b9faf58430da547512d91734858df13f2ddd48ecfa5e493455ffccb"}, + {file = "watchfiles-1.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4ff9c7e84e8b644a8f985c42bcc81457240316f900fc72769aaedec9d088055a"}, + {file = "watchfiles-1.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9c9a8d8fd97defe935ef8dd53d562e68942ad65067cd1c54d6ed8a088b1d931d"}, + {file = "watchfiles-1.0.0-cp311-none-win32.whl", hash = "sha256:a0abf173975eb9dd17bb14c191ee79999e650997cc644562f91df06060610e62"}, + {file = "watchfiles-1.0.0-cp311-none-win_amd64.whl", hash = "sha256:2a825ba4b32c214e3855b536eb1a1f7b006511d8e64b8215aac06eb680642d84"}, + {file = "watchfiles-1.0.0-cp311-none-win_arm64.whl", hash = "sha256:a5a7a06cfc65e34fd0a765a7623c5ba14707a0870703888e51d3d67107589817"}, + {file = "watchfiles-1.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:28fb64b5843d94e2c2483f7b024a1280662a44409bedee8f2f51439767e2d107"}, + {file = "watchfiles-1.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e3750434c83b61abb3163b49c64b04180b85b4dabb29a294513faec57f2ffdb7"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bedf84835069f51c7b026b3ca04e2e747ea8ed0a77c72006172c72d28c9f69fc"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90004553be36427c3d06ec75b804233f8f816374165d5225b93abd94ba6e7234"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b46e15c34d4e401e976d6949ad3a74d244600d5c4b88c827a3fdf18691a46359"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:487d15927f1b0bd24e7df921913399bb1ab94424c386bea8b267754d698f8f0e"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ff236d7a3f4b0a42f699a22fc374ba526bc55048a70cbb299661158e1bb5e1f"}, + {file = "watchfiles-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c01446626574561756067f00b37e6b09c8622b0fc1e9fdbc7cbcea328d4e514"}, + {file = "watchfiles-1.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b551c465a59596f3d08170bd7e1c532c7260dd90ed8135778038e13c5d48aa81"}, + {file = "watchfiles-1.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1ed613ee107269f66c2df631ec0fc8efddacface85314d392a4131abe299f00"}, + {file = "watchfiles-1.0.0-cp312-none-win32.whl", hash = "sha256:5f75cd42e7e2254117cf37ff0e68c5b3f36c14543756b2da621408349bd9ca7c"}, + {file = "watchfiles-1.0.0-cp312-none-win_amd64.whl", hash = "sha256:cf517701a4a872417f4e02a136e929537743461f9ec6cdb8184d9a04f4843545"}, + {file = "watchfiles-1.0.0-cp312-none-win_arm64.whl", hash = "sha256:8a2127cd68950787ee36753e6d401c8ea368f73beaeb8e54df5516a06d1ecd82"}, + {file = "watchfiles-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:95de85c254f7fe8cbdf104731f7f87f7f73ae229493bebca3722583160e6b152"}, + {file = "watchfiles-1.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:533a7cbfe700e09780bb31c06189e39c65f06c7f447326fee707fd02f9a6e945"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2218e78e2c6c07b1634a550095ac2a429026b2d5cbcd49a594f893f2bb8c936"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9122b8fdadc5b341315d255ab51d04893f417df4e6c1743b0aac8bf34e96e025"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9272fdbc0e9870dac3b505bce1466d386b4d8d6d2bacf405e603108d50446940"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a3b33c3aefe9067ebd87846806cd5fc0b017ab70d628aaff077ab9abf4d06b3"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc338ce9f8846543d428260fa0f9a716626963148edc937d71055d01d81e1525"}, + {file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ac778a460ea22d63c7e6fb0bc0f5b16780ff0b128f7f06e57aaec63bd339285"}, + {file = "watchfiles-1.0.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:53ae447f06f8f29f5ab40140f19abdab822387a7c426a369eb42184b021e97eb"}, + {file = "watchfiles-1.0.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1f73c2147a453315d672c1ad907abe6d40324e34a185b51e15624bc793f93cc6"}, + {file = "watchfiles-1.0.0-cp313-none-win32.whl", hash = "sha256:eba98901a2eab909dbd79681190b9049acc650f6111fde1845484a4450761e98"}, + {file = "watchfiles-1.0.0-cp313-none-win_amd64.whl", hash = "sha256:d562a6114ddafb09c33246c6ace7effa71ca4b6a2324a47f4b09b6445ea78941"}, + {file = "watchfiles-1.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3d94fd83ed54266d789f287472269c0def9120a2022674990bd24ad989ebd7a0"}, + {file = "watchfiles-1.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48051d1c504448b2fcda71c5e6e3610ae45de6a0b8f5a43b961f250be4bdf5a8"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29cf884ad4285d23453c702ed03d689f9c0e865e3c85d20846d800d4787de00f"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d3572d4c34c4e9c33d25b3da47d9570d5122f8433b9ac6519dca49c2740d23cd"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c2696611182c85eb0e755b62b456f48debff484b7306b56f05478b843ca8ece"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:550109001920a993a4383b57229c717fa73627d2a4e8fcb7ed33c7f1cddb0c85"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b555a93c15bd2c71081922be746291d776d47521a00703163e5fbe6d2a402399"}, + {file = "watchfiles-1.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:947ccba18a38b85c366dafeac8df2f6176342d5992ca240a9d62588b214d731f"}, + {file = "watchfiles-1.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ffd98a299b0a74d1b704ef0ed959efb753e656a4e0425c14e46ae4c3cbdd2919"}, + {file = "watchfiles-1.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f8c4f3a1210ed099a99e6a710df4ff2f8069411059ffe30fa5f9467ebed1256b"}, + {file = "watchfiles-1.0.0-cp39-none-win32.whl", hash = "sha256:1e176b6b4119b3f369b2b4e003d53a226295ee862c0962e3afd5a1c15680b4e3"}, + {file = "watchfiles-1.0.0-cp39-none-win_amd64.whl", hash = "sha256:2d9c0518fabf4a3f373b0a94bb9e4ea7a1df18dec45e26a4d182aa8918dee855"}, + {file = "watchfiles-1.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f159ac795785cde4899e0afa539f4c723fb5dd336ce5605bc909d34edd00b79b"}, + {file = "watchfiles-1.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c3d258d78341d5d54c0c804a5b7faa66cd30ba50b2756a7161db07ce15363b8d"}, + {file = "watchfiles-1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bbd0311588c2de7f9ea5cf3922ccacfd0ec0c1922870a2be503cc7df1ca8be7"}, + {file = "watchfiles-1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a13ac46b545a7d0d50f7641eefe47d1597e7d1783a5d89e09d080e6dff44b0"}, + {file = "watchfiles-1.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2bca898c1dc073912d3db7fa6926cc08be9575add9e84872de2c99c688bac4e"}, + {file = "watchfiles-1.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:06d828fe2adc4ac8a64b875ca908b892a3603d596d43e18f7948f3fef5fc671c"}, + {file = "watchfiles-1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:074c7618cd6c807dc4eaa0982b4a9d3f8051cd0b72793511848fd64630174b17"}, + {file = "watchfiles-1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95dc785bc284552d044e561b8f4fe26d01ab5ca40d35852a6572d542adfeb4bc"}, + {file = "watchfiles-1.0.0.tar.gz", hash = "sha256:37566c844c9ce3b5deb964fe1a23378e575e74b114618d211fbda8f59d7b5dab"}, ] [package.dependencies] @@ -7444,81 +7145,76 @@ files = [ [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -7537,93 +7233,93 @@ h11 = ">=0.9.0,<1" [[package]] name = "yarl" -version = "1.17.2" +version = "1.18.0" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"}, - {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"}, - {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"}, - {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"}, - {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"}, - {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"}, - {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"}, - {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"}, - {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"}, - {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"}, - {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"}, - {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:792155279dc093839e43f85ff7b9b6493a8eaa0af1f94f1f9c6e8f4de8c63500"}, - {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38bc4ed5cae853409cb193c87c86cd0bc8d3a70fd2268a9807217b9176093ac6"}, - {file = "yarl-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a8c83f6fcdc327783bdc737e8e45b2e909b7bd108c4da1892d3bc59c04a6d84"}, - {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6d5fed96f0646bfdf698b0a1cebf32b8aae6892d1bec0c5d2d6e2df44e1e2d"}, - {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:782ca9c58f5c491c7afa55518542b2b005caedaf4685ec814fadfcee51f02493"}, - {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff6af03cac0d1a4c3c19e5dcc4c05252411bf44ccaa2485e20d0a7c77892ab6e"}, - {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f47930fbbed0f6377639503848134c4aa25426b08778d641491131351c2c8"}, - {file = "yarl-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1fa68a3c921365c5745b4bd3af6221ae1f0ea1bf04b69e94eda60e57958907f"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:187df91395c11e9f9dc69b38d12406df85aa5865f1766a47907b1cc9855b6303"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:93d1c8cc5bf5df401015c5e2a3ce75a5254a9839e5039c881365d2a9dcfc6dc2"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11d86c6145ac5c706c53d484784cf504d7d10fa407cb73b9d20f09ff986059ef"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c42774d1d1508ec48c3ed29e7b110e33f5e74a20957ea16197dbcce8be6b52ba"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8e589379ef0407b10bed16cc26e7392ef8f86961a706ade0a22309a45414d7"}, - {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1056cadd5e850a1c026f28e0704ab0a94daaa8f887ece8dfed30f88befb87bb0"}, - {file = "yarl-1.17.2-cp311-cp311-win32.whl", hash = "sha256:be4c7b1c49d9917c6e95258d3d07f43cfba2c69a6929816e77daf322aaba6628"}, - {file = "yarl-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:ac8eda86cc75859093e9ce390d423aba968f50cf0e481e6c7d7d63f90bae5c9c"}, - {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd90238d3a77a0e07d4d6ffdebc0c21a9787c5953a508a2231b5f191455f31e9"}, - {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c74f0b0472ac40b04e6d28532f55cac8090e34c3e81f118d12843e6df14d0909"}, - {file = "yarl-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d486ddcaca8c68455aa01cf53d28d413fb41a35afc9f6594a730c9779545876"}, - {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25b7e93f5414b9a983e1a6c1820142c13e1782cc9ed354c25e933aebe97fcf2"}, - {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a0baff7827a632204060f48dca9e63fbd6a5a0b8790c1a2adfb25dc2c9c0d50"}, - {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:460024cacfc3246cc4d9f47a7fc860e4fcea7d1dc651e1256510d8c3c9c7cde0"}, - {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5870d620b23b956f72bafed6a0ba9a62edb5f2ef78a8849b7615bd9433384171"}, - {file = "yarl-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2941756754a10e799e5b87e2319bbec481ed0957421fba0e7b9fb1c11e40509f"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9611b83810a74a46be88847e0ea616794c406dbcb4e25405e52bff8f4bee2d0a"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cd7e35818d2328b679a13268d9ea505c85cd773572ebb7a0da7ccbca77b6a52e"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6b981316fcd940f085f646b822c2ff2b8b813cbd61281acad229ea3cbaabeb6b"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:688058e89f512fb7541cb85c2f149c292d3fa22f981d5a5453b40c5da49eb9e8"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56afb44a12b0864d17b597210d63a5b88915d680f6484d8d202ed68ade38673d"}, - {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:17931dfbb84ae18b287279c1f92b76a3abcd9a49cd69b92e946035cff06bcd20"}, - {file = "yarl-1.17.2-cp312-cp312-win32.whl", hash = "sha256:ff8d95e06546c3a8c188f68040e9d0360feb67ba8498baf018918f669f7bc39b"}, - {file = "yarl-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:4c840cc11163d3c01a9d8aad227683c48cd3e5be5a785921bcc2a8b4b758c4f3"}, - {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3294f787a437cb5d81846de3a6697f0c35ecff37a932d73b1fe62490bef69211"}, - {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1e7fedb09c059efee2533119666ca7e1a2610072076926fa028c2ba5dfeb78c"}, - {file = "yarl-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da9d3061e61e5ae3f753654813bc1cd1c70e02fb72cf871bd6daf78443e9e2b1"}, - {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91c012dceadc695ccf69301bfdccd1fc4472ad714fe2dd3c5ab4d2046afddf29"}, - {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f11fd61d72d93ac23718d393d2a64469af40be2116b24da0a4ca6922df26807e"}, - {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46c465ad06971abcf46dd532f77560181387b4eea59084434bdff97524444032"}, - {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef6eee1a61638d29cd7c85f7fd3ac7b22b4c0fabc8fd00a712b727a3e73b0685"}, - {file = "yarl-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4434b739a8a101a837caeaa0137e0e38cb4ea561f39cb8960f3b1e7f4967a3fc"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:752485cbbb50c1e20908450ff4f94217acba9358ebdce0d8106510859d6eb19a"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:17791acaa0c0f89323c57da7b9a79f2174e26d5debbc8c02d84ebd80c2b7bff8"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5c6ea72fe619fee5e6b5d4040a451d45d8175f560b11b3d3e044cd24b2720526"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db5ac3871ed76340210fe028f535392f097fb31b875354bcb69162bba2632ef4"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7a1606ba68e311576bcb1672b2a1543417e7e0aa4c85e9e718ba6466952476c0"}, - {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9bc27dd5cfdbe3dc7f381b05e6260ca6da41931a6e582267d5ca540270afeeb2"}, - {file = "yarl-1.17.2-cp313-cp313-win32.whl", hash = "sha256:52492b87d5877ec405542f43cd3da80bdcb2d0c2fbc73236526e5f2c28e6db28"}, - {file = "yarl-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e1bf59e035534ba4077f5361d8d5d9194149f9ed4f823d1ee29ef3e8964ace3"}, - {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c556fbc6820b6e2cda1ca675c5fa5589cf188f8da6b33e9fc05b002e603e44fa"}, - {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f44a4247461965fed18b2573f3a9eb5e2c3cad225201ee858726cde610daca"}, - {file = "yarl-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a3ede8c248f36b60227eb777eac1dbc2f1022dc4d741b177c4379ca8e75571a"}, - {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2654caaf5584449d49c94a6b382b3cb4a246c090e72453493ea168b931206a4d"}, - {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d41c684f286ce41fa05ab6af70f32d6da1b6f0457459a56cf9e393c1c0b2217"}, - {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2270d590997445a0dc29afa92e5534bfea76ba3aea026289e811bf9ed4b65a7f"}, - {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18662443c6c3707e2fc7fad184b4dc32dd428710bbe72e1bce7fe1988d4aa654"}, - {file = "yarl-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75ac158560dec3ed72f6d604c81090ec44529cfb8169b05ae6fcb3e986b325d9"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1fee66b32e79264f428dc8da18396ad59cc48eef3c9c13844adec890cd339db5"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:585ce7cd97be8f538345de47b279b879e091c8b86d9dbc6d98a96a7ad78876a3"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c019abc2eca67dfa4d8fb72ba924871d764ec3c92b86d5b53b405ad3d6aa56b0"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c6e659b9a24d145e271c2faf3fa6dd1fcb3e5d3f4e17273d9e0350b6ab0fe6e2"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d17832ba39374134c10e82d137e372b5f7478c4cceeb19d02ae3e3d1daed8721"}, - {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bc3003710e335e3f842ae3fd78efa55f11a863a89a72e9a07da214db3bf7e1f8"}, - {file = "yarl-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f5ffc6b7ace5b22d9e73b2a4c7305740a339fbd55301d52735f73e21d9eb3130"}, - {file = "yarl-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:48e424347a45568413deec6f6ee2d720de2cc0385019bedf44cd93e8638aa0ed"}, - {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"}, - {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:074fee89caab89a97e18ef5f29060ef61ba3cae6cd77673acc54bfdd3214b7b7"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b026cf2c32daf48d90c0c4e406815c3f8f4cfe0c6dfccb094a9add1ff6a0e41a"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae38bd86eae3ba3d2ce5636cc9e23c80c9db2e9cb557e40b98153ed102b5a736"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:685cc37f3f307c6a8e879986c6d85328f4c637f002e219f50e2ef66f7e062c1d"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8254dbfce84ee5d1e81051ee7a0f1536c108ba294c0fdb5933476398df0654f3"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20de4a8b04de70c49698dc2390b7fd2d18d424d3b876371f9b775e2b462d4b41"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0a2074a37285570d54b55820687de3d2f2b9ecf1b714e482e48c9e7c0402038"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f576ed278860df2721a5d57da3381040176ef1d07def9688a385c8330db61a1"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3a3709450a574d61be6ac53d582496014342ea34876af8dc17cc16da32826c9a"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bd80ed29761490c622edde5dd70537ca8c992c2952eb62ed46984f8eff66d6e8"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:32141e13a1d5a48525e519c9197d3f4d9744d818d5c7d6547524cc9eccc8971e"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8b8d3e4e014fb4274f1c5bf61511d2199e263909fb0b8bda2a7428b0894e8dc6"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:701bb4a8f4de191c8c0cc9a1e6d5142f4df880e9d1210e333b829ca9425570ed"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a45d94075ac0647621eaaf693c8751813a3eccac455d423f473ffed38c8ac5c9"}, + {file = "yarl-1.18.0-cp310-cp310-win32.whl", hash = "sha256:34176bfb082add67cb2a20abd85854165540891147f88b687a5ed0dc225750a0"}, + {file = "yarl-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:73553bbeea7d6ec88c08ad8027f4e992798f0abc459361bf06641c71972794dc"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc"}, + {file = "yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716"}, + {file = "yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, + {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, + {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af"}, + {file = "yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88"}, + {file = "yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fa2c9cb607e0f660d48c54a63de7a9b36fef62f6b8bd50ff592ce1137e73ac7d"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0f4808644baf0a434a3442df5e0bedf8d05208f0719cedcd499e168b23bfdc4"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7db9584235895a1dffca17e1c634b13870852094f6389b68dcc6338086aa7b08"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:309f8d27d6f93ceeeb80aa6980e883aa57895270f7f41842b92247e65d7aeddf"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:609ffd44fed2ed88d9b4ef62ee860cf86446cf066333ad4ce4123505b819e581"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f172b8b2c72a13a06ea49225a9c47079549036ad1b34afa12d5491b881f5b993"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89ae7de94631b60d468412c18290d358a9d805182373d804ec839978b120422"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:466d31fd043ef9af822ee3f1df8fdff4e8c199a7f4012c2642006af240eade17"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7609b8462351c4836b3edce4201acb6dd46187b207c589b30a87ffd1813b48dc"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d9d4f5e471e8dc49b593a80766c2328257e405f943c56a3dc985c125732bc4cf"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:67b336c15e564d76869c9a21316f90edf546809a5796a083b8f57c845056bc01"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b212452b80cae26cb767aa045b051740e464c5129b7bd739c58fbb7deb339e7b"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:38b39b7b3e692b6c92b986b00137a3891eddb66311b229d1940dcbd4f025083c"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ee6884a8848792d58b854946b685521f41d8871afa65e0d4a774954e9c9e89"}, + {file = "yarl-1.18.0-cp39-cp39-win32.whl", hash = "sha256:b4095c5019bb889aa866bf12ed4c85c0daea5aafcb7c20d1519f02a1e738f07f"}, + {file = "yarl-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:2d90f2e4d16a5b0915ee065218b435d2ef619dd228973b1b47d262a6f7cd8fa5"}, + {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, + {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, ] [package.dependencies] @@ -7634,4 +7330,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "492a583cef90f1f859ccf8143b4e188afecb3f2c9e0161fe328fb7dda562f604" +content-hash = "f4a45fa6e7137024c241ae0efb6bc8cb72ec42277cc29ee94f9d95e4e10b2932" diff --git a/apps/chatbot/pyproject.toml b/apps/chatbot/pyproject.toml index b9f86cad73..fc09de7619 100644 --- a/apps/chatbot/pyproject.toml +++ b/apps/chatbot/pyproject.toml @@ -2,7 +2,7 @@ name = "chatbot" version = "0.1.0" description = "Chatbot repository for PagoPA" -authors = ["Marco Cirillo "] +authors = ["Marco Domenico Cirillo ", "Devis Battisti "] readme = "README.md" package-mode = false @@ -35,13 +35,13 @@ google-generativeai = "^0.5.2" llama-index-embeddings-gemini = "^0.2.0" llama-index-llms-bedrock-converse = "^0.3.0" llama-index-postprocessor-presidio = "^0.2.0" +langfuse = "^2.53.9" [tool.poetry.group.test.dependencies] httpx = "^0.27.2" pytest = "^8.3.3" [tool.poetry.group.dev.dependencies] -gradio = "^4.36.1" jupyter = "^1.0.0" [build-system] diff --git a/apps/chatbot/scripts/dynamodb-create-table-queries-local.sh b/apps/chatbot/scripts/dynamodb-create-table-queries-local.sh deleted file mode 100755 index d9d351cae4..0000000000 --- a/apps/chatbot/scripts/dynamodb-create-table-queries-local.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -aws dynamodb create-table \ - --table-name chatbot-local-queries \ - --key-schema \ - AttributeName=sessionId,KeyType=HASH \ - AttributeName=id,KeyType=RANGE \ - --attribute-definitions \ - AttributeName=id,AttributeType=S \ - AttributeName=sessionId,AttributeType=S \ - AttributeName=createdAt,AttributeType=S \ - --local-secondary-indexes '[ - { - "IndexName": "QueriesByCreatedAtIndex", - "KeySchema": [ - { - "AttributeName": "sessionId", - "KeyType": "HASH" - }, - { - "AttributeName": "createdAt", - "KeyType": "RANGE" - } - ], - "Projection": { - "ProjectionType": "ALL" - } - } - ]' \ - --table-class STANDARD \ - --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ - --endpoint-url http://localhost:8000 \ - --region eu-south-1 \ - --profile dummy diff --git a/apps/chatbot/scripts/dynamodb-create-table-sessions-local.sh b/apps/chatbot/scripts/dynamodb-create-table-sessions-local.sh deleted file mode 100755 index 52ff0505f4..0000000000 --- a/apps/chatbot/scripts/dynamodb-create-table-sessions-local.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -aws dynamodb create-table \ - --table-name chatbot-local-sessions \ - --key-schema \ - AttributeName=userId,KeyType=HASH \ - AttributeName=id,KeyType=RANGE \ - --attribute-definitions \ - AttributeName=id,AttributeType=S \ - AttributeName=userId,AttributeType=S \ - AttributeName=createdAt,AttributeType=S \ - --local-secondary-indexes '[ - { - "IndexName": "SessionsByCreatedAtIndex", - "KeySchema": [ - { - "AttributeName": "userId", - "KeyType": "HASH" - }, - { - "AttributeName": "createdAt", - "KeyType": "RANGE" - } - ], - "Projection": { - "ProjectionType": "ALL" - } - } - ]' \ - --table-class STANDARD \ - --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ - --endpoint-url http://localhost:8000 \ - --region eu-south-1 \ - --profile dummy diff --git a/apps/chatbot/scripts/dynamodb-init.sh b/apps/chatbot/scripts/dynamodb-init.sh index 6403db6937..2f2c521364 100755 --- a/apps/chatbot/scripts/dynamodb-init.sh +++ b/apps/chatbot/scripts/dynamodb-init.sh @@ -9,12 +9,11 @@ aws dynamodb create-table \ --cli-input-json file://./docker/files/dynamodb_schemas/queries.json \ --region eu-south-1 -aws dynamodb scan \ - --table-name chatbot-local-sessions \ - --endpoint-url http://dynamodb:8000 \ - --region eu-south-1 +aws dynamodb create-table \ +--endpoint-url http://dynamodb:8000 \ +--cli-input-json file://./docker/files/dynamodb_schemas/salts.json \ +--region eu-south-1 -aws dynamodb scan \ - --table-name chatbot-local-queries \ +aws dynamodb list-tables \ --endpoint-url http://dynamodb:8000 \ --region eu-south-1 diff --git a/apps/chatbot/scripts/run.local.sh b/apps/chatbot/scripts/run.local.sh index 8d39c6a4d5..95bab83f65 100755 --- a/apps/chatbot/scripts/run.local.sh +++ b/apps/chatbot/scripts/run.local.sh @@ -3,8 +3,8 @@ echo '-=-=-=-=-=-=-=-=-= init DynamoDB -==-=-=-=-=-=-=-=-' ./scripts/dynamodb-init.sh -echo '-=-=-=-=-=-=-= create redis index =-=-=-=-=-=-=-=-' -./scripts/create_redis_index.sh +#echo '-=-=-=-=-=-=-= create redis index =-=-=-=-=-=-=-=-' +#./scripts/create_redis_index.sh echo '-=-=-=-=-=-=-=-=-= run FastAPI =-==-=-=-=-=-=-=-=-' fastapi dev src/app/main.py --port 8080 --host 0.0.0.0 diff --git a/apps/chatbot/src/app/api.md b/apps/chatbot/src/app/api.md index c0a5543728..56f560f337 100644 --- a/apps/chatbot/src/app/api.md +++ b/apps/chatbot/src/app/api.md @@ -1,87 +1,94 @@ -POST /queries -{ - "sessionId": string, - "question": string, - "queriedAt": string -} +### POST /queries + + { + "sessionId": string, + "question": string, + "queriedAt": string + } response: -{ - "id": string, - "sessionId": string, - "question": string, - "answer": string, - "createdAt": string, - "queriedAt": string -} ---------------------------------------------- + { + "id": string, + "sessionId": string, + "question": string, + "answer": string, + "createdAt": string, + "queriedAt": string + } + +--- -GET /healthz +### GET /healthz response: -{ - "message": "OK" -} ---------------------------------------------- + { + "message": "OK" + } + +--- -GET /queries/{id} +### GET /queries/{id} response: -{ - "id": string, - "sessionId": string, - "question": string, - "answer": string, - "createdAt": string, - "queriedAt": string -} ---------------------------------------------- + { + "id": string, + "sessionId": string, + "question": string, + "answer": string, + "createdAt": string, + "queriedAt": string + } -GET /sessions +--- + +### GET /sessions response: -[ - { - "id": string, - "title": string, - "createdAt": string - } -] ---------------------------------------------- + [ + { + "id": string, + "title": string, + "createdAt": string + } + ] + +--- -POST /sessions +### POST /sessions response: -{ - "id": string, - "title": string, - "createdAt": string -} ---------------------------------------------- + { + "id": string, + "title": string, + "createdAt": string + } -GET /queries?sessionId={sessionId} +--- + +### GET /queries?sessionId={sessionId} response: -[ - { - "id": string, - "sessionId": string, - "question": string, - "answer": string, - "createdAt": string, - "queriedAt": string - } -] - ---------------------------------------------- - -PATCH /queries/{id} - -{ - "badAnswer": boolean -} + + [ + { + "id": string, + "sessionId": string, + "question": string, + "answer": string, + "createdAt": string, + "queriedAt": string + } + ] + +--- + +### PATCH /queries/{id} + + { + "badAnswer": boolean + } diff --git a/apps/chatbot/src/app/main.py b/apps/chatbot/src/app/main.py index 3a6b54329c..8d64f18290 100644 --- a/apps/chatbot/src/app/main.py +++ b/apps/chatbot/src/app/main.py @@ -1,8 +1,10 @@ +import os import yaml import mangum import uvicorn +import logging import json -import os +import hashlib import uuid import boto3 import datetime @@ -16,6 +18,7 @@ from src.modules.chatbot import Chatbot +logging.basicConfig(level=logging.INFO) params = yaml.safe_load(open("config/params.yaml", "r")) prompts = yaml.safe_load(open("config/prompts.yaml", "r")) AWS_DEFAULT_REGION = os.getenv('CHB_AWS_DEFAULT_REGION', os.getenv('AWS_DEFAULT_REGION', None)) @@ -58,6 +61,9 @@ class QueryFeedback(BaseModel): table_sessions = dynamodb.Table( f"{os.getenv('CHB_QUERY_TABLE_PREFIX', 'chatbot')}-sessions" ) +table_salts = dynamodb.Table( + f"{os.getenv('CHB_QUERY_TABLE_PREFIX', 'chatbot')}-salts" +) app = FastAPI() app.add_middleware( @@ -68,6 +74,10 @@ class QueryFeedback(BaseModel): allow_headers=["*"], ) +def hash_func(user_id: str, salt: str) -> str: + salted_user_id = user_id + salt + return hashlib.sha256(salted_user_id.encode()).hexdigest() + @app.get("/healthz") async def healthz (): return {"message": "OK"} @@ -78,11 +88,17 @@ async def query_creation ( authorization: Annotated[str | None, Header()] = None ): now = datetime.datetime.now(datetime.UTC) + trace_id = str(uuid.uuid4()) userId = current_user_id(authorization) session = find_or_create_session(userId, now=now) + salt = session_salt(session['id']) + answer = chatbot.chat_generate( query_str = query.question, - messages = [item.dict() for item in query.history] if query.history else None + messages = [item.dict() for item in query.history] if query.history else None, + trace_id = trace_id, + user_id = hash_func(userId, salt), + session_id = session["id"] ) @@ -92,7 +108,7 @@ async def query_creation ( queriedAt = query.queriedAt bodyToReturn = { - "id": f'{uuid.uuid4()}', + "id": trace_id, "sessionId": session['id'], "question": query.question, "answer": answer, @@ -111,7 +127,7 @@ async def query_creation ( return bodyToReturn -def current_user_id(authorization: str): +def current_user_id(authorization: str) -> str: if authorization is None: # TODO remove fake user and return None # return None @@ -155,7 +171,7 @@ def find_or_create_session(userId: str, now: datetime.datetime): "createdAt": now.isoformat() } try: - table_sessions.put_item(Item = body) + create_session_record(body) except (BotoCoreError, ClientError) as e: raise HTTPException(status_code=422, detail=f"[find_or_create_session] body: {body}, error: {e}") @@ -164,6 +180,30 @@ def find_or_create_session(userId: str, now: datetime.datetime): return body +def create_session_record(body: dict): + saltValue = str(uuid.uuid4()) + saltBody = { + 'sessionId': body['id'], + 'value': saltValue + } + # TODO: transaction https://github.com/boto/boto3/pull/4010 + table_sessions.put_item(Item = body) + table_salts.put_item(Item = saltBody) + +def session_salt(sessionId: str): + try: + dbResponse = table_salts.query( + KeyConditionExpression=Key("sessionId").eq(sessionId) + ) + except (BotoCoreError, ClientError) as e: + raise HTTPException(status_code=422, detail=f"[salts_fetching] sessionId: {sessionId}, error: {e}") + result = dbResponse.get('Items', []) + if len(result) == 0: + result = None + else: + result = result[0] + return result.get('value', None) + @app.get("/queries") async def queries_fetching( @@ -235,7 +275,7 @@ async def session_delete( KeyConditionExpression=Key("sessionId").eq(id) ) # TODO: use batch writer -# with table_sessions.batch_writer() as batch: + # with table_sessions.batch_writer() as batch: for query in dbResponse_queries['Items']: table_queries.delete_item( Key={ @@ -290,6 +330,14 @@ async def query_feedback ( }, ReturnValues='ALL_NEW' ) + + chatbot.add_langfuse_score( + trace_id = id, + name = 'user-feedback', + value = (-1 if query.badAnswer else 1), + data_type = 'NUMERIC' + ) + except (BotoCoreError, ClientError) as e: raise HTTPException(status_code=422, detail=f"[query_feedback] id: {id}, sessionId: {sessionId}, error: {e}") diff --git a/apps/chatbot/src/modules/chatbot.py b/apps/chatbot/src/modules/chatbot.py index 2a29d56fcb..7cd0d67ad3 100644 --- a/apps/chatbot/src/modules/chatbot.py +++ b/apps/chatbot/src/modules/chatbot.py @@ -1,55 +1,72 @@ import os import re -import logging -# import nest_asyncio -from typing import Union, Tuple, Optional, List +import yaml +import uuid +from pathlib import Path +from datetime import datetime +from logging import getLogger +from typing import Union, Tuple, Sequence, Optional, List, Any, Dict, Literal from llama_index.core import PromptTemplate from llama_index.core.llms import ChatMessage, MessageRole from llama_index.core.base.response.schema import Response, StreamingResponse, AsyncStreamingResponse, PydanticResponse -from llama_index.core.chat_engine.types import AgentChatResponse, StreamingAgentChatResponse +from llama_index.core.chat_engine.types import BaseChatEngine, AgentChatResponse, StreamingAgentChatResponse from llama_index.core.async_utils import asyncio_run +from langfuse import Langfuse +from langfuse.llama_index import LlamaIndexInstrumentor +from langfuse.api.resources.trace.types.traces import Traces +from langfuse.model import TraceWithFullDetails + from src.modules.models import get_llm, get_embed_model from src.modules.vector_database import load_automerging_index_redis, REDIS_KVSTORE, INDEX_ID from src.modules.engine import get_automerging_engine +from src.modules.handlers import EventHandler from src.modules.presidio import PresidioPII +from src.modules.utils import get_ssm_parameter from dotenv import load_dotenv -load_dotenv() -# nest_asyncio.apply() +load_dotenv() +logger = getLogger(__name__) +CWF = Path(__file__) +ROOT = CWF.parent.parent.parent.absolute().__str__() USE_PRESIDIO = True if (os.getenv("CHB_USE_PRESIDIO", "True")).lower() == "true" else False +USE_CHAT_ENGINE = True if (os.getenv("CHB_USE_CHAT_ENGINE", "True")).lower() == "true" else False USE_ASYNC = True if (os.getenv('CHB_ENGINE_USE_ASYNC', "True")).lower() == "true" else False USE_STREAMING = True if (os.getenv('CHB_ENGINE_USE_STREAMING', "False")).lower() == "true" else False -USE_CHAT_ENGINE = True if (os.getenv('CHB_ENGINE_USE_CHAT_ENGINE', "True")).lower() == "true" else False RESPONSE_TYPE = Union[ Response, StreamingResponse, AsyncStreamingResponse, PydanticResponse, AgentChatResponse, StreamingAgentChatResponse -] -START_CHAT_MESSAGE = [ChatMessage( - role = MessageRole.ASSISTANT, - content = ( - "Ciao! Io sono Discovery, l'assistente virtuale di PagoPA.\n" - "Rispondo solo e soltanto a domande riguardanti la documentazione di PagoPA DevPortal, " - "che puoi trovare sul sito: https://dev.developer.pagopa.it!" - ) -)] - -logging.getLogger().setLevel(os.getenv("LOG_LEVEL", "INFO")) +] +SYSTEM_PROMPT = ( + "You are the virtual PagoPA S.p.A. assistant. Your name is Discovery.\n" + "Your role is to provide accurate, professional, and helpful responses to users' queries regarding " + "the PagoPA DevPortal documentation available at: https://dev.developer.pagopa.it" +) +LANGFUSE_PUBLIC_KEY = get_ssm_parameter(os.getenv("CHB_LANGFUSE_PUBLIC_KEY"), os.getenv("LANGFUSE_INIT_PROJECT_PUBLIC_KEY")) +LANGFUSE_SECRET_KEY = get_ssm_parameter(os.getenv("CHB_LANGFUSE_SECRET_KEY"), os.getenv("LANGFUSE_INIT_PROJECT_SECRET_KEY")) +LANGFUSE_HOST = os.getenv("CHB_LANGFUSE_HOST") +LANGFUSE = Langfuse( + public_key = LANGFUSE_PUBLIC_KEY, + secret_key = LANGFUSE_SECRET_KEY, + host = LANGFUSE_HOST +) class Chatbot(): def __init__( self, - params, - prompts + params: dict | None = None, + prompts: dict | None = None, + use_chat_engine: bool | None = None ): - self.params = params - self.prompts = prompts + self.params = params if params else yaml.safe_load(open(os.path.join(ROOT, "config", "params.yaml"), "r")) + self.prompts = prompts if prompts else yaml.safe_load(open(os.path.join(ROOT, "config", "prompts.yaml"), "r")) + self.use_chat_engine = use_chat_engine if use_chat_engine else USE_CHAT_ENGINE if USE_PRESIDIO: self.pii = PresidioPII(config=params["config_presidio"]) @@ -65,17 +82,28 @@ def __init__( self.qa_prompt_tmpl, self.ref_prompt_tmpl, self.condense_prompt_tmpl = self._get_prompt_templates() self.engine = get_automerging_engine( self.index, - llm=self.model, - text_qa_template=self.qa_prompt_tmpl, - refine_template=self.ref_prompt_tmpl, - condense_template=self.condense_prompt_tmpl, - verbose=self.params["engine"]["verbose"] + llm = self.model, + text_qa_template = self.qa_prompt_tmpl, + refine_template = self.ref_prompt_tmpl, + condense_template = self.condense_prompt_tmpl, + verbose = self.params["engine"]["verbose"], + use_chat_engine = self.use_chat_engine + ) + self.system_message = ChatMessage( + role = self.model.metadata.system_role, + content = SYSTEM_PROMPT + ) if isinstance(self.engine, BaseChatEngine) else None + self.instrumentor = LlamaIndexInstrumentor( + public_key = LANGFUSE_PUBLIC_KEY, + secret_key = LANGFUSE_SECRET_KEY, + host = LANGFUSE_HOST, + mask=self._mask_trace ) + self.instrumentor._event_handler = EventHandler(langfuse_client=LANGFUSE) def _get_prompt_templates(self) -> Tuple[PromptTemplate, PromptTemplate]: - # create templates qa_prompt_tmpl = PromptTemplate( self.prompts["qa_prompt_str"], template_var_mappings={ @@ -106,18 +134,15 @@ def _get_prompt_templates(self) -> Tuple[PromptTemplate, PromptTemplate]: def _get_response_str(self, engine_response: RESPONSE_TYPE) -> str: - if USE_CHAT_ENGINE: - if isinstance(engine_response, StreamingAgentChatResponse): - response_str = "" - for token in engine_response.response_gen: - response_str += token - else: - response_str = engine_response.response + if isinstance(engine_response, StreamingAgentChatResponse): + response_str = "" + for token in engine_response.response_gen: + response_str += token + if isinstance(engine_response, AgentChatResponse): + response_str = engine_response.response else: - if isinstance(engine_response, StreamingResponse): - engine_response = engine_response.get_response() - - response_str = engine_response.response.strip() + engine_response = engine_response.get_response() + response_str = engine_response.response response_str = response_str.strip() nodes = engine_response.source_nodes @@ -137,7 +162,7 @@ def _unmask_reference(self, response_str: str, nodes) -> str: # Find all matches in the text hashed_urls = re.findall(pattern, response_str) - logging.info(f"[chatbot.py - _unmask_reference] Generated answer has {len(hashed_urls)} references taken from {len(nodes)} nodes. First node has score: {nodes[0].score:.4f}.") + logger.info(f"Generated answer has {len(hashed_urls)} references taken from {len(nodes)} nodes. First node has score: {nodes[0].score:.4f}.") for hashed_url in hashed_urls: url = REDIS_KVSTORE.get( collection=f"hash_table_{INDEX_ID}", @@ -150,8 +175,8 @@ def _unmask_reference(self, response_str: str, nodes) -> str: # remove sentences with generated masked url: {URL} parts = re.split(r"(?<=[\.\?\!\n])", response_str) - filtered_parts = [part for part in parts if "{URL}" not in part] # filter out parts containing {URL} - response_str = "".join(filtered_parts) # join the filtered parts back into a single string + filtered_parts = [part for part in parts if "{URL}" not in part] + response_str = "".join(filtered_parts) return response_str @@ -165,14 +190,14 @@ def mask_pii(self, message: str) -> str: masked_message = masked_message + "Rif:" + split_message[1] return masked_message except Exception as e: - logging.warning(f"[chatbot.py - mask_pii] exception in mask_pii: {e}") + logger.warning(f"Exception: {e}") else: return message - def _messages_to_chathistory(self, messages: Optional[List[dict]] = None) -> List[ChatMessage]: + def _messages_to_chathistory(self, messages: Optional[List[Dict[str, str]]] = None) -> List[ChatMessage]: - chat_history = [] + chat_history = [self.system_message] if messages: for message in messages: chat_history += [ @@ -182,46 +207,188 @@ def _messages_to_chathistory(self, messages: Optional[List[dict]] = None) -> Lis ), ChatMessage( role = MessageRole.ASSISTANT, - content = message["answer"] + content = message["answer"].split("Rif:")[0].strip() ) ] - - chat_history = START_CHAT_MESSAGE + chat_history return chat_history - - def generate(self, query_str: str) -> str: + + def get_trace(self, trace_id: str, as_dict: bool = False) -> TraceWithFullDetails | dict: try: - engine_response = self.engine.query(query_str) - response_str = self._get_response_str(engine_response) + trace = LANGFUSE.fetch_trace(trace_id) + trace = trace.data + except Exception as e: + logger.error(e) + + if as_dict: + return trace.dict() + else: + return trace + + def get_traces( + self, + user_id: str | None = None, + session_id: str | None = None, + from_timestamp: datetime | None = None, + to_timestamp: datetime | None = None, + order_by: str | None = None, + tags: str | Sequence[str] | None = None, + ) -> Traces: + + try: + traces = LANGFUSE.get_traces( + user_id=user_id, + session_id = session_id, + from_timestamp = from_timestamp, + to_timestamp = to_timestamp, + order_by = order_by, + tags = tags + ) except Exception as e: - response_str = "Scusa, non sono riuscito ad elaborare questa domanda.\nChiedimi un'altra domanda." - logging.info(f"[chatbot.py - generate] Exception: {e}") + logger.error(e) - return response_str + return traces - def chat_generate(self, query_str: str, messages: Optional[List[dict]] = None) -> str: + def add_langfuse_tag(self, trace_id: str, tag: str) -> None: + with self.instrumentor.observe(trace_id=trace_id) as trace: + trace_info = self.get_trace(trace_id, as_dict=False) + if tag not in trace_info.tags: + trace.update( + tags = trace_info.tags + [tag] + ) + logger.info(f"Added tag {tag} to trace {trace_id}") + else: + logger.warning(f"Tag {tag} already present in trace {trace_id}") + + + def remove_langfuse_tag(self, trace_id: str, tag: str) -> None: + with self.instrumentor.observe(trace_id=trace_id) as trace: + trace_info = self.get_trace(trace_id, as_dict=False) + if tag in trace_info.tags: + trace_info.tags.pop(trace_info.tags.index(tag)) + trace.update( + tags = trace_info.tags + ) + logger.info(f"Removed tag {tag} from trace {trace_id}") + else: + logger.warning(f"Tag {tag} not present in trace {trace_id}") + + def add_langfuse_score( + self, + trace_id: str, + name: str, + value: float, + data_type: Literal['NUMERIC', 'BOOLEAN'] | None = None + ) -> None: + + with self.instrumentor.observe(trace_id=trace_id) as trace: + trace_info = self.get_trace(trace_id, as_dict=False) + flag = True + for score in trace_info.scores: + if score.name == name: + flag = False + score_id = score.id + break + + if flag: + trace.score(name=name, value=value, data_type=data_type) + logger.warning(f"Add score {name}: {value} in trace {trace_id}") + else: + trace.score(id=score_id, name=name, value=value, data_type=data_type) + logger.warning(f"Updating score {name} to {value} in trace {trace_id}") + + + def _mask_trace(self, data: Any) -> None: + if isinstance(data, dict): + for key, value in data.items(): + + if isinstance(value, str): + data[key] = self.mask_pii(value) + + if isinstance(value, list): + for message in value: + if isinstance(message, ChatMessage): + message.content = self.mask_pii(message.content) + if isinstance(message, str): + message = self.mask_pii(message) + + if isinstance(value, dict): + for k, v in value.items(): + if isinstance(v, list): + for message in v: + if isinstance(message, ChatMessage): + message.content = self.mask_pii(message.content) + if isinstance(message, str): + message = self.mask_pii(message) + if isinstance(v, str): + value[k] = self.mask_pii(v) + + if isinstance(data, str): + data = self.mask_pii(data) + + return data + + + def chat_generate( + self, + query_str: str, + trace_id: str | None = None, + session_id: str | None = None, + user_id: str | None = None, + messages: Optional[List[Dict[str, str]]] | None = None, + tags: Optional[Union[str, List[str]]] | None = None + ) -> str: + + if isinstance(tags, str): + tags = [tags] + chat_history = self._messages_to_chathistory(messages) + + if not trace_id: + logger.debug(f"[Langfuse] Trace id not provided. Generating a new one") + trace_id = str(uuid.uuid4()) - try: - if USE_ASYNC and not USE_STREAMING: - engine_response = asyncio_run(self.engine.achat(query_str, chat_history)) - elif not USE_ASYNC and USE_STREAMING: - engine_response = self.engine.stream_chat(query_str, chat_history) - elif USE_ASYNC and USE_STREAMING: - engine_response = asyncio_run(self.engine.astream_chat(query_str, chat_history)) - else: - engine_response = self.engine.chat(query_str, chat_history) - response_str = self._get_response_str(engine_response) + logger.info(f"[Langfuse] Trace id: {trace_id}") - except Exception as e: - response_str = "Scusa, non sono riuscito ad elaborare questa domanda.\nChiedimi un'altra domanda." - logging.info(f"[chatbot.py - generate] Exception: {e}") + with self.instrumentor.observe( + trace_id = trace_id, + session_id = session_id, + user_id = user_id, + tags = tags + ) as trace: + + try: + if USE_ASYNC and not USE_STREAMING: + engine_response = asyncio_run(self.engine.achat(query_str, chat_history)) + elif not USE_ASYNC and USE_STREAMING: + engine_response = self.engine.stream_chat(query_str, chat_history) + elif USE_ASYNC and USE_STREAMING: + engine_response = asyncio_run(self.engine.astream_chat(query_str, chat_history)) + else: + engine_response = self.engine.chat(query_str, chat_history) + response_str = self._get_response_str(engine_response) + + context = "" + for node in engine_response.source_nodes: + url = REDIS_KVSTORE.get( + collection=f"hash_table_{INDEX_ID}", + key=node.metadata["filename"] + ) + context += f"URL: {url}\n\n{node.text}\n\n------------------\n\n" + + except Exception as e: + response_str = "Scusa, non posso elaborare la tua richiesta.\nProva a chierdimi una nuova domanda." + context = "" + logger.error(f"Exception: {e}") + + trace.update(output=self.mask_pii(response_str), metadata={"context": context}) + trace.score(name="user-feedback", value=0, data_type="NUMERIC") + self.instrumentor.flush() return response_str diff --git a/apps/chatbot/src/modules/create_vector_index.py b/apps/chatbot/src/modules/create_vector_index.py index 5fb0b31385..fe9767e252 100644 --- a/apps/chatbot/src/modules/create_vector_index.py +++ b/apps/chatbot/src/modules/create_vector_index.py @@ -8,8 +8,10 @@ from dotenv import load_dotenv + load_dotenv() -logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO")) +logging.basicConfig(level=logging.INFO) + DOCUMENTATION_DIR = os.getenv("CHB_DOCUMENTATION_DIR") @@ -32,4 +34,3 @@ chunk_sizes=params["vector_index"]["chunk_sizes"], chunk_overlap=params["vector_index"]["chunk_overlap"] ) - diff --git a/apps/chatbot/src/modules/engine.py b/apps/chatbot/src/modules/engine.py index 6fb199cd82..d7c54a62c5 100644 --- a/apps/chatbot/src/modules/engine.py +++ b/apps/chatbot/src/modules/engine.py @@ -3,18 +3,25 @@ from llama_index.core.llms.llm import LLM from llama_index.core.retrievers import AutoMergingRetriever from llama_index.core.query_engine import RetrieverQueryEngine -from llama_index.core.chat_engine import CondenseQuestionChatEngine +from llama_index.core.chat_engine import CondensePlusContextChatEngine from llama_index.core.postprocessor import SimilarityPostprocessor from dotenv import load_dotenv + load_dotenv() -SIMILARITY_TOPK = os.getenv('CHB_ENGINE_SIMILARITY_TOPK', "5") -SIMILARITY_CUTOFF = os.getenv('CHB_ENGINE_SIMILARITY_CUTOFF', "0.55") -USE_ASYNC = True if (os.getenv('CHB_ENGINE_USE_ASYNC', "True")).lower() == "true" else False -USE_STREAMING = True if (os.getenv('CHB_ENGINE_USE_STREAMING', "False")).lower() == "true" else False -USE_CHAT_ENGINE = True if (os.getenv('CHB_ENGINE_USE_CHAT_ENGINE', "True")).lower() == "true" else False + +USE_CHAT_ENGINE = True if (os.getenv("CHB_USE_CHAT_ENGINE", "True")).lower() == "true" else False +SIMILARITY_TOPK = os.getenv("CHB_ENGINE_SIMILARITY_TOPK", "5") +SIMILARITY_CUTOFF = os.getenv("CHB_ENGINE_SIMILARITY_CUTOFF", "0.55") +USE_ASYNC = True if (os.getenv("CHB_ENGINE_USE_ASYNC", "True")).lower() == "true" else False +USE_STREAMING = True if (os.getenv("CHB_ENGINE_USE_STREAMING", "False")).lower() == "true" else False +SYSTEM_PROMPT = ( + "You are the virtual PagoPA S.p.A. assistant. Your name is Discovery.\n" + "Your role is to provide accurate, professional, and helpful responses to users' queries regarding " + "the PagoPA DevPortal documentation available at: https://dev.developer.pagopa.it" +) def get_automerging_engine( @@ -26,10 +33,10 @@ def get_automerging_engine( condense_template: PromptTemplate | None = None, verbose: bool = True, use_chat_engine: bool | None = None - ) -> (RetrieverQueryEngine | CondenseQuestionChatEngine): + ) -> (RetrieverQueryEngine | CondensePlusContextChatEngine): - if use_chat_engine is None: - use_chat_engine = USE_CHAT_ENGINE + + use_chat_engine = use_chat_engine if use_chat_engine else USE_CHAT_ENGINE base_retriever = index.as_retriever( similarity_top_k=int(SIMILARITY_TOPK) @@ -43,23 +50,23 @@ def get_automerging_engine( similarity_cutoff=float(SIMILARITY_CUTOFF) ) - automerging_engine = RetrieverQueryEngine.from_args( + if use_chat_engine: + return CondensePlusContextChatEngine.from_defaults( + retriever = retriever, + llm = llm, + context_prompt = text_qa_template, + context_refine_prompt = refine_template, + condense_prompt = condense_template, + node_postprocessors = [similarity_postprocessor] + ) + else: + return RetrieverQueryEngine.from_args( retriever, - llm=llm, - response_mode=response_mode, - node_postprocessors=[ - similarity_postprocessor - ], - text_qa_template=text_qa_template, - refine_template=refine_template, - use_async=USE_ASYNC, - streaming=USE_STREAMING + llm = llm, + response_mode = response_mode, + node_postprocessors = [similarity_postprocessor], + text_qa_template = text_qa_template, + refine_template = refine_template, + use_async = USE_ASYNC, + streaming = USE_STREAMING ) - - if use_chat_engine: - automerging_engine = CondenseQuestionChatEngine.from_defaults( - query_engine = automerging_engine, - condense_question_prompt = condense_template - ) - - return automerging_engine \ No newline at end of file diff --git a/apps/chatbot/src/modules/evaluation.py b/apps/chatbot/src/modules/evaluation.py index 68aa118f14..9e0278933b 100644 --- a/apps/chatbot/src/modules/evaluation.py +++ b/apps/chatbot/src/modules/evaluation.py @@ -3,9 +3,8 @@ import json import yaml import datetime -import logging +from logging import getLogger import asyncio -import nest_asyncio from typing import Any import pandas as pd @@ -19,14 +18,13 @@ ContextRelevancyEvaluator ) from llama_index.core.evaluation.base import BaseEvaluator, EvaluationResult -from llama_index.core.evaluation.eval_utils import aget_responses +from llama_index.core.evaluation.eval_utils import get_responses from src.modules.chatbot import Chatbot from src.modules.models import get_llm -nest_asyncio.apply() -logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO")) +logger = getLogger(__name__) def parser_function(output_str: str): @@ -160,7 +158,7 @@ def table_results(responses, eval_results): params = yaml.safe_load(open("config/params.yaml", "r")) prompts = yaml.safe_load(open("config/prompts.yaml", "r")) eval_prompts = yaml.safe_load(open("config/eval_prompts.yaml", "r")) - bot = Chatbot(params, prompts) + bot = Chatbot(params, prompts, use_chat_engine=False) eval_model = get_llm() # load FAQs @@ -192,18 +190,18 @@ def table_results(responses, eval_results): batch_runner = BatchEvalRunner(evaluator_dict, workers=12, show_progress=True) # get predition responses - pred_responses = asyncio.run(aget_responses(questions, bot.engine._query_engine, show_progress=True)) + pred_responses = get_responses(questions, bot.engine, show_progress=True) for i, pr in enumerate(pred_responses): after = bot._get_response_str(pr) pred_responses[i].response = after # get evaluation results - eval_results = asyncio.run(batch_runner.aevaluate_responses( + eval_results = batch_runner.evaluate_responses( questions, responses=pred_responses, reference=ref_responses - )) + ) # save results now = datetime.datetime.now() @@ -224,4 +222,4 @@ def table_results(responses, eval_results): ) with open(os.path.join(results_dir, "avg_scores.json"), "w") as f: json.dump(avg_scores, f, indent=4) - logging.info(f"Results stored in {results_dir}") \ No newline at end of file + logger.info(f"Results stored in {results_dir}") \ No newline at end of file diff --git a/apps/chatbot/src/modules/handlers.py b/apps/chatbot/src/modules/handlers.py new file mode 100644 index 0000000000..5a3910c50f --- /dev/null +++ b/apps/chatbot/src/modules/handlers.py @@ -0,0 +1,259 @@ +import os +from typing import Optional, Any, Union, Mapping + +from langfuse.client import ( + Langfuse, + StatefulGenerationClient, + StateType, +) +from langfuse.utils import _get_timestamp +from langfuse.model import ModelUsage +from langfuse.llama_index._context import InstrumentorContext +from uuid import uuid4 as create_uuid + +try: + from llama_index.core.base.llms.types import ( + ChatResponse, + CompletionResponse, + ) + from llama_index.core.instrumentation.events import BaseEvent + from llama_index.core.instrumentation.events.embedding import ( + EmbeddingStartEvent, + EmbeddingEndEvent, + ) + from llama_index.core.instrumentation.event_handlers import BaseEventHandler + from llama_index.core.instrumentation.events.llm import ( + LLMCompletionEndEvent, + LLMCompletionStartEvent, + LLMChatEndEvent, + LLMChatStartEvent, + ) + from llama_index.core.utilities.token_counting import TokenCounter + +except ImportError: + raise ModuleNotFoundError( + "Please install llama-index to use the Langfuse llama-index integration: 'pip install llama-index'" + ) + +from logging import getLogger +from dotenv import load_dotenv + + +load_dotenv() +logger = getLogger(__name__) + + +MODEL_ID = os.getenv("CHB_MODEL_ID") +EMBED_MODEL_ID = os.getenv("CHB_EMBED_MODEL_ID") +LLMS_COST = { + "mistral.mistral-large-2402-v1:0": {"input_cost": 0.0052 * 1.e-3, "output_cost": 0.0156 * 1.e-3}, + "models/gemini-1.5-flash": {"input_cost": 0.075 * 1.e-6, "output_cost": 0.30 * 1.e-6} +} +EMBEDDERS_COST = { + "cohere.embed-multilingual-v3": 0.0001 * 1.e-3, + "models/models/text-embedding-004": 0 +} + + +class EventHandler(BaseEventHandler, extra="allow"): + def __init__(self, *, langfuse_client: Langfuse): + super().__init__() + + self._langfuse = langfuse_client + self._token_counter = TokenCounter() + self._context = InstrumentorContext() + + @classmethod + def class_name(cls) -> str: + """Class name.""" + return "EventHandler" + + def handle(self, event: BaseEvent) -> None: + logger.debug(f"Event {type(event).__name__} received: {event}") + + if isinstance( + event, (LLMCompletionStartEvent, LLMChatStartEvent, EmbeddingStartEvent) + ): + self.update_generation_from_start_event(event) + elif isinstance( + event, (LLMCompletionEndEvent, LLMChatEndEvent, EmbeddingEndEvent) + ): + self.update_generation_from_end_event(event) + + def update_generation_from_start_event( + self, + event: Union[LLMCompletionStartEvent, LLMChatStartEvent, EmbeddingStartEvent], + ) -> None: + if event.span_id is None: + logger.warning("Span ID is not set") + return + + model_data = event.model_dict + model = model_data.pop("model", None) or model_data.pop("model_name", None) + traced_model_data = { + k: str(v) + for k, v in model_data.items() + if v is not None + and k + in [ + "max_tokens", + "max_retries", + "temperature", + "timeout", + "strict", + "top_logprobs", + "logprobs", + "embed_batch_size", + ] + } + + self._get_generation_client(event.span_id).update( + model=model, model_parameters=traced_model_data + ) + + def update_generation_from_end_event( + self, event: Union[LLMCompletionEndEvent, LLMChatEndEvent, EmbeddingEndEvent] + ) -> None: + if event.span_id is None: + logger.warning("Span ID is not set") + return + + usage = None + + if isinstance(event, (LLMCompletionEndEvent, LLMChatEndEvent)): + if event.response: + usage = self._parse_token_usage(event.response) if event.response else None + logger.info(f"[{MODEL_ID}] Input Tokens: {usage["input"]}") + logger.info(f"[{MODEL_ID}] Output Tokens: {usage["output"]}") + + if isinstance(event, EmbeddingEndEvent): + token_count = sum( + self._token_counter.get_string_tokens(chunk) for chunk in event.chunks + ) + usage = { + "input": 0, + "output": 0, + "total": token_count or 0, + "total_cost": token_count * EMBEDDERS_COST[EMBED_MODEL_ID] if MODEL_ID in LLMS_COST.keys() else 0 + } + logger.info(f"[{EMBED_MODEL_ID}] Embedding Tokens: {usage["total"]}") + + self._get_generation_client(event.span_id).update( + usage=usage, end_time=_get_timestamp() + ) + + + def _parse_token_usage( + self, response: Union[ChatResponse, CompletionResponse] + ) -> Optional[ModelUsage]: + if ( + (raw := getattr(response, "raw", None)) + and hasattr(raw, "get") + ) and ( + (usage := raw.get("usage")) + or (usage := raw.get("usage_metadata")) + ): + return _parse_usage_from_mapping(usage) + + if additional_kwargs := getattr(response, "additional_kwargs", None): + return _parse_usage_from_mapping(additional_kwargs) + + def _get_generation_client(self, id: str) -> StatefulGenerationClient: + trace_id = self._context.trace_id + if trace_id is None: + logger.warning( + "Trace ID is not set. Creating generation client with new trace id." + ) + trace_id = str(create_uuid()) + + return StatefulGenerationClient( + client=self._langfuse.client, + id=id, + trace_id=trace_id, + task_manager=self._langfuse.task_manager, + state_type=StateType.OBSERVATION, + ) + + +def _parse_usage_from_mapping( + usage: Union[object, Mapping[str, Any]], +) -> ModelUsage: + if isinstance(usage, Mapping): + return _get_token_counts_from_mapping(usage) + + return _parse_usage_from_object(usage) + + +def _parse_usage_from_object(usage: object) -> ModelUsage: + model_usage: ModelUsage = { + "unit": None, + "input": None, + "output": None, + "total": None, + "input_cost": None, + "output_cost": None, + "total_cost": None, + } + + if ( + (prompt_tokens := getattr(usage, "prompt_tokens", None)) is not None # openai + or (prompt_tokens := getattr(usage, "inputTokens", None)) is not None # bedrock + or (prompt_tokens := getattr(usage, "prompt_token_count", None)) is not None # gemini + ): + model_usage["input"] = prompt_tokens + model_usage["input_cost"] = prompt_tokens * LLMS_COST[MODEL_ID]["input_cost"] if MODEL_ID in LLMS_COST.keys() else 0 + + if ( + (completion_tokens := getattr(usage, "completion_tokens", None)) is not None # openai + or (completion_tokens := getattr(usage, "outputTokens", None)) is not None # bedrock + or (completion_tokens := getattr(usage, "candidates_token_count", None)) is not None # gemini + ): + model_usage["output"] = completion_tokens + model_usage["output_cost"] = completion_tokens * LLMS_COST[MODEL_ID]["input_cost"] if MODEL_ID in LLMS_COST.keys() else 0 + if ( + (total_tokens := getattr(usage, "total_tokens", None)) is not None # openai + or (total_tokens := getattr(usage, "totalTokens", None)) is not None # bedrock + or (total_tokens := getattr(usage, "total_token_count", None)) is not None # gemini + ): + model_usage["total"] = total_tokens + model_usage["total_cost"] = model_usage["input_cost"] + model_usage["output_cost"] + + return model_usage + + +def _get_token_counts_from_mapping( + usage_mapping: Mapping[str, Any], +) -> ModelUsage: + model_usage: ModelUsage = { + "unit": "TOKENS", + "input": None, + "output": None, + "total": None, + "input_cost": None, + "output_cost": None, + "total_cost": None, + } + if ( + (prompt_tokens := usage_mapping.get("prompt_tokens")) is not None # openai + or (prompt_tokens := usage_mapping.get("inputTokens")) is not None # bedrock + or (prompt_tokens := usage_mapping.get("prompt_token_count")) is not None # gemini + ): + model_usage["input"] = prompt_tokens + model_usage["input_cost"] = prompt_tokens * LLMS_COST[MODEL_ID]["input_cost"] if MODEL_ID in LLMS_COST.keys() else 0 + + if ( + (completion_tokens := usage_mapping.get("completion_tokens")) is not None # openai + or (completion_tokens := usage_mapping.get("outputTokens")) is not None # bedrock + or (completion_tokens := usage_mapping.get("candidates_token_count")) is not None # gemini + ): + model_usage["output"] = completion_tokens + model_usage["output_cost"] = completion_tokens * LLMS_COST[MODEL_ID]["input_cost"] if MODEL_ID in LLMS_COST.keys() else 0 + if ( + (total_tokens := usage_mapping.get("total_tokens")) is not None # openai + or (total_tokens := usage_mapping.get("totalTokens")) is not None # bedrock + or (total_tokens := usage_mapping.get("total_token_count")) is not None # gemini + ): + model_usage["total"] = total_tokens + model_usage["total_cost"] = model_usage["input_cost"] + model_usage["output_cost"] + + return model_usage diff --git a/apps/chatbot/src/modules/models.py b/apps/chatbot/src/modules/models.py index 986a92842e..41abfc642e 100644 --- a/apps/chatbot/src/modules/models.py +++ b/apps/chatbot/src/modules/models.py @@ -1,9 +1,5 @@ import os -import logging - -from llama_index.core.instrumentation import get_dispatcher -from llama_index.core.instrumentation.event_handlers import BaseEventHandler -from llama_index.core.instrumentation.events.llm import LLMCompletionEndEvent, LLMChatEndEvent +from logging import getLogger from llama_index.llms.bedrock_converse import BedrockConverse from llama_index.embeddings.bedrock import BedrockEmbedding @@ -17,15 +13,16 @@ from src.modules.utils import get_ssm_parameter load_dotenv() +logger = getLogger(__name__) PROVIDER = os.getenv("CHB_PROVIDER", "google") assert PROVIDER in ["aws", "google"] - GOOGLE_API_KEY = get_ssm_parameter(name=os.getenv("CHB_GOOGLE_API_KEY")) AWS_ACCESS_KEY_ID = os.getenv("CHB_AWS_ACCESS_KEY_ID") AWS_SECRET_ACCESS_KEY = os.getenv("CHB_AWS_SECRET_ACCESS_KEY") -AWS_BEDROCK_REGION = os.getenv("CHB_AWS_BEDROCK_REGION") +AWS_BEDROCK_LLM_REGION = os.getenv("CHB_AWS_BEDROCK_LLM_REGION") +AWS_BEDROCK_EMBED_REGION = os.getenv("CHB_AWS_BEDROCK_EMBED_REGION") AWS_GUARDRAIL_ID = os.getenv("CHB_AWS_GUARDRAIL_ID") AWS_GUARDRAIL_VERSION = os.getenv("CHB_AWS_GUARDRAIL_VERSION") @@ -38,24 +35,6 @@ def get_llm(): if PROVIDER == "aws": - - class ModelEventHandler(BaseEventHandler): - @classmethod - def class_name(cls) -> str: - """Class name.""" - return "ModelEventHandler" - - def handle(self, event) -> None: - """Logic for handling event.""" - if isinstance(event, (LLMCompletionEndEvent, LLMChatEndEvent)): - logging.info(f"[{MODEL_ID}] Bedrock request id: {event.response.raw["ResponseMetadata"]["RequestId"]}") - logging.info(f"[{MODEL_ID}] Stop Reason: {event.response.raw["stopReason"]}") - logging.info(f"[{MODEL_ID}] Input Tokens: {event.response.raw["usage"]["inputTokens"]}") - logging.info(f"[{MODEL_ID}] Output Tokens: {event.response.raw["usage"]["outputTokens"]}") - logging.info(f"[{MODEL_ID}] Latency (ms): {event.response.raw["metrics"]["latencyMs"]}") - - root_dispatcher = get_dispatcher() - root_dispatcher.add_event_handler(ModelEventHandler()) llm = BedrockConverse( model=MODEL_ID, @@ -63,10 +42,11 @@ def handle(self, event) -> None: max_tokens=int(MODEL_MAXTOKENS), aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, - region_name=AWS_BEDROCK_REGION + region_name=AWS_BEDROCK_LLM_REGION ) else: + llm = Gemini( model=MODEL_ID, temperature=float(MODEL_TEMPERATURE), @@ -80,7 +60,7 @@ def handle(self, event) -> None: api_key=GOOGLE_API_KEY, ) - logging.info(f"[models.py - get_llm] {MODEL_ID} LLM loaded successfully!") + logger.info(f"{MODEL_ID} LLM loaded successfully!") return llm @@ -92,13 +72,13 @@ def get_embed_model(): model_name = EMBED_MODEL_ID, aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, - region_name=AWS_BEDROCK_REGION + region_name=AWS_BEDROCK_EMBED_REGION ) else: embed_model = GeminiEmbedding( api_key=GOOGLE_API_KEY, model_name=EMBED_MODEL_ID, ) - logging.info(f"[models.py - get_embed_model] {EMBED_MODEL_ID} embegging model loaded successfully!") + logger.info(f"{EMBED_MODEL_ID} embegging model loaded successfully!") return embed_model diff --git a/apps/chatbot/src/modules/presidio.py b/apps/chatbot/src/modules/presidio.py index ef0122d88f..a73471e26d 100644 --- a/apps/chatbot/src/modules/presidio.py +++ b/apps/chatbot/src/modules/presidio.py @@ -1,6 +1,5 @@ -import logging -from pathlib import Path -from typing import Any, Dict, List, Union +from logging import getLogger +from typing import Any, Dict, List from langdetect import detect_langs from presidio_anonymizer.operators import Operator, OperatorType @@ -11,6 +10,9 @@ from presidio_anonymizer.entities import OperatorConfig +logger = getLogger(__name__) + + # see supported entities by Presidio with their description at: https://microsoft.github.io/presidio/supported_entities/ GLOBAL_ENTITIES = [ "CREDIT_CARD", @@ -130,17 +132,17 @@ def detect_language(self, text: str) -> str: lang_list.append(detected_lang.lang) if not lang_list: - logging.warning("[presidio.py - detect_language] No detected language.") + logger.warning("No detected language.") lang = "it" elif "it" in lang_list: lang = "it" else: lang = lang_list[0] except: - logging.warning("[presidio.py - detect_language] No detected language.") + logger.warning("No detected language.") lang = "it" - logging.info(f"[presidio.py - detect_language] Set presidio to detect PII in {lang} language.") + logger.debug(f"Set presidio to detect PII in {lang} language.") return lang diff --git a/apps/chatbot/src/modules/test_chatbot.py b/apps/chatbot/src/modules/test_chatbot.py index 9c05322002..88220520a4 100644 --- a/apps/chatbot/src/modules/test_chatbot.py +++ b/apps/chatbot/src/modules/test_chatbot.py @@ -1,11 +1,15 @@ import os +import re import yaml -import logging +from logging import getLogger from pathlib import Path -from src.modules.chatbot import Chatbot +from src.modules.vector_database import REDIS_CLIENT +from src.modules.models import get_llm, get_embed_model +from src.modules.chatbot import Chatbot, LANGFUSE -logging.getLogger().setLevel(os.getenv("LOG_LEVEL", "INFO")) + +logger = getLogger(__name__) CWF = Path(__file__) @@ -15,18 +19,45 @@ CHATBOT = Chatbot(params=PARAMS, prompts=PROMPTS) +def test_connection_redis(): + flag = False + try: + REDIS_CLIENT.ping() + flag = True + except Exception as e: + logger.error(e) + + assert flag == True + + +def test_connection_langfuse(): + assert LANGFUSE.auth_check() == True + + +def test_cloud_connection(): + + flag = False + try: + _ = get_llm() + _ = get_embed_model() + flag = True + except Exception as e: + logger.error(e) + + assert flag == True + + def test_prompt_templates(): - qa_prompt_tmpl, ref_prompt_tmpl, condense_prompt_tmpl = CHATBOT._get_prompt_templates() + for prompt_str, template in zip(PROMPTS.values(), CHATBOT._get_prompt_templates()): + vars_str = re.findall(r'\{(.*?)\}', prompt_str) + vars_tmp = list(template.template_var_mappings.keys()) + assert vars_str == vars_tmp - p1 = PROMPTS["qa_prompt_str"].format(context_str="aaaaa", query_str="bbbbb") - p2 = qa_prompt_tmpl.format(context_str="aaaaa", query_str="bbbbb") - p3 = PROMPTS["refine_prompt_str"].format(existing_answer="aaaaa", context_msg="bbbbb") - p4 = ref_prompt_tmpl.format(existing_answer="aaaaa", context_msg="bbbbb") - p5 = PROMPTS["condense_prompt_str"].format(chat_history="aaaaa", question="bbbbb") - p6 = condense_prompt_tmpl.format(chat_history="aaaaa", question="bbbbb") - assert p1 == p2 and p3 == p4 and p5 == p6 +def test_pii_mask(): + masked_str = CHATBOT.mask_pii("Il mio nome e' Mario Rossi") + assert masked_str == "Il mio nome e' " def test_messages_to_chathistory(): @@ -34,8 +65,6 @@ def test_messages_to_chathistory(): chat_history = CHATBOT._messages_to_chathistory() assert len(chat_history) == 1 - ###########################3 - messages = [ {"question": "aaaa", "answer": "bbbb"}, {"question": "cccc", "answer": "dddd"}, @@ -46,26 +75,33 @@ def test_messages_to_chathistory(): assert len(chat_history) == 2 * len(messages) + 1 -def test_pii_mask(): - masked_str = CHATBOT.mask_pii("Il mio nome e' Mario Rossi") - assert masked_str == "Il mio nome e' " - - def test_chat_generation(): query_str = "GPD gestisce i pagamenti spontanei?" try: - res = CHATBOT.chat_generate(query_str=query_str) res = CHATBOT.chat_generate( - query_str="sai dirmi di più?", - messages=[{ - "question": query_str, - "answer": res - }] + query_str = query_str, + trace_id = "abcde", + user_id = "user-test", + session_id = "session-test", + tags = "test" ) + res = CHATBOT.chat_generate( + query_str = "sai dirmi di più?", + trace_id = "fghik", + messages = [{"question": query_str, "answer": res}], + user_id = "user-test", + session_id = "session-test", + tags = "test" + ) + + trace1 = CHATBOT.get_trace("abcde") + print("trace 1:", trace1) + trace2 = CHATBOT.get_trace("fghik") + print("trace 2:", trace2) except Exception as e: - logging.error(e) + logger.error(e) res = f"Something went wrong!" - assert res != f"Something went wrong!" \ No newline at end of file + assert res != f"Something went wrong!" diff --git a/apps/chatbot/src/modules/utils.py b/apps/chatbot/src/modules/utils.py index 1e7e1bd1d3..88e335e3ab 100644 --- a/apps/chatbot/src/modules/utils.py +++ b/apps/chatbot/src/modules/utils.py @@ -1,10 +1,10 @@ import os import boto3 -import logging +from logging import getLogger from dotenv import load_dotenv load_dotenv() - +logger = getLogger(__name__) AWS_ACCESS_KEY_ID = os.getenv("CHB_AWS_ACCESS_KEY_ID") AWS_SECRET_ACCESS_KEY = os.getenv("CHB_AWS_SECRET_ACCESS_KEY") @@ -26,7 +26,7 @@ def get_ssm_parameter(name: str, default: str | None = None) -> str | None: :return: The value of the requested parameter. """ - logging.debug(f"[utils.py - get_ssm_parameter] Getting parameter {name} from SSM") + logger.debug(f"Getting parameter {name} from SSM") try: # Get the requested parameter response = SSM_CLIENT.get_parameter( @@ -34,16 +34,16 @@ def get_ssm_parameter(name: str, default: str | None = None) -> str | None: WithDecryption=True ) except SSM_CLIENT.exceptions.ParameterNotFound: - logging.warning(f"Parameter {name} not found in SSM, returning default") + logger.warning(f"Parameter {name} not found in SSM, returning default") return default - logging.debug(f"[utils.py - get_ssm_parameter] Parameter {name} retrieved from SSM") + logger.debug(f"Parameter {name} retrieved from SSM") return response["Parameter"]["Value"] def put_ssm_parameter(name: str, value: str) -> None: - logging.debug(f"[utils.py - put_ssm_parameter] Putting parameter {name} to SSM") + logger.debug(f"Putting parameter {name} to SSM") try: # Get the requested parameter SSM_CLIENT.put_parameter( @@ -52,5 +52,5 @@ def put_ssm_parameter(name: str, value: str) -> None: Overwrite=True ) except Exception as e: - logging.error(e) - + logger.error(e) + \ No newline at end of file diff --git a/apps/chatbot/src/modules/vector_database.py b/apps/chatbot/src/modules/vector_database.py index 425936107a..c4995b26b5 100644 --- a/apps/chatbot/src/modules/vector_database.py +++ b/apps/chatbot/src/modules/vector_database.py @@ -43,17 +43,9 @@ PROVIDER = os.getenv("CHB_PROVIDER") assert PROVIDER in ["google", "aws"] -INDEX_ID = get_ssm_parameter(os.getenv("CHB_LLAMAINDEX_INDEX_ID"), 'default-index') - -def calculate_new_index_id(current_index_id): - if current_index_id == 'default-index': - return current_index_id - TODAY = datetime.now(pytz.timezone("Europe/Rome")).strftime("%Y-%m-%d--%H:%M:%S") - rtn = f"index--{TODAY}" - return rtn - -NEW_INDEX_ID = calculate_new_index_id(INDEX_ID) - +TODAY = datetime.now(pytz.timezone("Europe/Rome")).strftime("%Y-%m-%d--%H:%M:%S") +INDEX_ID = get_ssm_parameter(os.getenv("CHB_LLAMAINDEX_INDEX_ID"), "default-index") +NEW_INDEX_ID = f"index--{TODAY}" if INDEX_ID != "default-index" else "default-index" REDIS_URL = os.getenv("CHB_REDIS_URL") WEBSITE_URL = os.getenv("CHB_WEBSITE_URL") REDIS_CLIENT = Redis.from_url(REDIS_URL, socket_timeout=10) @@ -63,7 +55,8 @@ def calculate_new_index_id(current_index_id): EMBED_MODEL_ID = os.getenv("CHB_EMBED_MODEL_ID") EMBEDDING_DIMS = { "models/text-embedding-004": 768, - "cohere.embed-multilingual-v3": 1024 + "cohere.embed-multilingual-v3": 1024, + "amazon.titan-embed-text-v2:0": 1024 } REDIS_SCHEMA = IndexSchema.from_dict({ "index": {"name": f"{INDEX_ID}", "prefix": f"{INDEX_ID}/vector"}, @@ -169,6 +162,7 @@ def create_documentation( if file in dynamic_htmls or "/webinars/" in file or "/api/" in file: url = file.replace(documentation_dir, f"{website_url}/").replace(".html", "") + driver = webdriver.Chrome( options=driver_options, service=driver_service @@ -224,7 +218,7 @@ def build_automerging_index_redis( chunk_overlap: int ) -> VectorStoreIndex: - logger.info(f"Storing vector index and hash table on Redis hash_table_{NEW_INDEX_ID}..") + logger.info("Storing vector index and hash table on Redis..") Settings.llm = llm Settings.embed_model = embed_model @@ -240,7 +234,7 @@ def build_automerging_index_redis( key=key, val=value ) - logger.info(f"[vector_database.py - build_automerging_index_redis] hash_table_{NEW_INDEX_ID} is now on Redis.") + logger.info(f"hash_table_{NEW_INDEX_ID} is now on Redis.") logger.info(f"Creating index {NEW_INDEX_ID} ...") nodes = Settings.node_parser.get_nodes_from_documents(documents) @@ -277,7 +271,7 @@ def build_automerging_index_redis( ) automerging_index.set_index_id(NEW_INDEX_ID) put_ssm_parameter(os.getenv("CHB_LLAMAINDEX_INDEX_ID"), NEW_INDEX_ID) - logger.info(f"Created vector index ${NEW_INDEX_ID} successfully and stored on Redis.") + logger.info("Created vector index successfully and stored on Redis.") delete_old_index() @@ -325,7 +319,7 @@ def load_automerging_index_redis( def delete_old_index(): - if INDEX_ID: # is in ssm there is nothing, INDEX_ID = None + if INDEX_ID != "default-index": # if in ssm there is nothing, INDEX_ID = None for key in REDIS_CLIENT.scan_iter(): if f"{INDEX_ID}/vector" in str(key) or f"hash_table_{INDEX_ID}" == str(key): REDIS_CLIENT.delete(key) diff --git a/apps/chatbot/src/webapp/app.py b/apps/chatbot/src/webapp/app.py deleted file mode 100644 index 3965f60c3e..0000000000 --- a/apps/chatbot/src/webapp/app.py +++ /dev/null @@ -1,82 +0,0 @@ -import argparse -import time -import yaml -import logging -import gradio as gr -from src.modules.chatbot import Chatbot - - -logging.basicConfig(level=logging.INFO) - - -def print_like_dislike(x: gr.LikeData): - print(x.index, x.value, x.liked) - - -def add_message(history, message): - for x in message["files"]: - history.append(((x,), None)) - if message["text"] is not None: - history.append((message["text"], None)) - return history, gr.MultimodalTextbox(value=None, interactive=False) - - -def bot(history): - - response_str = chatbot.generate(history[-1][0]) - history[-1][1] = "" - for character in response_str: - history[-1][1] += character - time.sleep(0.02) - yield history - - -with gr.Blocks() as demo: - - gr.Markdown("# PagoPA Chatbot") - - gr_chatbot = gr.Chatbot( - [], - elem_id="chatbot", - avatar_images=( - "src/webapp/user.png", - "src/webapp/chatbot.png" - ), - bubble_full_width=False - ) - - chat_input = gr.MultimodalTextbox( - interactive=True, - file_types=None, - placeholder="Enter message..", - show_label=False - ) - - chat_msg = chat_input.submit(add_message, [gr_chatbot, chat_input], [gr_chatbot, chat_input]) - bot_msg = chat_msg.then(bot, gr_chatbot, gr_chatbot, api_name="bot_response") - bot_msg.then(lambda: gr.MultimodalTextbox(interactive=True), None, [chat_input]) - - gr_chatbot.like(print_like_dislike, None, None) - - clear = gr.ClearButton( - value="Clear chat", - components=[chat_input, gr_chatbot] - ) - -demo.queue() - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser() - parser.add_argument("--params", type=str, default="config/params.yaml", help="params path") - parser.add_argument("--prompts", type=str, default="config/prompts.yaml", help="prompts path") - args = parser.parse_args() - - # load parameters - params = yaml.safe_load(open(args.params, "r")) - prompts = yaml.safe_load(open(args.prompts, "r")) - - chatbot = Chatbot(params, prompts) - - demo.launch() diff --git a/apps/chatbot/src/webapp/chatbot.png b/apps/chatbot/src/webapp/chatbot.png deleted file mode 100644 index 02034479b91a68ecc9771fa9fbb364ef54ac214e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22002 zcmd3Og;!Kx^zWUar5ow)QYisx1?d!!7Wh)q3>||s2#C_%!qD9?lA_Ym9g@-@&AiL+ z_ul{TSZmg>xaXX^`<#9DXA`BVu89AL`VjyC_^*`|v;hDL{t5-KF~P4h@88$p7mkaP zp*sK&^gMhZ1I{H@;2$4*yfpC8asJQ4%fihX@bdEFw{voEx3qAv=680p$vBXt1^`Cj zwSug!cjn(kuS{0!Ea{^W9lfl!uYM=L!qa9mU#ld3v?5@wFbBwAXv%6mZ_yb+`z_H2 zM8os9=<>I-Zilf;7-fkeuT^HO-3jWx$Zu65wk`&UJZBeYaTf1%FWUpI-dT9r)6Kq^z~6ByOI{+P-O@i z3| zA;nPZsb*J*$E-2gewRh&&1O!C5@{&?*Y`+RRl%|s3NMMq#I&lQdrE27Xw1n*ffF1C z5I{!@nKk}Af{)>-DVZ>Sb;#G5sGl4y-;(z|(x_-ikmkWr*pLSa;FeM53daq5o?J?Y zAIuVlWLDyZXjX~OALx<;HwAXxB0^6}?B2x?>~od=L`^Rd1u4MznFZcKWOOkX7oX-0 z421~e4k%kNa4^O}M@z(~gT*R<8Ol7I$3*#N6Gzd48>H#vt!)+0+fBiFO_mTDAxPTC z_k2Ib?c`QiacJ4#SAfuDOaD)N3}h!&YxXpThyykKq}9=IWAbPj;u&!ZJ}!{|WQNIF zDE-MYWJro!JM+m_kd%DHA5D0Y=}fMD4?o zi~(#F{)y0L137iAtkUsz1E4*t7)K&EMlGEwh=O;@ANGT6^-dt&7S90qRP~xmKIHMK zH;zvwQ8T(s-LC57Mg-K{D;VE^{%b^WfS!XG3QZd@gxFRos9{90;1 zo>rj7vSo&yu^?-2&b45T``@gt&lPVX(0i=KDJ{z!;+bw~UGcNILzGiD*=6&Xgg@ z03`3hbmLBZ^-b209qytTM4j$w zp=kO3>#pR6887f-b%TKydR7Oi!TzMfL zzS$@qiR0h`Fb}mlIobU!NBkN>T&8Hy5`L`anBlGPV%K1k=s<`8D;$#fTnmicJNl8p zw4Bl}y-@S~;cGkmM`0Rh-qP?{%S)O);Fb(y;RA=Xr17lFu*fI=tVc}F7}W+aiY`k? zZg!k8H1#@tA8>28#8U61uln|MC=VBjRnACOUqx>0NjV3=62p5A1I<=I>N zzyfg}j?<((}cE4)w{!Q76}X3zd#-u@}OlH^{0&vD2; z=0MllpBnF9eA@Iox*f_!sq#@$0G6;H@n4}+43L%*e@b#5;0{mnI(Yw2TXEf)^~sj~ z=m8*T0;8Ct!3Au_g@+ztH5koPuY15dk#Vp%L48rSBBLQ-pVB^GI|~TMDvt z8^zr%v~R#}xzuJieWYVz^0ZQXB$U^v80}=aY$Ek`PRXxcniqIAk zOFjFt_r4LhF<>;eLGQ(1!3)Zd{tURi+}nn@m$*CVZ@!=O>33XT@JjI+U$#v)?=dEj zkNbduv@L9JZr%STi~KC_9L-c9$WN9KY4eidasXwa(ZyK>$F;op5;eqw`g8L>e; z%0#P{wppZ*W17Ne)arXPQQh!L@;=X>e4e)H-ni04>CQn$G6Bqmqhb{Bz)~HRJ6C&@)NEP#21$2Q(dBvjt`jh))8mm=j zuH8UEWainbp+VR;4TghsO2_N)7I2`o`3rLT0p&B>LUb!wdU(-;qvN-p%6t$i*+6`P zcX<`+gI?-*riM%<^Swwr)w7w6;Uf=dEVZA$0>_&fye`vzl~muxaJRGeM{ecy$NgS; zX6;|K)`DN21%Y<6Uyk1&s(G6BNNo4nn)KelrI6j(rH{2u?>vLXCWMFZ_pandl-cI|}CK{m+3b}PAZl~mV; zY3pIk_Q=M_m*juE@DM#4ru;!3!>8#yZ{wYpl3HY86mAq00J^!AWlpf_Di3t7>YL%c zLiRhA$oDlK>-{D>5f6)i``;(+a7?$N9AFK1Wm8ijJ4qn@YsK>O_LeTQ+V30`K%l4) zD@}N9ku*-!Md`4dLXy5vMPv5DXmVCZnEn2s20dqOx5 z$UXDckCgH-8u5ueufHx+X{@@Bc>&2vogXvijh7NKrsd+e#Lvyf>gU|vd9P1>`zAhV zSW;^McpC(DsfN`SMF6g?poMJEznpO5w(1M7Fsjo5BhU{pT59dozo+;%ZVB~{co-qY zHlePv zD~?eR9@PDT(u-$&kGT_jb>`cy3H7qVe#BtFBMK*K4I_>P;g3OyCU_Yn<5?+RPZ)WT z6KI12A~4{Jc!WRuKXbl#gcCPStTk)cNcYPq%%;)v&urT^G015y=pMWkXNr&`4*_Nb z)kJMinD%iIU)xEYu1($`7)ad$0-kbxD2jl%_{T+ZS6a;{e9$xKER~o5X;cH1O1YQ# zv^YZf0!_>qM!|eSIPv*dd(gOpDa+|iRv3F623!TE{5Zx+CFm2<^?^oIYO?BgCO>OX zexN0h_CS$gg^9kb4og2Xq=`#)>;JZP`uiq5#9G`~Pz03J-;+C8n3jvgv52+C>eEGG z|7B}uh4jZ`z<+|g=1?Lh5$;699Zb&Y5sq`hwE?kUV`QWs%`9IN9 z7)GrV%bMWC2a3+NlsS~R4lo%Xq&kXfdr!cPqCBR2;OYCoHTxxeJpBlwqW; z(3RYdpM>v(1tG1l&kf$|m3eJ?Te$(C5@h6O$Dfcizl0Gm=MVm%+$Vg$ryL{$BY4<9BMfIu zDVx|1(2y0vQQt{x+4dAUXhq6o!Kb7kIXG0*2Y1~#KY{0Z4+Oi_ye|zpJlzTqBNNh9 z%v-DmTs~z~NkX5!C3SodWKu@)-m01ZT>!#z)Cr`v_eMP{jAuB#OdOL~tM8Yib2q+z z7D61e1C%4$uguTL=_*M%7#?$eblX|EyzB3^9fT#30l-NqD0F+&x=s{>uB*tzjF7}x zIIp4%K85@SPe3!20utydTW)T=#8--(WXMHPlYH^;!x}(ydxmYO`T8~tT!UC|k?Hj7 ziu~c)=vQT4fb4ajeDmJKfZViqs{rxU#5sc)&V-RR!t#;=7kKG(cd3;+MWsU*5~)N7 zxxFnr)XVB_0?9ZEezv*tVciGGK&%zO9bV;si#PeiKMF%8X$YiUU)rsCmr6k)&UI`D z%VLMw3I5iR7eFXsuO!DagxRM4G>eQ}VhuhFIFOs<@{hofAvX!Urp@$lDf^#UUn0Yf ztqCx6$#LP_c9pR!#f0>rWQY?i`6Tuke>rY-a!z(bbCo-<##j=fBXkECncaACR&OQZ4w&F=&fZPCWZ47I+z)Yvze5Q#pD2RrV4hB!oPt|_<=3L? znE)q6vZHriC-g8iPf8Pyh2HK-XFpO~cSLAkW>tK;$PvMf_*JP73h#Tv2U#@HfHR@V zCz3H3G8nxq5dZrCtg<*+g$-ZI98aQM9WC%tl;8Lpq>X^dhh*_i^DHH08D$(U2#uT7 z>Jw8`10jA<41$F-ZwJbPqPc2dN5`|=$k~u=LY-oGk8B<2(e=0+0Evc*DzpqQygGNO zI<4nOlC68{S$U1RYaI<5LmgFSs+Mne_^KRfb?Lro38^ufW21ZEe}l)FYszz$u+WYY z5j@7mfDP|yt$e!Dsqq-omF#-gw#%6fO8eLST~7oH*{I&Ykt7aM$dOEqhV5s#-7Ke} z+Xiut?T7b9`I?EGNKCg))2=Ez8CEMsY7wH??MTIt$Ou?9cZpDxk+eI%`sLAu9@a4# z1z_!Q`cJu+=R@INSR}Ob<22$ArvD*vxvQ3dj}XJ-3#F6Vl@etdyQc$4M>8;HqCwTP{Nhc(b+2 z#KZSywVCyW#-xp9E@TKo(wI+P#)t;F;r~qDrr|d4`DfAIjG*KZ#mlYZi1<91F=d5; zhFOUMMsPU66S{S-0~F=4Ba5(XPEM5Rw9RvFhMU|y$19Bap2C|m{F6fi1Ik30;Y*xDu_k-gYpCH_r6kF2#l7pUaGW`~H2n`*d>*N#KGF@t)wL=$8qq&+M#A;Cv^I186!I(h>x!V~~0 znUIkGE_2-7VT_{+UNP?W<4scOF$H`Z6@wNF0DP5e?Mh&#*Z8}CP*o@{9LM*tv~F~Y zR)?;~uuwrP!H|2L0pG%;+iEoKO@Bf$N8us}*7JK@cffgL!_zVeZ!*kY-^5S+wV z)T`MTnY{{C<=q;li#;DS^ybdR{lY6UNKYj&khXf)Ahi>yl#R+;O)ju!GJ^pnj+4VlCIqlnB=H``V&&el=gI%4KUA;Am%!-2>s_m_f%hNR2YIf@H zWEH=FBzJ>jE5*H}K1eMFiDwDq1vMkBl@ti9XGuU?e5Yd5pM&el>asr2%<3X}>m!;0 zx1B*^jbs*xznXl_1-cW`CE4U&!Ku1VBBsFzGvK-OR&I+k^YIOXJBPQP?jf;Xx9*jVf_sY5X;F>VIQ2c{KH9%GHQ$43bTuv`7`Nh+vkqZAP zW3DfvHSYqt4wHAXVZ8ciAHn_ONvcEzrsA-(E?t4Wa&hcZ9+a2ClZnJ03ymJO;&Vq?&=An5q` zDVdTwu#X7NMBcOFn9gP0(C-fKjozJaLhy?3YE)fT|Nf^SCkvW$JUBcv;LJmawL`kB z-u&&h2Br5W!UV-xk!s%wBFyj(Gjt`cqbQYGTo*=OfMBI|qFp*!SIF^&sn~wPl=Gs_^G(&Qm^ixqsh?0snFLxDe3ZP1gNh4 z^U4^dJvZU5`fOd`9BFwUc>arL5yA2a+R82%^xvc7$UJf7K5W2i=?UC%9?|;Ihf0Q8 z22(~LbcU5lAD5=gkxL&-IWOsAQS^oWkW7J=uY-|q3f^yW*FwxpXz&*%S3F?gtVuxP zcYj}muNQv1oyr-(W`NhJKsp8HI2#z{IMXP2jhMfjPHUHn-mVV9z&$G=5;M<%S`I>o zUrLqkP=Fl)MOf-3S=bs#@`Pz>>eCgy6LGFT3Sq!2iK}UoM9+q96jUD@EdQ$*k-Wbg z{2}F^NCtcjQtXtsZN@{g0rq-UR53>UPoD_y3}qDXDH5DN;d2fQxXKS}n2)HoKLw^7 z8M>zq@ETz@)diw^^BH$i_>P)c$mgNqGK`T*Vjt(ysfvZC->rURr-I@|S* zV@$Y?=g~!mcT5-&#iLi7|Mw_e)B(7?%@#5ZsK^!XHz>#GU2J4JxIJHdh8TC$I)<*C z9S*V&^?qeLas`BwoT`lZpa1F(i}2pUY-zjq_(rN2@sHroF;Zv#Xhub%#@~_fOAGkjPvuC7a`WS# zU3XPiJxR8?%oxa><)jqs6$(Iy+x1R4!<6S(jnETCsfHUMkI`IHK3mHZ+lH#9xRCCc zoW%IJUJY>42$jS=3zRco{m4r4m5Zt>5rdW6s1!!1Bys%NpV$ z$$KBHc>r}(rKA~v!oV8YW#AF;L|qV&8w+ze^%V#DqngT&ws9p)^y`}+;lh6q%WxaU zsAx$4(hHMera*pp%!N(3AGEe+0e|uF7vU%U`;(J-mG{-vl)lBa^_>@Wcl=ST%*AmP_?ONzDOyr zr#u+!lB4dM6}9rI-rXvqL4er%)}F(}bw=>yVC-@`6a-4b*lnWVGKE13%u9We>m4Og zC-%nfr>NB({U$`*Gj1d0@_F%%(l4@K)!aSDgdvJ)Z2M8C(#W>DPYv zbML15Z@=PkN{YCiB9k`v7y5q6!&^RjpQSYSCxwYK%>gqtIc)2~L4iuJ(CAMx75p0v z{Svf-o6wboHmi_N-c)eEsk)CLK($r0XtqKf1}R&_!D-Nl{NB-05b9auh4)v71lyDFxqq5)7S?7d5WAh-~&>P^4v8qsP^}cwmI;MKFdb(7X=TjbJsfvL#Y#P+8 ziNs=j;=Hz+S<#`MKLw+qI8;-P@)-6pL1{yqP`kqZ=SwNgd4yw9k~b&ZxATPbANG+x z67%BE;<7b_JV|gVed{P!V0HM5_vf|NJpJ_?=c$hXt|NRvQJp)vhfZ=5SHQ_!%%>=w~-2g1fXk3cw~%pPv*t`zQX7 zr2C7bGwHw8Q9+<(THmf7&Vxy@Tf?{Dz}tBf!m_wycCO(4HaCQ&>f8qm%XF5lK)K8( zbDBsgT)6w;XDuB60=LpkYxOT}11Pnhp1)@n98paq(gEICU@n|pZE3^N={d5Fuxu}N z<~+PMg(tsZ_=V;j!roc;el|KFTdrXQnrndUf>6Q!B6-l^v#|#U5SQ`Vt{eL0$iusT z!jn%TC9Nl0)h@@Jb9Cs?kV*n>Jder$9~MByrm4*j(rtk=bUFc;ay(gl6eiVFwLG_H zbTm9~{Q|wR(x2NV^$icPyQ}jjN0kkgVef0R4j2*2_0a8M<(;UlH!C~j!&Gnf9&_ey zR~JREGeLf(t*;T@yOK_4-(*kXJEN-n$N}*qF5p0{z7=ml>ON;UBQEtSXDH+HjBbR{ z%;PWuno#%p_6T+V;ojoB?PON_oqiQa7J<~v4JpKn6nDGd^yk$DCotTqHif-&CyZ)y zcZV<*dHgb1i1q4&Sn61-n9+uq;nBMdq%-=(VNjq3dNVV8hn7qBbe*;x#(!r5Al_qAR`S-Gt`v|c&~BwwVm!ZNpPq@xFr`%(`xmMk)QY+ml}G? zARQ33ey=de&gO*bGt>KubZOj3wfG(-wn1bzga!vFvQbMgmE}t>$EM{L)z{2nbM|14 z_&C138ZEw~S?7UzYO3vls{8W5K}WBg>(^1FlTUiQP60-t%L`+tGJ<8Xy zJFo*juu#(QAc9qgi_UT(w1nlmgAoC9&VqlVxu%pOXtwqz77(D_X7*_*S`{Vm4U;zv zY3hL9;pF=x3qz*Hic9+0?eKDYxZ{fhX{ylgL+|TC=MVj~?ZV#;_Pg{y&q#<>lsuS{ zU3qQCjWNXlZ8rsMkzDqtx;gA{JAUxx(W3V|kAJOm5LW1=2S>gtpRL9)630sVZ=1$r zYOK$)h~{V{4&FA_kl@#e323ibHMk%q8Owv+sDxZ zLJl&q7@3|}zLJ6AVe}3HxqNL}m=M}BF||oGuN`z`zFm*@%$@Wn{x!;=rIPXh=DGRn zq50}M(TeiBd^?seI?_*km^X*dCz6pYtS+}n`cjmm;TeJqGP6*;VJt; zfK^BBzbISOo2uoHOR_MUQ#^vUI>6TUXq6QJ8Y_k-7z5q{%`P~(d~C{(L{V3Nazrh} z_J(IW6-+sbVslVhi3oZX61lo@H{D1Ew5(W8$UjWH`$8BF5 zx$WAtcWJ(wAFTCgeW4COQ)LqREnJ^pnMZz_OdDk~FKRJVHo}xbSE;Q{9TQ31a~m!{ znvjkbJm%*JvQ2WXBG?p&gL%^7-LPlqVLkamIAy-SLc)BG0Gu8ubEwvH$yr>`gzdA)|Mma`nwyf4$v z#r9HLCY_Cxt=!qyw7g)Yq9V;6`ptu{Z2@C%iA-A2e?Up*9cntoi_4)cGyj;H7S{co zwDsyxeFFB&$RC|Re2sOxRUn6!R(8UJ*YO1;h9*9BbSTKHB1$B4!IhpQPd9D6^!%?f z?1iV(0tai_$sgk!YJB*ir>qNjv5mN40J2Rdi^})iqWT?N&Z4%MlR1~M{P*h9#5PKF zn2e_ucQByP0o51e`-8LAZU0GXhLFw=%kpmDtB>txb^Mqc-kfxLBSKu0Du4^m73kW1 zMcLV$P-jo|Y||01q1ZS3}nR zmw61mc;slYI9*TlSp!fb1M5Gc5Ps7+T2eS%DP`?QY3yz69RR{dMq=7r$`vP%yIxLo zhi4ruUb1WH#OMaNPtIkCSO!kcos>Opn7pAERWQ;d^*BVpwM%pV9#zYY1&~7a>hbHm6YdZ{Ey9vR8E-M}Ct(#Zh)q@+ZH8q*Be3P%%WgDx9@|&mjx)^bvq!5<(ei=59 ztf8wGd*~E#&jXNHOycxwO!D43zOYXwP6~m`S9%~{z#aynLA_0=)#r||XQXE~BUl}eM z(_)wge$^hG_OpnASow&Al3n!4tuC%VdQ4y3UGbBH8(eRHGzbGu!vUF#j^o*<;pen#qSb}XKk7Q*)W(kvEPg9ImGDNX zrerhHNN08YPt>D`#T)l*&gFo&Y~2Tb76|dmcIo{kC_ECF(5>Ui!Bqr^T$~k0La!=u`z2t=0m1pmTBMFdHes?%jQ}>HzdO7Hn+=yz-y$Dmivky9pG?rzd!?8_rM*$pPSF^+bc z6!lhtdzLxr$ZC#O$c7JHTDRVdG%}` zEFj*WH}gj#ti@lLIrOO z=f7B|vAutLqYQ#(wBOw!{^;5L9C`Dv)1cwcTL)jWO5b?-=Y5v;>;P0I^~L|vU9t-S z-~|*y+zxHDA{7A*++QF~&ZaSEnn8W@$8D?KKqFpdnYV<`vzYTc9uUsMHk7@TUuXgX z-*~)?PZ=HriVdT2pzX+g{krYXJ45z2oo7waQo@_HcI75l#(k9!3`-R2ryh41gTZpM};p67KrtI!xtRrM~@UkQg}`u@y}>vt#_jUN!XqoBDq%K#lO zYroerBM{U?Rnqe;Zm12zGY!MN8o_vCFWmb=W4UPzAvI)U8Omck@zHt-hT7$Pw27W` z8wuu(-_ZpJy@KUWkNT0fk#qf1Xr3t)xIP~H3m;+~OyxwLU2&*$=j7`lPfRo{Oi+)0 zRY+j#knCgc7K|9x6vZC=A}D9@#?P|ziofVGVb%(1q!7;V#z3R~AS+Oc-prFi*UDqVm$iX&yf8NCVdNpMI(y`?9B?;q@y{H-I#@?9Kwj{%ZhG17LU`N*)JO&3h2njRNYh94h$GbvvGeFNu zfah^ZJSGD8rE262=M_B6Z93%_CxVcpVvtd5P?M@ks}va#Lykwi*?@v6Sqz8Ec;2(b zhMZ{k+hxax=bR;t-S^u*r%8<(3OAkyI9Obc(rIAu72ySpUs)3Z0Bu|IW$&N*a93UEaq*=s65{V55 zmb|7CM#-Ee`4}}btS-7}K-2{j2Ob)&P#pm!ZPjMGD>L*)w2L=s@aykw6 zH&~dv#P5&7Y%Ah_2o02_WWTa` z5njn5hHWMOx`RIbFb5=GnH2f*D}C6%^)1gNjtB?D*8`^JsPyRa%5N`kyP?QGauHdQ)Y{u5R#sNgCVf0Xcb z`xTMdQ6suYbLnD%;OFK5bSso&R`NGNusr7 z#q7qGw~C0-=+BP>i+D>y6YNsm~E1e=Y2F$hr#x{uGyr%bs5yeDUGj8ln^s9LHU$mw&D`z8b8t%8aP^)nl#T52n^Vyf4=fcDX~T zu7K->&qAG4Omlh3cGxSCGOSByEkIY{N;rHQq{4Iv-e;AFD+uHJv;)}G;@z@av27#i z+97^jE+qfevxC4JH&zy+?k#CIiZ}zom$1Z+-yHHvVn?g_nQqU6)S%Tx`1r``UB=1Z zIma$IH?8SPqY3kG)$AhIY*4-=>XL?uNqUv3 zsgCps;aq&SMEBf4Yj~EIC9kLnrIJEs&C8?tqBU9nL!Cq9){>VXlpv!@rm*{V_Sw6Q1z>8}HqIJ&Ke}4{_HsCaZDD}DU>i5-N z<(bA==NACG5L2}&?2|qBTcpesgMcmQW4O=#*3`M_dz-4BQ={%iILtT6)QMP~Ct?}- z#r8QDPIlbs=Kr9=OJlWqX~h!_oS@K_52wB=JY0^Oxv!&y5h1$s|70g|5FGUQjJ9Gy zw+Gu{v6tui>U|*e;nyPCU$q?%>^6%6TyaA>7Sms7}96Bhu}Kq zGUg4SrW#xH&0Wi+16QCj+!S&b=JeyMAq)_c9>w9bhzY`+Xy^MiJ;{?>f|>Ezw5V5X z@Ht(+%Jvll-fdgWtp8Mn)Xb;Os7DSin*`AA?tQPZ;Pq)?OpfIg!$C5RbvuLc918daXcg0PXX*nUbkPAv(PrApbUPc zewGp2s4{J)n}6Z0`WJ$i@tmqJu>8@aCALiLuFT|G6WExQ&xH1J;#K8Jb`*cz*Qu3F z9>M_*eq*@beKP^-X8RSH8mdEUQ0<{OoIs;+ezsAGOvOQutqG558Tt$928^!zz5mJ= zMGD2^MDZT#s-)0wf)vBqaWU#|KQ@8^QjC-&mdZe=jv{?TiZTr7^q23dVuu|3x>zag z)IaVg8yQ$BfacmlGOp486TWotH^j~rp_dymUrMsvQ!5p$6m#Hz_&ii`owI4VFnuvk z5d{f^IC*&uEjWjg_LVFb2MmPr(}GPM{a#>^sah3P0c`WfmEVg3GT4&4M^_fsP5-5! zz~DJ596YB$6wrgwT#e~H@wZgC`Cu{TxHN`h?GOH)_jLomWL+)I&*}3#%{4)Y-UqOD zsW_1Minhj9JkDf14vza~h8Bc)Z8lC{dY-E}$9I8{_ED3W3P7wF>t_x^kpoVVl!vg> zOFA=9S5!`>Q|D@r?<;^aAd!r9f)?zo>>HVkje;lwe0j=Ib&XORy;6&_MQv4u7kFPW2BSvA7JGa zdb0u($(3&(3lbk!2Vd>K{^jhowNb9@yP0$a!Vj3$U>3{Ew@hJGpa`qk=C3xZmT8f` zm-aQZBmz9I3%{$(-!;)5?Q7RCGD{hqs%&_{28qO*&qaLO?u759HI*&D`|lk!ys)Xp zzSVC)E3NkjA({Xv?anMfVMDYbit)cDwp+LUkrLB@NwalSMxDgP<;9CfK-xeMbi49D z#w63l(qPj5<+t?Tnc?5(wI3$jIAko}ks!YWosMX2yqxddTx>-JH<1H`0dK5AdmZ)E ziZt`k%jfz;p+|3si3n=38Bg-((iu1Fr)Aa)q=DR2tf!ArzaT~#vrwIbtKPP0<~NW9 zO!M5gdAfdqF*no4$v9Ul3Wk^=h)nYT}SStYlSt|NZaGUe_V) z;^vN{j|knVLYW)O+r9vEUi#%qYT=r!f;=xYvOTv&>Vx3~=}Imt`~Hjr^_Q^L)0;>6 z-x9`%6hn|OjVPLd&W@(K;HPy#WGAboENj92B5mk*++vZw(I;%feyI7>m%&+C_XhVV zBJKtmv#le`^EQy98;$4>fRy2wF2TufOaipODnhg}j*`6`Sj;J4w)3}t!D28#z-!?!>yR*qC@2wG#hv^^HhZ=(cwp$zNUWqliuglu4K|}&h`CHp zciQXU9Cu#jhX&XX$=hn_R#ekg+gRG+{NZ8z^)^qi1K^P)kvM_38T@B{2De&TR$kun z>Brn}G7*n2`myWJyODV$C+<`vwuJo zG{Jivj2 zdU)shDOAI8Bg0NIe-)s1=$2H3mnefKPLOUClMF&yIV+z^0`C`h7Y9%ulLpNE%;vVj zrEi{9wk;k?bG16sYymUEOD;~w^C=Barqs_cO&HP`Q=_q-i^5CfpyA=5^`%ZHSbci| z3A(g=3l^ZcW?o9p-jJM3UH%iLx>!HxnT~EC5yPb4$C()ysD8)c{En0uhuT&(jF=Eh zj54Z36&?NUZh@G$6CJg-#iXlosR3Z>?|Sz5*eR*T?b3b3t#D|e8FdhP-NtYoI#c2x z2BFU)J!(raG|@<8M<*Er?=*;|iip&-xrw_!w{X>KM9EGY>S_EY4LaT&@51EH`_bNubhPL_Bd(< zZ^7w81Gbeh#g3-4sxmM+_A`}n%3Qo}%lQ4VN!o-BlXOVTLPUT{Bjz+!~S4{#HS}te$sC zpML^oSISjjwL4j)&OoY}z{GN9&a0jK-zDq;t%5c!yCM$2lI*{Zr<0N_w~nH7)a#oL z)+g}1{Z6T7AQEAU2*!|sp`%gneqs9kwL9{qSZUQ7`jMG5ZTIy#+vIEZa@!1pjHM3^ zX^z#_*7R}QODNx^p{H7rYnFf%T5ikuzFzlDT(!#*iB#4bow51^f%NZ`d=zNpz0h1Y z5NOsQ%=DWrM5$LSuPWX1eUr<;J{nm4R{F;O&e4}g#L83E_w#bFt|Rb2U^-f41mLd( zjnFS!bi>AiJDcgsIqJelg18My`tqaX249WUG8z&lf~~73W1%2gM~0hN;VHcg>o1M~ za&!>?JsF5c*y51y8e~TWZaX#4=W)v9G;W>0T47F=dVR+TkNwGZBn3=>sI{tfo7v_~ z1+R|Wb|nz>JjtWC0NTAb9`MoK|53>rJ1%AqJ{e#*oWROgBuy3OHuH{}ASLHd=s4ED^23I!} zQJo04Q!z-kvJk`s0fxNhw%8aRq4MJS7IX>K!L~Cpf=C>Hb)8>mqKg|VQ9;mvPnUIY zZ{06b1s97FHf+F3A_Lb|wYDkn_n@Dq=$|Uxe@ghLz^|s@7P)*hC_b>J&CCxMgBM2o z1$Y(c2;}7kYs%1EJ=^e>!(KS=kbS>Y{(fzl5nhiz4y6iD z>>zsg1(=dCPb!)%BTReZw;n4R-68D?-jDQvokg#?j_D?!NB*#|$?=+c{iQ2Rz8^Jg z8*PRV9|+~-24*6J)rAv~`$XQVV9N(HHSyE>POv%qMsLf7h5}e;4Xsv7O@SOaFLMzm z$lJ;(5r4A5Wm26qTmS)l=t2qw^F^OfC1C4I!tzVGYp?%=SaYsX!Jg z9-f(nL9Y>w{g+?CRe3;Iv>+M2KP@ump$p_HHqY)#TbI5{JR+k8NDbYQ+bI0c1RMDc zS0gI2{Uxc~s}E~`eT0RVp6}^{SHWL&X`iqw8C$fq3Aj zB~gzrRK5$8fsHL2uvPf6t)Kf}_Q~h%a15EW!u)R;g-8wEEk@=OL~fq*j%{34v3P_& z2%jTm3RQgxWmsjGRZ#dtDOmqaSFlqdGT?oY3Mq*5{}@X2QtOd1UhpK?R7C6(#;-6& z6fD2D*Y|0c*Yu$e;PdM-tRX2ynZKG~6VLa3u&uXScE3I@`TMI$!}f5nx1q3m^<1t= z9kW^m?2BP;8V4J*J?=g<7WbOz+8i@e0OZ=F1XT$nHgFqEBI4ML(NH{^Ypgk=cU?MJ zePv)vg{GtApws(1|f#mU|^dGBRQ^=^X!QNPK(aN0$<04XKIvINS1EPLcso%-yCv09xB;* zk&X`xK94Q_MzB2>HnCd(HsGyMg40Wi+1uyHiV7gS`VSm(;hBsKtbMbzssDZZ3PvGq z0nxO^AKU(?E#d-Y45|X#*b?kzP4;4x|4%Ph{twmr#fQO=4B1nbVeCTLcLrs~QVkKZ zgpze8OxBpmHbR&vDOD^_`Y8A!=3xw`NQI5EkmzQ;gqSNDh19`mi0S{-v72&dm=#e3AQQ0j|iMmf4{0Gc9E!TMXA zC=_C(S9BU^bSOmw4J{^LDZ;z#Hrj?|&9S6SCg*T(j?9T2tq(OgMcXS`n-8PBiiMLZ|mx8`udt- z6a*W(5^jq{f{9($AzZiAUmUvI`*}n-2ZuG&^lLCmppzBKf(N-uBFRj25Z;aW%ki2jp|aZ_@VMX zQwSi`9KAx3BHtKy2RSg!0J;(_7(ujKnKBp_5a~%DDPQ~Y9cV{B8Vcp16RxugS^)20 zNdvnWbj8Gh+D!IKEF{#+iga#H9EGixtMzXK%|CLENWb$5PFE=nKj_)N5Uk!+$@07S z3QTfbs;#%WEOY{HwB-Tt_i8h`{sJmyUH_2`TM5SU0c@=F0+^GI(jdR=fDc z+(a1$SCC4Lb10i^-9pq)qmo8I%Xluy9R1U0s*S{sJW+eDq2r0VO@|F+JktjVkX8yO zUENM_yFMQwKsmzsv>nrlGR6$I3#ZAx&tR2O+wt4_Tm5 zj)PtwExo<(7tJEigk*5Bt-JY}%ni?Wd*##gTd+N8ne!_i&u(OvpJTrW!iwYf*w%J_ zd=(T=ppJ5P`IJ{5%TSxidBxng9ce7&mOYpaWJs}cs3F%b6=1^Kp{_t-4>^eT1K}22 zo1pE7|7|lT7Z%@adD6?PLJ1r5T9H+6!krQan4%hZr{U z^Fz_iaY`a!8)mpHD*pWm5dCm-(GXQpWjMaQ^+xS2vWv|We5shg;&egvB$kh#dj_E` z;+knHui_z}4)kTo24Z9)k|x*6uRktdH^>f`Je5@}AP{d)`h;T6Y+~<-l_r{8G=Wc; z^Hz2D{REyr<*9#axqd6}(T}C+%K624{jop(n+Kb3s<#5!0wKiHg7pC-IIj{4zho!k z7QDTi0(VEW+4-1tF`riSs!R}e?LD$0^g+pa2yxSVi%?`Aq2tPxpa&|?dFlN7;K#GP z?&A~gU9x{1wbO-VS=!=20U4@)YtMD8Y}Yyn)wTTG@1t_v5hk|30vDveR%^S*Gs#JK z#Tur}`9sYS=6|K26Tg_!;qs}%5?08n5W&145b!Pj+XEZ6 z4p~RNsvk_oq+))Bm2EG-=~l)u9HFh#-!n4XxUTb05B8ls-j{Sf_I}2o)8pt777uOB z?%|A75JTF4)4WcsUFUepIg7dmI8w^-Pp_9BB%0;ln0@Eh{y0^sewx57Z9reU$igVL z~(-l&R_T9%!aZ2K1Cs@W~d&|Nxt%_3qMLJXY`Uxxe>+PN-$&Xn#& zJL)mzwz(O|I9LACuBYp_M}bCw#g$LxAH_#T&Yfh~Q8y5yo=8EG)re6g_1p|~?5ssC zWskidE9(Q*sqPLO&Md?-P`vbURx9;sx(cMD%!Ytf+=}-1#)#t>Ry*BFZBFWWe&@WdJEs?BT)PK^ntl5=z2P>DM zd8UI`M*=sx#Oez7)*}S4L^JtIa;B-3Zu7g81kv;dzWZ2~rB7>>^@X{_do&cjgM>>P zBYkk0cl}3pls&Ywcx;$#Sk9L94MTphh{3%DU~c9k&k{x1bAFQRMG;DsGO9Ybp1Fh6 zK1ZRAEeQY&A1i0<(e~t|74-Nga&SUFC*>XAn_RA;3Z!U}!oQWZ6Fojdm9KoB?!8nn zSJk-}Spdct56{X8{Aig&cx=PvF{wFyXAyK}Pv>_N6~=tq7h}^U=@ClXq>hwX&XIKxA zr~DWgGWB|y=NxSIEiW1vE1EIE}rdy7*h)Xhm)f}S_Dhdq=T40iT$U^>s zWQHZ$Tm22UTJ5ys;93$DX1%m;DTBVJ#T@fMwA&`Ygj?bEkREIQK z?d-iUjya>l4XS`O`SwlD-<%FS?=>h5R2}d#SSICh-|Cv;-YOjMJR4^Cjwf-)$^9Kw zUaITXksS{GrWskXX-?0&^Lbc;iiy4qt_Rd?Y;Tw+5S%|cBnxCwb?t?c{Q_^%!obC7 zO%gr(fy3AbQ@5WPy2TT?pY*^ge=)2*Ez_hcX~pzK&VIA6{-a8!bajiV9Wna-M~LwG z0m@hj)aP>9uLxcphyKfugQ2)(M_unrQ{&u=fDtKt6^11J5%v^R?wLCacd$xxLV+mJ zuc|=Ka{s94O^Sb>wDJpxB6vFnSS30<<+pCig@WK*S9%YQb03gv5ltL4nr6+0&n~Gb zX(g(zC5VH7Y)@!@H7SFbBKeBZTY)479xy!IkK1-5tF1Q*pTG8g+M%THnVzhQVfNr; zBFxq5XlF?u`Ob9r@5q^)eXrX5?~Hr+CYz`n!`AF;APD{&M#TK{cb`8K;5hBrF1;i# z>(#Y|TSRZJ&Q|f9KW-LZRU@aHLhnxm_|Dlx^D^S8@#*zpp?cK{EWe{>e75+xaWnRB z_pqag>VyZ@()7IP0I-VIemY<#~*#U-G;pwN+ zMcHni!3uw2K8CP8q>I3!GW#6g-&%$M7;Jb0Vd-u+;TW~zCVE75QI&mEp`be|rO(k# zWYL^noqxtP)1;wNB54KF!$K93`eqC5^ zvEnLc?!7+sqH-YO>bbMX+r+YBam$OY1Db8;b<$mYSU)P+1<p>njZ29Hzp+Qw}MB7EL5wli2Z3 zcyu_&w)T$7$cfqikg^_^4h4x2!NxBy;U9N@Dz<|oU?uXkcKZ!?UeSR~p zRr3n=S2llBVS8PjZk&SVH`ZoE7h{^6dM$TwAX4`24&L$lkF(N~tVBr;2Ak|ltpeG-9Eh^@(iftz~M-N2W zr;d;a0E=H~C??$WSP z@TslWtE89YSXw;8gBV&i^7s_W2eeS+< zz>jE$erRVck+{6-hiPA+Sn|{(>av7mEFbJYK+tuT!gq%AI$soKXq5p=f1Xg2==AG?Kb%;VL)fBUz1w#kKhDY6zO?|l zUTkxGh1p@X>*)Yl4PeRu85Mh9b6;xNf|hdZ)GGq=ypm0BVaGH`!e{(}N@aR5t9n1@ zXA#TeRqwoZf)4j}s)fx-AoOfy@93a*35 zJL9#==bCJC={GPLJ4&Z;N=4#80oUEdlUMr0ZD#OYIpE)~UtTEgCtS#8YD(8F=?;+g zW=m6wFvJmak^z_sokKr)w$C4RkECVF)Ph&5cP82nk)lukGG-j}Z}@xFW83y5b9umt z_G-s>GXyHk*T(h8Wi-ypSv55~hFe<>hvEw(C>bT!CX1nf`=$UtN0jy%9ho$sOpt9w zzTf9>JFeffTt+sf{$vDq#GuMgv%;w`%Gf3GyIn4s&ZXhY4yS;C^9if@eCUU05);nV zEn%9Mz)H_m><7_!Qcp7Kp7VQjDfShBL{F8+DSkob9SWQfG|1C6mtt5kp@kcLLlMGv zlWl2T*UwaVE!2jVK>NEGi|#Dy_=3SS@3zwNCRKxDKZUZ965xn%AV1MPD+QF(#UhH= zY91Py5g#&_fnO%Y`d$^ns+^8W<@&H>EPq}U4wSv9>A2^z=|akJVS?B*s+u^oKmgdD zZ(AAm?tX1@T`81w3-Be`u*Pka8Pc3giA*|aJuWwH;eJT<0Wa%~b4Wh!n)GZBGrBqF zq#0E!i_4~-01C5>g@&(TXG7D=OV diff --git a/apps/chatbot/src/webapp/user.png b/apps/chatbot/src/webapp/user.png deleted file mode 100644 index 4cc32ca73ae8351b5e5ed88ec2b4b64a46adace3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13491 zcmY*<2{_c>7xx_#DqE$ZWT|G-W@!-ynbKlX6tb_OEJckA|wPq zh0sC~_`?rspN2mR{P&W~7s9`gg|3nCyy&c% z+0P9H1_r8nczgM~IG=S>_3=A(e^_@lLQ06VZ;yFU(hqiUqANLcvo%1iY|egN6BV{+?A=NP|scFWiX&BLM7frClCFV&Y* z6F15v(GBqOTez~McQ}>AIc|5ien#<`!OYIhe$7{C**Y9gzr4+vn>mk@zR;64;51b| zGW@;ElFAPHmFRH1B}EQ~cmD`?L&@J{5%JYd{qIs{W7xS5dUL@=^vcq?n<<})N#ld< zNo`4EtDDCH2`%S|&9lwHU26DA1J0K~Sy5uSIzmQGQh$1J$(y-XXep2TBSL(X=Uz-n zQt!^RXpL5sC3CvJCrzr=d>xRNpQ=TTa#%F**smszAE2Q>YH}ywIvra!ULWX(hN8!2 zuXEhy-UZJECUHVlW!F?Z_X^jduG)sE#+zkANG%8+Y3LA~vQ&<_h$SDb_)C6}H+vT>E;FXUkglsUmh^iq0>)g&U-Bh;U6r)9zP z!X@YSYmTp1d5d)lblC7=cwsXE-!~;vzUkPddDq^1@vq#_Q1d%i z#nG9=4Z&TamulWeh~ZPSJH_bmpti#hUkuRvhH}8lj0tc2;stZ#HWaQRl1>HOPH8 zbJD1%R?*_+(dP|61CQr1z8VR>siP&KO%Z=W44BzDX4FsZud*}pLMBUcbf{B3%TQXb zos}xrhNNtrfx{%APxUSRVc(`|3IVY9$YSa;Nl1zD_Da3cbjt71g9|#gn3?#rZw@@J znPU$)Yy=#>H&f z1O}aNvYqu_(m8VrMcec}IFL(;Ad430i=z*omCcj)dp^$@#say4%q`ua*1be2ZkXXM5PSrD;BSBrf#u>0*~eAOjhR(8 zr|2uxu+MsvWKL419c0C0!de)@v9e%t`!9ug%ScUct3?HUQ+JcYiaD`PX9FV0VgSW} zgJb8a@~=yU)2%>aKJD4vCBq0Of*7X`GksZ0sn02HgO}fS$T*x}W7JV=aNo=OxMY`P z%)b4ho;@>gIBLbiM8;2f6kt(0x>F+w|gvF$ax^xvo~5;-WxQZd|Zj9QITmnhCvCuw+g>~~K8>A{nvW0jHnO}}pe zq)yvYPA8MlzEppQ^=)mFubj^E17X%KW27G5x7T>tGPAF2UrDcd;s22qe1hj~DO&T?J zx`A%GmmR2JDefAyvHcZ^U4XJAi45BFrvEgOG zx7Fi=ogjz9;;6C13n%X(kHOi4qS=sZKS}54#Oi{4^6W-&_O8ho`d-N+MIdxP7|ApHn<>9DqA_lZ?e7%44!f z?5=3fzLsn`mVzt$!gnY1;P}jhlBXWRd=eK+LPuu^G<|on=b0YjUkh zl)AJq)u(fxOCqH!(Uc{-R_k7o9;*X4dPgkcN$`k1b)kEEHpfa+34Ci}bRlkvwG`c3 z{e1AH0Ki4V#Bvan+$md86jXGeV$Ojl@(N;=9b05#ZUsCei%<`GwQu=CiwXvg!+-x! zjC@ew&~iMla-f4HAE_pS1O{TC`G+T|K5Xjm6UeFi?G=4#pIPj>>|@!wg$(C2bqws! zSE%~1U~WOd`_Wo;-Ijl^y6%Xj&@HV`p+sw|{EF8Mj9^^lOex(UcRgy%IhMV~j9qZ< zDOt290z(b`_FFOXg1Wf9?5-{s_J!Zh=qJw=7s6hou;_g4j=Br7i{vD#z#e7-+cLoR)ha`3BE0Kb5*e?K3N(`t+9thgP&}{* zT=BszGATIj5}r89^=S7pDex8qd3H79yv>*@AFpkq=nOw@&W zIwEL^zw?KnOJr=%1q_u9YKp37E=Sj;0wD$17ke8EgZej#EBYi;g8)yNc2*la01wou zMRMcVT)8Du;%Mll&pc7+a`b`Je^l&a02J!s&L7UgN;g3#_}fqcpwuu@UA#11^v`Ql zt!gKPXzRpN&m>a^T#%Ctuzz`BZJikq3>6SugkqOFzsbJv)KMIr6;p~;cmD9zf;c3D zMauxB*Ou)X6wCQL)X;8TbQ%8i&ho!LD^Tf^EW}oB!1JdV=bI4ADv{R62wjs_Em0*F z37%#JpSFkt3pZe-76#GWGs!3|8iTH35bo%kfA3!`Ksb{puUU&CcZnbzFt=c_RKY(A zzCsB1elHL01GFwvM#P@W&i_pk5R078+qVASl<$jbck>qf9agmoEdq=+3V6#QBkIKB zM>oh=!J?$qC6cJs!PuM0z`U5l4mqBND9efA>^hn)^TAai31hQ{7!)&H`kpRR6zG1J3`?HncKCLHPgC zTJ#-s7FMG1&+`yEGimg1AdPPek3V{Kt5%E0{MxS67zsOI7@5`*gox+0S~#oF2T)D= zgIY*xW6G&V7rb68CCx zyq|mj0}BZD#ETJYnZI+dNFyZ-a`zEpE;_)|?1*a)AdGR#}nDtJA%Lw82hUtr_Uu0oL;Ia4Er zV19rLeMtNJ*zkv_u0_d!Wg-2zD{*5ewy1`HtxgXPd+f@l27#{cdQmSMxs0=y z6RcR&{Lc$?l6v%diTi%v9SRq|ls=<*O;YJ z&tSR?4|j#NlxU-+zoRcn6QUzmXY_!KU0)R+@CY36%CHUR_p57t0s|`;Z7Iw{N)iCx zBu?@vaLKSSZ;=CGTOF1y2uM==KBpnOrft8nNmBfM~!=m!o}AG>}9DHyg!O5$ih zzP?=$-~eq+b-y@zKFEjkO;j&cP>JvX#$C_@`(~MZF_HeJcMEKvowCzC4J^W2J&^;$ zas1stXLv^Gd<+@O1m|#$ahTbXv!43mSD{{s=p|m>(_tb3;?v#O^<+|Qj~<5jE{W5j zr@zA;B1Ui(6|hew?he)};ulCuZ$f@QX&b1d2hs86Ktl%Dj7Ty4`+xSI8-MNfU!2%o z{pK>gidNJ{5RQbCxN$ygR2L#X@TJMy)PE_`xZMAM1!HSc5BBc}ir)nf2 zk%bcsfGv-S9GEj>+UD$_Zamv8HhX%w2qN1r3}J2^A_j`z2(i{xM6s#7siQz1(v50F z)U2@A-7LGQ|I~T!caX|qS@Kkfpfx3K96m(3LKlUE$s6KXgOt=Mf1achIDdwh(|1); z_N(kmx7MYke&mXl_CknB;;sDq(Z}h#GR?y1-ZNtip=m1Yb<2eA768Y0v0E<@HTuFW zA0tXM{VI8J>!#+h!MmqNqCf&VxwZoH;{+1mc~hbc$f=&IpRreakD>nYMCo7#Qfu)-lZbA7;)gy|$m{~uzqxY`e z$Tdi-RG{o4NXgZ(>$~Ildr6RZDe09TF8J6ou|`@vX6`LR*c}eK2hKx=mZHMdslyv$ zKtwA(NEClOLS@c&%UjV_fvmN-AZkee;J`qi-9`H z!7*BO1TOc^_Zwd8u1Qlvd*3K})FR@q+hSWfLT*<30a0f(B!6(uaJ?!&qcSmd$Nydw8UGgo@*Q7cI5b)h{FfVl!!mDk6xPZWna-p21hc-eo&H6p_P*pf^%}`HMvk z`aJW->fkVqINqNk#qaUIzDW(qDMK*Y_i`DDV?4iABaa)2OGV&xnPSgU z$<602)wOJ%4r9_{FlZ=KP$;q>af}GTIlU_O`)85os(ILIZ5hhlA)oTY{q|6P^@0U)u%Q1j z)ivw5TS@u10%*QXIj_BtR`8y)shm@lPzPSB@L8+~g62f1XIYU>nat}pyf}HlR~C-r zLl2ZwlQ>oSAk5EDPTdUURO7yvg&n#pw2YR9yf|tuN`-oY{f6K1oGC@YxfKp$m{bf3 z*jxHFb4u^R4m{MLGiga4acLTVWf3yZNf~i`i9JsphO#jGsOr{)fa~{MzCxXP?ImU3 zdlHEAed=yg^H}(>?)+-b7Y-P(2!^7N!1_5ow9_Io#oE^_$T&oarytIk|KJVd?FMGP zuI2pE_iZj?YEQm)I(z$|3U=vBgwh_^St)VDNfZX%1t+gF+ftt$tt@;-5j8gi&)ps? zKhhi=eztiwBPp=LKkrp<&;^Kp(J@xY>TlBH1IN@kzUmp6)|uGUfRvJt+9Q+Ar8<4( zsahQHR}s2lGLg!V7FqV~wO}qIi9HUVo}6rX+kB>FvD|Zoh9idF5&oandffkB+~5)Q zz1Z;6_oQ8<;XNd&LyRb?V5MM)oC`xp@9^??kGl%9&V?mX4-_=?56>xaCuzg+0bag_ z&xaGR6Bf}8*%|@oDjss$4djn|4UAF@-X)p)8%w9OUG`r+nN+Of0qgW96>EDGa`;qE zz{(-|QoZ4LdeH%-T6DU+$`IF%%h;?Dy57JTRt=8+p19Gf38XS*Sb z@~)VatbY7{cQ0K}xo`WuwmD$9MXzNFkW6{jw5NN8X0afiN^q}DNWb5zG8n{JY& zy`b2-9_3nTJg&T!l@}CbrWNb?->;0R z+S?>GyJ!C&gK!^+XkvO|=b8u$5~DAS6Gk4&+h`s;-pqKkqRr*2$*gs#9?Z^{V}-Jg z3~Uu43iTPiJw!MH(>rLA1uC9Va=5-IgXvuI!UD}Lb^P`-($jU1edXQQ+Z|zk7rU-{ zmUYBkUxaw^yAk0iv-{9nBf=Z44CxK{=tGPbT6FjF_ad1ko`>&V%i2BvRWkXw*N3Xn zOm>LLH|Fly9R2JP$J9<0mY%yJEdAYxa-AM%NI2N^=SSSIF{$?TTDGhF#Q>c%70q2c z^IC=yO{>U88QP?%Km3R*+M%O$8q>-=g+@iJQr$0ng&}jwGwh+7Z&h&P%N4XP>ov>` zye0H^Z?~ziw>^rM`qA3pF(Vh?Z2Vbfe6UU1(MwZuY$oQ#3H0i4B~BS^3E2L}zQ)VH zsBzD{UK`p$Sin^;a2N?X8=;z#v$??gDNFhZgKlX#E<%wmk*<@%DjoQR*K=eleBUbFMINSCj@5`>tM=TXmtK1X6 zuR;}la3D!!F@(UG{l_ju@!njbdy zoc!0te#Qj%3zZ$I9a+(}Syqz|u3?s7rfBg-(>Lfla&4Clmw1M0e$|0Bv^GPBaFZ0zZ@Rb<9@v|JyX)sq0Lh9s7LDCXFa=&IzrCrGe#UVQsvIxAul|gRO}Ew z_Ej=;v$xL=qwB9L7~!N;hah&raFI7@iwN}sH(}y*EZ>f|a=^=TH)+&_wRRxpjte2^ z&+WYMpoo;3?yzEt&~Yh;C%_-ih8MrH=iy5GU9&wYpI=3Uo0pq1^8v37gayfyJ@5D_ z=Sv2qq<(%=ToiX)IQ&bRk9baJF!1(j5mDwyRXK-8i?=Fq%CA)6e(8xFE|A=FK6m3F z{Y>2S;A3CC8iw%AK5cI7{^>^8QnytJeG&G75m0wvp29mQE%POlQseoRJ+TVKF*P%Q zP3F(*l@qO!6_K`o(ncO!Vf2-8xaPc=A}18Er;;v3qU4iBZJt>(|KMk_Cd+PQRJ}Ny z8sr|qI^1#lsdvqg%8xd7)OoUykIay+2vPJ%6=QOT=WdqFPyQB-`p21>=||p8llf5jJ;A2Aic=-uCKNfCLh1d?PcIS=7kW+lf;;7>+jKQ+ zQF2x2b!CqYHJA#@S?ko4HzXoQ9T9MjOgyd2gMFd6>>#rqXYa6vN%u7x%w27EGAr+< z&#KPup`0h34ACFY>6VkK+_v{}5mP?7(y~ZCR*k!!HrLF+%8x6P5=hf_zJ}pNF{Jx& zR-VtY-m6Fx{L`{>$Wnw;9;w6DU$R{^CH;S~yv3=z08R=Tj=fOa3K3=ki8MJK3B)-WE5S^h>@m6 z|D5YW>*1$a7@PCwRN@Gkrg1)OtlT@90h#Xb2;+ib!(}4G`(XT@)77AEvONsXT}*P^ zD9PR38~?#t`|Qj>FwJUk)niWSz zo_dpnM5=ZBj0omTDZIQV`{J9=^!`onSG-<3`+=}wv$5J>(Y36uD)QczM5+k^l(_QPhINr)v&G|U{^&aW;kqqufq3pWbnHmAj=11~BTfZ;V z?m3uE*`B30jO1IgFLNR=>QYm*N*q^E*seI^*+nWi#;gN)YYcmot=OMzmFd;A?|8j3lyj&l%^N#R?zt4KyXazA*54vdI6on#VroLCB#E_07g~@FgThg%-Vg^<>fM z{l{8zckzE6I+77%$q!IqUNQztG5@<}iqOnhFPIvu=JAN`g%69`W2w89JHbu;jGF~t zC3-qe;c40vX)lS2G}BJ83{Qf0d74`XLzkyYuYD*wAlALxGQV&*a=i#K>K9&qBUgqd zS?s+h>&z{_Evf3`SnBJwdhN~n?j4CM+YOT27m`m@JnZF3$lH4j6nNUdQ}(iXRWViY zU57i0r*I{L?Y-E`G{vba`-~U|n2t7qXvdRG?IpWR=1+ebpP&12iSjb&cvO=49dofq zUFzmOvRV0S`(7T^i#}R<;K_scM~|M_Xqnr<@maLbI^059RIPnaxz-bna^*7NDcV)& zC#R{c_n6|hq@PZuDRh0DReBJ2&Z506^pGZr5<@mhI-Ber5B}>o6VH-I)Ore-M+K|= zKBm&n!l1m%^8aRrY}B934n5 z)C>LpHprkhb%#;@BTiSwDO?u)0T8Q`6pMxtDjNQlO!?%&8wW}oU0_9Je3z*R@?Cz2 z5|mK~$_N5HE>5j@lTfsm2{|{U1to=P5F}N)vzNjLy~EvOEt-ZHB@C=3NOdVSX>k6Yvg=)n#x;h>!&RC)*r ze9NFBQhK=SCa<6^>Pt_B81@0zp0?8FAVLH$-sRnH>?JEQ6_LQ_QSOsPp(s;)c%Ze7 z#oG$(8qT7lV2Mc$DY&84UzB+)}QF0lSU3K+5PMdO6ej9Qy4QR+RD zSsv6RQ9x%g$=;Lgr1BiAimF^I>DvEEdWBG}{SJ#yU+`&X)je z(a@RX)(bEc3R+v~-pG&=4eckSex^L_IZI+CQwy1%uMkC}R<;`gzCbiqJUmcrE&*F; zxy={nNg`rE`)a>C_jaFVzdw_?8ugTfqiToKsfW7bFlIZ@FTC3${%knZZRU$jJh|7? zQoPvjk7TYwG!eW?A?$RY$wrT~teZB00cQ6^Q2jijhJGSsnps3Y;`nb{F`qU?le|;( zl7U4_?7_cwTy1_nJP>a#jz}ECU(otO?~4m*DVDD?+)#N90l~!s+j=tp?KZt;M!MWG zeOO=51R9b6uJ@Kwk23GEtOElKdPJ$ee<`8|!k?ANkI4p_I12i1G#D2U567ppyV%6z z8+U(h(eOagJ}E@Xk1c8i{47zEUI7XG!#3J(1U)HKbo$+8V+W1LIpl-N_;WDdW-~Zq z5XX%9;4e>!iY`Wa+%g@6OMdJ+{|AEz?#~`~+Gqxt()5+2=Y?S$=Y}Q!6iXuc_IFHm zdN>C87yBQY-BKR_1T%1cK#+3vc8sz%OkIE5JQF|3M%UJ$p5Kb7RYY1N_nEh#qzb8f zfs5%u{P>ERYkv~JF&|})3HJI^GgRlRBW!hV4}iETcDWUxmG;ooq~D+qiU5E4Z)(1t z;=*oSBo0(g7PuUWvW&rxG(X!XI9ikV0J=aH+Aoi0vEl-CoYF+70#LMK;*Lw$Xcj?r z7779%c0W?K)-19;Ap*El_&K4Eh@uc@XjeQ*unH_PI{{0Z;l>4uLd!HYV*Q|!R-+c^ zvLRfj`H_}lZ}$wG1T`)fXf4*pKw)pMk`=+*RJLA>JwNZ)AyeuGar6x-2!CRF2YiK!x6F5+>3I7Y@ma4 zMx(++cs|VHy8>k>U7*&BKd-OMUu{;$aH%|@2bBA8$xfikhBs{t@)SI;kn2NUQ;;Fy zn5h#ODZ>O$`%_k$jh0_T|AIR&yS-;#UMM9q`Se-hr2 zNXgOZUtbK0PgCQ{3LrJTb8n`?;BsEfR3xZ9e;>&j)SgJ_kfS^#*M__bM!K&7`mqkr zucmmg)fIge(6yjt(0@wFBFlUIdjY*R)M)NWc*Ssr&JO&paaHN^NsAssUzdUC4nJ2d z@!MLNfH|QJJ5q@&`XZ2(_xM$Z(`M3K-~wv3INpq z#HLd^N3MT!9+qkZ&;Di_Do?!=vtLLeW5MSQUT^bOo28QL?Ou5Uv=_HSLkOYAFZ+!y zIJmO6$vl-qw3ztYPr)D%X@e3K)eL9Vo_|2ycfihZ@$!01^-q1Iw7rL-Ok5*c-J1ib z`S6I8rh4q+CczRdrz`Tfp?;qKrzOS=4RLbqXLal6nVqbz6;{0TpgPgKx+|T zZ2MkPw0hXcg2)a4SP_xA7etNDbuJtS3|YMPM3Dj{EYR4i*T8sq+*b|>@U|{PVQ{11 z^BHtj2&g7e3?ghbi#B^>snWpu_jWnLhkv650$-;bV}iZ$8GQu?mT3EitX2}}P4M;J zHq^Td{bef&*s7-V<>=Vdzyzn1y`;)EUzU7sWD_t2M#UA7Ro!)&xs)X#co*9qtzWsvgL;=mfb)2$VwocHv+4iFJZ= z3w1^T#yNSp2r==?u@B7tiUQn@xM(?ug znASyKgyB2mL-~@8#{Z6@-B+j;1JES4zwVEw3NZQ!C$5bdSO9aB2DLB)=LvGCWwWFr3X5)TP zW_j8?sJ+#=u2>5%eH}-8AeRF zk_Eo9Bca2Ub#p#pUf>!NCj>|&`l$?e$Y@F`bBeULL1Y(S4V_pR8rSrsEAD+TOa900 zMA(lRjQk8GfN{Bq=e3OVEiH z(GvG9I(!Fd2(F;?#D?LxW`Z#Iw-uBm^j1}TWTdw((?gG;1b0s05BYAP8u1gncAVa? zKt~Aut{Y?>A{a5@Rw2Zw+9XjmrcS;h3;M6@*xwi>5>zMGb0z9lA?iXM_lIx$G^Xj~ zgC+D6$k5c+(9)~yQ@#aGE_Yd{gRAl6S7NA%{kQAIy>d^)XJ^6{n+R07p} zBT5{-l_88;oe&I+;hKyC z2}ODb)0H_9%|9c1VMU9t}Wbo?}Sq10A}?I z-{{?t9=eHBS1pey+Rt1}65PIp%s~{;w0z zE%RoQsLIh&{po!%x-H_OQq1H!KMmptu?9$b2OI|HX zKsLa?A})CYSCSx~ItYLOgcgR++Qz@1Ute%16(d&I_v zf2|H>LNx=fV5b8-bNh2IDz41Hpw<<}%x7V<9H==M?w;X9NK-)Z1S2kETA{3J zZ05f($(=1U6axde4Nr=598;UzimoR7E>grkF!+VnhL#$CH>rL#2hpG-9Fdb>#|#Ti zS8L_%5}11v=+qKUQx@jL79C)2{wa@sgc>c;O)nAAobPIG`z1q; zf=v!&7lgU6;|_=;m$pF3q;0dc2_o;0i6g7QMdtR2Z7mcbdxfCs#yaPYocqihf9uUL zw~K6=ww=9>>)yHW8uWfk#!qQfDrMN77h2)-hBt3B`E{u{H4<{1!%W9Rl+1f3Yjj^0 zFC>GOWpm9~|GFa|T0j*W7>UZ_n@B?=1{D z(;PHy_LX<)LcUi>hL4}TK6Km{-B#Olbc|Lroc?toNen+u8cd$!r07@BDB`sDcyTKK zSJHRwD=8UQIqjoKgDGZB{#k^KEROllqz$1a;ctT&p980#bGR8PZ9h6CyyD3EpGM}f ZO&e0|elF~A0Vjz_`;GVI?RC2Ne*l7hb87$q diff --git a/apps/infrastructure/src/modules/chatbot/cognito_user.tf b/apps/infrastructure/src/modules/chatbot/cognito_user.tf index 797f39629f..88b35aaa77 100644 --- a/apps/infrastructure/src/modules/chatbot/cognito_user.tf +++ b/apps/infrastructure/src/modules/chatbot/cognito_user.tf @@ -121,7 +121,7 @@ resource "aws_cognito_user_pool_client" "langfuse" { } resource "aws_cognito_user_pool_domain" "monitoring" { - domain = "monitoring" + domain = "monitoring${var.environment}" user_pool_id = aws_cognito_user_pool.monitoring.id } diff --git a/apps/infrastructure/src/modules/chatbot/data.tf b/apps/infrastructure/src/modules/chatbot/data.tf index a895dd6a5d..6aa3e88439 100644 --- a/apps/infrastructure/src/modules/chatbot/data.tf +++ b/apps/infrastructure/src/modules/chatbot/data.tf @@ -48,7 +48,9 @@ data "aws_iam_policy_document" "lambda_dynamodb_policy" { module.dynamodb_chatbot_queries.dynamodb_table_arn, "${module.dynamodb_chatbot_queries.dynamodb_table_arn}/*", module.dynamodb_chatbot_sessions.dynamodb_table_arn, - "${module.dynamodb_chatbot_sessions.dynamodb_table_arn}/*" + "${module.dynamodb_chatbot_sessions.dynamodb_table_arn}/*", + module.dynamodb_chatbot_salts.dynamodb_table_arn, + "${module.dynamodb_chatbot_salts.dynamodb_table_arn}/*" ] } } diff --git a/apps/infrastructure/src/modules/chatbot/dynamodb.tf b/apps/infrastructure/src/modules/chatbot/dynamodb.tf index 71183035be..0a2160b8d4 100644 --- a/apps/infrastructure/src/modules/chatbot/dynamodb.tf +++ b/apps/infrastructure/src/modules/chatbot/dynamodb.tf @@ -71,3 +71,21 @@ module "dynamodb_chatbot_sessions" { } ] } + +module "dynamodb_chatbot_salts" { + source = "git::github.com/terraform-aws-modules/terraform-aws-dynamodb-table.git?ref=715399dbe24f6443820bf5de80f6100b35d56355" # v4.0.0 + + billing_mode = "PAY_PER_REQUEST" + deletion_protection_enabled = false + + name = "${local.prefix}-salts" + hash_key = "sessionId" + server_side_encryption_enabled = true + + attributes = [ + { + name = "sessionId" + type = "S" + } + ] +} diff --git a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf index 5a7331ede0..ce85cb71d6 100644 --- a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf +++ b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf @@ -3,7 +3,6 @@ locals { CHB_AWS_S3_BUCKET = module.s3_bucket_llamaindex.s3_bucket_id CHB_AWS_GUARDRAIL_ID = awscc_bedrock_guardrail.guardrail.guardrail_id CHB_AWS_GUARDRAIL_VERSION = awscc_bedrock_guardrail_version.guardrail.version - CHB_AWS_BEDROCK_REGION = var.aws_chatbot_region CHB_REDIS_URL = "redis://${module.nlb.dns_name}:${var.ecs_redis.port}" CHB_WEBSITE_URL = "https://${var.dns_domain_name}" CORS_DOMAINS = var.environment == "dev" ? jsonencode(["https://www.${var.dns_domain_name}", "https://${var.dns_domain_name}", "http://localhost:3000"]) : jsonencode(["https://www.${var.dns_domain_name}", "https://${var.dns_domain_name}"]) @@ -17,14 +16,16 @@ locals { # Be extremely careful when changing the provider # both the generation and the embedding models would be changed # embeddings size change would break the application and requires reindexing - CHB_PROVIDER = "aws" - CHB_MODEL_ID = "mistral.mistral-large-2402-v1:0" - CHB_EMBED_MODEL_ID = "cohere.embed-multilingual-v3" - CHB_MODEL_MAXTOKENS = "768" - CHB_MODEL_TEMPERATURE = "0.3" - CHB_GOOGLE_API_KEY = module.google_api_key_ssm_parameter.ssm_parameter_name - CHB_QUERY_TABLE_PREFIX = local.prefix - CHB_LLAMAINDEX_INDEX_ID = module.index_id_ssm_parameter.ssm_parameter_name + CHB_PROVIDER = "aws" + CHB_AWS_BEDROCK_LLM_REGION = var.aws_chatbot_region + CHB_MODEL_ID = "mistral.mistral-large-2402-v1:0" + CHB_AWS_BEDROCK_EMBED_REGION = "eu-central-1" + CHB_EMBED_MODEL_ID = "amazon.titan-embed-text-v2:0" + CHB_MODEL_MAXTOKENS = "768" + CHB_MODEL_TEMPERATURE = "0.3" + CHB_GOOGLE_API_KEY = module.google_api_key_ssm_parameter.ssm_parameter_name + CHB_QUERY_TABLE_PREFIX = local.prefix + CHB_LLAMAINDEX_INDEX_ID = module.index_id_ssm_parameter.ssm_parameter_name } } diff --git a/apps/nextjs-website/.tmp-docs b/apps/nextjs-website/.tmp-docs new file mode 160000 index 0000000000..ff6582f21f --- /dev/null +++ b/apps/nextjs-website/.tmp-docs @@ -0,0 +1 @@ +Subproject commit ff6582f21f24f5fcddc910b11b5a92aff877733d diff --git a/package-lock.json b/package-lock.json index 5e054c02bf..cb7c44223b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19222,6 +19222,66 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.19.tgz", + "integrity": "sha512-vv1qrjXeGbuF2mOkhkdxMDtv9np7W4mcBtaDnHU+yJG+bBwa6rYsYSCI/9Xm5+TuF5SbZbrWO6G1NfTh1TMjvQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.19.tgz", + "integrity": "sha512-jyzO6wwYhx6F+7gD8ddZfuqO4TtpJdw3wyOduR4fxTUCm3aLw7YmHGYNjS0xRSYGAkLpBkH1E0RcelyId6lNsw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.19.tgz", + "integrity": "sha512-vdlnIlaAEh6H+G6HrKZB9c2zJKnpPVKnA6LBwjwT2BTjxI7e0Hx30+FoWCgi50e+YO49p6oPOtesP9mXDRiiUg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.19.tgz", + "integrity": "sha512-aU0HkH2XPgxqrbNRBFb3si9Ahu/CpaR5RPmN2s9GiM9qJCiBBlZtRTiEca+DC+xRPyCThTtWYgxjWHgU7ZkyvA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@next/swc-linux-x64-gnu": { "version": "13.4.19", "cpu": [ @@ -19250,6 +19310,51 @@ "node": ">= 10" } }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.19.tgz", + "integrity": "sha512-bUfDevQK4NsIAHXs3/JNgnvEY+LRyneDN788W2NYiRIIzmILjba7LaQTfihuFawZDhRtkYCv3JDC3B4TwnmRJw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.19.tgz", + "integrity": "sha512-Y5kikILFAr81LYIFaw6j/NrOtmiM4Sf3GtOc0pn50ez2GCkr+oejYuKGcwAwq3jiTKuzF6OF4iT2INPoxRycEA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.4.19", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.19.tgz", + "integrity": "sha512-YzA78jBDXMYiINdPdJJwGgPNT3YqBNNGhsthsDoWHL9p24tEJn9ViQf/ZqTbwSpX/RrkPupLfuuTH2sf73JBAw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "license": "MIT", From 4e4933de9df2786f2a3706ee42e27b71b10e050b Mon Sep 17 00:00:00 2001 From: tommaso1 Date: Thu, 19 Dec 2024 14:56:13 +0100 Subject: [PATCH 22/24] [DEV-1614] Add bulk import of contacts (#1273) * sync user wip * sync user * changeset * Update .changeset/cuddly-cats-retire.md Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/helpers/resyncUser.ts Co-authored-by: Marco Ponchia * pr comments * bulk add contact * bulk add contact * resync user * changeset * Update packages/active-campaign-client/src/clients/activeCampaignClient.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: Marco Ponchia * pr changes * Update packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/.env.example Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: Marco Ponchia * pr changes --------- Co-authored-by: t Co-authored-by: Marco Ponchia Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/loud-otters-unite.md | 5 ++ packages/active-campaign-client/.env.example | 1 + .../helpers/bulkAddContactToList.test.ts | 22 ++++++++ .../src/clients/activeCampaignClient.ts | 30 ++++++++++- .../src/helpers/bulkAddContactsToLists.ts | 52 +++++++++++++++++++ .../fetchSubscribedWebinarsFromDynamo.ts | 29 +++++++++++ .../src/types/bulkAddContactPayload.ts | 11 ++++ 7 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 .changeset/loud-otters-unite.md create mode 100644 packages/active-campaign-client/src/__tests__/helpers/bulkAddContactToList.test.ts create mode 100644 packages/active-campaign-client/src/helpers/bulkAddContactsToLists.ts create mode 100644 packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts create mode 100644 packages/active-campaign-client/src/types/bulkAddContactPayload.ts diff --git a/.changeset/loud-otters-unite.md b/.changeset/loud-otters-unite.md new file mode 100644 index 0000000000..6b7b9d4d7b --- /dev/null +++ b/.changeset/loud-otters-unite.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": patch +--- + +Add bulk import of contacts diff --git a/packages/active-campaign-client/.env.example b/packages/active-campaign-client/.env.example index c9ffddf5e6..3def88bcaa 100644 --- a/packages/active-campaign-client/.env.example +++ b/packages/active-campaign-client/.env.example @@ -7,3 +7,4 @@ COGNITO_USER_ID=66ae52a0-f051-7080-04a1-465b3a4f44cc LIST_NAME=test-webinar-1732097286071 AC_BASE_URL_PARAM='/ac/base_url' AC_API_KEY_PARAM='/ac/api_key' +TEST_AC_LIST_ID=28 diff --git a/packages/active-campaign-client/src/__tests__/helpers/bulkAddContactToList.test.ts b/packages/active-campaign-client/src/__tests__/helpers/bulkAddContactToList.test.ts new file mode 100644 index 0000000000..18d5dc3739 --- /dev/null +++ b/packages/active-campaign-client/src/__tests__/helpers/bulkAddContactToList.test.ts @@ -0,0 +1,22 @@ +import { bulkAddContactToList } from '../../helpers/bulkAddContactsToLists'; +import { User } from '../../types/user'; + +const user: User = { + username: '466e0280-9061-7007-c3e0-beb6be672f68', + email: `test@example${new Date().getTime()}e.com`, + given_name: 'Giovanni', + family_name: 'Doe', + 'custom:mailinglist_accepted': 'true', + 'custom:company_type': 'Test Co', + 'custom:job_role': 'Developer', +}; + +describe.skip('Active campaign integration contact flow', () => { + it('should bulk add contacts to a list', async () => { + const response = await bulkAddContactToList( + [user], + [[Number(process.env.TEST_AC_LIST_ID)]] + ); + expect(response.statusCode).toBe(200); + }); +}); diff --git a/packages/active-campaign-client/src/clients/activeCampaignClient.ts b/packages/active-campaign-client/src/clients/activeCampaignClient.ts index 7b3c12492f..e09f70bc38 100644 --- a/packages/active-campaign-client/src/clients/activeCampaignClient.ts +++ b/packages/active-campaign-client/src/clients/activeCampaignClient.ts @@ -3,6 +3,7 @@ import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'; import { ContactPayload } from '../types/contactPayload'; import { ListPayload } from '../types/listPayload'; import { ListStatusPayload } from '../types/listStatusPayload'; +import { BulkAddContactPayload } from '../types/bulkAddContactPayload'; async function getParameter( paramName: string, @@ -43,7 +44,11 @@ export class ActiveCampaignClient { private async makeRequest( method: string, path: string, - data?: ContactPayload | ListPayload | ListStatusPayload, + data?: + | ContactPayload + | ListPayload + | ListStatusPayload + | BulkAddContactPayload, params?: Record ): Promise { const [apiKey, baseUrl] = await Promise.all([ @@ -137,6 +142,29 @@ export class ActiveCampaignClient { return this.makeRequest('DELETE', `/api/3/lists/${id}`); } + async bulkAddContactToList( + contacts: readonly (ContactPayload & { + readonly listIds: readonly number[]; + })[] + ) { + const body = { + contacts: contacts.map((payload) => ({ + email: payload.contact.email, + first_name: payload.contact.firstName, + last_name: payload.contact.lastName, + phone: payload.contact.phone, + customer_acct_name: payload.contact.lastName, + fields: payload.contact.fieldValues.map((field) => ({ + id: Number(field.field), + value: field.value, + })), + subscribe: payload.listIds.map((listId) => ({ listid: listId })), + })), + }; + + return this.makeRequest('POST', `/api/3/import/bulk_import`, body); + } + async addContactToList(contactId: string, listId: number) { return this.makeRequest('POST', `/api/3/contactLists`, { contactList: { diff --git a/packages/active-campaign-client/src/helpers/bulkAddContactsToLists.ts b/packages/active-campaign-client/src/helpers/bulkAddContactsToLists.ts new file mode 100644 index 0000000000..fe1d6e2abe --- /dev/null +++ b/packages/active-campaign-client/src/helpers/bulkAddContactsToLists.ts @@ -0,0 +1,52 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; +import { acClient } from '../clients/activeCampaignClient'; +import { ContactPayload } from '../types/contactPayload'; +import { User } from '../types/user'; + +export async function bulkAddContactToList( + users: readonly User[], + listIds: readonly (readonly number[])[] +): Promise { + try { + // Transform to AC payload + const acPayload: readonly (ContactPayload & { + readonly listIds: readonly number[]; + })[] = users.map((user, index) => ({ + contact: { + email: user.email, + firstName: user.given_name, + lastName: user.family_name, + phone: `cognito:${user.username}`, + fieldValues: [ + { + field: '2', + value: user['custom:company_type'], + }, + { + field: '1', + value: user['custom:job_role'], + }, + { + field: '3', + value: + user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', + }, + ], + }, + listIds: listIds[index], + })); + + const response = await acClient.bulkAddContactToList(acPayload); + + return { + statusCode: 200, + body: JSON.stringify(response), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts b/packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts new file mode 100644 index 0000000000..ff17598aef --- /dev/null +++ b/packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts @@ -0,0 +1,29 @@ +import { DynamoDBClient, QueryCommand } from '@aws-sdk/client-dynamodb'; +import { APIGatewayProxyResult } from 'aws-lambda'; + +export async function fetchSubscribedWebinarsFromDynamo( + username: string +): Promise { + try { + const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION }); + const command = new QueryCommand({ + TableName: process.env.DYNAMO_WEBINARS_TABLE_NAME, + KeyConditionExpression: 'username = :username', + ExpressionAttributeValues: { + ':username': { S: username }, + }, + }); + + const response = await dynamoClient.send(command); + console.log('getWebinarSubscriptions', response); + return { + statusCode: 200, + body: JSON.stringify(response.Items), + }; + } catch (error) { + return { + statusCode: 500, + body: JSON.stringify({ message: 'Internal server error' }), + }; + } +} diff --git a/packages/active-campaign-client/src/types/bulkAddContactPayload.ts b/packages/active-campaign-client/src/types/bulkAddContactPayload.ts new file mode 100644 index 0000000000..dea49a5db2 --- /dev/null +++ b/packages/active-campaign-client/src/types/bulkAddContactPayload.ts @@ -0,0 +1,11 @@ +export type BulkAddContactPayload = { + readonly contacts: readonly { + readonly email: string; + readonly first_name: string; + readonly last_name: string; + readonly phone: string | undefined; + readonly customer_acct_name: string; + readonly fields: readonly { readonly id: number; readonly value: string }[]; + readonly subscribe: readonly { readonly listid: number }[]; + }[]; +}; From fb6d962a0f98105e118f44d001e71637b4971377 Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Thu, 19 Dec 2024 15:54:07 +0100 Subject: [PATCH 23/24] [DEV-2071] Fix ac env var lifecycle (#1280) * Fix lifcecycle env variable * update package lock * Apply suggestions from code review Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * fix after review --------- Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/empty-lies-sniff.md | 5 +++++ .../src/api/webinar/content-types/webinar/lifecycles.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/empty-lies-sniff.md diff --git a/.changeset/empty-lies-sniff.md b/.changeset/empty-lies-sniff.md new file mode 100644 index 0000000000..9b3ae26daa --- /dev/null +++ b/.changeset/empty-lies-sniff.md @@ -0,0 +1,5 @@ +--- +"strapi-cms": patch +--- + +Fix env variable in lifecycle diff --git a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts index 5bfe1df738..227b174c80 100644 --- a/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts +++ b/apps/strapi-cms/src/api/webinar/content-types/webinar/lifecycles.ts @@ -13,7 +13,7 @@ interface IActiveCampaignListPayload { } function getActiveCampaignIntegrationIsEnabled() { - return env('ACTIVE_CAMPAIGN_INTEGRATION_ENABLED', 'false') === 'true'; + return env('ACTIVE_CAMPAIGN_INTEGRATION_IS_ENABLED', 'False') === 'True'; } function getHeaders() { From 3f202f734fb1d77aaec3ba4e581bc448d9c30204 Mon Sep 17 00:00:00 2001 From: Marco Ponchia Date: Fri, 20 Dec 2024 11:16:50 +0100 Subject: [PATCH 24/24] [DEV-2064] Refactor resync error handler (#1285) * sync user wip * sync user * changeset * Update .changeset/cuddly-cats-retire.md Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/index.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/helpers/resyncUser.ts Co-authored-by: Marco Ponchia * pr comments * bulk add contact * bulk add contact * resync user * changeset * Update packages/active-campaign-client/src/clients/activeCampaignClient.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: Marco Ponchia * pr changes * Update packages/active-campaign-client/src/helpers/fetchSubscribedWebinarsFromDynamo.ts Co-authored-by: Marco Ponchia * Update packages/active-campaign-client/.env.example Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts Co-authored-by: Marco Ponchia * pr changes * add makeContactPayload * Add types * refactor AC client * add getListByName return type * refactor getListIdByName and add error manage to sqsQueueHandler * Add addOrUpdateContact helper * add getNewWebinarsAndUnsubsriptionLists * add addArrayOfListToContact and removeArrayOfListFromContact helpers * Update resync user handlers * Fix manageError * Fix after merge * add changeset * Fix list ac client call * Refactor env var for test * fix make payload * fix resync function * Apply suggestions from code review Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> * Fix after review * Apply suggestions from code review Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --------- Co-authored-by: t Co-authored-by: tommaso1 Co-authored-by: marcobottaro <39835990+marcobottaro@users.noreply.github.com> --- .changeset/khaki-knives-unite.md | 5 + packages/active-campaign-client/.env.example | 11 ++- .../helpers/manageListSubscription.test.ts | 8 +- .../src/clients/activeCampaignClient.ts | 47 ++++++++-- .../src/handlers/resyncUserHandler.ts | 93 +++++++++---------- .../src/handlers/sqsQueueHandler.ts | 42 +++++++-- .../src/helpers/addArrayOfListToContact.ts | 36 +++++++ .../src/helpers/addContact.ts | 27 +----- .../src/helpers/addOrUpdateContact.ts | 14 +++ .../src/helpers/deleteContact.ts | 2 +- .../getNewWebinarsAndUnsubsriptionLists.ts | 54 +++++++++++ .../src/helpers/makeContactPayload.ts | 28 ++++++ .../src/helpers/manageListSubscription.ts | 36 ++++--- .../helpers/removeArrayOfListFromContact.ts | 36 +++++++ .../src/helpers/updateContact.ts | 28 +----- .../src/types/activeCampaignList.ts | 4 + .../src/types/contactResponse.ts | 12 +++ 17 files changed, 344 insertions(+), 139 deletions(-) create mode 100644 .changeset/khaki-knives-unite.md create mode 100644 packages/active-campaign-client/src/helpers/addArrayOfListToContact.ts create mode 100644 packages/active-campaign-client/src/helpers/addOrUpdateContact.ts create mode 100644 packages/active-campaign-client/src/helpers/getNewWebinarsAndUnsubsriptionLists.ts create mode 100644 packages/active-campaign-client/src/helpers/makeContactPayload.ts create mode 100644 packages/active-campaign-client/src/helpers/removeArrayOfListFromContact.ts create mode 100644 packages/active-campaign-client/src/types/activeCampaignList.ts create mode 100644 packages/active-campaign-client/src/types/contactResponse.ts diff --git a/.changeset/khaki-knives-unite.md b/.changeset/khaki-knives-unite.md new file mode 100644 index 0000000000..74981dd781 --- /dev/null +++ b/.changeset/khaki-knives-unite.md @@ -0,0 +1,5 @@ +--- +"active-campaign-client": minor +--- + +Refactor resyncUserHandler to align contacts and subscriptions in Active Campaign diff --git a/packages/active-campaign-client/.env.example b/packages/active-campaign-client/.env.example index 3def88bcaa..3dad1f2978 100644 --- a/packages/active-campaign-client/.env.example +++ b/packages/active-campaign-client/.env.example @@ -1,10 +1,11 @@ -AC_BASE_URL=your_account_url -AC_API_KEY=your_api_key SENDER_URL=localhost:3000 AWS_REGION="region" -AWS_USER_POOL_ID="region_DFWF81fRa" -COGNITO_USER_ID=66ae52a0-f051-7080-04a1-465b3a4f44cc -LIST_NAME=test-webinar-1732097286071 +COGNITO_USER_POOL_ID="your_region" AC_BASE_URL_PARAM='/ac/base_url' AC_API_KEY_PARAM='/ac/api_key' + +TEST_AC_BASE_URL=your_account_url +TEST_AC_API_KEY=your_api_key TEST_AC_LIST_ID=28 +TEST_COGNITO_USER_ID=66ae52a0-f051-7080-04a1-465b3a4f44cc +TEST_LIST_NAME=test-webinar-1732097286071 diff --git a/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts b/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts index a49abb0dd2..b9b6ee49b4 100644 --- a/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts +++ b/packages/active-campaign-client/src/__tests__/helpers/manageListSubscription.test.ts @@ -1,12 +1,12 @@ // remove .skip to run the test, be aware it does real API calls import { addContactToList, - removeContactToList, + removeContactFromList, } from '../../helpers/manageListSubscription'; describe.skip('manage list subscription', () => { - const cognitoUserId = process.env.COGNITO_USER_ID || ''; - const listName = process.env.LIST_NAME || ''; + const cognitoUserId = process.env.TEST_COGNITO_USER_ID || ''; + const listName = process.env.TEST_LIST_NAME || ''; it('should subscribe the contact to the list', async () => { const result = await addContactToList(cognitoUserId, listName); @@ -15,7 +15,7 @@ describe.skip('manage list subscription', () => { }); it('should unsubscribe the contact from the list', async () => { - const result = await removeContactToList(cognitoUserId, listName); + const result = await removeContactFromList(cognitoUserId, listName); expect(result.statusCode).toBe(200); }); }); diff --git a/packages/active-campaign-client/src/clients/activeCampaignClient.ts b/packages/active-campaign-client/src/clients/activeCampaignClient.ts index e09f70bc38..608f6c776c 100644 --- a/packages/active-campaign-client/src/clients/activeCampaignClient.ts +++ b/packages/active-campaign-client/src/clients/activeCampaignClient.ts @@ -4,6 +4,13 @@ import { ContactPayload } from '../types/contactPayload'; import { ListPayload } from '../types/listPayload'; import { ListStatusPayload } from '../types/listStatusPayload'; import { BulkAddContactPayload } from '../types/bulkAddContactPayload'; +import { + ContactResponse, + ContactResponseWithLists, +} from '../types/contactResponse'; +import { ActiveCampaignList } from '../types/activeCampaignList'; + +const MAX_NUMBER_OF_LISTS = '1000'; async function getParameter( paramName: string, @@ -52,8 +59,9 @@ export class ActiveCampaignClient { params?: Record ): Promise { const [apiKey, baseUrl] = await Promise.all([ - getParameter(this.apiKeyParam, this.ssm, process.env.AC_API_KEY), - getParameter(this.baseUrlParam, this.ssm, process.env.AC_BASE_URL), + // Fallback env variable exists only for manual testing purposes + getParameter(this.apiKeyParam, this.ssm, process.env.TEST_AC_API_KEY), + getParameter(this.baseUrlParam, this.ssm, process.env.TEST_AC_BASE_URL), ]); return new Promise((resolve, reject) => { // Parse the base URL to get hostname and path and remove any trailing slashes from the baseUrl @@ -109,29 +117,42 @@ export class ActiveCampaignClient { } async createContact(data: ContactPayload) { - return this.makeRequest('POST', '/api/3/contacts', data); + return this.makeRequest('POST', '/api/3/contacts', data); } async updateContact(contactId: string, data: ContactPayload) { - return this.makeRequest('PUT', `/api/3/contacts/${contactId}`, data); + return this.makeRequest( + 'PUT', + `/api/3/contacts/${contactId}`, + data + ); } async deleteContact(contactId: string) { return this.makeRequest('DELETE', `/api/3/contacts/${contactId}`); } - async getContactByCognitoId(cognitoId: string) { + async getContactByCognitoUsername(cognitoUsername: string) { const response = await this.makeRequest<{ readonly contacts: ReadonlyArray<{ readonly id: string }>; - }>('GET', '/api/3/contacts', undefined, { phone: `cognito:${cognitoId}` }); + }>('GET', '/api/3/contacts', undefined, { + phone: `cognito:${cognitoUsername}`, + }); return response?.contacts?.[0]?.id; } + async getContact(id: string) { + return await this.makeRequest( + 'GET', + `/api/3/contacts/${id}` + ); + } + async createList(data: ListPayload) { return this.makeRequest('POST', '/api/3/lists', data); } - async getListIdByName(name: string) { + async getListIdByName(name: string): Promise { const response = await this.makeRequest<{ readonly lists: ReadonlyArray<{ readonly id: number }>; }>('GET', '/api/3/lists', undefined, { 'filters[name][eq]': name }); @@ -142,6 +163,18 @@ export class ActiveCampaignClient { return this.makeRequest('DELETE', `/api/3/lists/${id}`); } + async getLists(ids?: readonly string[]) { + const limitParams = { limit: MAX_NUMBER_OF_LISTS }; + return this.makeRequest<{ readonly lists: readonly ActiveCampaignList[] }>( + 'GET', + '/api/3/lists', + undefined, + ids && ids.length > 0 + ? { ids: ids.join(','), ...limitParams } + : limitParams + ); + } + async bulkAddContactToList( contacts: readonly (ContactPayload & { readonly listIds: readonly number[]; diff --git a/packages/active-campaign-client/src/handlers/resyncUserHandler.ts b/packages/active-campaign-client/src/handlers/resyncUserHandler.ts index a9edc97d5d..2d82df59c8 100644 --- a/packages/active-campaign-client/src/handlers/resyncUserHandler.ts +++ b/packages/active-campaign-client/src/handlers/resyncUserHandler.ts @@ -1,74 +1,65 @@ import { deleteContact } from '../helpers/deleteContact'; import { getUserFromCognitoUsername } from '../helpers/getUserFromCognito'; -import { getSubscribedWebinars } from '../helpers/getSubscribedWebinars'; -import { addContact } from '../helpers/addContact'; import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda'; -import { addContactToList } from '../helpers/manageListSubscription'; import { queueEventParser } from '../helpers/queueEventParser'; +import { addOrUpdateContact } from '../helpers/addOrUpdateContact'; +import { getNewWebinarsAndUnsubsriptionLists } from '../helpers/getNewWebinarsAndUnsubsriptionLists'; +import { addArrayOfListToContact } from '../helpers/addArrayOfListToContact'; +import { removeArrayOfListFromContact } from '../helpers/removeArrayOfListFromContact'; export async function resyncUserHandler(event: { readonly Records: SQSEvent['Records']; }): Promise { try { + console.log('resyncUserHandler: Event:', event); // TODO: Remove after testing const queueEvent = queueEventParser(event); const cognitoUsername = queueEvent.detail.additionalEventData.sub; - const deletionResult = await deleteContact(cognitoUsername); - if ( - deletionResult.statusCode !== 200 && - deletionResult.statusCode !== 404 - ) { - // eslint-disable-next-line functional/no-throw-statements - throw new Error('Error adding contact'); - } const user = await getUserFromCognitoUsername(cognitoUsername); + console.log('user:', user); // TODO: Remove after testing + if (!user) { - console.log( - `User: ${cognitoUsername} not present on Cognito, sync done.` - ); - return { - statusCode: 200, - body: JSON.stringify({ - message: 'User not present on Cognito, sync done.', - }), - }; - } + const deletionResult = await deleteContact(cognitoUsername); + if ( + deletionResult.statusCode !== 200 && + deletionResult.statusCode !== 404 + ) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Error deleting contact'); + } + } else { + const contactResponse = await addOrUpdateContact(user); - const userWebinarsSubscriptions = await getSubscribedWebinars( - cognitoUsername - ); + console.log('contactResponse:', contactResponse); // TODO: Remove after testing - const webinarIds = JSON.parse(userWebinarsSubscriptions.body) - .map( - (webinar: { readonly webinarId: { readonly S: string } }) => - webinar?.webinarId?.S - ) - .filter(Boolean); + const { listsToUnsubscribe, newWebinarSlugs } = + await getNewWebinarsAndUnsubsriptionLists( + contactResponse, + cognitoUsername + ); - const res = await addContact(user); - if (res.statusCode !== 200) { - // eslint-disable-next-line functional/no-throw-statements - throw new Error('Error adding contact'); - } + const resyncTimeoutMilliseconds: number = parseInt( + process.env.AC_RESYNC_TIMEOUT_IN_MS || '1000' + ); - await webinarIds.reduce( - async ( - prevPromise: Promise, - webinarId: string - ) => { - await prevPromise; - try { - const result = await addContactToList(cognitoUsername, webinarId); - console.log('Add contact to list result:', result, webinarId); // TODO: Remove after testing - await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 sec to avoid rate limiting - } catch (e) { - console.error('Error adding contact to list', e); // TODO: Remove after testing - } - }, - Promise.resolve() - ); + const subscriptionsresult = await addArrayOfListToContact({ + webinarSlugs: newWebinarSlugs, + cognitoUsername: cognitoUsername, + resyncTimeoutMilliseconds, + }); + const unsubscriptionsResult = await removeArrayOfListFromContact({ + listsToUnsubscribe, + contactId: contactResponse.contact.id, + resyncTimeoutMilliseconds, + }); + + if (!subscriptionsresult || !unsubscriptionsResult) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Error managing list subscriptions'); + } + } return { statusCode: 200, body: JSON.stringify({ message: 'User resynced' }), diff --git a/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts b/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts index 3522ef77fb..dac54b2352 100644 --- a/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts +++ b/packages/active-campaign-client/src/handlers/sqsQueueHandler.ts @@ -6,9 +6,21 @@ import { deleteContact } from '../helpers/deleteContact'; import { queueEventParser } from '../helpers/queueEventParser'; import { addContactToList, - removeContactToList, + removeContactFromList, } from '../helpers/manageListSubscription'; +function manageError(result: APIGatewayProxyResult) { + if (result.statusCode === 500) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Internal server error'); + } + + return { + statusCode: 200, + body: JSON.stringify(result), + }; +} + export async function sqsQueueHandler(event: { readonly Records: SQSEvent['Records']; }): Promise { @@ -17,20 +29,30 @@ export async function sqsQueueHandler(event: { const queueEvent = queueEventParser(event); switch (queueEvent.detail.eventName) { case 'ConfirmSignUp': - return await addContact(await getUserFromCognito(queueEvent)); + return manageError( + await addContact(await getUserFromCognito(queueEvent)) + ); case 'UpdateUserAttributes': - return await updateContact(await getUserFromCognito(queueEvent)); + return manageError( + await updateContact(await getUserFromCognito(queueEvent)) + ); case 'DeleteUser': - return await deleteContact(queueEvent.detail.additionalEventData.sub); + return manageError( + await deleteContact(queueEvent.detail.additionalEventData.sub) + ); case 'DynamoINSERT': - return await addContactToList( - queueEvent.detail.additionalEventData.sub, - queueEvent.webinarId || '' + return manageError( + await addContactToList( + queueEvent.detail.additionalEventData.sub, + queueEvent.webinarId || '' + ) ); case 'DynamoREMOVE': - return await removeContactToList( - queueEvent.detail.additionalEventData.sub, - queueEvent.webinarId || '' + return manageError( + await removeContactFromList( + queueEvent.detail.additionalEventData.sub, + queueEvent.webinarId || '' + ) ); default: // eslint-disable-next-line functional/no-throw-statements diff --git a/packages/active-campaign-client/src/helpers/addArrayOfListToContact.ts b/packages/active-campaign-client/src/helpers/addArrayOfListToContact.ts new file mode 100644 index 0000000000..e009290fbd --- /dev/null +++ b/packages/active-campaign-client/src/helpers/addArrayOfListToContact.ts @@ -0,0 +1,36 @@ +import { addContactToList } from './manageListSubscription'; + +export async function addArrayOfListToContact(event: { + readonly webinarSlugs: ReadonlyArray; + readonly cognitoUsername: string; + readonly resyncTimeoutMilliseconds: number; +}) { + const { webinarSlugs, cognitoUsername, resyncTimeoutMilliseconds } = event; + // eslint-disable-next-line functional/prefer-readonly-type + const subscriptionsWithErrors: string[] = []; + await webinarSlugs.reduce( + async (prevPromise: Promise, webinarSlug: string) => { + await prevPromise; + try { + const result = await addContactToList(cognitoUsername, webinarSlug); + console.log('Add contact to list result:', result, webinarSlug); // TODO: Remove after testing + await new Promise((resolve) => + setTimeout(resolve, resyncTimeoutMilliseconds) + ); // wait to avoid rate limiting + } catch (e) { + subscriptionsWithErrors.push(webinarSlug); + } + }, + Promise.resolve() + ); + + if (subscriptionsWithErrors.length > 0) { + console.error( + 'Error adding contact to list', + subscriptionsWithErrors.join(',') + ); + return false; + } + + return true; +} diff --git a/packages/active-campaign-client/src/helpers/addContact.ts b/packages/active-campaign-client/src/helpers/addContact.ts index 1b5c843d9d..022548a828 100644 --- a/packages/active-campaign-client/src/helpers/addContact.ts +++ b/packages/active-campaign-client/src/helpers/addContact.ts @@ -1,34 +1,11 @@ import { APIGatewayProxyResult } from 'aws-lambda'; import { acClient } from '../clients/activeCampaignClient'; -import { ContactPayload } from '../types/contactPayload'; import { User } from '../types/user'; +import { makeContactPayload } from './makeContactPayload'; export async function addContact(user: User): Promise { try { - // Transform to AC payload - const acPayload: ContactPayload = { - contact: { - email: user.email, - firstName: user.given_name, - lastName: user.family_name, - phone: `cognito:${user.username}`, - fieldValues: [ - { - field: '2', - value: user['custom:company_type'], - }, - { - field: '1', - value: user['custom:job_role'], - }, - { - field: '3', - value: - user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', - }, - ], - }, - }; + const acPayload = makeContactPayload(user); const response = await acClient.createContact(acPayload); diff --git a/packages/active-campaign-client/src/helpers/addOrUpdateContact.ts b/packages/active-campaign-client/src/helpers/addOrUpdateContact.ts new file mode 100644 index 0000000000..2f25e23ffa --- /dev/null +++ b/packages/active-campaign-client/src/helpers/addOrUpdateContact.ts @@ -0,0 +1,14 @@ +import { User } from '../types/user'; +import { makeContactPayload } from './makeContactPayload'; +import { acClient } from '../clients/activeCampaignClient'; + +export async function addOrUpdateContact(user: User) { + const contactId = await acClient.getContactByCognitoUsername(user.username); + + const acPayload = makeContactPayload(user); + const { contact } = contactId + ? await acClient.updateContact(contactId, acPayload) + : await acClient.createContact(acPayload); + + return await acClient.getContact(contact.id); +} diff --git a/packages/active-campaign-client/src/helpers/deleteContact.ts b/packages/active-campaign-client/src/helpers/deleteContact.ts index 085c6bc1a8..1a984ce14b 100644 --- a/packages/active-campaign-client/src/helpers/deleteContact.ts +++ b/packages/active-campaign-client/src/helpers/deleteContact.ts @@ -5,7 +5,7 @@ export async function deleteContact( cognitoId: string ): Promise { try { - const contactId = await acClient.getContactByCognitoId(cognitoId); + const contactId = await acClient.getContactByCognitoUsername(cognitoId); if (!contactId) { return { diff --git a/packages/active-campaign-client/src/helpers/getNewWebinarsAndUnsubsriptionLists.ts b/packages/active-campaign-client/src/helpers/getNewWebinarsAndUnsubsriptionLists.ts new file mode 100644 index 0000000000..35a5f38484 --- /dev/null +++ b/packages/active-campaign-client/src/helpers/getNewWebinarsAndUnsubsriptionLists.ts @@ -0,0 +1,54 @@ +import { acClient } from '../clients/activeCampaignClient'; +import { fetchSubscribedWebinarsFromDynamo } from './fetchSubscribedWebinarsFromDynamo'; +import { ContactResponseWithLists } from '../types/contactResponse'; + +const AC_STATUS_SUBSCRIBED = '1'; + +export async function getNewWebinarsAndUnsubsriptionLists( + contactResponse: ContactResponseWithLists, + cognitoUsername: string +) { + const listIds = contactResponse.contactLists + .filter(({ status }) => status === AC_STATUS_SUBSCRIBED) + .map(({ list }) => list); + + console.log('idsParams:', listIds); // TODO: Remove after testing + const getListResponse = await acClient.getLists(listIds); + // eslint-disable-next-line functional/prefer-readonly-type + const contactCurrentlySubscribedLists: { name: string; id: string }[] = + getListResponse.lists.map(({ name, id }) => ({ name, id })); + + const userWebinarsSubscriptions = await fetchSubscribedWebinarsFromDynamo( + cognitoUsername + ); + + const webinarSlugs: readonly string[] = JSON.parse( + userWebinarsSubscriptions.body + ) + .map( + (webinar: { readonly webinarId: { readonly S: string } }) => + webinar?.webinarId?.S + ) + .filter(Boolean); + + // eslint-disable-next-line functional/prefer-readonly-type + const newWebinarSlugs: string[] = []; + + webinarSlugs.forEach((webinarSlug) => { + const index = contactCurrentlySubscribedLists.findIndex( + ({ name }) => name === webinarSlug + ); + if (index >= 0) { + contactCurrentlySubscribedLists.splice(index, 1); + } else { + newWebinarSlugs.push(webinarSlug); + } + }); + + const listsToUnsubscribe: readonly number[] = + contactCurrentlySubscribedLists.map(({ id }) => Number(id)); + console.log('listsToUnsubscribe:', listsToUnsubscribe); // TODO: Remove after testing + console.log('New webinar Slugs:', newWebinarSlugs); // TODO: Remove after testing + + return { listsToUnsubscribe, newWebinarSlugs }; +} diff --git a/packages/active-campaign-client/src/helpers/makeContactPayload.ts b/packages/active-campaign-client/src/helpers/makeContactPayload.ts new file mode 100644 index 0000000000..f848b453e0 --- /dev/null +++ b/packages/active-campaign-client/src/helpers/makeContactPayload.ts @@ -0,0 +1,28 @@ +import { ContactPayload } from '../types/contactPayload'; +import { User } from '../types/user'; + +export function makeContactPayload(user: User): ContactPayload { + return { + contact: { + email: user.email, + firstName: user.given_name, + lastName: user.family_name, + phone: `cognito:${user.username}`, + fieldValues: [ + { + field: '2', + value: user['custom:company_type'], + }, + { + field: '1', + value: user['custom:job_role'], + }, + { + field: '3', + value: + user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', + }, + ], + }, + }; +} diff --git a/packages/active-campaign-client/src/helpers/manageListSubscription.ts b/packages/active-campaign-client/src/helpers/manageListSubscription.ts index fe610f656b..ddf6c237ce 100644 --- a/packages/active-campaign-client/src/helpers/manageListSubscription.ts +++ b/packages/active-campaign-client/src/helpers/manageListSubscription.ts @@ -2,20 +2,27 @@ import { APIGatewayProxyResult } from 'aws-lambda'; import { acClient } from '../clients/activeCampaignClient'; export async function addContactToList( - cognitoId: string, + cognitoUsername: string, listName: string ): Promise { try { - const contactId = await acClient.getContactByCognitoId(cognitoId); + const contactId = await acClient.getContactByCognitoUsername( + cognitoUsername + ); if (!contactId) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Contact not found'); + } + + const listId = await acClient.getListIdByName(listName); + + if (!listId) { return { statusCode: 404, - body: JSON.stringify({ message: 'Contact not found' }), + body: JSON.stringify({ message: 'List not found' }), }; } - const listId = await acClient.getListIdByName(listName); - const response = await acClient.addContactToList(contactId, listId); return { statusCode: 200, @@ -30,21 +37,28 @@ export async function addContactToList( } } -export async function removeContactToList( - cognitoId: string, +export async function removeContactFromList( + cognitoUsername: string, listName: string ): Promise { try { - const contactId = await acClient.getContactByCognitoId(cognitoId); + const contactId = await acClient.getContactByCognitoUsername( + cognitoUsername + ); if (!contactId) { + // eslint-disable-next-line functional/no-throw-statements + throw new Error('Contact not found'); + } + + const listId = await acClient.getListIdByName(listName); + + if (!listId) { return { statusCode: 404, - body: JSON.stringify({ message: 'Contact not found' }), + body: JSON.stringify({ message: 'List not found' }), }; } - const listId = await acClient.getListIdByName(listName); - const response = await acClient.removeContactFromList(contactId, listId); return { statusCode: 200, diff --git a/packages/active-campaign-client/src/helpers/removeArrayOfListFromContact.ts b/packages/active-campaign-client/src/helpers/removeArrayOfListFromContact.ts new file mode 100644 index 0000000000..e53be7400d --- /dev/null +++ b/packages/active-campaign-client/src/helpers/removeArrayOfListFromContact.ts @@ -0,0 +1,36 @@ +import { acClient } from '../clients/activeCampaignClient'; + +export async function removeArrayOfListFromContact(event: { + readonly listsToUnsubscribe: readonly number[]; + readonly contactId: string; + readonly resyncTimeoutMilliseconds: number; +}) { + const { listsToUnsubscribe, contactId, resyncTimeoutMilliseconds } = event; + // eslint-disable-next-line functional/prefer-readonly-type + const unsubscriptionsWithErrors: string[] = []; + await listsToUnsubscribe.reduce( + async (prevPromise: Promise, id: number) => { + await prevPromise; + try { + const result = await acClient.removeContactFromList(contactId, id); + console.log('Remove contact from list result:', result, id); // TODO: Remove after testing + await new Promise((resolve) => + setTimeout(resolve, resyncTimeoutMilliseconds) + ); // wait to avoid rate limiting + } catch (e) { + unsubscriptionsWithErrors.push(id.toString()); + } + }, + Promise.resolve() + ); + + if (unsubscriptionsWithErrors.length > 0) { + console.error( + 'Error removing contact from list', + unsubscriptionsWithErrors.join(',') + ); + return false; + } + + return true; +} diff --git a/packages/active-campaign-client/src/helpers/updateContact.ts b/packages/active-campaign-client/src/helpers/updateContact.ts index 469b7b138d..9c9c71ada6 100644 --- a/packages/active-campaign-client/src/helpers/updateContact.ts +++ b/packages/active-campaign-client/src/helpers/updateContact.ts @@ -1,36 +1,14 @@ import { APIGatewayProxyResult } from 'aws-lambda'; import { acClient } from '../clients/activeCampaignClient'; -import { ContactPayload } from '../types/contactPayload'; import { User } from '../types/user'; +import { makeContactPayload } from './makeContactPayload'; export async function updateContact( user: User ): Promise { try { - const acPayload: ContactPayload = { - contact: { - email: user.email, - firstName: user.given_name, - lastName: user.family_name, - phone: `cognito:${user.username}`, - fieldValues: [ - { - field: '2', - value: user['custom:company_type'], - }, - { - field: '1', - value: user['custom:job_role'], - }, - { - field: '3', - value: - user['custom:mailinglist_accepted'] === 'true' ? 'TRUE' : 'FALSE', - }, - ], - }, - }; - const contactId = await acClient.getContactByCognitoId(user.username); + const acPayload = makeContactPayload(user); + const contactId = await acClient.getContactByCognitoUsername(user.username); if (!contactId) { return { statusCode: 404, diff --git a/packages/active-campaign-client/src/types/activeCampaignList.ts b/packages/active-campaign-client/src/types/activeCampaignList.ts new file mode 100644 index 0000000000..0ed43ba70e --- /dev/null +++ b/packages/active-campaign-client/src/types/activeCampaignList.ts @@ -0,0 +1,4 @@ +export type ActiveCampaignList = { + readonly id: string; + readonly name: string; +}; diff --git a/packages/active-campaign-client/src/types/contactResponse.ts b/packages/active-campaign-client/src/types/contactResponse.ts new file mode 100644 index 0000000000..e72fe264fd --- /dev/null +++ b/packages/active-campaign-client/src/types/contactResponse.ts @@ -0,0 +1,12 @@ +export type ContactResponse = { + readonly contact: { + readonly id: string; + }; +}; + +export type ContactResponseWithLists = { + readonly contactLists: ReadonlyArray<{ + readonly list: string; + readonly status: string; + }>; +} & ContactResponse;