From a0ab602e009b80e94958f2316955a7e6269dbb14 Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Wed, 12 Mar 2025 15:02:29 -0700 Subject: [PATCH 01/10] 26030 - Remove sbc-common-component vuex and upgrade vitest to 1.6.0 (#3284) Co-authored-by: Travis Semple <travis8814@gmail.com> --- auth-web/package-lock.json | 4011 +++++++++++++---- auth-web/package.json | 6 +- auth-web/src/App.vue | 50 +- .../account-info/AccountInfo.vue | 7 +- .../team-management/UserManagement.vue | 3 +- .../auth/common/ConfirmCancelButton.vue | 4 +- .../auth/create-account/AccountCreate.vue | 5 +- .../non-bcsc/AffidavitDownload.vue | 10 +- .../auth/manage-business/EntityManagement.vue | 4 +- .../auth/mixins/TeamManagementMixin.vue | 10 +- auth-web/src/main.ts | 14 +- auth-web/src/routes/index.ts | 18 +- auth-web/src/stores/app.ts | 25 +- auth-web/src/stores/index.ts | 14 +- auth-web/src/views/auth/AcceptInviteView.vue | 4 +- auth-web/src/views/auth/AccountDeactivate.vue | 4 +- .../src/views/auth/ChooseAuthMethodView.vue | 6 +- auth-web/src/views/auth/SigninView.vue | 4 +- auth-web/src/views/auth/SignoutView.vue | 2 - .../src/views/auth/TermsOfServiceView.vue | 4 +- .../create-account/AccountSetupLanding.vue | 10 +- .../auth/create-account/AccountSetupView.vue | 4 +- .../DuplicateAccountWarningView.vue | 4 +- .../create-account/GovmAccountSetupView.vue | 5 +- .../NonBcscAccountSetupView.vue | 4 +- .../non-bcsc/NonBcscAdminInviteSetupView.vue | 4 +- .../tests/unit/services/codes.service.spec.ts | 18 +- .../tests/unit/services/task.service.spec.ts | 43 +- auth-web/tests/unit/setup.ts | 10 + .../unit/views/ChooseAuthMethodView.spec.ts | 15 +- .../unit/views/GovmAccountSetupView.spec.ts | 26 +- auth-web/tests/unit/views/SignoutView.spec.ts | 9 - auth-web/vite.config.ts | 4 +- auth-web/volar.config.js | 4 +- 34 files changed, 3281 insertions(+), 1084 deletions(-) diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index 63c8d9c446..88f4942548 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -1,12 +1,12 @@ { "name": "auth-web", - "version": "2.8.16", + "version": "2.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "auth-web", - "version": "2.8.16", + "version": "2.9.0", "dependencies": { "@bcrs-shared-components/base-address": "2.0.39", "@bcrs-shared-components/bread-crumb": "1.0.8", @@ -29,7 +29,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "3.0.15-a", + "sbc-common-components": "3.1.1", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", @@ -77,7 +77,7 @@ "vite-plugin-environment": "^1.1.3", "vite-plugin-rewrite-all": "^1.0.1", "vite-plugin-vue2": "^2.0.3", - "vitest": "^0.34.6", + "vitest": "^1.6.0", "vue-class-component": "^7.1.0", "vue-cli-plugin-vuetify": "^2.0.3", "vue-template-compiler": "2.6.14", @@ -86,6 +86,62 @@ "vuex-module-decorators": "^1.2.0" } }, + "../../sbc-common-components/vue/sbc-common-components": { + "version": "3.1.1", + "license": "Apache-2.0", + "dependencies": { + "@mdi/font": "^4.5.95", + "axios": "^1.8.1", + "clickout-event": "^1.1.2", + "core-js": "^3.1.4", + "country-list": "^2.2.0", + "jsdom": "^26.0.0", + "keycloak-js": "^26.2.0", + "launchdarkly-js-client-sdk": "^2.16.1", + "lodash.uniqueid": "^4.0.1", + "postcss-nesting": "^13.0.1", + "provinces": "^1.11.0", + "regenerator-runtime": "^0.13.3", + "vite": "^4.5.9", + "vue": "^2.6.11", + "vue-i18n": "^8.0.0", + "vue-router": "^3.0.3", + "vue2-filters": "^0.7.1", + "vuelidate": "^0.7.4", + "vuetify": "^2.1.5" + }, + "devDependencies": { + "@types/vuelidate": "^0.7.4", + "@typescript-eslint/eslint-plugin": "^2.3.1", + "@typescript-eslint/parser": "^2.3.1", + "@vitest/coverage-v8": "^1.6.0", + "@vue/babel-preset-app": "^5.0.8", + "@vue/composition-api": "^1.7.2", + "@vue/eslint-config-standard": "^4.0.0", + "@vue/eslint-config-typescript": "^4.0.0", + "@vue/test-utils": "1.0.0-beta.29", + "axios-mock-adapter": "^1.17.0", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.16.0", + "eslint-plugin-vue": "^5.2.3", + "mutationobserver-shim": "^0.3.7", + "node-fetch": "^2.7.0", + "pinia": "^2.1.6", + "sass": "~1.32.12", + "sass-loader": "^7.2.0", + "typescript": "^5.8.2", + "vite-plugin-environment": "^1.1.3", + "vite-plugin-vue2": "^2.0.3", + "vitest": "^1.6.0", + "vue-class-component": "^7.1.0", + "vue-cli-plugin-vuetify": "^2.0.3", + "vue-plugin-helper-decorator": "^0.0.11", + "vue-property-decorator": "^8.5.1", + "vue-template-compiler": "^2.6.14", + "vuepress": "^0.14.11" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -989,6 +1045,22 @@ "postcss-selector-parser": "^6.0.13" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -996,6 +1068,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -1011,6 +1084,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -1026,6 +1100,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -1041,6 +1116,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -1056,6 +1132,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -1071,6 +1148,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -1086,6 +1164,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -1101,6 +1180,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1116,6 +1196,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1131,6 +1212,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1146,6 +1228,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1161,6 +1244,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1176,6 +1260,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1191,6 +1276,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1206,6 +1292,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1221,6 +1308,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1236,6 +1324,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -1251,6 +1340,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -1266,6 +1356,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -1281,6 +1372,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -1296,6 +1388,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -1311,6 +1404,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -1535,9 +1629,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -1634,6 +1728,253 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", + "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", + "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", + "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", + "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", + "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", + "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", + "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", + "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", + "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", + "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", + "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", + "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", + "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", + "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", + "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", + "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", + "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", + "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", + "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sentry-internal/browser-utils": { "version": "8.33.1", "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.1.tgz", @@ -1810,21 +2151,6 @@ "node": ">= 10" } }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "node_modules/@types/chai-subset": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", - "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", - "dev": true, - "dependencies": { - "@types/chai": "*" - } - }, "node_modules/@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1832,9 +2158,9 @@ "dev": true }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "node_modules/@types/json-schema": { "version": "7.0.12", @@ -1869,9 +2195,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz", - "integrity": "sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==" + "version": "22.13.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz", + "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==", + "peer": true, + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@types/sanitize-html": { "version": "2.11.0", @@ -2346,13 +2676,13 @@ } }, "node_modules/@vitest/expect": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", - "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, "dependencies": { - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "chai": "^4.3.10" }, "funding": { @@ -2360,13 +2690,13 @@ } }, "node_modules/@vitest/runner": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", - "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, "dependencies": { - "@vitest/utils": "0.34.6", - "p-limit": "^4.0.0", + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", "pathe": "^1.1.1" }, "funding": { @@ -2374,49 +2704,59 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", - "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "dependencies": { - "magic-string": "^0.30.1", + "magic-string": "^0.30.5", "pathe": "^1.1.1", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", - "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, "dependencies": { - "tinyspy": "^2.1.1" + "tinyspy": "^2.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", - "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@volar-plugins/vetur": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@volar-plugins/vetur/-/vetur-0.1.0.tgz", - "integrity": "sha512-Qaws7TI8d/kkjihSQrW/3YGqiLeLZ1dMjfxDBe4vJKhzXw82sN4+Wr8NwGf2s15KyVDPQTjkPHv6ukn4vFD9Og==", + "node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@volar-plugins/vetur": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@volar-plugins/vetur/-/vetur-0.1.0.tgz", + "integrity": "sha512-Qaws7TI8d/kkjihSQrW/3YGqiLeLZ1dMjfxDBe4vJKhzXw82sN4+Wr8NwGf2s15KyVDPQTjkPHv6ukn4vFD9Og==", "dev": true, "dependencies": { "@volar/vue-language-service-types": "^0.34.0", @@ -3292,10 +3632,25 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { "node": ">=0.4.0" } @@ -3360,7 +3715,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3458,7 +3813,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "devOptional": true, + "dev": true, "bin": { "atob": "bin/atob.js" }, @@ -3467,9 +3822,9 @@ } }, "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz", + "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3494,7 +3849,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "dev": true }, "node_modules/base64-js": { "version": "1.3.1", @@ -3513,7 +3868,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -3533,7 +3888,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3543,7 +3898,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "devOptional": true, + "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -3619,6 +3974,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -3719,7 +4086,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "funding": [ { "type": "individual", @@ -3751,11 +4118,6 @@ "node": ">=6.0" } }, - "node_modules/clickout-event": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/clickout-event/-/clickout-event-1.1.3.tgz", - "integrity": "sha512-Ttc8IzBpQv1GeruTfAcT4Gv8am0QIr9j625le/P4HnFjr3r9tYTqZHhrmWoWRGmauIG2v+W/Ub70Jl6TTWjleQ==" - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3792,7 +4154,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "devOptional": true + "dev": true }, "node_modules/condense-newlines": { "version": "0.2.1", @@ -3892,16 +4254,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/core-js": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", - "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/country-list": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/country-list/-/country-list-2.3.0.tgz", @@ -4018,7 +4370,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "devOptional": true, + "dev": true, "dependencies": { "css": "^2.0.0" } @@ -4027,7 +4379,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "devOptional": true, + "dev": true, "dependencies": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -4040,7 +4392,7 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "devOptional": true, + "dev": true, "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -4124,7 +4476,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10" } @@ -4296,6 +4648,19 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -4443,12 +4808,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "peer": true }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -4479,6 +4885,7 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -5659,6 +6066,100 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -5732,7 +6233,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "devOptional": true, + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5801,12 +6302,13 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -5831,12 +6333,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "devOptional": true + "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -5847,10 +6350,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -5904,19 +6409,52 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -5937,7 +6475,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "devOptional": true, + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5957,7 +6495,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -6009,6 +6547,17 @@ "node": ">= 4" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -6079,10 +6628,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "engines": { "node": ">= 0.4" }, @@ -6091,12 +6639,11 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -6111,6 +6658,17 @@ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", "dev": true }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -6191,6 +6749,15 @@ "node": ">= 6" } }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6252,7 +6819,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -6283,7 +6850,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "devOptional": true, + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6293,7 +6860,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "devOptional": true + "dev": true }, "node_modules/ini": { "version": "1.3.8", @@ -6340,7 +6907,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6452,7 +7019,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6470,7 +7037,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -6494,7 +7061,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.12.0" } @@ -6565,6 +7132,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -6819,47 +7398,12 @@ "js-sha256": "0.9.0" } }, - "node_modules/launchdarkly-js-client-sdk": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/launchdarkly-js-client-sdk/-/launchdarkly-js-client-sdk-2.24.2.tgz", - "integrity": "sha512-8jrLOia0vfZ4stqQRv9TjAYfRGK2JyWpLIL6PbTl99LqTtJMuYtryFUQp0b8WH1153YN+gVdoqPVI7uwbbzLLQ==", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "launchdarkly-js-sdk-common": "3.8.2" - } - }, - "node_modules/launchdarkly-js-client-sdk/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launchdarkly-js-sdk-common": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/launchdarkly-js-sdk-common/-/launchdarkly-js-sdk-common-3.8.2.tgz", - "integrity": "sha512-pEqZ3FTKtYrTaPdbPntFJs87svzcezrkoRWY2GEFmyPC33txOqU788x0yby2+haC/saFPNfXpH6bbiJE/GjMSA==", - "dependencies": { - "base64-js": "^1.3.0", - "fast-deep-equal": "^2.0.1", - "uuid": "^3.3.2" - } - }, - "node_modules/launchdarkly-js-sdk-common/node_modules/fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "peer": true, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "peer": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -6892,10 +7436,14 @@ } }, "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", "dev": true, + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, "engines": { "node": ">=14" }, @@ -6979,15 +7527,20 @@ } }, "node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "engines": { - "node": ">=12" + "node": ">= 0.4" } }, "node_modules/merge-source-map": { @@ -7001,8 +7554,7 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "peer": true + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "node_modules/merge2": { "version": "1.4.1", @@ -7045,11 +7597,23 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7087,9 +7651,9 @@ } }, "node_modules/mlly/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -7099,9 +7663,9 @@ } }, "node_modules/mlly/node_modules/pathe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", - "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true }, "node_modules/moment": { @@ -7215,6 +7779,33 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -7266,9 +7857,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "version": "2.2.18", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", + "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", "dev": true }, "node_modules/object-assign": { @@ -7337,11 +7928,26 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "devOptional": true, + "dev": true, "dependencies": { "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -7371,24 +7977,24 @@ } }, "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, "dependencies": { "yocto-queue": "^1.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-limit/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.0.tgz", + "integrity": "sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==", "dev": true, "engines": { "node": ">=12.20" @@ -7424,12 +8030,12 @@ "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -7448,7 +8054,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -7516,15 +8122,15 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8.6" }, @@ -7578,15 +8184,15 @@ } }, "node_modules/pkg-types/node_modules/pathe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", - "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true }, "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "funding": [ { "type": "opencollective", @@ -7602,9 +8208,9 @@ } ], "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -7936,9 +8542,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } @@ -7988,7 +8594,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -8008,11 +8614,6 @@ "node": ">= 0.10" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -8094,7 +8695,7 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "devOptional": true + "dev": true }, "node_modules/reusify": { "version": "1.0.4", @@ -8110,6 +8711,7 @@ "version": "3.29.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -8182,7 +8784,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "dev": true }, "node_modules/sanitize-html": { "version": "2.13.0", @@ -8212,7 +8814,7 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.51.0.tgz", "integrity": "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -8229,7 +8831,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "devOptional": true + "dev": true }, "node_modules/saxes": { "version": "6.0.0", @@ -8244,132 +8846,8 @@ } }, "node_modules/sbc-common-components": { - "version": "3.0.15-a", - "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.0.15-a.tgz", - "integrity": "sha512-fY0FAtgZVo5AfPnmajUbXH+ZDDJHzVUqfgX6RY54eSiBLsduYpbsogGlOKR5P6IVio7GFIWktLkEGfhvv4qh7Q==", - "dependencies": { - "@mdi/font": "^4.5.95", - "axios": "^0.21.1", - "clickout-event": "^1.1.2", - "core-js": "^3.1.4", - "country-list": "^2.2.0", - "keycloak-js": "^26.2.0", - "launchdarkly-js-client-sdk": "^2.16.1", - "lodash.uniqueid": "^4.0.1", - "postcss-nesting": "^13.0.1", - "provinces": "^1.11.0", - "regenerator-runtime": "^0.13.3", - "vite": "^4.5.9", - "vue": "^2.6.11", - "vue-i18n": "^8.0.0", - "vue-router": "^3.0.3", - "vue2-filters": "^0.7.1", - "vuelidate": "^0.7.4", - "vuetify": "^2.1.5", - "vuex": "^3.1.2" - } - }, - "node_modules/sbc-common-components/node_modules/@csstools/selector-resolve-nested": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", - "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/sbc-common-components/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/sbc-common-components/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/sbc-common-components/node_modules/keycloak-js": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz", - "integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw==" - }, - "node_modules/sbc-common-components/node_modules/postcss-nesting": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", - "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "dependencies": { - "@csstools/selector-resolve-nested": "^3.0.0", - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/sbc-common-components/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sbc-common-components/node_modules/vuelidate": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.7.tgz", - "integrity": "sha512-pT/U2lDI67wkIqI4tum7cMSIfGcAMfB+Phtqh2ttdXURwvHRBJEAQ0tVbUsW9Upg83Q5QH59bnCoXI7A9JDGnA==", - "engines": { - "node": ">= 4.0.0", - "npm": ">= 3.0.0" - } + "resolved": "../../sbc-common-components/vue/sbc-common-components", + "link": true }, "node_modules/schema-utils": { "version": "2.7.1", @@ -8539,9 +9017,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -8561,7 +9039,7 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "devOptional": true + "dev": true }, "node_modules/sourcemap-codec": { "version": "1.4.8", @@ -8583,9 +9061,9 @@ "dev": true }, "node_modules/std-env": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", - "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", "dev": true }, "node_modules/string-width": { @@ -8651,6 +9129,18 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8664,34 +9154,28 @@ } }, "node_modules/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", "dev": true, "dependencies": { - "acorn": "^8.10.0" + "js-tokens": "^9.0.1" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/strip-literal/node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true }, "node_modules/stylus": { "version": "0.54.8", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", - "devOptional": true, + "dev": true, "dependencies": { "css-parse": "~2.0.0", "debug": "~3.1.0", @@ -8713,7 +9197,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "devOptional": true, + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -8722,7 +9206,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "devOptional": true, + "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -8734,13 +9218,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "devOptional": true + "dev": true }, "node_modules/stylus/node_modules/source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">= 8" } @@ -8963,15 +9447,15 @@ "peer": true }, "node_modules/tinybench": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", - "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true }, "node_modules/tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", "dev": true, "engines": { "node": ">=14.0.0" @@ -9012,7 +9496,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -9178,6 +9662,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "peer": true + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -9288,7 +9778,7 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "devOptional": true + "dev": true }, "node_modules/url-parse": { "version": "1.5.10", @@ -9305,15 +9795,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -9324,6 +9805,7 @@ "version": "4.5.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", + "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.18.10", @@ -9376,254 +9858,1203 @@ } }, "node_modules/vite-node": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", - "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", - "mlly": "^1.4.0", "pathe": "^1.1.1", "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-plugin-environment": { - "version": "1.1.3", + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite-node/node_modules/rollup": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", + "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.9", + "@rollup/rollup-android-arm64": "4.34.9", + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-freebsd-arm64": "4.34.9", + "@rollup/rollup-freebsd-x64": "4.34.9", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", + "@rollup/rollup-linux-arm-musleabihf": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", + "@rollup/rollup-linux-riscv64-gnu": "4.34.9", + "@rollup/rollup-linux-s390x-gnu": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-ia32-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9", + "fsevents": "~2.3.2" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-environment": { + "version": "1.1.3", "resolved": "https://registry.npmjs.org/vite-plugin-environment/-/vite-plugin-environment-1.1.3.tgz", "integrity": "sha512-9LBhB0lx+2lXVBEWxFZC+WO7PKEyE/ykJ7EPWCq95NEcCpblxamTbs5Dm3DLBGzwODpJMEnzQywJU8fw6XGGGA==", "dev": true, "peerDependencies": { - "vite": ">= 2.7" + "vite": ">= 2.7" + } + }, + "node_modules/vite-plugin-rewrite-all": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-1.0.1.tgz", + "integrity": "sha512-W0DAchC8ynuQH0lYLIu5/5+JGfYlUTRD8GGNtHFXRJX4FzzB9MajtqHBp26zq/ly9sDt5BqrfdT08rv3RbB0LQ==", + "dev": true, + "dependencies": { + "connect-history-api-fallback": "^1.6.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "vite": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/vite-plugin-vue2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.3.tgz", + "integrity": "sha512-t3Tu93GWsMHbpeIv66MTO5e/rRAo8/+/eWoUtFYuAdKDMyEnn1dqsrXh+CfG+SJAlxJvcTP8U0eXkzhLjKNyMg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.17.9", + "@babel/parser": "^7.17.9", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-decorators": "^7.17.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.17.3", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.17.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-typescript": "^7.16.8", + "@rollup/pluginutils": "^4.2.1", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-preset-jsx": "^1.2.4", + "@vue/component-compiler-utils": "^3.3.0", + "consolidate": "^0.16.0", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "hash-sum": "^2.0.0", + "magic-string": "^0.26.1", + "prettier": "^2.6.2", + "querystring": "^0.2.1", + "rollup": "^2.70.2", + "slash": "^3.0.0", + "source-map": "^0.7.3", + "vue-template-babel-compiler": "^1.2.0" + }, + "peerDependencies": { + "vite": "^2.0.0 || ^3.0.0 || ^4.0.0", + "vue-template-compiler": "^2.2.0" + } + }, + "node_modules/vite-plugin-vue2/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/vite-plugin-vue2/node_modules/consolidate": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", + "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", + "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/vite-plugin-vue2/node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-plugin-vue2/node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/vite-plugin-vue2/node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/vite-plugin-vue2/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/vite-plugin-rewrite-all": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-1.0.1.tgz", - "integrity": "sha512-W0DAchC8ynuQH0lYLIu5/5+JGfYlUTRD8GGNtHFXRJX4FzzB9MajtqHBp26zq/ly9sDt5BqrfdT08rv3RbB0LQ==", + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "connect-history-api-fallback": "^1.6.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "vite": "^2.0.0 || ^3.0.0 || ^4.0.0" + "node": ">=12" } }, - "node_modules/vite-plugin-vue2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.3.tgz", - "integrity": "sha512-t3Tu93GWsMHbpeIv66MTO5e/rRAo8/+/eWoUtFYuAdKDMyEnn1dqsrXh+CfG+SJAlxJvcTP8U0eXkzhLjKNyMg==", + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/core": "^7.17.9", - "@babel/parser": "^7.17.9", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-decorators": "^7.17.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.17.3", - "@babel/plugin-proposal-optional-chaining": "^7.16.7", - "@babel/plugin-transform-arrow-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.16.7", - "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.17.7", - "@babel/plugin-transform-parameters": "^7.16.7", - "@babel/plugin-transform-spread": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.8", - "@rollup/pluginutils": "^4.2.1", - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "@vue/babel-preset-jsx": "^1.2.4", - "@vue/component-compiler-utils": "^3.3.0", - "consolidate": "^0.16.0", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "hash-sum": "^2.0.0", - "magic-string": "^0.26.1", - "prettier": "^2.6.2", - "querystring": "^0.2.1", - "rollup": "^2.70.2", - "slash": "^3.0.0", - "source-map": "^0.7.3", - "vue-template-babel-compiler": "^1.2.0" - }, - "peerDependencies": { - "vite": "^2.0.0 || ^3.0.0 || ^4.0.0", - "vue-template-compiler": "^2.2.0" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/vite-plugin-vue2/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 8.0.0" + "node": ">=12" } }, - "node_modules/vite-plugin-vue2/node_modules/consolidate": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", - "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", - "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "bluebird": "^3.7.2" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 0.10.0" + "node": ">=12" } }, - "node_modules/vite-plugin-vue2/node_modules/magic-string": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { "node": ">=12" } }, - "node_modules/vite-plugin-vue2/node_modules/querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], "dev": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.4.x" + "node": ">=12" } }, - "node_modules/vite-plugin-vue2/node_modules/rollup": { - "version": "2.79.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", - "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest/node_modules/rollup": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", + "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.9", + "@rollup/rollup-android-arm64": "4.34.9", + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-freebsd-arm64": "4.34.9", + "@rollup/rollup-freebsd-x64": "4.34.9", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", + "@rollup/rollup-linux-arm-musleabihf": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", + "@rollup/rollup-linux-riscv64-gnu": "4.34.9", + "@rollup/rollup-linux-s390x-gnu": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-ia32-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9", "fsevents": "~2.3.2" } }, - "node_modules/vite-plugin-vue2/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/vitest": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", - "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "node_modules/vitest/node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.6", - "@vitest/runner": "0.34.6", - "@vitest/snapshot": "0.34.6", - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.10", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", - "vite-node": "0.34.6", - "why-is-node-running": "^2.2.2" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { - "vitest": "vitest.mjs" + "vite": "bin/vite.js" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", - "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { - "@edge-runtime/vm": { + "@types/node": { "optional": true }, - "@vitest/browser": { + "less": { "optional": true }, - "@vitest/ui": { + "lightningcss": { "optional": true }, - "happy-dom": { + "sass": { "optional": true }, - "jsdom": { + "sass-embedded": { "optional": true }, - "playwright": { + "stylus": { "optional": true }, - "safaridriver": { + "sugarss": { "optional": true }, - "webdriverio": { + "terser": { "optional": true } } }, - "node_modules/vitest/node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/vls": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/vls/-/vls-0.8.2.tgz", @@ -10570,11 +12001,6 @@ "resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz", "integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ==" }, - "node_modules/vue2-filters": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/vue2-filters/-/vue2-filters-0.7.2.tgz", - "integrity": "sha512-7I74isiBUQFGaNbVv57NzHGqh54cLe0JNJmJmu66wxP5eOK/CqHN4iqHMgwPPPvPbgbFbpI/GjbHiIx8tNruwg==" - }, "node_modules/vuelidate": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.6.2.tgz", @@ -10887,7 +12313,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "devOptional": true + "dev": true }, "node_modules/write": { "version": "1.0.3", @@ -10903,9 +12329,9 @@ } }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", "dev": true, "engines": { "node": ">=10.0.0" @@ -11638,136 +13064,165 @@ "dev": true, "requires": {} }, + "@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, "optional": true }, "@esbuild/android-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, "optional": true }, "@esbuild/android-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, "optional": true }, "@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, "optional": true }, "@esbuild/darwin-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, "optional": true }, "@esbuild/freebsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, "optional": true }, "@esbuild/linux-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, "optional": true }, "@esbuild/linux-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, "optional": true }, "@esbuild/linux-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, "optional": true }, "@esbuild/linux-mips64el": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, "optional": true }, "@esbuild/linux-ppc64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, "optional": true }, "@esbuild/linux-riscv64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, "optional": true }, "@esbuild/linux-s390x": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, "optional": true }, "@esbuild/linux-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, "optional": true }, "@esbuild/netbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, "optional": true }, "@esbuild/openbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, "optional": true }, "@esbuild/sunos-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, "optional": true }, "@esbuild/win32-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, "optional": true }, "@esbuild/win32-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, "optional": true }, "@esbuild/win32-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, "optional": true }, "@eslint-community/eslint-utils": { @@ -11931,9 +13386,9 @@ } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "@jridgewell/trace-mapping": { "version": "0.3.25", @@ -11986,20 +13441,153 @@ "resolved": "https://registry.npmjs.org/@pinia/testing/-/testing-0.1.3.tgz", "integrity": "sha512-D2Ds2s69kKFaRf2KCcP1NhNZEg5+we59aRyQalwRm7ygWfLM25nDH66267U3hNvRUOTx8ofL24GzodZkOmB5xw==", "dev": true, - "requires": { - "vue-demi": ">=0.14.5" - } + "requires": { + "vue-demi": ">=0.14.5" + } + }, + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", + "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", + "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", + "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", + "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", + "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", + "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", + "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", + "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", + "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", + "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", + "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", + "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", + "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", + "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", + "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", + "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", + "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", + "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", + "dev": true, + "optional": true }, - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "@rollup/rollup-win32-x64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", + "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } + "optional": true }, "@sentry-internal/browser-utils": { "version": "8.33.1", @@ -12146,21 +13734,6 @@ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, - "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "@types/chai-subset": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", - "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", - "dev": true, - "requires": { - "@types/chai": "*" - } - }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -12168,9 +13741,9 @@ "dev": true }, "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "@types/json-schema": { "version": "7.0.12", @@ -12205,9 +13778,13 @@ "dev": true }, "@types/node": { - "version": "17.0.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz", - "integrity": "sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==" + "version": "22.13.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz", + "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==", + "peer": true, + "requires": { + "undici-types": "~6.20.0" + } }, "@types/sanitize-html": { "version": "2.11.0", @@ -12523,56 +14100,68 @@ } }, "@vitest/expect": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", - "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, "requires": { - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "chai": "^4.3.10" } }, "@vitest/runner": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", - "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, "requires": { - "@vitest/utils": "0.34.6", - "p-limit": "^4.0.0", + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", "pathe": "^1.1.1" } }, "@vitest/snapshot": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", - "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "requires": { - "magic-string": "^0.30.1", + "magic-string": "^0.30.5", "pathe": "^1.1.1", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" } }, "@vitest/spy": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", - "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, "requires": { - "tinyspy": "^2.1.1" + "tinyspy": "^2.2.0" } }, "@vitest/utils": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", - "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, "requires": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "dependencies": { + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0" + } + } } }, "@volar-plugins/vetur": { @@ -13325,10 +14914,21 @@ "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "requires": { + "acorn": "^8.11.0" + }, + "dependencies": { + "acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true + } + } }, "agent-base": { "version": "6.0.2", @@ -13375,7 +14975,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "devOptional": true, + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -13449,12 +15049,12 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "devOptional": true + "dev": true }, "axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz", + "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -13476,7 +15076,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "dev": true }, "base64-js": { "version": "1.3.1", @@ -13492,7 +15092,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true + "dev": true }, "bluebird": { "version": "3.7.2", @@ -13509,7 +15109,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13519,7 +15119,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "devOptional": true, + "dev": true, "requires": { "fill-range": "^7.1.1" } @@ -13563,6 +15163,15 @@ "get-intrinsic": "^1.0.2" } }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -13636,7 +15245,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -13654,11 +15263,6 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "peer": true }, - "clickout-event": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/clickout-event/-/clickout-event-1.1.3.tgz", - "integrity": "sha512-Ttc8IzBpQv1GeruTfAcT4Gv8am0QIr9j625le/P4HnFjr3r9tYTqZHhrmWoWRGmauIG2v+W/Ub70Jl6TTWjleQ==" - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -13692,7 +15296,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "devOptional": true + "dev": true }, "condense-newlines": { "version": "0.2.1", @@ -13776,11 +15380,6 @@ "safe-buffer": "~5.1.1" } }, - "core-js": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", - "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==" - }, "country-list": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/country-list/-/country-list-2.3.0.tgz", @@ -13872,7 +15471,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "devOptional": true, + "dev": true, "requires": { "css": "^2.0.0" }, @@ -13881,7 +15480,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "devOptional": true, + "dev": true, "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -13893,7 +15492,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "devOptional": true, + "dev": true, "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -13959,7 +15558,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "devOptional": true + "dev": true }, "deep-eql": { "version": "4.1.4", @@ -14080,6 +15679,16 @@ "domhandler": "^5.0.3" } }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -14201,12 +15810,41 @@ "unbox-primitive": "^1.0.2" } }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "es-module-lexer": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "peer": true }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, "es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -14231,6 +15869,7 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, "requires": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", @@ -15069,6 +16708,72 @@ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "peer": true }, + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -15133,7 +16838,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "devOptional": true, + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -15181,12 +16886,13 @@ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, @@ -15205,19 +16911,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "devOptional": true + "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.5", @@ -15256,16 +16962,37 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" } }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -15280,7 +17007,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "devOptional": true, + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15294,7 +17021,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -15333,6 +17060,11 @@ } } }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -15388,18 +17120,16 @@ } }, "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" } }, "hash-sum": { @@ -15408,6 +17138,14 @@ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", "dev": true }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -15466,6 +17204,12 @@ "debug": "4" } }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -15513,7 +17257,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "devOptional": true + "dev": true }, "import-fresh": { "version": "3.3.0", @@ -15535,7 +17279,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "devOptional": true, + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -15545,7 +17289,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "devOptional": true + "dev": true }, "ini": { "version": "1.3.8", @@ -15583,7 +17327,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -15648,7 +17392,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "devOptional": true + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -15660,7 +17404,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -15675,7 +17419,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true + "dev": true }, "is-number-object": { "version": "1.0.7", @@ -15722,6 +17466,12 @@ "call-bind": "^1.0.2" } }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -15912,39 +17662,6 @@ "js-sha256": "0.9.0" } }, - "launchdarkly-js-client-sdk": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/launchdarkly-js-client-sdk/-/launchdarkly-js-client-sdk-2.24.2.tgz", - "integrity": "sha512-8jrLOia0vfZ4stqQRv9TjAYfRGK2JyWpLIL6PbTl99LqTtJMuYtryFUQp0b8WH1153YN+gVdoqPVI7uwbbzLLQ==", - "requires": { - "escape-string-regexp": "^4.0.0", - "launchdarkly-js-sdk-common": "3.8.2" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - } - } - }, - "launchdarkly-js-sdk-common": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/launchdarkly-js-sdk-common/-/launchdarkly-js-sdk-common-3.8.2.tgz", - "integrity": "sha512-pEqZ3FTKtYrTaPdbPntFJs87svzcezrkoRWY2GEFmyPC33txOqU788x0yby2+haC/saFPNfXpH6bbiJE/GjMSA==", - "requires": { - "base64-js": "^1.3.0", - "fast-deep-equal": "^2.0.1", - "uuid": "^3.3.2" - }, - "dependencies": { - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" - } - } - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -15974,10 +17691,14 @@ } }, "local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", - "dev": true + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "requires": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + } }, "lodash": { "version": "4.17.21", @@ -16055,14 +17776,19 @@ } }, "magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", @@ -16074,8 +17800,7 @@ "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "peer": true + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { "version": "1.4.1", @@ -16106,11 +17831,17 @@ "mime-db": "1.52.0" } }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -16142,15 +17873,15 @@ }, "dependencies": { "acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true }, "pathe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", - "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true } } @@ -16241,6 +17972,23 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + } + } + }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -16274,9 +18022,9 @@ } }, "nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "version": "2.2.18", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", + "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", "dev": true }, "object-assign": { @@ -16324,11 +18072,20 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "devOptional": true, + "dev": true, "requires": { "wrappy": "1" } }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -16352,18 +18109,18 @@ "peer": true }, "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, "requires": { "yocto-queue": "^1.0.0" }, "dependencies": { "yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.0.tgz", + "integrity": "sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==", "dev": true } } @@ -16391,12 +18148,12 @@ "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, "requires": { - "entities": "^4.4.0" + "entities": "^4.5.0" } }, "path-exists": { @@ -16409,7 +18166,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "devOptional": true + "dev": true }, "path-is-inside": { "version": "1.0.2", @@ -16467,15 +18224,15 @@ "dev": true }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true + "dev": true }, "pinia": { "version": "2.1.7", @@ -16504,21 +18261,21 @@ }, "dependencies": { "pathe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", - "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true } } }, "postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, "postcss-modules-extract-imports": { @@ -16770,9 +18527,9 @@ } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, "querystringify": { "version": "2.2.0", @@ -16805,7 +18562,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -16819,11 +18576,6 @@ "resolve": "^1.1.6" } }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -16880,7 +18632,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "devOptional": true + "dev": true }, "reusify": { "version": "1.0.4", @@ -16892,6 +18644,7 @@ "version": "3.29.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -16937,7 +18690,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "dev": true }, "sanitize-html": { "version": "2.13.0", @@ -16963,7 +18716,7 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.51.0.tgz", "integrity": "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA==", - "devOptional": true, + "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -16974,7 +18727,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "devOptional": true + "dev": true }, "saxes": { "version": "6.0.0", @@ -16986,80 +18739,56 @@ } }, "sbc-common-components": { - "version": "3.0.15-a", - "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.0.15-a.tgz", - "integrity": "sha512-fY0FAtgZVo5AfPnmajUbXH+ZDDJHzVUqfgX6RY54eSiBLsduYpbsogGlOKR5P6IVio7GFIWktLkEGfhvv4qh7Q==", + "version": "file:../../sbc-common-components/vue/sbc-common-components", "requires": { "@mdi/font": "^4.5.95", - "axios": "^0.21.1", + "@types/vuelidate": "^0.7.4", + "@typescript-eslint/eslint-plugin": "^2.3.1", + "@typescript-eslint/parser": "^2.3.1", + "@vitest/coverage-v8": "^1.6.0", + "@vue/babel-preset-app": "^5.0.8", + "@vue/composition-api": "^1.7.2", + "@vue/eslint-config-standard": "^4.0.0", + "@vue/eslint-config-typescript": "^4.0.0", + "@vue/test-utils": "1.0.0-beta.29", + "axios": "^1.8.1", + "axios-mock-adapter": "^1.17.0", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "^10.0.1", "clickout-event": "^1.1.2", "core-js": "^3.1.4", "country-list": "^2.2.0", + "eslint": "^5.16.0", + "eslint-plugin-vue": "^5.2.3", + "jsdom": "^26.0.0", "keycloak-js": "^26.2.0", "launchdarkly-js-client-sdk": "^2.16.1", "lodash.uniqueid": "^4.0.1", + "mutationobserver-shim": "^0.3.7", + "node-fetch": "^2.7.0", + "pinia": "^2.1.6", "postcss-nesting": "^13.0.1", "provinces": "^1.11.0", "regenerator-runtime": "^0.13.3", + "sass": "~1.32.12", + "sass-loader": "^7.2.0", + "typescript": "^5.8.2", "vite": "^4.5.9", + "vite-plugin-environment": "^1.1.3", + "vite-plugin-vue2": "^2.0.3", + "vitest": "^1.6.0", "vue": "^2.6.11", + "vue-class-component": "^7.1.0", + "vue-cli-plugin-vuetify": "^2.0.3", "vue-i18n": "^8.0.0", + "vue-plugin-helper-decorator": "^0.0.11", + "vue-property-decorator": "^8.5.1", "vue-router": "^3.0.3", + "vue-template-compiler": "^2.6.14", "vue2-filters": "^0.7.1", "vuelidate": "^0.7.4", - "vuetify": "^2.1.5", - "vuex": "^3.1.2" - }, - "dependencies": { - "@csstools/selector-resolve-nested": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", - "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", - "requires": {} - }, - "@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "requires": {} - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "keycloak-js": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz", - "integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw==" - }, - "postcss-nesting": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", - "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", - "requires": { - "@csstools/selector-resolve-nested": "^3.0.0", - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - } - }, - "postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "vuelidate": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.7.tgz", - "integrity": "sha512-pT/U2lDI67wkIqI4tum7cMSIfGcAMfB+Phtqh2ttdXURwvHRBJEAQ0tVbUsW9Upg83Q5QH59bnCoXI7A9JDGnA==" - } + "vuepress": "^0.14.11", + "vuetify": "^2.1.5" } }, "schema-utils": { @@ -17195,9 +18924,9 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" }, "source-map-support": { "version": "0.5.21", @@ -17213,7 +18942,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "devOptional": true + "dev": true }, "sourcemap-codec": { "version": "1.4.8", @@ -17234,9 +18963,9 @@ "dev": true }, "std-env": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", - "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", "dev": true }, "string-width": { @@ -17287,6 +19016,12 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -17294,18 +19029,18 @@ "dev": true }, "strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", "dev": true, "requires": { - "acorn": "^8.10.0" + "js-tokens": "^9.0.1" }, "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true } } @@ -17314,7 +19049,7 @@ "version": "0.54.8", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", - "devOptional": true, + "dev": true, "requires": { "css-parse": "~2.0.0", "debug": "~3.1.0", @@ -17330,7 +19065,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "devOptional": true, + "dev": true, "requires": { "ms": "2.0.0" } @@ -17339,19 +19074,19 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "devOptional": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "devOptional": true + "dev": true }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "devOptional": true + "dev": true } } }, @@ -17512,15 +19247,15 @@ "peer": true }, "tinybench": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", - "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true }, "tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", "dev": true }, "tinyspy": { @@ -17549,7 +19284,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -17674,6 +19409,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "peer": true + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -17743,7 +19484,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "devOptional": true + "dev": true }, "url-parse": { "version": "1.5.10", @@ -17760,11 +19501,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -17775,6 +19511,7 @@ "version": "4.5.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", + "dev": true, "requires": { "esbuild": "^0.18.10", "fsevents": "~2.3.2", @@ -17783,17 +19520,244 @@ } }, "vite-node": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", - "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, "requires": { "cac": "^6.7.14", "debug": "^4.3.4", - "mlly": "^1.4.0", "pathe": "^1.1.1", "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + "vite": "^5.0.0" + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "rollup": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", + "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.34.9", + "@rollup/rollup-android-arm64": "4.34.9", + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-freebsd-arm64": "4.34.9", + "@rollup/rollup-freebsd-x64": "4.34.9", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", + "@rollup/rollup-linux-arm-musleabihf": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", + "@rollup/rollup-linux-riscv64-gnu": "4.34.9", + "@rollup/rollup-linux-s390x-gnu": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-ia32-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9", + "@types/estree": "1.0.6", + "fsevents": "~2.3.2" + } + }, + "vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "requires": { + "esbuild": "^0.21.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + } + } } }, "vite-plugin-environment": { @@ -17901,42 +19865,258 @@ } }, "vitest": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", - "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", "dev": true, "requires": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.6", - "@vitest/runner": "0.34.6", - "@vitest/snapshot": "0.34.6", - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", "pathe": "^1.1.1", "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", - "vite-node": "0.34.6", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", "why-is-node-running": "^2.2.2" }, "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true + "@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "rollup": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", + "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.34.9", + "@rollup/rollup-android-arm64": "4.34.9", + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-freebsd-arm64": "4.34.9", + "@rollup/rollup-freebsd-x64": "4.34.9", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", + "@rollup/rollup-linux-arm-musleabihf": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", + "@rollup/rollup-linux-riscv64-gnu": "4.34.9", + "@rollup/rollup-linux-s390x-gnu": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-ia32-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9", + "@types/estree": "1.0.6", + "fsevents": "~2.3.2" + } + }, + "vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "requires": { + "esbuild": "^0.21.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + } } } }, @@ -18661,11 +20841,6 @@ "resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz", "integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ==" }, - "vue2-filters": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/vue2-filters/-/vue2-filters-0.7.2.tgz", - "integrity": "sha512-7I74isiBUQFGaNbVv57NzHGqh54cLe0JNJmJmu66wxP5eOK/CqHN4iqHMgwPPPvPbgbFbpI/GjbHiIx8tNruwg==" - }, "vuelidate": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.6.2.tgz", @@ -18886,7 +21061,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "devOptional": true + "dev": true }, "write": { "version": "1.0.3", @@ -18899,9 +21074,9 @@ } }, "ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", "dev": true, "requires": {} }, diff --git a/auth-web/package.json b/auth-web/package.json index 4faa13c8be..6eb2c92932 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -1,6 +1,6 @@ { "name": "auth-web", - "version": "2.8.16", + "version": "2.9.0", "appName": "Auth Web", "sbcName": "SBC Common Components", "private": true, @@ -38,7 +38,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "3.0.15-a", + "sbc-common-components": "3.1.1", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", @@ -86,7 +86,7 @@ "vite-plugin-environment": "^1.1.3", "vite-plugin-rewrite-all": "^1.0.1", "vite-plugin-vue2": "^2.0.3", - "vitest": "^0.34.6", + "vitest": "^1.6.0", "vue-class-component": "^7.1.0", "vue-cli-plugin-vuetify": "^2.0.3", "vue-template-compiler": "2.6.14", diff --git a/auth-web/src/App.vue b/auth-web/src/App.vue index ec01984d08..ec56a662a6 100644 --- a/auth-web/src/App.vue +++ b/auth-web/src/App.vue @@ -6,7 +6,7 @@ > <sbc-loader :show="showLoading" /> <sbc-header - :key="$store.state.refreshKey" + :key="refreshKey" ref="header" class="flex-column" :in-auth="true" @@ -66,8 +66,7 @@ import { Component, Mixins } from 'vue-property-decorator' import { LDFlags, LoginSource, Pages, SessionStorageKeys } from '@/util/constants' import { mapActions, mapState } from 'pinia' -import { useOrgStore, useUserStore } from '@/stores' -import AuthModule from 'sbc-common-components/src/store/modules/auth' +import { useAppStore, useOrgStore, useUserStore } from '@/stores' import { BreadCrumb } from '@bcrs-shared-components/bread-crumb' import { BreadcrumbIF } from '@bcrs-shared-components/interfaces' import CommonUtils from '@/util/common-util' @@ -82,8 +81,7 @@ import SbcFooter from 'sbc-common-components/src/components/SbcFooter.vue' import SbcHeader from 'sbc-common-components/src/components/SbcHeader.vue' import SbcLoader from 'sbc-common-components/src/components/SbcLoader.vue' import { appendAccountId } from 'sbc-common-components/src/util/common-util' -import { getModule } from 'vuex-module-decorators' -import { mapGetters } from 'vuex' +import { useAuthStore } from 'sbc-common-components/src/stores' @Component({ components: { @@ -97,17 +95,17 @@ import { mapGetters } from 'vuex' 'currentAccountSettings', 'permissions' ]), - ...mapState(useUserStore, ['currentUser']), - ...mapGetters('auth', ['isAuthenticated']) + ...mapState(useUserStore, ['currentUser']) }, methods: { ...mapActions(useOrgStore, ['setCurrentOrganization']), - ...mapActions(useUserStore, ['loadUserInfo']) + ...mapActions(useUserStore, ['loadUserInfo']), + ...mapActions(useAppStore, ['updateHeader', 'loadComplete']) } }) export default class App extends Mixins(NextPageMixin) { - // Remove these with sbc-common-components and Vue3 upgrade. - private authModule = getModule(AuthModule, this.$store) + private appStore = useAppStore() + authStore = useAuthStore() private readonly loadUserInfo!: () => KCUserProfile showNotification = false notificationText = '' @@ -156,6 +154,14 @@ export default class App extends Mixins(NextPageMixin) { return import.meta.env.ABOUT_TEXT } + get refreshKey () { + return this.appStore.refreshKey + } + + get isAuthenticated (): boolean { + return this.authStore.isAuthenticated + } + startAccountSwitch () { this.showLoading = true } @@ -167,8 +173,7 @@ export default class App extends Mixins(NextPageMixin) { this.notificationText = `Switched to account '${this.currentAccountSettings.label}'` this.showNotification = true - // Remove Vuex with Vue 3 - this.$store.commit('updateHeader') + this.appStore.updateHeader() this.accountFreezeRedirect() this.accountPendingRedirect() @@ -179,8 +184,7 @@ export default class App extends Mixins(NextPageMixin) { if (ConfigHelper.getFromSession(SessionStorageKeys.SessionSynced) === 'true' && !CommonUtils.isSigningIn() && !CommonUtils.isSigningOut()) { this.loadUserInfo() await this.syncUser() - // Remove Vuex with Vue 3 - this.$store.commit('loadComplete') + this.appStore.loadComplete() } } @@ -207,9 +211,8 @@ export default class App extends Mixins(NextPageMixin) { } private setLogOutUrl () { - // Auth store, still exists in sbc-common-components v2, uses pinia in Vue 3 version. - // Remove Vuex with Vue 3 - this.logoutUrl = (this.$store.getters['auth/currentLoginSource'] === LoginSource.BCROS) ? ConfigHelper.getBcrosURL() : '' + const authStore = useAuthStore() + this.logoutUrl = (authStore.currentLoginSource === LoginSource.BCROS) ? ConfigHelper.getBcrosURL() : '' } private destroyed () { @@ -217,12 +220,11 @@ export default class App extends Mixins(NextPageMixin) { } async setup (isSigninComplete?: boolean) { - // Header added modules to store so can access mapped actions now - // Remove Vuex with Vue 3 - if (this.$store.getters['auth/isAuthenticated']) { + const authStore = useAuthStore() + if (authStore.isAuthenticated) { try { if (!isSigninComplete) { - await KeyCloakService.initializeToken(this.$store) + await KeyCloakService.initializeToken() } this.loadUserInfo() await this.syncUser() @@ -231,13 +233,11 @@ export default class App extends Mixins(NextPageMixin) { console.log('App.vue.setup Error: ' + e) const userStore = useUserStore() await userStore.reset() - // Remove Vuex with Vue 3 - this.$store.commit('loadComplete') + this.appStore.loadComplete() this.$router.push('/home') } } - // Remove Vuex with Vue 3 - this.$store.commit('loadComplete') + this.appStore.loadComplete() } } </script> diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue index 4af2eba47e..809260cc76 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue @@ -286,6 +286,7 @@ import AccountMailingAddress from '@/components/auth/account-settings/account-in import { Address } from '@/models/address' import ModalDialog from '../../common/ModalDialog.vue' import OrgAdminContact from '@/components/auth/account-settings/account-info/OrgAdminContact.vue' +import { useAppStore } from '@/stores/app' import { useCodesStore } from '@/stores/codes' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -298,7 +299,7 @@ export default defineComponent({ AccountMailingAddress, AccountAccessType }, - setup (props, { root }) { + setup () { const codesStore = useCodesStore() const orgStore = useOrgStore() const userStore = useUserStore() @@ -453,7 +454,7 @@ export default defineComponent({ try { await orgStore.updateOrg(createRequestBody) - if (!(state.isStaff && !isStaffAccount.value)) root.$store.commit('updateHeader') + if (!(state.isStaff && !isStaffAccount.value)) useAppStore().updateHeader() if (!isBusinessInfoIncomplete.value && !state.isAddressInfoIncomplete) { state.isCompleteAccountInfo = true state.warningMessage = '' @@ -480,7 +481,7 @@ export default defineComponent({ try { await orgStore.updateOrgMailingAddress(createRequestBody) - if (!(state.isStaff && !isStaffAccount.value)) root.$store.commit('updateHeader') + if (!(state.isStaff && !isStaffAccount.value)) useAppStore().updateHeader() state.addressChanged = false state.originalAddress = currentOrgAddress.value if (!isBusinessInfoIncomplete.value && !state.isAddressInfoIncomplete) { diff --git a/auth-web/src/components/auth/account-settings/team-management/UserManagement.vue b/auth-web/src/components/auth/account-settings/team-management/UserManagement.vue index 66091bd8f0..ad94eb6bc4 100644 --- a/auth-web/src/components/auth/account-settings/team-management/UserManagement.vue +++ b/auth-web/src/components/auth/account-settings/team-management/UserManagement.vue @@ -233,6 +233,7 @@ import PendingMemberDataTable from '@/components/auth/account-settings/team-mana import SearchFilterInput from '@/components/auth/common/SearchFilterInput.vue' import { SearchFilterParam } from '@/models/searchfilter' import TeamManagementMixin from '@/components/auth/mixins/TeamManagementMixin.vue' +import { useAppStore } from '@/stores' import { useBusinessStore } from '@/stores/business' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -394,7 +395,7 @@ export default class UserManagement extends Mixins(AccountChangeMixin, TeamManag memberId: this.memberToBeApproved.id, status: MembershipStatus.Active }) - this.$store.commit('updateHeader') + useAppStore().updateHeader() } catch ({ response }) { this.errorTitle = 'Error Approving Access' this.errorText = response?.data?.message || 'An unexpected error occurred.' diff --git a/auth-web/src/components/auth/common/ConfirmCancelButton.vue b/auth-web/src/components/auth/common/ConfirmCancelButton.vue index 49b28cbb85..e49f49e69d 100644 --- a/auth-web/src/components/auth/common/ConfirmCancelButton.vue +++ b/auth-web/src/components/auth/common/ConfirmCancelButton.vue @@ -54,6 +54,7 @@ import { Component, Emit, Prop } from 'vue-property-decorator' import { Action } from 'pinia-class' import ModalDialog from '@/components/auth/common/ModalDialog.vue' import Vue from 'vue' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' @Component({ @@ -94,8 +95,7 @@ export default class ConfirmCancelButton extends Vue { if (this.clearCurrentOrg) { await this.resetAccountSetupProgress() await this.setCurrentOrganizationFromUserAccountSettings() - // Remove in Vue 3 - await this.$store.commit('updateHeader') + await useAppStore().updateHeader() } if (this.isEmit) { this.emitClickConfirm() diff --git a/auth-web/src/components/auth/create-account/AccountCreate.vue b/auth-web/src/components/auth/create-account/AccountCreate.vue index 4431ef8783..c598642418 100644 --- a/auth-web/src/components/auth/create-account/AccountCreate.vue +++ b/auth-web/src/components/auth/create-account/AccountCreate.vue @@ -86,6 +86,8 @@ import ConfirmCancelButton from '@/components/auth/common/ConfirmCancelButton.vu import { LoginSource } from '@/util/constants' import Steppable from '@/components/auth/common/stepper/Steppable.vue' import { addressSchema } from '@/schemas' +import { getActivePinia } from 'pinia' +import { useAuthStore } from 'sbc-common-components/src/stores' import { useOrgStore } from '@/stores/org' export default defineComponent({ @@ -130,7 +132,8 @@ export default defineComponent({ isOrgBusinessTypeValid: false, isExtraProvUser: computed(() => { // Remove Vuex with Vue 3 - return root.$store.getters['auth/currentLoginSource'] === LoginSource.BCEID + const authStore = useAuthStore(getActivePinia()) + return authStore.currentLoginSource === LoginSource.BCEID }), isFormValid: computed(() => { return !!state.isOrgBusinessTypeValid && !state.errorMessage && !!state.isBaseAddressValid diff --git a/auth-web/src/components/auth/create-account/non-bcsc/AffidavitDownload.vue b/auth-web/src/components/auth/create-account/non-bcsc/AffidavitDownload.vue index 255f436933..5bf09d140c 100644 --- a/auth-web/src/components/auth/create-account/non-bcsc/AffidavitDownload.vue +++ b/auth-web/src/components/auth/create-account/non-bcsc/AffidavitDownload.vue @@ -125,24 +125,20 @@ <script lang="ts"> import { Component, Vue } from 'vue-property-decorator' import { IdpHint, Pages, SessionStorageKeys } from '@/util/constants' -import AuthModule from 'sbc-common-components/src/store/modules/auth' import CommonUtils from '@/util/common-util' import ConfigHelper from '@/util/config-helper' import DocumentService from '@/services/document.services' -// Will be removing these two lines with Vue 3 upgrade. -import { getModule } from 'vuex-module-decorators' -import { mapGetters } from 'vuex' +import { mapState } from 'pinia' +import { useAuthStore } from 'sbc-common-components/src/stores' @Component({ computed: { - ...mapGetters('auth', [ + ...mapState(useAuthStore, [ 'isAuthenticated' ]) } }) export default class AffidavitDownload extends Vue { - private authModule = getModule(AuthModule, this.$store) - private readonly isAuthenticated!: boolean private downloadFailedMsg = 'Failed download' private isDownloadFailed = false private affidavitSize = ConfigHelper.getAffidavitSize() || '' diff --git a/auth-web/src/components/auth/manage-business/EntityManagement.vue b/auth-web/src/components/auth/manage-business/EntityManagement.vue index c5808db0fa..c6bc770302 100644 --- a/auth-web/src/components/auth/manage-business/EntityManagement.vue +++ b/auth-web/src/components/auth/manage-business/EntityManagement.vue @@ -300,7 +300,7 @@ import { Component, Mixins, Prop } from 'vue-property-decorator' import { CorpTypes, LoginSource, MagicLinkInvitationStatus, Pages } from '@/util/constants' import { MembershipStatus, Organization, RemoveBusinessPayload } from '@/models/Organization' import { mapActions, mapState } from 'pinia' -import { useBusinessStore, useOrgStore, useUserStore } from '@/stores' +import { useAppStore, useBusinessStore, useOrgStore, useUserStore } from '@/stores' import AccountChangeMixin from '@/components/auth/mixins/AccountChangeMixin.vue' import AccountMixin from '@/components/auth/mixins/AccountMixin.vue' import { Action } from 'pinia-class' @@ -446,7 +446,7 @@ export default class EntityManagement extends Mixins(AccountMixin, AccountChange await this.syncOrganization(this.currentAccountSettings.id) await this.addOrgSettings(this.currentOrganization) await this.syncBusinessesAndToggleLoading() - this.$store.commit('updateHeader') + useAppStore().updateHeader() this.parseUrlAndAddAffiliation(token, legalName, this.base64Token) return } catch (error) { diff --git a/auth-web/src/components/auth/mixins/TeamManagementMixin.vue b/auth-web/src/components/auth/mixins/TeamManagementMixin.vue index d0698b3f12..19766d438d 100644 --- a/auth-web/src/components/auth/mixins/TeamManagementMixin.vue +++ b/auth-web/src/components/auth/mixins/TeamManagementMixin.vue @@ -10,6 +10,7 @@ import { Event } from '@/models/event' import { EventBus } from '@/event-bus' import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile' import ModalDialog from '@/components/auth/common/ModalDialog.vue' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -162,8 +163,7 @@ export default class TeamManagementMixin extends Vue { memberId: this.memberToBeRemoved.id, status: MembershipStatus.Rejected }) - // Remove Vuex with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() this.modal.close() } @@ -174,16 +174,14 @@ export default class TeamManagementMixin extends Vue { await this.leaveTeam(this.currentMembership.id) } this.modal.close() - // Remove Vuex with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() this.$router.push('/leaveteam') } protected async dissolve () { await this.leaveTeam(this.currentMembership.id) this.modal.close() - // Remove Vuex with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() const event:Event = { message: 'Dissolved the account', type: 'error', timeout: 1000 } EventBus.$emit('show-toast', event) // remove this account from the current account session storage.Header will automatically get the next valid account diff --git a/auth-web/src/main.ts b/auth-web/src/main.ts index 34fb272dba..f2ac53f051 100644 --- a/auth-web/src/main.ts +++ b/auth-web/src/main.ts @@ -1,7 +1,7 @@ - import './composition-api-setup' // ensure this happens before any imports trigger use of composition-api import '@mdi/font/css/materialdesignicons.min.css' // icon library (https://materialdesignicons.com/) import * as Sentry from '@sentry/vue' +import { PiniaVuePlugin, createPinia, setActivePinia } from 'pinia' import App from './App.vue' import CommonUtils from '@/util/common-util' import ConfigHelper from '@/util/config-helper' @@ -16,21 +16,22 @@ import VueSanitize from 'vue-sanitize-directive' import Vuelidate from 'vuelidate' import can from '@/directives/can' import displayMode from '@/directives/displayMode' -import { getPiniaStore } from '@/stores' import initializeI18n from './plugins/i18n' import router from './routes/index' -import store from '@/stores/vuex' import vuetify from './plugins/vuetify' // eslint-disable-next-line sort-imports import { LDFlags } from '@/util/constants' Vue.use(VueCompositionAPI) +Vue.use(PiniaVuePlugin) +const pinia = createPinia() +setActivePinia(pinia) Vue.config.productionTip = false Vue.use(Vuelidate) +Vue.use(VueSanitize) const i18n = initializeI18n(Vue) -Vue.use(VueSanitize) /** * The server side configs are necessary for app to work , since they are reference in templates and all @@ -81,13 +82,10 @@ async function syncSession () { }) } } - function renderVue () { new Vue({ + pinia, router, - // We still need Vuex for sbc-common-components. - store, - pinia: getPiniaStore(), vuetify, i18n, render: (h) => h(App) diff --git a/auth-web/src/routes/index.ts b/auth-web/src/routes/index.ts index a435fb47a5..c6cca19404 100644 --- a/auth-web/src/routes/index.ts +++ b/auth-web/src/routes/index.ts @@ -16,9 +16,10 @@ import Router from 'vue-router' import { User } from '@/models/user' import Vue from 'vue' import { getRoutes } from './router' -import store from '@/stores/vuex' +import { useAppStore } from '@/stores/app' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' +import { watch } from '@vue/composition-api' Vue.use(Router) @@ -57,18 +58,21 @@ router.beforeEach(async (to, from, next) => { } // Enforce navigation guards are checked before navigating anywhere else - // Remove Vuex with Vue3 upgrade. - Will be replaced by Pinia onAction. - if (store.getters.loading) { - await new Promise(resolve => { - const unsubscribeFn = store.subscribe(mutation => { - if (mutation.type === 'loadComplete') { + const appStore = useAppStore() + if (appStore.loading) { + new Promise(resolve => { + const unsubscribeFn = watch(() => appStore.loading, (newLoading) => { + if (!newLoading) { unsubscribeFn() resolve(null) } }) + }).then(() => { + proceed() }) + } else { + proceed() } - proceed() function proceed () { const orgStore = useOrgStore() diff --git a/auth-web/src/stores/app.ts b/auth-web/src/stores/app.ts index ff2ced49c0..1bb0ca8039 100644 --- a/auth-web/src/stores/app.ts +++ b/auth-web/src/stores/app.ts @@ -21,17 +21,34 @@ headache in the long term. Depending on the circumstances, there are various alt */ export const useAppStore = defineStore('app', () => { const state = reactive({ - errorMessage: '', // Unused for now - refreshKey: 0, // Unused for now - loading: true // Unused for now + errorMessage: '', + refreshKey: 0, + loading: true }) + function updateHeader () { + state.refreshKey++ + } + + function loadComplete () { + state.loading = false + } + function dismissError () { state.errorMessage = '' } + function $reset () { + state.errorMessage = '' + state.refreshKey = 0 + state.loading = true + } + return { ...toRefs(state), - dismissError + updateHeader, + loadComplete, + dismissError, + $reset } }) diff --git a/auth-web/src/stores/index.ts b/auth-web/src/stores/index.ts index 9bcce066e8..2def6af8a0 100644 --- a/auth-web/src/stores/index.ts +++ b/auth-web/src/stores/index.ts @@ -1,6 +1,7 @@ import { PiniaVuePlugin, createPinia } from 'pinia' import Vue from 'vue' import { useActivityStore } from './activityLog' +import { useAppStore } from './app' import { useBusinessStore } from './business' import { useCodesStore } from './codes' import { useOrgStore } from './org' @@ -25,11 +26,20 @@ export * from './org' export * from './staff' export * from './task' export * from './user' +export * from 'sbc-common-components/src/stores' /* Resets all values for a store, eg on Logout */ export function resetAllStores () { - [useActivityStore(), useBusinessStore(), useCodesStore(), useOrgStore(), - useStaffStore(), useTaskStore(), useUserStore()].forEach((store) => { + [ + useActivityStore(), + useBusinessStore(), + useCodesStore(), + useOrgStore(), + useStaffStore(), + useTaskStore(), + useUserStore(), + useAppStore() + ].forEach((store) => { store.$reset() }) } diff --git a/auth-web/src/views/auth/AcceptInviteView.vue b/auth-web/src/views/auth/AcceptInviteView.vue index 163a9596dd..a67d83dd91 100644 --- a/auth-web/src/views/auth/AcceptInviteView.vue +++ b/auth-web/src/views/auth/AcceptInviteView.vue @@ -16,6 +16,7 @@ import { Member, MembershipStatus } from '@/models/Organization' import { defineComponent, getCurrentInstance, onMounted, reactive, toRefs } from '@vue/composition-api' import InterimLanding from '@/components/auth/common/InterimLanding.vue' import NextPageMixin from '@/components/auth/mixins/NextPageMixin.vue' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -92,8 +93,7 @@ export default defineComponent({ } else { await orgStore.syncMembership(invitation?.membership[0]?.org?.id) } - // Remove Vuex with Vue 3 - root.$store.commit('updateHeader') + useAppStore().updateHeader() root.$router.push((instance?.proxy as any).getNextPageUrl()) // This for the mixin. } } catch (exception) { diff --git a/auth-web/src/views/auth/AccountDeactivate.vue b/auth-web/src/views/auth/AccountDeactivate.vue index 363b22dcfb..75b4294024 100644 --- a/auth-web/src/views/auth/AccountDeactivate.vue +++ b/auth-web/src/views/auth/AccountDeactivate.vue @@ -203,6 +203,7 @@ import { DEACTIVATE_ACCOUNT_MESSAGE } from '@/util/constants' import DeactivateCard from '@/components/auth/account-deactivate/DeactivateCard.vue' import ModalDialog from '@/components/auth/common/ModalDialog.vue' import Vue from 'vue' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' @Component({ @@ -272,8 +273,7 @@ export default class AccountDeactivate extends Vue { this.$refs.successModal.close() await this.setCurrentOrganizationFromUserAccountSettings() // Update header - // Remove with Vue 3 - await this.$store.commit('updateHeader') + await useAppStore().updateHeader() this.$router.push(`/home`) } diff --git a/auth-web/src/views/auth/ChooseAuthMethodView.vue b/auth-web/src/views/auth/ChooseAuthMethodView.vue index a5acf6b735..be6d1b6e17 100644 --- a/auth-web/src/views/auth/ChooseAuthMethodView.vue +++ b/auth-web/src/views/auth/ChooseAuthMethodView.vue @@ -382,15 +382,15 @@ import { Component, Vue } from 'vue-property-decorator' import { LoginSource, Pages, SessionStorageKeys } from '@/util/constants' import ConfigHelper from '@/util/config-helper' import ModalDialog from '@/components/auth/common/ModalDialog.vue' -// Remove with Vue3 upgrade. -import { mapGetters } from 'vuex' +import { mapState } from 'pinia' +import { useAuthStore } from 'sbc-common-components/src/stores/auth' @Component({ components: { ModalDialog }, computed: { - ...mapGetters('auth', [ + ...mapState(useAuthStore, [ 'isAuthenticated', 'currentLoginSource' ]), diff --git a/auth-web/src/views/auth/SigninView.vue b/auth-web/src/views/auth/SigninView.vue index 6991756189..c703bcbf99 100644 --- a/auth-web/src/views/auth/SigninView.vue +++ b/auth-web/src/views/auth/SigninView.vue @@ -13,6 +13,7 @@ import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile' import NextPageMixin from '@/components/auth/mixins/NextPageMixin.vue' import SbcSignin from 'sbc-common-components/src/components/SbcSignin.vue' import { mapActions } from 'pinia' +import { useAuthStore } from 'sbc-common-components/src/stores' import { useUserStore } from '@/stores/user' @Component({ @@ -36,7 +37,8 @@ export default class Signin extends Mixins(NextPageMixin) { // Check if user is authenticated, and redirect according to specified redirect // or fallback to default route for their login source // Remove with Vue 3 - if (this.$store.getters['auth/isAuthenticated']) { + const authStore = useAuthStore() + if (authStore.isAuthenticated) { this.$root.$emit('signin-complete', () => { if (this.redirectUrl) { if (this.redirectUrl.startsWith('/')) { diff --git a/auth-web/src/views/auth/SignoutView.vue b/auth-web/src/views/auth/SignoutView.vue index 59c49a695a..36efb42c57 100644 --- a/auth-web/src/views/auth/SignoutView.vue +++ b/auth-web/src/views/auth/SignoutView.vue @@ -29,8 +29,6 @@ export default class SignoutView extends Vue { } async mounted () { - // Remove with Vue 3 - this.$store.replaceState({}) resetAllStores() } } diff --git a/auth-web/src/views/auth/TermsOfServiceView.vue b/auth-web/src/views/auth/TermsOfServiceView.vue index 790f484eb9..55c428e71e 100644 --- a/auth-web/src/views/auth/TermsOfServiceView.vue +++ b/auth-web/src/views/auth/TermsOfServiceView.vue @@ -67,6 +67,7 @@ import NextPageMixin from '@/components/auth/mixins/NextPageMixin.vue' import TermsOfUse from '@/components/auth/common/TermsOfUse.vue' import { TermsOfUseDocument } from '@/models/TermsOfUseDocument' import { User } from '@/models/user' +import { useAppStore } from '@/stores' import { useUserStore } from '@/stores/user' @Component({ @@ -102,8 +103,7 @@ export default class TermsOfServiceView extends Mixins(NextPageMixin) { } mounted () { - // Remove with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() this.isGovmUser = this.isGovmUserLoggedin() } diff --git a/auth-web/src/views/auth/create-account/AccountSetupLanding.vue b/auth-web/src/views/auth/create-account/AccountSetupLanding.vue index fdbe7d7203..dc4f91238d 100644 --- a/auth-web/src/views/auth/create-account/AccountSetupLanding.vue +++ b/auth-web/src/views/auth/create-account/AccountSetupLanding.vue @@ -35,13 +35,10 @@ import { Component, Prop, Vue, Watch } from 'vue-property-decorator' import AccountSetupView from '@/views/auth/create-account/AccountSetupView.vue' import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile' import NonBcscAccountSetupView from '@/views/auth/create-account/NonBcscAccountSetupView.vue' -import { namespace } from 'vuex-class' +import { useAuthStore } from 'sbc-common-components/src/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' -// Will be taken out with Vue 3. -const AuthModule = namespace('auth') - @Component export default class AccountSetupLanding extends Vue { @Prop({ default: false }) skipConfirmation!: boolean @@ -53,7 +50,10 @@ export default class AccountSetupLanding extends Vue { @State(useUserStore) private currentUser!: KCUserProfile @Action(useUserStore) private getUserAccountSettings!: () => Promise<any> - @AuthModule.Getter('isAuthenticated') private isAuthenticated!: boolean + authStore = useAuthStore() + get isAuthenticated (): boolean { + return this.authStore.isAuthenticated + } // Watch property access type and update model @Watch('skipConfirmation') diff --git a/auth-web/src/views/auth/create-account/AccountSetupView.vue b/auth-web/src/views/auth/create-account/AccountSetupView.vue index 7a0972b121..f0d3fc6ba8 100644 --- a/auth-web/src/views/auth/create-account/AccountSetupView.vue +++ b/auth-web/src/views/auth/create-account/AccountSetupView.vue @@ -76,6 +76,7 @@ import SelectProductPayment from '@/components/auth/create-account/SelectProduct import Stepper from '@/components/auth/common/stepper/Stepper.vue' import UserProfileForm from '@/components/auth/create-account/UserProfileForm.vue' import { useAccountCreate } from '@/composables/account-create-factory' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -179,8 +180,7 @@ export default defineComponent({ await orgStore.syncMembership(organization.id) // remove GOVN account type from session ConfigHelper.removeFromSession(SessionStorageKeys.GOVN_USER) - // Remove with Vue 3 - root.$store.commit('updateHeader') + useAppStore().updateHeader() root.$router.push('/setup-account-success') } catch (err) { // eslint-disable-next-line no-console diff --git a/auth-web/src/views/auth/create-account/DuplicateAccountWarningView.vue b/auth-web/src/views/auth/create-account/DuplicateAccountWarningView.vue index 154d3e89a3..6386ae9334 100644 --- a/auth-web/src/views/auth/create-account/DuplicateAccountWarningView.vue +++ b/auth-web/src/views/auth/create-account/DuplicateAccountWarningView.vue @@ -105,6 +105,7 @@ import { OrgWithAddress, Organization } from '@/models/Organization' import { Address } from '@/models/address' import { Pages } from '@/util/constants' import { UserSettings } from '@/models/user' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -157,8 +158,7 @@ export default class DuplicateAccountWarningView extends Vue { private async navigateToRedirectUrl (accountId: number): Promise<void> { await this.syncOrganization(accountId) await this.addOrgSettings(this.currentOrganization) - // Remove with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() if (this.redirectToUrl) { window.location.assign(this.redirectToUrl.toString()) } else { diff --git a/auth-web/src/views/auth/create-account/GovmAccountSetupView.vue b/auth-web/src/views/auth/create-account/GovmAccountSetupView.vue index 63e59fe61b..03fbd61b2f 100644 --- a/auth-web/src/views/auth/create-account/GovmAccountSetupView.vue +++ b/auth-web/src/views/auth/create-account/GovmAccountSetupView.vue @@ -59,6 +59,7 @@ import GovmContactInfoForm from '@/components/auth/create-account/GovmContactInf import ModalDialog from '@/components/auth/common/ModalDialog.vue' import SelectProductPayment from '@/components/auth/create-account/SelectProductPayment.vue' import { useAccountCreate } from '@/composables/account-create-factory' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' export default defineComponent({ @@ -69,6 +70,7 @@ export default defineComponent({ }, setup (props, { root }) { const { createGovmOrg, syncOrganization, syncMembership } = useOrgStore() + const appStore = useAppStore() const state = reactive({ isLoading: false, errorTitle: 'Account creation failed', @@ -112,8 +114,7 @@ export default defineComponent({ const organization: any = await createGovmOrg() await syncOrganization(organization.id) await syncMembership(organization.id) - // Remove with Vue 3 - root.$store.commit('updateHeader') + appStore.updateHeader() root.$router.push(Pages.SETUP_GOVM_ACCOUNT_SUCCESS) state.isLoading = false } catch (err) { diff --git a/auth-web/src/views/auth/create-account/NonBcscAccountSetupView.vue b/auth-web/src/views/auth/create-account/NonBcscAccountSetupView.vue index be3cfcbaa5..14c4b1312c 100644 --- a/auth-web/src/views/auth/create-account/NonBcscAccountSetupView.vue +++ b/auth-web/src/views/auth/create-account/NonBcscAccountSetupView.vue @@ -58,6 +58,7 @@ import Stepper from '@/components/auth/common/stepper/Stepper.vue' import UploadAffidavitStep from '@/components/auth/create-account/non-bcsc/UploadAffidavitStep.vue' import UserProfileForm from '@/components/auth/create-account/UserProfileForm.vue' import { useAccountCreate } from '@/composables/account-create-factory' +import { useAppStore } from '@/stores' import { useOrgStore } from '@/stores/org' import { useUserStore } from '@/stores/user' @@ -216,8 +217,7 @@ export default defineComponent({ await userStore.getUserProfile('@me') } - // Remove with Vue 3 - root.$store.commit('updateHeader') + useAppStore().updateHeader() const nextRoute = !state.isAffidavitAlreadyApproved ? '/setup-non-bcsc-account-success' : '/setup-account-success' root.$router.push(nextRoute) } catch (err) { diff --git a/auth-web/src/views/auth/create-account/non-bcsc/NonBcscAdminInviteSetupView.vue b/auth-web/src/views/auth/create-account/non-bcsc/NonBcscAdminInviteSetupView.vue index 6f8bfec3ca..db20c8332e 100644 --- a/auth-web/src/views/auth/create-account/non-bcsc/NonBcscAdminInviteSetupView.vue +++ b/auth-web/src/views/auth/create-account/non-bcsc/NonBcscAdminInviteSetupView.vue @@ -56,6 +56,7 @@ import NextPageMixin from '@/components/auth/mixins/NextPageMixin.vue' import UploadAffidavitStep from '@/components/auth/create-account/non-bcsc/UploadAffidavitStep.vue' import { User } from '@/models/user' import UserProfileForm from '@/components/auth/create-account/UserProfileForm.vue' +import { useAppStore } from '@/stores' import { useUserStore } from '@/stores/user' @Component({ @@ -84,8 +85,7 @@ export default class NonBcscAdminInviteSetupView extends Mixins(NextPageMixin) { if (this.token) { this.$router.push('/confirmtoken/' + this.token) } else if (this.orgId) { - // Remove with Vue 3 - this.$store.commit('updateHeader') + useAppStore().updateHeader() this.$router.push(this.getNextPageUrl()) } } diff --git a/auth-web/tests/unit/services/codes.service.spec.ts b/auth-web/tests/unit/services/codes.service.spec.ts index bf61d9d3ea..3fdaa33842 100644 --- a/auth-web/tests/unit/services/codes.service.spec.ts +++ b/auth-web/tests/unit/services/codes.service.spec.ts @@ -1,19 +1,21 @@ import { Code } from '@/models/Code' import CodesService from '../../../src/services/codes.service' +const testCodeSuspensionReasons = vi.hoisted(() => ({ + data: [{ + code: 'testSuspensionCode', + desc: 'testSuspensionDesc', + default: true + }] as Code[] +})) + const mockob = { 'PAY_API_URL': 'https://pay-api-dev.apps.silver.devops.gov.bc.ca/api/v1', 'AUTH_API_URL': 'https://auth-api-dev.apps.silver.devops.gov.bc.ca/api/v1' } -const testCodeSuspensionReasons: Code[] = [{ - code: 'testSuspensionCode', - desc: 'testSuspensionDesc', - default: true -}] - const mocks = vi.hoisted(() => ({ - get: vi.fn().mockReturnValue({ data: testCodeSuspensionReasons }) + get: vi.fn().mockReturnValue(testCodeSuspensionReasons) })) describe('Codes service', () => { @@ -38,7 +40,7 @@ describe('Codes service', () => { it('call getCodes() for suspended_reason_codes ', () => { CodesService.getCodes('suspension-reason-codes').then((response) => { - expect(response).toEqual(testCodeSuspensionReasons) + expect(response).toEqual(testCodeSuspensionReasons.data) }) }) }) diff --git a/auth-web/tests/unit/services/task.service.spec.ts b/auth-web/tests/unit/services/task.service.spec.ts index 574939d889..d97d0ac617 100644 --- a/auth-web/tests/unit/services/task.service.spec.ts +++ b/auth-web/tests/unit/services/task.service.spec.ts @@ -1,24 +1,27 @@ import { Task } from '@/models/Task' import TaskService from '../../../src/services/task.services' +const mockTask = vi.hoisted(() => ({ + data: [{ + 'accountId': 2628, + 'created': new Date('2021-04-19T16:21:28.989168+00:00'), + 'createdBy': 'BCREGTEST Jing SIXTEEN', + 'dateSubmitted': new Date('2021-04-19T16:22:28.989168+00:00'), + 'id': 44, + 'modified': new Date('2021-04-19T16:23:28.989168+00:00'), + 'name': 'sb 16.3', + 'relationshipId': 3674, + 'relationshipStatus': 'PENDING_STAFF_REVIEW', + 'relationshipType': 'PRODUCT', + 'status': 'OPEN', + 'type': 'Wills Registry' + }] as Task[] +})) + const mockob = { 'PAY_API_URL': 'https://pay-api-dev.pathfinder.gov.bc.ca/api/v1', 'AUTH_API_URL': 'https://auth-api-dev.silver.devops.gov.bc.ca/api/v1' } -const mockTask: Task[] = [{ - 'accountId': 2628, - 'created': new Date('2021-04-19T16:21:28.989168+00:00'), - 'createdBy': 'BCREGTEST Jing SIXTEEN', - 'dateSubmitted': new Date('2021-04-19T16:22:28.989168+00:00'), - 'id': 44, - 'modified': new Date('2021-04-19T16:23:28.989168+00:00'), - 'name': 'sb 16.3', - 'relationshipId': 3674, - 'relationshipStatus': 'PENDING_STAFF_REVIEW', - 'relationshipType': 'PRODUCT', - 'status': 'OPEN', - 'type': 'Wills Registry' -}] const mocks = vi.hoisted(() => ({ get: vi.fn().mockReturnValue(mockTask), @@ -47,7 +50,7 @@ describe('Task service', () => { it('call getTaskById() for task Details ', () => { TaskService.getTaskById(1).then((response) => { - expect(response).toEqual(mockTask) + expect(response).toEqual(mockTask.data) }) }) it('call fetchTasks() for all tasks ', () => { @@ -59,19 +62,19 @@ describe('Task service', () => { } TaskService.fetchTasks(taskFilter).then((response) => { - expect(response).toEqual(mockTask) + expect(response).toEqual(mockTask.data) }) }) it('call approvePendingTask() to approve request ', async () => { - TaskService.approvePendingTask(mockTask).then((response) => { - expect(response).toEqual(mockTask) + TaskService.approvePendingTask(mockTask.data).then((response) => { + expect(response).toEqual(mockTask.data) }) }) it('call rejectPendingTask() to reject request ', async () => { - TaskService.rejectPendingTask(mockTask).then((response) => { - expect(response).toEqual(mockTask) + TaskService.rejectPendingTask(mockTask.data).then((response) => { + expect(response).toEqual(mockTask.data) }) }) }) diff --git a/auth-web/tests/unit/setup.ts b/auth-web/tests/unit/setup.ts index 53ebc87789..459c7c0bc0 100644 --- a/auth-web/tests/unit/setup.ts +++ b/auth-web/tests/unit/setup.ts @@ -18,6 +18,16 @@ Vue.use(VueRouter) Vue.use(VueSanitize) Vue.directive('can', can) +// mock fix Error: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead. +// remove this once when vuex-module-decorators removed from bcrs-shared-components +vi.mock('@bcrs-shared-components/base-address/BaseAddress.vue', () => ({ + default: { + name: 'BaseAddress', + template: '<div class="base-address-mock" />', + props: ['editing', 'schema', 'address'] + } +})) + // Prevent the warning "[Vuetify] Unable to locate target [data-app]" document.body.setAttribute('data-app', 'true') diff --git a/auth-web/tests/unit/views/ChooseAuthMethodView.spec.ts b/auth-web/tests/unit/views/ChooseAuthMethodView.spec.ts index b907e5b727..16d958048f 100644 --- a/auth-web/tests/unit/views/ChooseAuthMethodView.spec.ts +++ b/auth-web/tests/unit/views/ChooseAuthMethodView.spec.ts @@ -1,9 +1,10 @@ +import '@/composition-api-setup' import { createLocalVue, mount } from '@vue/test-utils' import ChooseAuthMethodView from '@/views/auth/ChooseAuthMethodView.vue' import { LoginSource } from '@/util/constants' import VueRouter from 'vue-router' import Vuetify from 'vuetify' -import Vuex from 'vuex' +import { createPinia } from 'pinia' document.body.setAttribute('data-app', true) @@ -13,23 +14,15 @@ describe('ChooseAuthMethodView.vue', () => { beforeEach(() => { const localVue = createLocalVue() localVue.use(VueRouter) - localVue.use(Vuex) const router = new VueRouter() const vuetify = new Vuetify({}) - - const store = new Vuex.Store({ - state: {}, - getters: { - isAuthenticated: () => false - } - }) - + const pinia = createPinia() wrapper = mount(ChooseAuthMethodView, { localVue, router, vuetify, - store, + pinia, mocks: { $t: (mock) => mock } diff --git a/auth-web/tests/unit/views/GovmAccountSetupView.spec.ts b/auth-web/tests/unit/views/GovmAccountSetupView.spec.ts index 9d7b3cd98c..f66c3cbd55 100644 --- a/auth-web/tests/unit/views/GovmAccountSetupView.spec.ts +++ b/auth-web/tests/unit/views/GovmAccountSetupView.spec.ts @@ -1,3 +1,4 @@ +import '@/composition-api-setup' import { createLocalVue, mount } from '@vue/test-utils' import GovmAccountSetupView from '@/views/auth/create-account/GovmAccountSetupView.vue' import ModalDialog from '@/components/auth/common/ModalDialog.vue' @@ -5,7 +6,7 @@ import Vue from 'vue' import VueRouter from 'vue-router' import Vuelidate from 'vuelidate' import Vuetify from 'vuetify' -import Vuex from 'vuex' +import { createTestingPinia } from '@pinia/testing' Vue.use(Vuetify) Vue.use(VueRouter) @@ -17,30 +18,21 @@ document.body.setAttribute('data-app', 'true') describe('GovmAccountSetupView.vue', () => { let wrapper: any + const localVue = createLocalVue() beforeEach(async () => { - const localVue = createLocalVue() - localVue.use(Vuex) localVue.use(Vuelidate) - const orgModule = { - namespaced: true, - state: { - } - } - - // Remove with Vue 3 upgrade - // We need a store for this one it calls auth/currentLoginSource - which is in sbc-common-components for now. - const store = new Vuex.Store({ - state: {}, - strict: false, - modules: { - org: orgModule + const pinia = createTestingPinia({ + initialState: { + auth: { + loginSource: 'BCEID' + } } }) wrapper = mount(GovmAccountSetupView, { - store, + pinia, localVue, router, vuetify, diff --git a/auth-web/tests/unit/views/SignoutView.spec.ts b/auth-web/tests/unit/views/SignoutView.spec.ts index 5b889ace60..b8f233649b 100644 --- a/auth-web/tests/unit/views/SignoutView.spec.ts +++ b/auth-web/tests/unit/views/SignoutView.spec.ts @@ -3,7 +3,6 @@ import SignoutView from '@/views/auth/SignoutView.vue' import Vue from 'vue' import VueRouter from 'vue-router' import Vuetify from 'vuetify' -import Vuex from 'vuex' Vue.use(Vuetify) Vue.use(VueRouter) @@ -18,16 +17,8 @@ describe('SignoutView.vue', () => { beforeEach(() => { const localVue = createLocalVue() - localVue.use(Vuex) - - // Requires Vuex, because it clears the store state. - // Remove in Vue 3 - const store = new Vuex.Store({ - strict: false - }) wrapper = mount(SignoutView, { - store, localVue }) diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index 1474990128..3535c002c7 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -94,6 +94,9 @@ export default defineConfig({ if (log.includes('Download the Vue Devtools extension')) { return false } + }, + deps: { + inline: ['vuetify'] } }, optimizeDeps: { @@ -101,6 +104,5 @@ export default defineConfig({ // Otherwise FAS complains about not having Vue.use(VueCompositionAPI) // sbc-common-components will fail at login. // Remove with Vue 3 for most of these. - exclude: ['@vue/composition-api', 'sbc-common-components'] } }) diff --git a/auth-web/volar.config.js b/auth-web/volar.config.js index 4daae45983..88c6ee3360 100644 --- a/auth-web/volar.config.js +++ b/auth-web/volar.config.js @@ -1,6 +1,6 @@ -const vetur = require('@volar-plugins/vetur') +import vetur from '@volar-plugins/vetur' -module.exports = { +export default { plugins: [ vetur() ] From 33bbee0e84691f05eb6d2e7fd27700fa093528b7 Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Wed, 12 Mar 2025 15:53:50 -0700 Subject: [PATCH 02/10] bug fix - /gcbrun error (#3300) --- auth-web/vite.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index 3535c002c7..299771f66c 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -74,6 +74,7 @@ export default defineConfig({ // Fix for bcrs-shared-components unit tests fail '@bcrs-shared-components/mixins': path.resolve(__dirname, './node_modules/@bcrs-shared-components/mixins/index.ts'), '@bcrs-shared-components/enums': path.resolve(__dirname, './node_modules/@bcrs-shared-components/enums/index.ts'), + 'sbc-common-components': path.resolve(__dirname, 'node_modules/sbc-common-components'), // Fix for module decorator unit tests fail 'vuex-module-decorators': path.resolve(__dirname, './node_modules/vuex-module-decorators/dist/esm/index.js'), 'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.runtime.js') From f95c4f3bb2398c73afab4563587e1e6eff0c955f Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Wed, 12 Mar 2025 16:40:01 -0700 Subject: [PATCH 03/10] fix sbc-common-components not found error (#3301) --- auth-web/package-lock.json | 1183 ++++++++++++++++++++++++++++-------- auth-web/package.json | 2 +- auth-web/vite.config.ts | 7 - 3 files changed, 924 insertions(+), 268 deletions(-) diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index 88f4942548..eb70ba9745 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -29,7 +29,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "3.1.1", + "sbc-common-components": "^3.1.1", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", @@ -86,62 +86,6 @@ "vuex-module-decorators": "^1.2.0" } }, - "../../sbc-common-components/vue/sbc-common-components": { - "version": "3.1.1", - "license": "Apache-2.0", - "dependencies": { - "@mdi/font": "^4.5.95", - "axios": "^1.8.1", - "clickout-event": "^1.1.2", - "core-js": "^3.1.4", - "country-list": "^2.2.0", - "jsdom": "^26.0.0", - "keycloak-js": "^26.2.0", - "launchdarkly-js-client-sdk": "^2.16.1", - "lodash.uniqueid": "^4.0.1", - "postcss-nesting": "^13.0.1", - "provinces": "^1.11.0", - "regenerator-runtime": "^0.13.3", - "vite": "^4.5.9", - "vue": "^2.6.11", - "vue-i18n": "^8.0.0", - "vue-router": "^3.0.3", - "vue2-filters": "^0.7.1", - "vuelidate": "^0.7.4", - "vuetify": "^2.1.5" - }, - "devDependencies": { - "@types/vuelidate": "^0.7.4", - "@typescript-eslint/eslint-plugin": "^2.3.1", - "@typescript-eslint/parser": "^2.3.1", - "@vitest/coverage-v8": "^1.6.0", - "@vue/babel-preset-app": "^5.0.8", - "@vue/composition-api": "^1.7.2", - "@vue/eslint-config-standard": "^4.0.0", - "@vue/eslint-config-typescript": "^4.0.0", - "@vue/test-utils": "1.0.0-beta.29", - "axios-mock-adapter": "^1.17.0", - "babel-core": "7.0.0-bridge.0", - "babel-eslint": "^10.0.1", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.2.3", - "mutationobserver-shim": "^0.3.7", - "node-fetch": "^2.7.0", - "pinia": "^2.1.6", - "sass": "~1.32.12", - "sass-loader": "^7.2.0", - "typescript": "^5.8.2", - "vite-plugin-environment": "^1.1.3", - "vite-plugin-vue2": "^2.0.3", - "vitest": "^1.6.0", - "vue-class-component": "^7.1.0", - "vue-cli-plugin-vuetify": "^2.0.3", - "vue-plugin-helper-decorator": "^0.0.11", - "vue-property-decorator": "^8.5.1", - "vue-template-compiler": "^2.6.14", - "vuepress": "^0.14.11" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -173,6 +117,23 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.1.tgz", + "integrity": "sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==", + "dependencies": { + "@csstools/css-calc": "^2.1.2", + "@csstools/css-color-parser": "^3.0.8", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, "node_modules/@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -1023,6 +984,111 @@ "csstype": "^3.1.0" } }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.2.tgz", + "integrity": "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz", + "integrity": "sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@csstools/selector-specificity": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", @@ -1068,7 +1134,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -1084,7 +1149,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -1100,7 +1164,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -1116,7 +1179,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1132,7 +1194,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1148,7 +1209,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1164,7 +1224,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1180,7 +1239,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1196,7 +1254,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1212,7 +1269,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1228,7 +1284,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1244,7 +1299,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1260,7 +1314,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1276,7 +1329,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1292,7 +1344,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1308,7 +1359,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1324,7 +1374,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -1340,7 +1389,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -1356,7 +1404,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -1372,7 +1419,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1388,7 +1434,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1404,7 +1449,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -3715,7 +3759,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3813,7 +3857,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, + "devOptional": true, "bin": { "atob": "bin/atob.js" }, @@ -3849,7 +3893,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "node_modules/base64-js": { "version": "1.3.1", @@ -3868,7 +3912,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -3888,7 +3932,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3898,7 +3942,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "devOptional": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -4086,7 +4130,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, + "devOptional": true, "funding": [ { "type": "individual", @@ -4118,6 +4162,11 @@ "node": ">=6.0" } }, + "node_modules/clickout-event": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/clickout-event/-/clickout-event-1.1.3.tgz", + "integrity": "sha512-Ttc8IzBpQv1GeruTfAcT4Gv8am0QIr9j625le/P4HnFjr3r9tYTqZHhrmWoWRGmauIG2v+W/Ub70Jl6TTWjleQ==" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -4154,7 +4203,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "devOptional": true }, "node_modules/condense-newlines": { "version": "0.2.1", @@ -4254,6 +4303,16 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/core-js": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz", + "integrity": "sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/country-list": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/country-list/-/country-list-2.3.0.tgz", @@ -4370,7 +4429,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, + "devOptional": true, "dependencies": { "css": "^2.0.0" } @@ -4379,7 +4438,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, + "devOptional": true, "dependencies": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -4392,7 +4451,7 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, + "devOptional": true, "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -4453,7 +4512,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -4469,14 +4527,13 @@ "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10" } @@ -4885,7 +4942,6 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -6233,7 +6289,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6333,13 +6389,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "devOptional": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -6475,7 +6530,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, + "devOptional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6495,7 +6550,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -6819,7 +6874,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true + "devOptional": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -6850,7 +6905,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, + "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6860,7 +6915,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "devOptional": true }, "node_modules/ini": { "version": "1.3.8", @@ -6907,7 +6962,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, + "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7019,7 +7074,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7037,7 +7092,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -7061,7 +7116,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.12.0" } @@ -7101,8 +7156,7 @@ "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, "node_modules/is-regex": { "version": "1.1.4", @@ -7398,6 +7452,41 @@ "js-sha256": "0.9.0" } }, + "node_modules/launchdarkly-js-client-sdk": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/launchdarkly-js-client-sdk/-/launchdarkly-js-client-sdk-2.24.2.tgz", + "integrity": "sha512-8jrLOia0vfZ4stqQRv9TjAYfRGK2JyWpLIL6PbTl99LqTtJMuYtryFUQp0b8WH1153YN+gVdoqPVI7uwbbzLLQ==", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "launchdarkly-js-sdk-common": "3.8.2" + } + }, + "node_modules/launchdarkly-js-client-sdk/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launchdarkly-js-sdk-common": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/launchdarkly-js-sdk-common/-/launchdarkly-js-sdk-common-3.8.2.tgz", + "integrity": "sha512-pEqZ3FTKtYrTaPdbPntFJs87svzcezrkoRWY2GEFmyPC33txOqU788x0yby2+haC/saFPNfXpH6bbiJE/GjMSA==", + "dependencies": { + "base64-js": "^1.3.0", + "fast-deep-equal": "^2.0.1", + "uuid": "^3.3.2" + } + }, + "node_modules/launchdarkly-js-sdk-common/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -7613,7 +7702,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7690,8 +7779,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.8", @@ -7859,8 +7947,7 @@ "node_modules/nwsapi": { "version": "2.2.18", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", - "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", - "dev": true + "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -7928,7 +8015,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, + "devOptional": true, "dependencies": { "wrappy": "1" } @@ -8033,7 +8120,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", - "dev": true, "dependencies": { "entities": "^4.5.0" }, @@ -8054,7 +8140,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8130,7 +8216,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8.6" }, @@ -8594,7 +8680,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -8614,6 +8700,11 @@ "node": ">= 0.10" } }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -8695,7 +8786,7 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true + "devOptional": true }, "node_modules/reusify": { "version": "1.0.4", @@ -8711,7 +8802,6 @@ "version": "3.29.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", - "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -8783,8 +8873,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sanitize-html": { "version": "2.13.0", @@ -8814,7 +8903,7 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.51.0.tgz", "integrity": "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA==", - "dev": true, + "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -8831,13 +8920,12 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "devOptional": true }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -8846,8 +8934,318 @@ } }, "node_modules/sbc-common-components": { - "resolved": "../../sbc-common-components/vue/sbc-common-components", - "link": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.1.tgz", + "integrity": "sha512-OXi3HOxSWmQJQPtsBaZO7kH7QNnvbCzbxi0sSD1wNCam0eN80lwx4L6XB9Uv7Xz3C8sB7+9+rCOx6iNuCQzt5g==", + "dependencies": { + "@mdi/font": "^4.5.95", + "axios": "^1.8.1", + "clickout-event": "^1.1.2", + "core-js": "^3.1.4", + "country-list": "^2.2.0", + "jsdom": "^26.0.0", + "keycloak-js": "^26.2.0", + "launchdarkly-js-client-sdk": "^2.16.1", + "lodash.uniqueid": "^4.0.1", + "postcss-nesting": "^13.0.1", + "provinces": "^1.11.0", + "regenerator-runtime": "^0.13.3", + "vite": "^4.5.9", + "vue": "^2.6.11", + "vue-i18n": "^8.0.0", + "vue-router": "^3.0.3", + "vue2-filters": "^0.7.1", + "vuelidate": "^0.7.4", + "vuetify": "^2.1.5" + } + }, + "node_modules/sbc-common-components/node_modules/@csstools/selector-resolve-nested": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", + "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/sbc-common-components/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/sbc-common-components/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/sbc-common-components/node_modules/cssstyle": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.0.tgz", + "integrity": "sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==", + "dependencies": { + "@asamuzakjp/css-color": "^3.1.1", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/sbc-common-components/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/sbc-common-components/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sbc-common-components/node_modules/jsdom": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz", + "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/sbc-common-components/node_modules/keycloak-js": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz", + "integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw==" + }, + "node_modules/sbc-common-components/node_modules/postcss-nesting": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", + "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-resolve-nested": "^3.0.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/sbc-common-components/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sbc-common-components/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "node_modules/sbc-common-components/node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/sbc-common-components/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/vuelidate": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.7.tgz", + "integrity": "sha512-pT/U2lDI67wkIqI4tum7cMSIfGcAMfB+Phtqh2ttdXURwvHRBJEAQ0tVbUsW9Upg83Q5QH59bnCoXI7A9JDGnA==", + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sbc-common-components/node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/whatwg-url": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", + "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sbc-common-components/node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "engines": { + "node": ">=18" + } }, "node_modules/schema-utils": { "version": "2.7.1", @@ -9039,7 +9437,7 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true + "devOptional": true }, "node_modules/sourcemap-codec": { "version": "1.4.8", @@ -9175,7 +9573,7 @@ "version": "0.54.8", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", - "dev": true, + "devOptional": true, "dependencies": { "css-parse": "~2.0.0", "debug": "~3.1.0", @@ -9197,7 +9595,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, + "devOptional": true, "dependencies": { "ms": "2.0.0" } @@ -9206,7 +9604,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, + "devOptional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -9218,13 +9616,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "devOptional": true }, "node_modules/stylus/node_modules/source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 8" } @@ -9262,8 +9660,7 @@ "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/table": { "version": "5.4.6", @@ -9470,6 +9867,22 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "6.1.84", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.84.tgz", + "integrity": "sha512-aRGIbCIF3teodtUFAYSdQONVmDRy21REM3o6JnqWn5ZkQBJJ4gHxhw6OfwQ+WkSAi3ASamrS4N4nyazWx6uTYg==", + "dependencies": { + "tldts-core": "^6.1.84" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.84", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.84.tgz", + "integrity": "sha512-NaQa1W76W2aCGjXybvnMYzGSM4x8fvG2AN/pla7qxcg0ZHbooOPhA8kctmOZUDfZyhDL27OGNbwAeig8P4p1vg==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -9496,7 +9909,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -9778,7 +10191,7 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true + "devOptional": true }, "node_modules/url-parse": { "version": "1.5.10", @@ -9795,6 +10208,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -9805,7 +10227,6 @@ "version": "4.5.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.18.10", @@ -12001,6 +12422,11 @@ "resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz", "integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ==" }, + "node_modules/vue2-filters": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/vue2-filters/-/vue2-filters-0.7.2.tgz", + "integrity": "sha512-7I74isiBUQFGaNbVv57NzHGqh54cLe0JNJmJmu66wxP5eOK/CqHN4iqHMgwPPPvPbgbFbpI/GjbHiIx8tNruwg==" + }, "node_modules/vuelidate": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.6.2.tgz", @@ -12105,7 +12531,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, "engines": { "node": ">=12" } @@ -12313,7 +12738,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "devOptional": true }, "node_modules/write": { "version": "1.0.3", @@ -12332,7 +12757,6 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -12361,8 +12785,7 @@ "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "node_modules/yallist": { "version": "3.1.1", @@ -12406,6 +12829,25 @@ "integrity": "sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==", "dev": true }, + "@asamuzakjp/css-color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.1.tgz", + "integrity": "sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==", + "requires": { + "@csstools/css-calc": "^2.1.2", + "@csstools/css-color-parser": "^3.0.8", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + } + } + }, "@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -13057,6 +13499,37 @@ } } }, + "@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==" + }, + "@csstools/css-calc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.2.tgz", + "integrity": "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==", + "requires": {} + }, + "@csstools/css-color-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz", + "integrity": "sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==", + "requires": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.2" + } + }, + "@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==" + }, "@csstools/selector-specificity": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", @@ -13075,154 +13548,132 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "dev": true, "optional": true }, "@esbuild/android-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "dev": true, "optional": true }, "@esbuild/android-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "dev": true, "optional": true }, "@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "dev": true, "optional": true }, "@esbuild/darwin-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "dev": true, "optional": true }, "@esbuild/freebsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "dev": true, "optional": true }, "@esbuild/linux-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "dev": true, "optional": true }, "@esbuild/linux-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "dev": true, "optional": true }, "@esbuild/linux-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "dev": true, "optional": true }, "@esbuild/linux-mips64el": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "dev": true, "optional": true }, "@esbuild/linux-ppc64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "dev": true, "optional": true }, "@esbuild/linux-riscv64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "dev": true, "optional": true }, "@esbuild/linux-s390x": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "dev": true, "optional": true }, "@esbuild/linux-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "dev": true, "optional": true }, "@esbuild/netbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "dev": true, "optional": true }, "@esbuild/openbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "dev": true, "optional": true }, "@esbuild/sunos-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "dev": true, "optional": true }, "@esbuild/win32-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "dev": true, "optional": true }, "@esbuild/win32-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "dev": true, "optional": true }, "@esbuild/win32-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "dev": true, "optional": true }, "@eslint-community/eslint-utils": { @@ -14975,7 +15426,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, + "devOptional": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -15049,7 +15500,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "devOptional": true }, "axios": { "version": "1.8.2", @@ -15076,7 +15527,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "base64-js": { "version": "1.3.1", @@ -15092,7 +15543,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "devOptional": true }, "bluebird": { "version": "3.7.2", @@ -15109,7 +15560,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15119,7 +15570,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "devOptional": true, "requires": { "fill-range": "^7.1.1" } @@ -15245,7 +15696,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, + "devOptional": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -15263,6 +15714,11 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "peer": true }, + "clickout-event": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/clickout-event/-/clickout-event-1.1.3.tgz", + "integrity": "sha512-Ttc8IzBpQv1GeruTfAcT4Gv8am0QIr9j625le/P4HnFjr3r9tYTqZHhrmWoWRGmauIG2v+W/Ub70Jl6TTWjleQ==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -15296,7 +15752,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "devOptional": true }, "condense-newlines": { "version": "0.2.1", @@ -15380,6 +15836,11 @@ "safe-buffer": "~5.1.1" } }, + "core-js": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz", + "integrity": "sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==" + }, "country-list": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/country-list/-/country-list-2.3.0.tgz", @@ -15471,7 +15932,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, + "devOptional": true, "requires": { "css": "^2.0.0" }, @@ -15480,7 +15941,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, + "devOptional": true, "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -15492,7 +15953,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, + "devOptional": true, "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -15543,7 +16004,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -15551,14 +16011,13 @@ "decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true + "devOptional": true }, "deep-eql": { "version": "4.1.4", @@ -15869,7 +16328,6 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, "requires": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", @@ -16838,7 +17296,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "devOptional": true, "requires": { "to-regex-range": "^5.0.1" } @@ -16911,13 +17369,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "devOptional": true }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "optional": true }, "function-bind": { @@ -17007,7 +17464,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, + "devOptional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -17021,7 +17478,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "devOptional": true, "requires": { "is-glob": "^4.0.1" } @@ -17257,7 +17714,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true + "devOptional": true }, "import-fresh": { "version": "3.3.0", @@ -17279,7 +17736,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, + "devOptional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -17289,7 +17746,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "devOptional": true }, "ini": { "version": "1.3.8", @@ -17327,7 +17784,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, + "devOptional": true, "requires": { "binary-extensions": "^2.0.0" } @@ -17392,7 +17849,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "devOptional": true }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -17404,7 +17861,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "requires": { "is-extglob": "^2.1.1" } @@ -17419,7 +17876,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "devOptional": true }, "is-number-object": { "version": "1.0.7", @@ -17444,8 +17901,7 @@ "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, "is-regex": { "version": "1.1.4", @@ -17662,6 +18118,39 @@ "js-sha256": "0.9.0" } }, + "launchdarkly-js-client-sdk": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/launchdarkly-js-client-sdk/-/launchdarkly-js-client-sdk-2.24.2.tgz", + "integrity": "sha512-8jrLOia0vfZ4stqQRv9TjAYfRGK2JyWpLIL6PbTl99LqTtJMuYtryFUQp0b8WH1153YN+gVdoqPVI7uwbbzLLQ==", + "requires": { + "escape-string-regexp": "^4.0.0", + "launchdarkly-js-sdk-common": "3.8.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + } + } + }, + "launchdarkly-js-sdk-common": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/launchdarkly-js-sdk-common/-/launchdarkly-js-sdk-common-3.8.2.tgz", + "integrity": "sha512-pEqZ3FTKtYrTaPdbPntFJs87svzcezrkoRWY2GEFmyPC33txOqU788x0yby2+haC/saFPNfXpH6bbiJE/GjMSA==", + "requires": { + "base64-js": "^1.3.0", + "fast-deep-equal": "^2.0.1", + "uuid": "^3.3.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + } + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -17841,7 +18330,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -17902,8 +18391,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nanoid": { "version": "3.3.8", @@ -18024,8 +18512,7 @@ "nwsapi": { "version": "2.2.18", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", - "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", - "dev": true + "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==" }, "object-assign": { "version": "4.1.1", @@ -18072,7 +18559,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, + "devOptional": true, "requires": { "wrappy": "1" } @@ -18151,7 +18638,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", - "dev": true, "requires": { "entities": "^4.5.0" } @@ -18166,7 +18652,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "devOptional": true }, "path-is-inside": { "version": "1.0.2", @@ -18232,7 +18718,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "devOptional": true }, "pinia": { "version": "2.1.7", @@ -18562,7 +19048,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "devOptional": true, "requires": { "picomatch": "^2.2.1" } @@ -18576,6 +19062,11 @@ "resolve": "^1.1.6" } }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -18632,7 +19123,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "devOptional": true }, "reusify": { "version": "1.0.4", @@ -18644,7 +19135,6 @@ "version": "3.29.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", - "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -18689,8 +19179,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sanitize-html": { "version": "2.13.0", @@ -18716,7 +19205,7 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.51.0.tgz", "integrity": "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA==", - "dev": true, + "devOptional": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -18727,68 +19216,224 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "devOptional": true }, "saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, "requires": { "xmlchars": "^2.2.0" } }, "sbc-common-components": { - "version": "file:../../sbc-common-components/vue/sbc-common-components", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.1.tgz", + "integrity": "sha512-OXi3HOxSWmQJQPtsBaZO7kH7QNnvbCzbxi0sSD1wNCam0eN80lwx4L6XB9Uv7Xz3C8sB7+9+rCOx6iNuCQzt5g==", "requires": { "@mdi/font": "^4.5.95", - "@types/vuelidate": "^0.7.4", - "@typescript-eslint/eslint-plugin": "^2.3.1", - "@typescript-eslint/parser": "^2.3.1", - "@vitest/coverage-v8": "^1.6.0", - "@vue/babel-preset-app": "^5.0.8", - "@vue/composition-api": "^1.7.2", - "@vue/eslint-config-standard": "^4.0.0", - "@vue/eslint-config-typescript": "^4.0.0", - "@vue/test-utils": "1.0.0-beta.29", "axios": "^1.8.1", - "axios-mock-adapter": "^1.17.0", - "babel-core": "7.0.0-bridge.0", - "babel-eslint": "^10.0.1", "clickout-event": "^1.1.2", "core-js": "^3.1.4", "country-list": "^2.2.0", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.2.3", "jsdom": "^26.0.0", "keycloak-js": "^26.2.0", "launchdarkly-js-client-sdk": "^2.16.1", "lodash.uniqueid": "^4.0.1", - "mutationobserver-shim": "^0.3.7", - "node-fetch": "^2.7.0", - "pinia": "^2.1.6", "postcss-nesting": "^13.0.1", "provinces": "^1.11.0", "regenerator-runtime": "^0.13.3", - "sass": "~1.32.12", - "sass-loader": "^7.2.0", - "typescript": "^5.8.2", "vite": "^4.5.9", - "vite-plugin-environment": "^1.1.3", - "vite-plugin-vue2": "^2.0.3", - "vitest": "^1.6.0", "vue": "^2.6.11", - "vue-class-component": "^7.1.0", - "vue-cli-plugin-vuetify": "^2.0.3", "vue-i18n": "^8.0.0", - "vue-plugin-helper-decorator": "^0.0.11", - "vue-property-decorator": "^8.5.1", "vue-router": "^3.0.3", - "vue-template-compiler": "^2.6.14", "vue2-filters": "^0.7.1", "vuelidate": "^0.7.4", - "vuepress": "^0.14.11", "vuetify": "^2.1.5" + }, + "dependencies": { + "@csstools/selector-resolve-nested": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", + "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", + "requires": {} + }, + "@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "requires": {} + }, + "agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==" + }, + "cssstyle": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.0.tgz", + "integrity": "sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==", + "requires": { + "@asamuzakjp/css-color": "^3.1.1", + "rrweb-cssom": "^0.8.0" + } + }, + "data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "requires": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + } + }, + "html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "requires": { + "whatwg-encoding": "^3.1.1" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "jsdom": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz", + "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==", + "requires": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + } + }, + "keycloak-js": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz", + "integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw==" + }, + "postcss-nesting": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", + "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", + "requires": { + "@csstools/selector-resolve-nested": "^3.0.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + } + }, + "postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "requires": { + "tldts": "^6.1.32" + } + }, + "tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "requires": { + "punycode": "^2.3.1" + } + }, + "vuelidate": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.7.tgz", + "integrity": "sha512-pT/U2lDI67wkIqI4tum7cMSIfGcAMfB+Phtqh2ttdXURwvHRBJEAQ0tVbUsW9Upg83Q5QH59bnCoXI7A9JDGnA==" + }, + "w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "requires": { + "xml-name-validator": "^5.0.0" + } + }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", + "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "requires": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==" + } } }, "schema-utils": { @@ -18942,7 +19587,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true + "devOptional": true }, "sourcemap-codec": { "version": "1.4.8", @@ -19049,7 +19694,7 @@ "version": "0.54.8", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", - "dev": true, + "devOptional": true, "requires": { "css-parse": "~2.0.0", "debug": "~3.1.0", @@ -19065,7 +19710,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, + "devOptional": true, "requires": { "ms": "2.0.0" } @@ -19074,19 +19719,19 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "devOptional": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "devOptional": true }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true + "devOptional": true } } }, @@ -19114,8 +19759,7 @@ "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "table": { "version": "5.4.6", @@ -19264,6 +19908,19 @@ "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true }, + "tldts": { + "version": "6.1.84", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.84.tgz", + "integrity": "sha512-aRGIbCIF3teodtUFAYSdQONVmDRy21REM3o6JnqWn5ZkQBJJ4gHxhw6OfwQ+WkSAi3ASamrS4N4nyazWx6uTYg==", + "requires": { + "tldts-core": "^6.1.84" + } + }, + "tldts-core": { + "version": "6.1.84", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.84.tgz", + "integrity": "sha512-NaQa1W76W2aCGjXybvnMYzGSM4x8fvG2AN/pla7qxcg0ZHbooOPhA8kctmOZUDfZyhDL27OGNbwAeig8P4p1vg==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -19284,7 +19941,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "requires": { "is-number": "^7.0.0" } @@ -19484,7 +20141,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "devOptional": true }, "url-parse": { "version": "1.5.10", @@ -19501,6 +20158,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -19511,7 +20173,6 @@ "version": "4.5.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", - "dev": true, "requires": { "esbuild": "^0.18.10", "fsevents": "~2.3.2", @@ -20841,6 +21502,11 @@ "resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz", "integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ==" }, + "vue2-filters": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/vue2-filters/-/vue2-filters-0.7.2.tgz", + "integrity": "sha512-7I74isiBUQFGaNbVv57NzHGqh54cLe0JNJmJmu66wxP5eOK/CqHN4iqHMgwPPPvPbgbFbpI/GjbHiIx8tNruwg==" + }, "vuelidate": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.6.2.tgz", @@ -20911,8 +21577,7 @@ "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" }, "webpack": { "version": "5.94.0", @@ -21061,7 +21726,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "devOptional": true }, "write": { "version": "1.0.3", @@ -21077,7 +21742,6 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "dev": true, "requires": {} }, "xml-name-validator": { @@ -21089,8 +21753,7 @@ "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "yallist": { "version": "3.1.1", diff --git a/auth-web/package.json b/auth-web/package.json index 6eb2c92932..dfb3876d78 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -38,7 +38,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "3.1.1", + "sbc-common-components": "^3.1.1", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index 299771f66c..f0aca22bd0 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -74,7 +74,6 @@ export default defineConfig({ // Fix for bcrs-shared-components unit tests fail '@bcrs-shared-components/mixins': path.resolve(__dirname, './node_modules/@bcrs-shared-components/mixins/index.ts'), '@bcrs-shared-components/enums': path.resolve(__dirname, './node_modules/@bcrs-shared-components/enums/index.ts'), - 'sbc-common-components': path.resolve(__dirname, 'node_modules/sbc-common-components'), // Fix for module decorator unit tests fail 'vuex-module-decorators': path.resolve(__dirname, './node_modules/vuex-module-decorators/dist/esm/index.js'), 'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.runtime.js') @@ -99,11 +98,5 @@ export default defineConfig({ deps: { inline: ['vuetify'] } - }, - optimizeDeps: { - // This needs to be done for sbc-common-components to work. - // Otherwise FAS complains about not having Vue.use(VueCompositionAPI) - // sbc-common-components will fail at login. - // Remove with Vue 3 for most of these. } }) From 3aa134c6dc79334c2a5a8d7771375284f004143d Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Thu, 20 Mar 2025 16:04:22 -0700 Subject: [PATCH 04/10] Vitest conflict fix (#3316) --- ...b69b3c83578_26014_permissions_updates_2.py | 24 +++ ...879befaf0b6_26014_permissions_updates_3.py | 27 +++ auth-api/src/auth_api/resources/v1/user.py | 9 +- auth-api/src/auth_api/services/invitation.py | 3 + auth-api/src/auth_api/services/membership.py | 4 +- auth-api/src/auth_api/services/org.py | 2 +- auth-api/src/auth_api/services/user.py | 8 +- auth-api/src/auth_api/utils/roles.py | 1 + auth-api/tests/unit/services/test_org.py | 13 +- auth-web/.env.example | 4 +- auth-web/firebase.json | 3 +- auth-web/package-lock.json | 4 +- auth-web/package.json | 2 +- .../account-info/AccountInfo.vue | 15 +- .../account-info/OrgAdminContact.vue | 7 +- .../team-management/InvitationsDataTable.vue | 121 +++++------ .../team-management/MemberDataTable.vue | 8 +- .../PendingMemberDataTable.vue | 9 +- .../transaction/Transactions.vue | 9 +- .../components/auth/common/PaymentMethods.vue | 1 + .../src/components/auth/common/ProductTOS.vue | 2 +- .../src/components/auth/home/BcscPanel.vue | 6 +- .../components/auth/mixins/AccountMixin.vue | 4 + .../components/auth/mixins/NextPageMixin.vue | 8 +- .../StaffAccountManagement.vue | 190 ++++++++---------- auth-web/src/locales/en.json | 4 +- auth-web/src/models/Organization.ts | 4 +- .../display-mappers/product-display.ts | 2 +- auth-web/src/routes/index.ts | 6 +- auth-web/src/routes/router.ts | 22 +- auth-web/src/services/permission.services.ts | 4 +- auth-web/src/stores/business.ts | 5 +- auth-web/src/stores/codes.ts | 2 +- auth-web/src/stores/org.ts | 64 +++--- auth-web/src/util/common-util.ts | 61 +----- auth-web/src/util/constants.ts | 14 +- auth-web/src/util/http-util.ts | 1 + auth-web/src/views/auth/AccountSettings.vue | 52 ++--- .../src/views/auth/BusinessProfileView.vue | 7 +- .../views/auth/staff/StaffDashboardView.vue | 29 ++- .../tests/unit/components/AccountInfo.spec.ts | 7 + .../unit/components/ProductPayment.spec.ts | 8 +- .../unit/components/Transactions.spec.ts | 3 +- .../unit/test-utils/test-data/permissions.ts | 27 +++ auth-web/tests/unit/util/common-util.spec.ts | 13 -- .../StaffDashboard/StaffDashboardView.spec.ts | 14 ++ auth-web/vite.config.ts | 3 +- .../src/account_mailer/auth_utils.py | 7 + .../email_templates/pad_invoice_email.html | 13 +- .../src/account_mailer/resources/worker.py | 6 +- .../tests/unit/test_worker_queue.py | 15 +- 51 files changed, 477 insertions(+), 400 deletions(-) create mode 100644 auth-api/migrations/versions/2025_03_13_2b69b3c83578_26014_permissions_updates_2.py create mode 100644 auth-api/migrations/versions/2025_03_14_0879befaf0b6_26014_permissions_updates_3.py create mode 100644 auth-web/tests/unit/test-utils/test-data/permissions.ts diff --git a/auth-api/migrations/versions/2025_03_13_2b69b3c83578_26014_permissions_updates_2.py b/auth-api/migrations/versions/2025_03_13_2b69b3c83578_26014_permissions_updates_2.py new file mode 100644 index 0000000000..8d580a882d --- /dev/null +++ b/auth-api/migrations/versions/2025_03_13_2b69b3c83578_26014_permissions_updates_2.py @@ -0,0 +1,24 @@ +"""26014-permissions-updates-2 + +Revision ID: 2b69b3c83578 +Revises: 2ef3f0be3759 +Create Date: 2025-03-13 13:40:59.972418 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '2b69b3c83578' +down_revision = '2ef3f0be3759' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("""INSERT INTO permissions (membership_type_code, actions) VALUES ('COORDINATOR', 'edit_user');""") + + +def downgrade(): + op.execute("delete from permissions where membership_type_code = 'COORDINATOR' and actions = 'edit_user'") diff --git a/auth-api/migrations/versions/2025_03_14_0879befaf0b6_26014_permissions_updates_3.py b/auth-api/migrations/versions/2025_03_14_0879befaf0b6_26014_permissions_updates_3.py new file mode 100644 index 0000000000..d25e0a4d7d --- /dev/null +++ b/auth-api/migrations/versions/2025_03_14_0879befaf0b6_26014_permissions_updates_3.py @@ -0,0 +1,27 @@ +"""26014-permissions-updates-3 + +Revision ID: 0879befaf0b6 +Revises: 2b69b3c83578 +Create Date: 2025-03-14 09:04:07.238735 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '0879befaf0b6' +down_revision = '2b69b3c83578' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("""INSERT INTO permissions (membership_type_code, actions) VALUES ('CC_STAFF', 'view_account_invitations');""") + op.execute("""INSERT INTO permissions (membership_type_code, actions) VALUES ('CC_STAFF', 'view_pending_tasks');""") + op.execute("""INSERT INTO permissions (membership_type_code, actions) VALUES ('CC_STAFF', 'view_suspended_accounts');""") + +def downgrade(): + op.execute("delete from permissions where membership_type_code = 'CC_STAFF' and actions = 'view_account_invitations'") + op.execute("delete from permissions where membership_type_code = 'CC_STAFF' and actions = 'view_pending_tasks'") + op.execute("delete from permissions where membership_type_code = 'CC_STAFF' and actions = 'view_suspended_accounts'") diff --git a/auth-api/src/auth_api/resources/v1/user.py b/auth-api/src/auth_api/resources/v1/user.py index 372f77b00d..4a84b1ec2b 100644 --- a/auth-api/src/auth_api/resources/v1/user.py +++ b/auth-api/src/auth_api/resources/v1/user.py @@ -137,7 +137,14 @@ def post_user(): @bp.route("/<path:username>/otp", methods=["DELETE", "OPTIONS"]) @cross_origin(origins="*", methods=["DELETE"]) -@_jwt.has_one_of_roles([Role.STAFF_MANAGE_ACCOUNTS.value, Role.PUBLIC_USER.value, Role.STAFF_VIEW_ACCOUNTS.value]) +@_jwt.has_one_of_roles( + [ + Role.STAFF_MANAGE_ACCOUNTS.value, + Role.PUBLIC_USER.value, + Role.STAFF_VIEW_ACCOUNTS.value, + Role.MANAGE_RESET_OTP.value, + ] +) def delete_user_otp(username): """Delete/Reset the OTP of user profile associated with the provided username.""" try: diff --git a/auth-api/src/auth_api/services/invitation.py b/auth-api/src/auth_api/services/invitation.py index f31e09f360..faa49df7bc 100644 --- a/auth-api/src/auth_api/services/invitation.py +++ b/auth-api/src/auth_api/services/invitation.py @@ -451,6 +451,9 @@ def accept_invitation(invitation_id, user: UserService, origin, add_membership: Invitation._publish_activity_if_active(membership_model, user_from_context) + if org_model.access_type == AccessType.GOVM.value: + MembershipService.add_or_remove_group_for_staff(membership_model) + # Create staff review task. Invitation._create_affidavit_review_task(org_model, membership_model) try: diff --git a/auth-api/src/auth_api/services/membership.py b/auth-api/src/auth_api/services/membership.py index 7279419266..36e8591190 100644 --- a/auth-api/src/auth_api/services/membership.py +++ b/auth-api/src/auth_api/services/membership.py @@ -333,11 +333,11 @@ def _add_or_remove_group(model: MembershipModel): KeycloakService.remove_from_account_holders_group(model.user.keycloak_guid) # Add or Remove from STAFF group in keycloak - Membership._add_or_remove_group_for_staff(model) + Membership.add_or_remove_group_for_staff(model) ProductService.update_users_products_keycloak_groups([model.user.id]) @staticmethod - def _add_or_remove_group_for_staff(model: MembershipModel): + def add_or_remove_group_for_staff(model: MembershipModel): mapping_group = org_type_to_group_mapping.get(model.org.type_code) if not mapping_group: return diff --git a/auth-api/src/auth_api/services/org.py b/auth-api/src/auth_api/services/org.py index 0848ee97db..1bf1c6e1e5 100644 --- a/auth-api/src/auth_api/services/org.py +++ b/auth-api/src/auth_api/services/org.py @@ -240,7 +240,7 @@ def _create_payment_settings( ) match response.status_code: - case HTTPStatus.OK: + case HTTPStatus.OK | HTTPStatus.CREATED: payment_account_status = PaymentAccountStatus.CREATED case HTTPStatus.ACCEPTED: payment_account_status = PaymentAccountStatus.PENDING diff --git a/auth-api/src/auth_api/services/user.py b/auth-api/src/auth_api/services/user.py index f94341d598..1d760694f8 100644 --- a/auth-api/src/auth_api/services/user.py +++ b/auth-api/src/auth_api/services/user.py @@ -238,13 +238,17 @@ def _create_new_user_and_membership(db_username, kc_user, membership, org_id): return user_model @staticmethod - def delete_otp_for_user(user_name, origin_url: str = None): + @user_context + def delete_otp_for_user(user_name, origin_url: str = None, **kwargs): """Reset the OTP of the user.""" # TODO - handle when the multiple teams implemented for bceid.. user = UserModel.find_by_username(user_name) membership = MembershipModel.find_membership_by_userid(user.id) org_id = membership.org_id - check_auth(org_id=org_id, one_of_roles=(ADMIN, COORDINATOR, STAFF)) + + user_from_context: UserContext = kwargs["user_context"] + if not user_from_context.has_role(Role.MANAGE_RESET_OTP.value): + check_auth(org_id=org_id, one_of_roles=(ADMIN, COORDINATOR, STAFF)) try: KeycloakService.reset_otp(str(user.keycloak_guid)) User.send_otp_authenticator_reset_notification(user.email, origin_url, org_id) diff --git a/auth-api/src/auth_api/utils/roles.py b/auth-api/src/auth_api/utils/roles.py index 192e2475d8..7f7f32f1db 100644 --- a/auth-api/src/auth_api/utils/roles.py +++ b/auth-api/src/auth_api/utils/roles.py @@ -50,6 +50,7 @@ class Role(Enum): VIEW_ACCOUNT_PENDING_INVITATIONS = "view_account_pending_invitations" VIEW_MEMBERS_PENDING_INVITATIONS = "view_members_pending_invitations" VIEW_ACTIVITY_LOGS = "view_activity_logs" + MANAGE_RESET_OTP = "manage_reset_otp" # Membership types diff --git a/auth-api/tests/unit/services/test_org.py b/auth-api/tests/unit/services/test_org.py index b7bb8a85e0..bd5a7202b1 100644 --- a/auth-api/tests/unit/services/test_org.py +++ b/auth-api/tests/unit/services/test_org.py @@ -119,13 +119,22 @@ def test_create_org_products(session, keycloak_mock, monkeypatch): patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) with patch.object(ActivityLogPublisher, "publish_activity", return_value=None) as mock_alp: org = OrgService.create_org(TestOrgInfo.org_with_products, user_id=user.id) - mock_alp.assert_called_with( + mock_alp.assert_any_call( Activity( action=ActivityAction.ADD_PRODUCT_AND_SERVICE.value, org_id=ANY, value=ANY, id=ANY, - name="Business Registry & Name Request", + name=ANY, + ) + ) + mock_alp.assert_any_call( + Activity( + action=ActivityAction.PAYMENT_INFO_CHANGE.value, + org_id=ANY, + value=ANY, + id=ANY, + name=ANY, ) ) assert org diff --git a/auth-web/.env.example b/auth-web/.env.example index 6ab46cc442..b042fb3481 100644 --- a/auth-web/.env.example +++ b/auth-web/.env.example @@ -38,7 +38,7 @@ VUE_APP_NAMEX_WEB_URL="https://dev.namex.bcregistry.gov.bc.ca/" VUE_APP_BUSINESS_REGISTRY_URL="https://business-registry-dev.web.app/" #vaults API -VUE_APP_AUTH_API_URL="https://auth-api-dev.apps.silver.devops.gov.bc.ca" +VUE_APP_AUTH_API_URL="https://auth-api-dev-142173140222.northamerica-northeast1.run.app" VUE_APP_AUTH_API_VERSION="/api/v1" VUE_APP_LEGAL_API_URL="https://legal-api-dev.apps.silver.devops.gov.bc.ca" VUE_APP_LEGAL_API_VERSION="/api/v1" @@ -72,4 +72,4 @@ VUE_APP_KEYCLOAK_CLIENTID="account-web" VUE_APP_SENTRY_DSN= #vaults hotjar -VUE_APP_HOTJAR_ID= \ No newline at end of file +VUE_APP_HOTJAR_ID= diff --git a/auth-web/firebase.json b/auth-web/firebase.json index ff47ebe6a8..fd7bd7698c 100644 --- a/auth-web/firebase.json +++ b/auth-web/firebase.json @@ -1,3 +1,4 @@ +// This is for GCBRUN only for DEV/TEST/PROD - see https://github.com/bcgov/bcregistry-sre/tree/main/.github/actions/frontend-deploy/files { "hosting": { @@ -20,7 +21,7 @@ { "key" : "X-XSS-Protection", "value" : "1; mode=block" }, { "key": "Content-Security-Policy", - "value": "default-src 'self'; frame-src 'self' *.gov.bc.ca *.hotjar.com *.googleapis.com https://*.nr-data.net https://*.newrelic.com https://*.cac1.pure.cloud; script-src 'self' 'unsafe-eval' 'unsafe-inline' *.gov.bc.ca *.hotjar.com *.googleapis.com https://*.nr-data.net https://*.newrelic.com https://*.cac1.pure.cloud; style-src 'self' 'unsafe-inline' *.cloudflare.com *.googleapis.com; font-src 'self' *.gov.bc.ca *.hotjar.com *.cloudflare.com *.googleapis.com *.gstatic.com *.jsdelivr.net; img-src 'self' data: *.hotjar.com https://*.cac1.pure.cloud; connect-src 'self' *.gov.bc.ca *.launchdarkly.com *.hotjar.com *.postescanada-canadapost.ca *.sentry.io *.apigee.net wss://*.hotjar.com *.hotjar.io https://*.nr-data.net https://shyrka-prod-cac1.s3.ca-central-1.amazonaws.com https://*.newrelic.com https://*.cac1.pure.cloud wss://*.cac1.pure.cloud; manifest-src 'self'; media-src 'self' https://*.cac1.pure.cloud; object-src 'self' https://*.cac1.pure.cloud; child-src 'self' https://*.cac1.pure.cloud;" + "value": "default-src 'self'; frame-src 'self' *.gov.bc.ca *.hotjar.com *.googleapis.com https://*.nr-data.net https://*.newrelic.com https://*.cac1.pure.cloud; script-src 'self' 'unsafe-eval' 'unsafe-inline' *.gov.bc.ca *.hotjar.com *.googleapis.com https://*.nr-data.net https://*.newrelic.com https://*.cac1.pure.cloud; style-src 'self' 'unsafe-inline' *.cloudflare.com *.googleapis.com; font-src 'self' *.gov.bc.ca *.hotjar.com *.cloudflare.com *.googleapis.com *.gstatic.com *.jsdelivr.net; img-src 'self' data: *.hotjar.com https://*.cac1.pure.cloud; connect-src 'self' *.run.app *.gov.bc.ca *.launchdarkly.com *.hotjar.com *.postescanada-canadapost.ca *.sentry.io *.apigee.net wss://*.hotjar.com *.hotjar.io https://*.nr-data.net https://shyrka-prod-cac1.s3.ca-central-1.amazonaws.com https://*.newrelic.com https://*.cac1.pure.cloud wss://*.cac1.pure.cloud; manifest-src 'self'; media-src 'self' https://*.cac1.pure.cloud; object-src 'self' https://*.cac1.pure.cloud; child-src 'self' https://*.cac1.pure.cloud;" }, { "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate"}, { "key": "Pragma", "value": "no-cache"}, diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index eb70ba9745..73851adf88 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -1,12 +1,12 @@ { "name": "auth-web", - "version": "2.9.0", + "version": "2.10.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "auth-web", - "version": "2.9.0", + "version": "2.10.0", "dependencies": { "@bcrs-shared-components/base-address": "2.0.39", "@bcrs-shared-components/bread-crumb": "1.0.8", diff --git a/auth-web/package.json b/auth-web/package.json index dfb3876d78..b80c150b65 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -1,6 +1,6 @@ { "name": "auth-web", - "version": "2.9.0", + "version": "2.10.0", "appName": "Auth Web", "sbcName": "SBC Common Components", "private": true, diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue index 809260cc76..31e1cca16c 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue @@ -131,7 +131,7 @@ class="value" aria-labelledby="adminContact" > - <OrgAdminContact /> + <OrgAdminContact :orgId="orgId" /> </div> </div> @@ -299,7 +299,8 @@ export default defineComponent({ AccountMailingAddress, AccountAccessType }, - setup () { + props: ['orgId'], + setup (props, { root }) { const codesStore = useCodesStore() const orgStore = useOrgStore() const userStore = useUserStore() @@ -310,7 +311,6 @@ export default defineComponent({ currentOrgPaymentType, currentOrgAddress, permissions, - getAccountFromSession, anonAccount, isGovmAccount, isStaffAccount, @@ -344,7 +344,7 @@ export default defineComponent({ isBusinessAccount: computed(() => orgStore.isBusinessAccount), baseAddress: computed(() => currentOrgAddress.value), - isStaff: computed(() => userStore.currentUser.roles.includes(Role.Staff)) || userStore.currentUser.roles.includes(Role.ContactCentreStaff), + isStaff: computed(() => userStore.currentUser.roles.includes(Role.Staff)) || userStore.currentUser.roles.includes(Role.ExternalStaffReadonly), isSuspendButtonVisible: computed(() => ( (currentOrganization.value.statusCode === AccountStatus.ACTIVE || currentOrganization.value.statusCode === AccountStatus.SUSPENDED) && @@ -352,8 +352,7 @@ export default defineComponent({ )), isDeactivateButtonVisible: computed(() => currentOrganization.value?.statusCode !== AccountStatus.INACTIVE), canChangeAccessType: computed(() => ( - userStore.currentUser.roles.includes(Role.StaffManageAccounts) && - !userStore.currentUser.roles.includes(Role.ContactCentreStaff) + userStore.currentUser.roles.includes(Role.StaffManageAccounts) )), isAdminContactViewable: computed(() => [Permission.VIEW_ADMIN_CONTACT].some(per => permissions.value.includes(per))), isAccountStatusActive: computed(() => currentOrganization.value.statusCode === AccountStatus.ACTIVE), @@ -369,7 +368,7 @@ export default defineComponent({ currentOrgAddress.value ? Object.keys(currentOrgAddress.value).length === 0 : true )), nameChangeNotAllowed: computed(() => (anonAccount.value || isGovmAccount.value)) && - userStore.currentUser.roles.includes(Role.ContactCentreStaff) + userStore.currentUser.roles.includes(Role.ExternalStaffReadonly) }) const suspensionSelectRules = [ @@ -592,8 +591,6 @@ export default defineComponent({ } onMounted(async () => { - const accountSettings = getAccountFromSession() - await orgStore.syncOrganization(accountSettings?.id) setAccountChangedHandler(setup) await setup() }) diff --git a/auth-web/src/components/auth/account-settings/account-info/OrgAdminContact.vue b/auth-web/src/components/auth/account-settings/account-info/OrgAdminContact.vue index e35cd111f7..b76422fac9 100644 --- a/auth-web/src/components/auth/account-settings/account-info/OrgAdminContact.vue +++ b/auth-web/src/components/auth/account-settings/account-info/OrgAdminContact.vue @@ -26,7 +26,7 @@ </template> <script lang="ts"> -import { Component, Vue } from 'vue-property-decorator' +import { Component, Prop, Vue } from 'vue-property-decorator' import { Member, MembershipType, @@ -49,12 +49,13 @@ import { useOrgStore } from '@/stores/org' }) export default class OrgAdminContact extends Vue { + @Prop() private orgId: number private activeOrgMembers!: Member[] - private readonly syncActiveOrgMembers!: () => Member[] + private readonly syncActiveOrgMembers!: (orgId: number) => Member[] private readonly currentOrganization!: Organization private async mounted () { - this.syncActiveOrgMembers() + this.syncActiveOrgMembers(this.orgId) } private get getActiveAdmins (): Member[] { diff --git a/auth-web/src/components/auth/account-settings/team-management/InvitationsDataTable.vue b/auth-web/src/components/auth/account-settings/team-management/InvitationsDataTable.vue index 9c1cc134cb..dfe893320c 100644 --- a/auth-web/src/components/auth/account-settings/team-management/InvitationsDataTable.vue +++ b/auth-web/src/components/auth/account-settings/team-management/InvitationsDataTable.vue @@ -30,7 +30,7 @@ <template #[`item.action`]="{ item }"> <!-- Resend Invitation --> <v-btn - v-if="canApproveOrDeny()" + v-can:EDIT_USER.hide icon class="mr-1" aria-label="Resend invitation" @@ -43,7 +43,7 @@ <!-- Remove Invitation --> <v-btn - v-if="canApproveOrDeny()" + v-can:EDIT_USER.hide icon aria-label="Remove Invitation" title="Remove Invitation" @@ -57,72 +57,75 @@ </template> <script lang="ts"> -import { Component, Emit, Vue } from 'vue-property-decorator' +import { computed, defineComponent, reactive, toRefs } from '@vue/composition-api' import CommonUtils from '@/util/common-util' import { Invitation } from '@/models/Invitation' -import { Role } from '@/util/constants' -import { mapState } from 'pinia' +import { storeToRefs } from 'pinia' import { useOrgStore } from '@/stores/org' -import { useUserStore } from '@/stores/user' -@Component({ - computed: { - ...mapState(useOrgStore, ['pendingOrgInvitations']), - ...mapState(useUserStore, ['currentUser']) - } -}) -export default class InvitationsDataTable extends Vue { - private readonly pendingOrgInvitations!: Invitation[] - readonly headerInvitations = [ - { - text: 'Email', - align: 'left', - sortable: true, - value: 'recipientEmail' - }, - { - text: 'Invitation Sent', - align: 'left', - sortable: true, - value: 'sentDate' - }, - { - text: 'Expires', - align: 'left', - sortable: true, - value: 'expiresOn' - }, - { - text: 'Actions', - align: 'right', - value: 'action', - sortable: false - } - ] +export default defineComponent({ + name: 'InvitationsDataTable', + emits: ['confirmRemoveInvite', 'resend'], + setup (props, { emit }) { + const orgStore = useOrgStore() + const { pendingOrgInvitations } = storeToRefs(orgStore) + const headerInvitations = [ + { + text: 'Email', + align: 'left', + sortable: true, + value: 'recipientEmail' + }, + { + text: 'Invitation Sent', + align: 'left', + sortable: true, + value: 'sentDate' + }, + { + text: 'Expires', + align: 'left', + sortable: true, + value: 'expiresOn' + }, + { + text: 'Actions', + align: 'right', + value: 'action', + sortable: false + } + ] - private canApproveOrDeny (): boolean { - return !this.currentUser.roles?.includes(Role.ContactCentreStaff) - } + const state = reactive({ + indexedInvitations: computed(() => + pendingOrgInvitations.value.map((item: Invitation, index: number) => ({ + index, + ...item + }))) + }) - formatDate = CommonUtils.formatDisplayDate - - getIndexedTag (tag, index): string { - return `${tag}-${index}` - } + function getIndexedTag (tag: string, index: number): string { + return `${tag}-${index}` + } - get indexedInvitations () { - return this.pendingOrgInvitations.map((item, index) => ({ - index, - ...item - })) - } + function confirmRemoveInvite (invitation) { + emit('confirm-remove-invite', invitation) + } - @Emit() - confirmRemoveInvite () {} + function resend (invitation) { + emit('resend', invitation) + } - @Emit() - resend () {} -} + return { + headerInvitations, + ...toRefs(state), + formatDate: CommonUtils.formatDisplayDate, + getIndexedTag, + confirmRemoveInvite, + resend + } + } +}) </script> <style lang="scss" scoped> diff --git a/auth-web/src/components/auth/account-settings/team-management/MemberDataTable.vue b/auth-web/src/components/auth/account-settings/team-management/MemberDataTable.vue index ec70e29004..01008f167a 100644 --- a/auth-web/src/components/auth/account-settings/team-management/MemberDataTable.vue +++ b/auth-web/src/components/auth/account-settings/team-management/MemberDataTable.vue @@ -404,10 +404,6 @@ export default class MemberDataTable extends Vue { } private canChangeRole (memberBeingChanged: Member): boolean { - if (this.currentUser.roles?.includes(Role.ContactCentreStaff)) { - return false - } - if (this.currentMembership.membershipStatus !== MembershipStatus.Active) { return false } @@ -435,8 +431,8 @@ export default class MemberDataTable extends Vue { } private canRemove (memberToRemove: Member): boolean { - // Contact Centre Staff can't remove anyone - if (this.currentUser.roles?.includes(Role.ContactCentreStaff)) { + // External Staff cannot remove members from orgs they do not belong + if (!this.currentMembership.id && this.currentUser && this.currentUser.roles?.includes(Role.ExternalStaffReadonly)) { return false } diff --git a/auth-web/src/components/auth/account-settings/team-management/PendingMemberDataTable.vue b/auth-web/src/components/auth/account-settings/team-management/PendingMemberDataTable.vue index 513c93dda3..c1ecc8002a 100644 --- a/auth-web/src/components/auth/account-settings/team-management/PendingMemberDataTable.vue +++ b/auth-web/src/components/auth/account-settings/team-management/PendingMemberDataTable.vue @@ -28,7 +28,7 @@ </template> <template #[`item.action`]="{ item }"> <v-btn - v-if="canApproveOrDeny()" + v-can:EDIT_USER.hide icon class="mr-1" aria-label="Approve user access to this account" @@ -39,7 +39,7 @@ <v-icon>mdi-check-circle-outline</v-icon> </v-btn> <v-btn - v-if="canApproveOrDeny()" + v-can:EDIT_USER.hide icon aria-label="Deny access to this account" title="Deny access to this account" @@ -56,7 +56,6 @@ import { Component, Emit, Prop, Vue } from 'vue-property-decorator' import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile' import { Member } from '@/models/Organization' -import { Role } from '@/util/constants' import { mapState } from 'pinia' /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ import moment from 'moment' @@ -88,10 +87,6 @@ export default class PendingMemberDataTable extends Vue { } ] - private canApproveOrDeny (): boolean { - return !this.currentUser.roles?.includes(Role.ContactCentreStaff) - } - getIndexedTag (tag, index): string { return `${tag}-${index}` } diff --git a/auth-web/src/components/auth/account-settings/transaction/Transactions.vue b/auth-web/src/components/auth/account-settings/transaction/Transactions.vue index 4bd145b8b2..81542c02b7 100644 --- a/auth-web/src/components/auth/account-settings/transaction/Transactions.vue +++ b/auth-web/src/components/auth/account-settings/transaction/Transactions.vue @@ -115,13 +115,13 @@ </template> <script lang="ts"> -import { Account, Pages } from '@/util/constants' -import { MembershipType, OrgPaymentDetails } from '@/models/Organization' +import { Pages, Permission } from '@/util/constants' import { Ref, computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, toRefs, watch } from '@vue/composition-api' import { useAccountChangeHandler, useTransactions } from '@/composables' import { BaseTableHeaderI } from '@/components/datatable/interfaces' import CommonUtils from '@/util/common-util' import ModalDialog from '@/components/auth/common/ModalDialog.vue' +import { OrgPaymentDetails } from '@/models/Organization' import { StatusCodes } from 'http-status-codes' import TransactionsDataTable from './TransactionsDataTable.vue' import { getTransactionTableHeaders } from '@/resources/table-headers' @@ -141,7 +141,6 @@ export default defineComponent({ const orgStore = useOrgStore() const currentOrgPaymentDetails = computed(() => orgStore.currentOrgPaymentDetails) const currentOrganization = computed(() => orgStore.currentOrganization) - const currentMembership = computed(() => orgStore.currentMembership) const csvErrorDialog: Ref<InstanceType<typeof ModalDialog>> = ref(null) const csvErrorTextBasic = 'We were unable to process your CSV export. Please try again later.' @@ -190,9 +189,7 @@ export default defineComponent({ const credit = ref(0) const isTransactionsAllowed = computed((): boolean => { - return [Account.PREMIUM, Account.STAFF, Account.SBC_STAFF] - .includes(currentOrganization.value.orgType as Account) && - [MembershipType.Admin, MembershipType.Coordinator].includes(currentMembership.value.membershipTypeCode) + return orgStore.hasPermission(Permission.TRANSACTION_HISTORY) }) const getCredits = async () => { diff --git a/auth-web/src/components/auth/common/PaymentMethods.vue b/auth-web/src/components/auth/common/PaymentMethods.vue index 1f6ce859da..96eeb02014 100644 --- a/auth-web/src/components/auth/common/PaymentMethods.vue +++ b/auth-web/src/components/auth/common/PaymentMethods.vue @@ -119,6 +119,7 @@ </div> <PADInfoForm v-else + :isCreateAccount="isCreateAccount" :isChangeView="isChangeView" :isAcknowledgeNeeded="isAcknowledgeNeeded" :isInitialAcknowledged="isInitialAcknowledged" diff --git a/auth-web/src/components/auth/common/ProductTOS.vue b/auth-web/src/components/auth/common/ProductTOS.vue index c42e824590..7700b51534 100644 --- a/auth-web/src/components/auth/common/ProductTOS.vue +++ b/auth-web/src/components/auth/common/ProductTOS.vue @@ -69,7 +69,7 @@ export default defineComponent({ const state = reactive({ termsAccepted: false, istosTouched: false, - canAcceptTos: computed(() => !userStore?.currentUser?.roles.includes(Role.ContactCentreStaff)) + canAcceptTos: computed(() => !userStore?.currentUser?.roles.includes(Role.ExternalStaffReadonly)) }) watch(() => props.isTOSAlreadyAccepted, (newTos, oldTos) => { diff --git a/auth-web/src/components/auth/home/BcscPanel.vue b/auth-web/src/components/auth/home/BcscPanel.vue index ad16c5fb9b..16364419d2 100644 --- a/auth-web/src/components/auth/home/BcscPanel.vue +++ b/auth-web/src/components/auth/home/BcscPanel.vue @@ -48,7 +48,7 @@ <v-list-item-subtitle class="list-item-text"> It normally takes about 5 minutes to <a - :href="cardSetUpUrl" + :href="learnMoreUrl" class="link" target="_blank" >set up a mobile card</a> @@ -108,8 +108,7 @@ export default defineComponent({ } }, setup () { - const cardSetUpUrl = 'https://www2.gov.bc.ca/gov/content/governments/government-id/bcservicescardapp/setup' - const learnMoreUrl = 'https://www2.gov.bc.ca/gov/content/governments/government-id/bcservicescardapp/setup' + const learnMoreUrl = 'https://www.id.gov.bc.ca' const secureBulletPoints = [ { text: `A mobile card is a representation of your BC Services Card on your mobile device. ` + `It's used to prove who you are when you log in to access government services online.` }, @@ -122,7 +121,6 @@ export default defineComponent({ ] return { - cardSetUpUrl, learnMoreUrl, secureBulletPoints, easeBulletPoints diff --git a/auth-web/src/components/auth/mixins/AccountMixin.vue b/auth-web/src/components/auth/mixins/AccountMixin.vue index b5daac6b69..a273074df4 100644 --- a/auth-web/src/components/auth/mixins/AccountMixin.vue +++ b/auth-web/src/components/auth/mixins/AccountMixin.vue @@ -54,5 +54,9 @@ export default class AccountMixin extends Vue { get isSbcStaffAccount (): boolean { return this.currentOrganization?.orgType === Account.SBC_STAFF } + + get isExternalStaffAccount (): boolean { + return [Account.CONTACT_CENTRE_STAFF, Account.MAXIMUS_STAFF].includes(this.currentOrganization?.orgType) + } } </script> diff --git a/auth-web/src/components/auth/mixins/NextPageMixin.vue b/auth-web/src/components/auth/mixins/NextPageMixin.vue index fe8459f9b4..704c961f6f 100644 --- a/auth-web/src/components/auth/mixins/NextPageMixin.vue +++ b/auth-web/src/components/auth/mixins/NextPageMixin.vue @@ -22,7 +22,7 @@ import Vue from 'vue' methods: { ...mapActions(useUserStore, ['loadUserInfo', 'syncUserProfile', 'getUserProfile']), ...mapActions(useOrgStore, ['syncOrganization', 'syncMembership', 'resetCurrentOrganization', - 'setCurrentAccountSettings']) + 'setCurrentAccountSettings', 'syncStaffPermissions']) } }) export default class NextPageMixin extends Vue { @@ -38,6 +38,7 @@ export default class NextPageMixin extends Vue { protected readonly syncUserProfile!: () => void protected readonly syncOrganization!: (currentAccount: number) => Promise<Organization> protected readonly syncMembership!: (currentAccount: number) => Promise<Member> + protected readonly syncStaffPermissions!: () => Promise<string[]> protected readonly resetCurrentOrganization!: () => Promise<void> private readonly needMissingBusinessDetailsRedirect!: boolean // its used to determine if any pending redirect like NFS or account pending page @@ -192,6 +193,11 @@ export default class NextPageMixin extends Vue { await this.resetCurrentOrganization() } } + + // This occurs on account switching, if we are on the dashboard, we want to resync staff permissions + if (this.$route.fullPath.includes(Pages.STAFF_DASHBOARD)) { + await this.syncStaffPermissions() + } } protected accountFreezeRedirect () { diff --git a/auth-web/src/components/auth/staff/account-management/StaffAccountManagement.vue b/auth-web/src/components/auth/staff/account-management/StaffAccountManagement.vue index 3660b0fa60..464fdc183c 100644 --- a/auth-web/src/components/auth/staff/account-management/StaffAccountManagement.vue +++ b/auth-web/src/components/auth/staff/account-management/StaffAccountManagement.vue @@ -29,80 +29,24 @@ @change="tabChange" > <v-tab - v-if="canViewAccounts" - data-test="active-tab" - :to="pagesEnum.STAFF_DASHBOARD_ACTIVE" + v-for="tab in tabs" + :key="tab.code" + :data-test="tab.code" + :to="tab.page" > - Active - </v-tab> - - <template v-if="canViewInvitations"> - <v-tab - data-test="invitations-tab" - :to="pagesEnum.STAFF_DASHBOARD_INVITATIONS" - > - <v-badge - inline - color="primary" - :content="pendingInvitationsCount" - :value="pendingInvitationsCount" - > - Invitations - </v-badge> - </v-tab> - </template> - - <template v-if="canManageAccounts"> - <v-tab - data-test="pending-review-tab" - :to="pagesEnum.STAFF_DASHBOARD_REVIEW" - > + <template v-if="tab.hasBadge"> <v-badge inline color="primary" - :content="pendingTasksCount" - :value="pendingTasksCount" + :content="tab.count.value" + :value="tab.count.value" > - Pending Review + {{ tab.tabName }} </v-badge> - </v-tab> - <v-tab - data-test="rejected-tab" - :to="pagesEnum.STAFF_DASHBOARD_REJECTED" - > - <v-badge - inline - color="primary" - :content="rejectedTasksCount" - :value="rejectedTasksCount" - > - Rejected - </v-badge> - </v-tab> - </template> - - <template v-if="canSuspendAccounts"> - <v-tab - data-test="suspended-tab" - :to="pagesEnum.STAFF_DASHBOARD_SUSPENDED" - > - <v-badge - inline - color="primary" - :content="suspendedReviewCount" - :value="suspendedReviewCount" - > - Suspended - </v-badge> - </v-tab> - </template> - - <v-tab - v-if="canViewAccounts" - data-test="inactive-tab" - :to="pagesEnum.STAFF_DASHBOARD_INACTIVE" - > - Inactive + </template> + <template v-else> + {{ tab.tabName }} + </template> </v-tab> </v-tabs> @@ -115,10 +59,12 @@ </template> <script lang="ts"> -import { Pages, Role } from '@/util/constants' -import { computed, defineComponent, onMounted, reactive, toRefs } from '@vue/composition-api' +import { ComputedRef, computed, defineComponent, onMounted, reactive, toRefs } from '@vue/composition-api' +import { Pages, Permission, Role } from '@/util/constants' import StaffCreateAccountModal from '@/components/auth/staff/account-management/StaffCreateAccountModal.vue' +import { storeToRefs } from 'pinia' import { useCodesStore } from '@/stores/codes' +import { useOrgStore } from '@/stores' import { useStaffStore } from '@/stores/staff' import { useTaskStore } from '@/stores/task' import { useUserStore } from '@/stores/user' @@ -138,6 +84,8 @@ export default defineComponent({ StaffCreateAccountModal }, setup () { + const orgStore = useOrgStore() + const { permissions } = storeToRefs(orgStore) const { currentUser } = useUserStore() const { syncPendingInvitationOrgs, syncSuspendedStaffOrgs } = useStaffStore() const { getCodes } = useCodesStore() @@ -149,18 +97,76 @@ export default defineComponent({ const pendingTasksCount = computed(() => taskStore.pendingTasksCount) const rejectedTasksCount = computed(() => taskStore.rejectedTasksCount) + interface TabConfig { + permission: Permission; + tabName: string; + code: string; + page: string; + hasBadge?: boolean; + count?: ComputedRef<number>; + } + + const TAB_CONFIGS: TabConfig[] = [ + { permission: Permission.VIEW_ACTIVE_ACCOUNTS, + tabName: 'Active', + code: TAB_CODE.Active, + page: Pages.STAFF_DASHBOARD_ACTIVE + }, + { permission: Permission.VIEW_ACCOUNT_INVITATIONS, + tabName: 'Invitations', + code: TAB_CODE.Invitations, + hasBadge: true, + count: pendingInvitationsCount, + page: Pages.STAFF_DASHBOARD_INVITATIONS + }, + { permission: Permission.VIEW_PENDING_TASKS, + tabName: 'Pending Review', + code: TAB_CODE.PendingReview, + hasBadge: true, + count: pendingTasksCount, + page: Pages.STAFF_DASHBOARD_REVIEW + }, + { permission: Permission.VIEW_REJECTED_TASKS, + tabName: 'Rejected', + code: TAB_CODE.Rejected, + hasBadge: true, + count: rejectedTasksCount, + page: Pages.STAFF_DASHBOARD_REJECTED + }, + { permission: Permission.VIEW_SUSPENDED_ACCOUNTS, + tabName: 'Suspended', + code: TAB_CODE.Suspended, + hasBadge: true, + count: suspendedReviewCount, + page: Pages.STAFF_DASHBOARD_SUSPENDED + }, + { permission: Permission.VIEW_INACTIVE_ACCOUNTS, + tabName: 'Inactive', + code: TAB_CODE.Inactive, + page: Pages.STAFF_DASHBOARD_INACTIVE + } + ] + const state = reactive({ tab: 0, - pagesEnum: Pages, canManageAccounts: computed(() => currentUser?.roles?.includes(Role.StaffManageAccounts) || - currentUser?.roles?.includes(Role.ContactCentreStaff)), + currentUser?.roles?.includes(Role.ExternalStaffReadonly)), canViewInvitations: computed(() => currentUser?.roles?.includes(Role.StaffCreateAccounts) || - currentUser?.roles?.includes(Role.ContactCentreStaff)), + currentUser?.roles?.includes(Role.ExternalStaffReadonly)), canCreateAccounts: computed(() => currentUser?.roles?.includes(Role.StaffCreateAccounts) && - !currentUser?.roles?.includes(Role.ContactCentreStaff)), + !currentUser?.roles?.includes(Role.ExternalStaffReadonly)), canViewAccounts: computed(() => currentUser?.roles?.includes(Role.StaffViewAccounts)), canSuspendAccounts: computed(() => currentUser?.roles?.includes(Role.StaffSuspendAccounts) || - currentUser?.roles?.includes(Role.StaffViewAccounts)) + currentUser?.roles?.includes(Role.StaffViewAccounts)), + tabs: computed(() => { + return TAB_CONFIGS + .filter(({ permission }) => permissions.value.some(code => code === permission)) + .map((tabConfig, index) => ({ + id: index, + hasBadge: false, + ...tabConfig + })) + }) }) onMounted(async () => { @@ -172,39 +178,6 @@ export default defineComponent({ } }) - const tabs = reactive([ - { - id: 0, - tabName: 'Active', - code: TAB_CODE.Active - }, - { - id: 1, - tabName: 'Invitations', - code: TAB_CODE.Invitations - }, - { - id: 2, - tabName: 'Pending Review', - code: TAB_CODE.PendingReview - }, - { - id: 3, - tabName: 'Rejected', - code: TAB_CODE.Rejected - }, - { - id: 4, - tabName: 'Suspended', - code: TAB_CODE.Suspended - }, - { - id: 5, - tabName: 'Inactive', - code: TAB_CODE.Inactive - } - ]) - function openCreateAccount () { this.$refs.staffCreateAccountDialog.open() } @@ -220,7 +193,6 @@ export default defineComponent({ ...toRefs(state), openCreateAccount, tabChange, - tabs, pendingInvitationsCount, pendingTasksCount, rejectedTasksCount, diff --git a/auth-web/src/locales/en.json b/auth-web/src/locales/en.json index aba5b6fac3..18270af4c3 100644 --- a/auth-web/src/locales/en.json +++ b/auth-web/src/locales/en.json @@ -140,7 +140,7 @@ "csoCodeSubtitle": "Make applications or file any other court documents in any B.C. court registry, browse daily court listings across the province, or search court file information.", "pprCodeSubtitle": "Record security interests and liens or search existing records.", "businessCodeSubtitle": "Register or incorporate a business and keep business records up to date.", - "business_searchCodeSubtitle": "Search for businesses registered in B.C. and request copies of business documents.", + "business_searchCodeSubtitle": "Search for businesses registered in B.C. and their related individuals, and request copies of business documents.", "mhrStaffCodeSubtitle": "Search for manufactured homes in BC or complete a combined Manufactured Home and Personal Property Registry search.", "mhrCodeSubtitle": "Search for manufactured homes, and search for personal property legal claims on manufactured homes.", "mhrCodeNote": "<b>Note:</b> You can request Qualified Supplier access from your Manufactured Home Registry <br>(or Asset Registries) page once you have added this product to your account.", @@ -167,7 +167,7 @@ "esraCodeDescription": "Search by the following:<ul><li>Parcel ID (PID)</li><li>Crown Lands PIN</li><li>Crown Lands File Number</li><li>Site ID</li><li>Address</li><li>Area</li></ul>", "accountBusinessTypeText": "Select a user type for your BC Registries and Online Service Account:", "businessCodeActiveSubtitle": "This account has access to Business Registry & Name Request.", - "business_searchCodeActiveSubtitle": "This account has access to Business Search.", + "business_searchCodeActiveSubtitle": "This account has access to Business and Person Search.", "mhrStaffCodeActiveSubtitle": "This account has search access to Manufactured Home Registry", "mhrCodeActiveSubtitle": "This account has search access to Manufactured Home Registry", "strrStaffCodeActiveSubtitle": "This account has search access to Short Term Rental Registry", diff --git a/auth-web/src/models/Organization.ts b/auth-web/src/models/Organization.ts index e3082d9b4e..c781794f18 100644 --- a/auth-web/src/models/Organization.ts +++ b/auth-web/src/models/Organization.ts @@ -150,7 +150,9 @@ export enum MembershipStatus { export enum MembershipType { 'Admin' = 'ADMIN', 'Coordinator' = 'COORDINATOR', - 'User' = 'USER' + 'User' = 'USER', + 'Staff' = 'STAFF', + 'ExternalStaff' = 'EXTERNAL_STAFF' } export interface Permissions { diff --git a/auth-web/src/resources/display-mappers/product-display.ts b/auth-web/src/resources/display-mappers/product-display.ts index 54550a9ade..4ea5c685c5 100644 --- a/auth-web/src/resources/display-mappers/product-display.ts +++ b/auth-web/src/resources/display-mappers/product-display.ts @@ -3,7 +3,7 @@ import { Product } from '@/util/constants' export const productDisplay = { [Product.BCA]: 'BC Assessment', [Product.BUSINESS]: 'Business Registry & Name Request', - [Product.BUSINESS_SEARCH]: 'Business Search', + [Product.BUSINESS_SEARCH]: 'Business and Person Search', [Product.CSO]: 'Court Services Online', [Product.ESRA]: 'Site Registry', [Product.MHR]: 'Manufactured Home Registry', diff --git a/auth-web/src/routes/index.ts b/auth-web/src/routes/index.ts index c6cca19404..21ce3bc54b 100644 --- a/auth-web/src/routes/index.ts +++ b/auth-web/src/routes/index.ts @@ -44,7 +44,7 @@ router.beforeEach(async (to, from, next) => { }) } } else { - if (to.meta.allowedRoles?.length === 1 && [Role.Staff, Role.ContactCentreStaff].includes(to.meta.allowedRoles[0])) { + if (to.meta.allowedRoles?.length === 1 && [Role.Staff, Role.ExternalStaffReadonly].includes(to.meta.allowedRoles[0])) { return next({ path: `/signin/idir${to.path}`, query: { redirect: to.fullPath } @@ -142,8 +142,8 @@ router.beforeEach(async (to, from, next) => { } // need to check for govm account also. so we are checking roles if (to.matched.some(record => record.meta.requiresActiveAccount) && - (currentUser.loginSource === LoginSource.BCSC || currentUser.loginSource === LoginSource.BCEID || - currentUser.roles.includes(Role.GOVMAccountUser))) { + ((currentUser.loginSource === LoginSource.BCSC || currentUser.loginSource === LoginSource.BCEID || + currentUser.roles.includes(Role.GOVMAccountUser)) && !currentUser.roles.includes(Role.ExternalStaffReadonly))) { // if (currentOrganization?.statusCode === AccountStatus.NSF_SUSPENDED) { if ([AccountStatus.NSF_SUSPENDED, AccountStatus.SUSPENDED].some(status => status === currentOrganization?.statusCode)) { console.log('[NG] Redirecting user to Account Freeze message since the account is temporarly suspended.') diff --git a/auth-web/src/routes/router.ts b/auth-web/src/routes/router.ts index 731aeca275..9f1e4df7f1 100644 --- a/auth-web/src/routes/router.ts +++ b/auth-web/src/routes/router.ts @@ -129,7 +129,7 @@ function mapPendingDetails (route: any) { function isStaff (): boolean { const userProfile = KeyCloakService.getUserInfo() const roles = userProfile?.roles || [] - return roles.includes('Staff') || roles.includes('ContactCentreStaff') + return roles.includes(Role.Staff) || roles.includes(Role.ExternalStaffReadonly) } export function getRoutes (): RouteConfig[] { @@ -309,6 +309,7 @@ export function getRoutes (): RouteConfig[] { { path: 'account-info', name: 'account-info', + props: (route) => ({ orgId: route.params.orgId }), component: accountInfo }, { @@ -457,7 +458,7 @@ export function getRoutes (): RouteConfig[] { path: '/review-account/:orgId', name: 'review-account', component: ReviewAccountView, - meta: { requiresAuth: true, allowedRoles: [Role.StaffManageAccounts, Role.ContactCentreStaff] }, + meta: { requiresAuth: true, allowedRoles: [Role.StaffManageAccounts, Role.ExternalStaffReadonly] }, props: true }, { @@ -571,6 +572,9 @@ export function getRoutes (): RouteConfig[] { path: '/businessprofile', name: 'businessprofile', component: BusinessProfileView, + props: (route) => ( + { businessid: route.query.businessid } + ), meta: { requiresAuth: true, requiresProfile: true, requiresActiveAccount: true } }, { @@ -633,7 +637,7 @@ export function getRoutes (): RouteConfig[] { path: Pages.STAFF_DASHBOARD, component: StaffDashboardView, props: true, - meta: { requiresAuth: true, allowedRoles: [Role.Staff, Role.ContactCentreStaff] }, + meta: { requiresAuth: true, allowedRoles: [Role.Staff, Role.ViewStaffDashboard] }, children: [ { path: '', @@ -646,7 +650,7 @@ export function getRoutes (): RouteConfig[] { component: StaffActiveAccountsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, @@ -662,7 +666,7 @@ export function getRoutes (): RouteConfig[] { component: StaffPendingAccountInvitationsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, @@ -678,7 +682,7 @@ export function getRoutes (): RouteConfig[] { component: StaffPendingAccountsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, @@ -694,7 +698,7 @@ export function getRoutes (): RouteConfig[] { component: StaffRejectedAccountsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, @@ -710,7 +714,7 @@ export function getRoutes (): RouteConfig[] { component: StaffSuspendedAccountsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, @@ -726,7 +730,7 @@ export function getRoutes (): RouteConfig[] { component: StaffInactiveAccountsTable, meta: { requiresAuth: true, - allowedRoles: [Role.Staff, Role.ContactCentreStaff], + allowedRoles: [Role.Staff, Role.ViewStaffDashboard], breadcrumb: [ { text: StaffDashboardBreadcrumb.text, diff --git a/auth-web/src/services/permission.services.ts b/auth-web/src/services/permission.services.ts index 3a5b8d733b..94e9964dbd 100644 --- a/auth-web/src/services/permission.services.ts +++ b/auth-web/src/services/permission.services.ts @@ -3,7 +3,7 @@ import ConfigHelper from '@/util/config-helper' import { axios } from '@/util/http-util' export default class PermissionService { - static async getPermissions (orgStatus:string, role: string): Promise<AxiosResponse<string[]>> { - return axios.get(`${ConfigHelper.getAuthAPIUrl()}/permissions/${orgStatus}/${role}?case=upper`) + static async getPermissions (orgStatus:string, role: string, includeAllPermissions: boolean = false): Promise<AxiosResponse<string[]>> { + return axios.get(`${ConfigHelper.getAuthAPIUrl()}/permissions/${orgStatus}/${role}?case=upper&includeAllPermissions=${includeAllPermissions}`) } } diff --git a/auth-web/src/stores/business.ts b/auth-web/src/stores/business.ts index a001ea8963..772e8aa717 100644 --- a/auth-web/src/stores/business.ts +++ b/auth-web/src/stores/business.ts @@ -253,8 +253,9 @@ export const useBusinessStore = defineStore('business', () => { state.businesses = [...affiliatedEntities] } - async function loadBusiness () { - const businessIdentifier = ConfigHelper.getFromSession(SessionStorageKeys.BusinessIdentifierKey) + async function loadBusiness (businessQueryIdentifier = '') { + // Check session first or use query string if available. + const businessIdentifier = ConfigHelper.getFromSession(SessionStorageKeys.BusinessIdentifierKey) || businessQueryIdentifier // Need to look at LEAR, because it has the up-to-date names. const learBusiness = await searchBusiness(businessIdentifier) const response = await BusinessService.getBusiness(businessIdentifier) diff --git a/auth-web/src/stores/codes.ts b/auth-web/src/stores/codes.ts index 7d9139bbc4..2c59c41a97 100644 --- a/auth-web/src/stores/codes.ts +++ b/auth-web/src/stores/codes.ts @@ -78,7 +78,7 @@ export const useCodesStore = defineStore('codes', () => { async function getProductPaymentMethods (productCode?: string): Promise<any> { const data = await CodesService.getProductPaymentMethods(productCode) - data.BUSINESS_SEARCH = data.BUSINESSSearch // Force to match enum. + data.BUSINESS_SEARCH = data?.BUSINESSSearch // Force to match enum. state.productPaymentMethods = data } diff --git a/auth-web/src/stores/org.ts b/auth-web/src/stores/org.ts index 7d062bd6a9..4f585f7c11 100644 --- a/auth-web/src/stores/org.ts +++ b/auth-web/src/stores/org.ts @@ -22,7 +22,6 @@ import { CreateRequestBody, GLInfo, Member, - MembershipStatus, MembershipType, OrgBusinessType, OrgPaymentDetails, @@ -317,51 +316,59 @@ export const useOrgStore = defineStore('org', () => { const rolesMapping = [ { - role: Role.ContactCentreStaff, - permissions: CommonUtils.getContactCentreStaffPermissions(), - membershipType: MembershipType.Admin + role: Role.ExternalStaffReadonly, + membershipType: MembershipType.ExternalStaff }, { role: Role.StaffManageAccounts, - permissions: CommonUtils.getAdminPermissions(), - membershipType: MembershipType.Admin - }, - { - role: Role.StaffViewAccounts, - permissions: CommonUtils.getViewOnlyPermissions(), - membershipType: MembershipType.User + membershipType: MembershipType.Staff } ] - async function syncMembership (orgId: number): Promise<Member> { - const { roles } = KeyCloakService.getUserInfo() + function getMembershipType (membership: Member, roles: string[]) { + if (membership?.membershipTypeCode) { + return membership.membershipTypeCode + } // In the sequential order of the rolesMapping array, check if user has any of the roles in the mapping // and assign the permissions and membership type const assignedRole = rolesMapping.find((role) => roles.includes(role.role)) - if (assignedRole) { - state.permissions = assignedRole.permissions - state.currentMembership = { - membershipTypeCode: assignedRole.membershipType, - id: null, - membershipStatus: MembershipStatus.Active, - user: null - } - return state.currentMembership + return assignedRole.membershipType } + } - // If user doesn't have any of the roles in the mapping, get the membership from the API + async function syncMembership (orgId: number): Promise<Member> { + const { roles } = KeyCloakService.getUserInfo() const { data: membership } = await UserService.getMembership(orgId) const { accountStatus: statusCode } = state.currentAccountSettings - const { data: permissions } = await PermissionService.getPermissions(statusCode, membership?.membershipTypeCode) + + let includeAllPermissions = false + if (roles.includes(Role.Staff) || (roles.includes(Role.ExternalStaffReadonly) && !membership?.id)) { + includeAllPermissions = true + } + + const { data: permissions } = await PermissionService.getPermissions(statusCode, + getMembershipType(membership, roles), includeAllPermissions) state.permissions = permissions || [] state.currentMembership = membership - return membership } + async function syncStaffPermissions (): Promise<string[]> { + const { roles } = KeyCloakService.getUserInfo() + const { data: permissions } = await PermissionService.getPermissions('ACTIVE', + getMembershipType(undefined, roles), true) + + state.permissions = permissions || [] + return permissions + } + + function hasPermission (permission: string) { + return state.permissions.indexOf(permission) > -1 + } + /* * staff doesnt need any other store set up's since he doesnt belong to an account * So a minimal method to create org @@ -635,8 +642,9 @@ export const useOrgStore = defineStore('org', () => { return result } - async function syncActiveOrgMembers () { - const response = await OrgService.getOrgMembers(state.currentOrganization.id, 'ACTIVE') + async function syncActiveOrgMembers (orgId?: number) { + const organizationId = orgId || state.currentOrganization.id + const response = await OrgService.getOrgMembers(organizationId, 'ACTIVE') const result = response?.data?.members || [] state.activeOrgMembers = result return result @@ -1077,6 +1085,7 @@ export const useOrgStore = defineStore('org', () => { needMissingBusinessDetailsRedirect, canEditBusinessInfo, isBusinessAccount, + hasPermission, setAccessType, setMemberLoginOption, resetCurrentOrganisation, @@ -1103,6 +1112,7 @@ export const useOrgStore = defineStore('org', () => { suspendOrganization, syncMemberLoginOption, syncMembership, + syncStaffPermissions, createOrgByStaff, updateLoginOption, createOrg, diff --git a/auth-web/src/util/common-util.ts b/auth-web/src/util/common-util.ts index a5003f1277..a645e98018 100644 --- a/auth-web/src/util/common-util.ts +++ b/auth-web/src/util/common-util.ts @@ -1,7 +1,7 @@ import 'moment-timezone' import { Address, BaseAddressModel } from '@/models/address' import { NrRequestActionCodes, NrRequestTypeCodes } from '@bcrs-shared-components/enums' -import { NrRequestTypeStrings, Permission } from '@/util/constants' +import { NrRequestTypeStrings } from '@/util/constants' import moment from 'moment' type DateLike = string | Date | moment.Moment @@ -215,65 +215,6 @@ export default class CommonUtils { return path.includes('/signout') } - static getAdminPermissions (): string[] { - return [ - Permission.CHANGE_ADDRESS, - Permission.CHANGE_ORG_NAME, - Permission.CHANGE_ROLE, - Permission.EDIT_REQUEST_PRODUCT_PACKAGE, - Permission.DEACTIVATE_ACCOUNT, - Permission.GENERATE_INVOICE, - Permission.INVITE_MEMBERS, - Permission.MAKE_PAYMENT, - Permission.MANAGE_STATEMENTS, - Permission.REMOVE_BUSINESS, - Permission.RESET_OTP, - Permission.RESET_PASSWORD, - Permission.TRANSACTION_HISTORY, - Permission.VIEW_ACTIVITYLOG, - Permission.VIEW_ADDRESS, - Permission.VIEW_ADMIN_CONTACT, - Permission.VIEW_AUTH_OPTIONS, - Permission.VIEW_REQUEST_PRODUCT_PACKAGE, - Permission.VIEW_USER_LOGINSOURCE, - Permission.EDIT_USER, - Permission.VIEW_BUSINESS_REGISTRY_DASHBOARD, - Permission.VIEW_LAUNCH_TITLES, - Permission.VIEW_CONTINUATION_AUTHORIZATION_REVIEWS - ] - } - - static getContactCentreStaffPermissions (): string[] { - return [ - Permission.CHANGE_ORG_NAME, - Permission.CHANGE_ROLE, - Permission.GENERATE_INVOICE, - Permission.MAKE_PAYMENT, - Permission.MANAGE_STATEMENTS, - Permission.REMOVE_BUSINESS, - Permission.RESET_OTP, - Permission.RESET_PASSWORD, - Permission.TRANSACTION_HISTORY, - Permission.VIEW_ACTIVITYLOG, - Permission.VIEW_ADDRESS, - Permission.VIEW_ADMIN_CONTACT, - Permission.VIEW_AUTH_OPTIONS, - Permission.VIEW_REQUEST_PRODUCT_PACKAGE, - Permission.VIEW_USER_LOGINSOURCE - ] - } - - static getViewOnlyPermissions (): string[] { - return [ - Permission.VIEW_ACCOUNT, - Permission.VIEW_ADDRESS, - Permission.VIEW_ADMIN_CONTACT, - Permission.RESET_OTP, - Permission.VIEW_AUTH_OPTIONS, - Permission.VIEW_REQUEST_PRODUCT_PACKAGE - ] - } - // for converting address object of sbc-auth to as needed for BaseAddress component static convertAddressForComponent (address: Address) : BaseAddressModel { return { diff --git a/auth-web/src/util/constants.ts b/auth-web/src/util/constants.ts index cd0151c26f..40c075f182 100644 --- a/auth-web/src/util/constants.ts +++ b/auth-web/src/util/constants.ts @@ -59,7 +59,8 @@ export enum Role { CreateCredits = 'create_credits', FasRefund = 'fas_refund', BcolStaffAdmin = 'bcol_staff_admin', - ContactCentreStaff = 'contact_centre_staff' + ExternalStaffReadonly = 'external_staff_readonly', + ViewStaffDashboard = 'view_staff_dashboard' } export enum Pages { @@ -115,7 +116,9 @@ export enum Account { PREMIUM = 'PREMIUM', BASIC = 'BASIC', STAFF = 'STAFF', - SBC_STAFF = 'SBC_STAFF' + SBC_STAFF = 'SBC_STAFF', + MAXIMUS_STAFF = 'MAXIMUS_STAFF', + CONTACT_CENTRE_STAFF = 'CONTACT_CENTRE_STAFF' } export enum AccountStatus { @@ -435,6 +438,12 @@ export enum Permission { CHANGE_ROLE = 'CHANGE_ROLE', RESET_PASSWORD = 'RESET_PASSWORD', VIEW_ACCOUNT = 'VIEW_ACCOUNT', + VIEW_ACTIVE_ACCOUNTS = 'VIEW_ACTIVE_ACCOUNTS', + VIEW_ACCOUNT_INVITATIONS = 'VIEW_ACCOUNT_INVITATIONS', + VIEW_PENDING_TASKS = 'VIEW_PENDING_TASKS', + VIEW_REJECTED_TASKS = 'VIEW_REJECTED_TASKS', + VIEW_SUSPENDED_ACCOUNTS = 'VIEW_SUSPENDED_ACCOUNTS', + VIEW_INACTIVE_ACCOUNTS = 'VIEW_INACTIVE_ACCOUNTS', TRANSACTION_HISTORY = 'TRANSACTION_HISTORY', MANAGE_STATEMENTS = 'MANAGE_STATEMENTS', VIEW_ADMIN_CONTACT = 'VIEW_ADMIN_CONTACT', @@ -453,6 +462,7 @@ export enum Permission { EDIT_USER = 'EDIT_USER', VIEW_BUSINESS_REGISTRY_DASHBOARD = 'VIEW_BUSINESS_REGISTRY_DASHBOARD', VIEW_LAUNCH_TITLES = 'VIEW_LAUNCH_TITLES', + VIEW_ALL_PRODUCTS_LAUNCHER = 'VIEW_ALL_PRODUCTS_LAUNCHER', VIEW_CONTINUATION_AUTHORIZATION_REVIEWS = 'VIEW_CONTINUATION_AUTHORIZATION_REVIEWS', CHANGE_PAYMENT_METHOD = 'CHANGE_PAYMENT_METHOD' } diff --git a/auth-web/src/util/http-util.ts b/auth-web/src/util/http-util.ts index b55e618203..f036d423f4 100644 --- a/auth-web/src/util/http-util.ts +++ b/auth-web/src/util/http-util.ts @@ -12,6 +12,7 @@ axios.interceptors.request.use( return request } + request.headers['App-Name'] = import.meta.env.APP_NAME const token = ConfigHelper.getFromSession(SessionStorageKeys.KeyCloakToken) if (token) { request.headers.Authorization = `Bearer ${token}` diff --git a/auth-web/src/views/auth/AccountSettings.vue b/auth-web/src/views/auth/AccountSettings.vue index b0339fabc5..a0ec44a69a 100644 --- a/auth-web/src/views/auth/AccountSettings.vue +++ b/auth-web/src/views/auth/AccountSettings.vue @@ -22,7 +22,7 @@ <!-- Staff - Breadcrumbs / Back Navigation --> <nav - v-if="isStaff" + v-if="isStaff || isExternalStaff" class="crumbs py-6" aria-label="breadcrumb" > @@ -42,7 +42,7 @@ <!-- Back Button --> <nav - v-if="!isDirSearchUser && !isStaff" + v-if="!isDirSearchUser && !isStaff && !isExternalStaff" class="crumbs py-6" aria-label="breadcrumb" > @@ -185,7 +185,6 @@ <v-list-item-title>Authentication</v-list-item-title> </v-list-item> <v-list-item - v-if="isAdmin" v-can:VIEW_REQUEST_PRODUCT_PACKAGE.hide dense class="py-1 px-4" @@ -221,7 +220,6 @@ ACCOUNT ACTIVITY </v-subheader> <v-list-item - v-if="isPremiumAccount || isSbcStaffAccount || isStaffAccount" v-can:MANAGE_STATEMENTS.hide dense class="py-1 px-4" @@ -241,7 +239,7 @@ <v-list-item-title>Statements</v-list-item-title> </v-list-item> <v-list-item - v-can:MANAGE_STATEMENTS.hide + v-can:TRANSACTION_HISTORY.hide dense class="py-1 px-4" aria-label="Account Transactions" @@ -334,7 +332,7 @@ <script lang="ts"> import { AccountStatus, LoginSource, Pages, Permission, Role } from '@/util/constants' import { Component, Mixins, Prop } from 'vue-property-decorator' -import { Member, MembershipType, Organization } from '@/models/Organization' +import { Member, Organization } from '@/models/Organization' import { mapActions, mapState } from 'pinia' import AccountInactiveAlert from '@/components/auth/common/AccountInactiveAlert.vue' import AccountMixin from '@/components/auth/mixins/AccountMixin.vue' @@ -361,15 +359,17 @@ import { useUserStore } from '@/stores/user' }, methods: { ...mapActions(useOrgStore, [ - 'syncOrganization' + 'syncOrganization', + 'syncMembership' ]) } }) export default class AccountSettings extends Mixins(AccountMixin) { - @Prop({ default: '' }) private orgId: string + @Prop({ default: -1 }) private orgId: number private readonly currentMembership!: Member private readonly currentUser!: KCUserProfile protected readonly syncOrganization!: (orgId: number) => Promise<Organization> + protected readonly syncMembership!: (orgId: number) => Promise<Member> private isLoading = true private isDirSearchUser: boolean = false private dirSearchUrl = ConfigHelper.getDirectorSearchURL() @@ -377,17 +377,17 @@ export default class AccountSettings extends Mixins(AccountMixin) { private readonly permissions!: string[] private handleBackButton (): void { - this.isStaff + this.isStaff || this.isExternalStaff ? this.$router.push(Pages.STAFF_DASHBOARD) : window.location.assign(ConfigHelper.getBcrosDashboardURL()) } private get isStaff ():boolean { - return this.currentUser.roles.includes(Role.Staff) || this.currentUser.roles.includes(Role.ContactCentreStaff) + return this.currentUser.roles.includes(Role.Staff) } - private get isAdmin ():boolean { - return this.currentMembership.membershipTypeCode === MembershipType.Admin + private get isExternalStaff ():boolean { + return this.currentUser.roles.includes(Role.ExternalStaffReadonly) } private get accountInfoUrl (): string { @@ -436,7 +436,7 @@ export default class AccountSettings extends Mixins(AccountMixin) { // show baner for staff user and account suspended private get showAccountFreezeBanner () { - return this.isStaff && ( + return (this.isStaff || this.isExternalStaff) && ( this.currentOrganization?.statusCode === AccountStatus.NSF_SUSPENDED || this.currentOrganization?.statusCode === AccountStatus.SUSPENDED ) @@ -444,36 +444,16 @@ export default class AccountSettings extends Mixins(AccountMixin) { // show baner for staff user and account inactive private get showInactiveFreezeBanner () { - return this.isStaff && ( + return (this.isStaff || this.isExternalStaff) && ( this.currentOrganization?.statusCode === AccountStatus.INACTIVE ) } private async mounted () { + await this.syncOrganization(this.orgId) + await this.syncMembership(this.orgId) this.isLoading = false this.isDirSearchUser = (this.currentUser?.loginSource === LoginSource.BCROS) - if (this.$route.query?.tryOrgRefresh === 'true') { - this.isLoading = true - let count = 0 - let timerId = setInterval(async () => { - // eslint-disable-next-line no-console - console.log(`[OrgRefreshTimer] Org refresh ${++count}`) - if (this.currentOrganization?.statusCode !== AccountStatus.ACTIVE) { - await this.syncOrganization(this.currentOrganization?.id) - } else { - // eslint-disable-next-line no-console - console.log('[OrgRefreshTimer] Org refresh stopped (ACTIVE)') - clearInterval(timerId) - this.isLoading = false - } - }, 3000) - setTimeout(() => { - // eslint-disable-next-line no-console - console.log('[OrgRefreshTimer] Org refresh stopped') - clearInterval(timerId) - this.isLoading = false - }, 10000) - } } } </script> diff --git a/auth-web/src/views/auth/BusinessProfileView.vue b/auth-web/src/views/auth/BusinessProfileView.vue index b5f84a0d5c..6fb5390f53 100644 --- a/auth-web/src/views/auth/BusinessProfileView.vue +++ b/auth-web/src/views/auth/BusinessProfileView.vue @@ -92,13 +92,13 @@ import { useBusinessStore } from '@/stores/business' ...mapActions(useBusinessStore, ['loadBusiness']) } }) + export default class BusinessProfileView extends Mixins(AccountChangeMixin, NextPageMixin) { private businessType = 'cooperative' private editing = false private isLoading = true private readonly currentBusiness!: Business - private readonly loadBusiness!: () => Business - + private readonly loadBusiness!: (businessId) => Business private navigateBack (): void { if (this.$route.query.redirect) { if (this.currentOrganization) { @@ -113,8 +113,9 @@ export default class BusinessProfileView extends Mixins(AccountChangeMixin, Next async mounted () { this.isLoading = true + // Include businessid from query string in case session is empty. + await this.loadBusiness(this.$attrs.businessid) // Check if there is already contact info so that we display the appropriate copy - await this.loadBusiness() if ((this.currentBusiness?.contacts?.length || 0) > 0) { this.editing = true } diff --git a/auth-web/src/views/auth/staff/StaffDashboardView.vue b/auth-web/src/views/auth/staff/StaffDashboardView.vue index c3d95c7783..3c68281711 100644 --- a/auth-web/src/views/auth/staff/StaffDashboardView.vue +++ b/auth-web/src/views/auth/staff/StaffDashboardView.vue @@ -135,7 +135,7 @@ <PPRLauncher /> </v-col> <v-col - v-if="isContactCentreStaff" + v-if="canViewAllProductsLauncher" class="pr-2" cols="6" > @@ -154,7 +154,8 @@ <!-- Continuation Applications --> <v-card - v-can:VIEW_CONTINUATION_AUTHORIZATION_REVIEWS.hide + v-if="canViewContinuationAuthorization" + v-can:VIEW_CONTINUATION_AUTHORIZATION_REVIEWS.card flat class="mb-4 pa-8" > @@ -315,8 +316,17 @@ <script lang="ts"> import { BaseVExpansionPanel, LaunchTile } from '@/components' -import { ComputedRef, Ref, computed, defineComponent, reactive, ref, toRefs } from '@vue/composition-api' -import { LDFlags, Role, SessionStorageKeys } from '@/util/constants' +import { + ComputedRef, + Ref, + computed, + defineComponent, + onBeforeMount, + reactive, + ref, + toRefs +} from '@vue/composition-api' +import { LDFlags, Permission, Role, SessionStorageKeys } from '@/util/constants' import AllProductsLauncher from '@/components/auth/staff/AllProductsLauncher.vue' import CommonUtils from '@/util/common-util' import ConfigHelper from '@/util/config-helper' @@ -392,7 +402,7 @@ export default defineComponent({ canViewAllTransactions: computed((): boolean => currentUser.value?.roles?.includes(Role.ViewAllTransactions)), canViewEFTPayments: computed((): boolean => currentUser.value?.roles?.includes(Role.ManageEft)), canViewGLCodes: computed((): boolean => currentUser.value?.roles?.includes(Role.ManageGlCodes)), - isContactCentreStaff: computed(() => currentUser.value?.roles?.includes(Role.ContactCentreStaff)), + canViewContinuationAuthorization: computed((): boolean => currentUser.value?.roles?.includes(Role.Staff)), canViewIncorporationSearchResult: false, errorMessage: '', isFasDashboardEnabled: computed((): boolean => currentUser.value?.roles?.includes(Role.FasSearch)), @@ -403,7 +413,10 @@ export default defineComponent({ showBusSearchlink: computed((): boolean => true), showInvoluntaryDissolutionTile: computed((): boolean => LaunchDarklyService.getFlag(LDFlags.EnableInvoluntaryDissolution) || false), - showDrsTile: computed((): boolean => LaunchDarklyService.getFlag(LDFlags.EnableDRSLookup) || false) + showDrsTile: computed((): boolean => LaunchDarklyService.getFlag(LDFlags.EnableDRSLookup) || false), + canViewAllProductsLauncher: computed((): boolean => + orgStore.permissions.includes(Permission.VIEW_ALL_PRODUCTS_LAUNCHER) || false + ) }) as unknown) as StaffDashboardViewI const isFormValid = () => localVars.searchIdentifier && searchIdentifierForm.value?.validate() @@ -432,6 +445,10 @@ export default defineComponent({ } ] + onBeforeMount(async () => { + await orgStore.syncStaffPermissions() + }) + const isFilingID = (identifier: string) => { // Check if the identifier contains only numeric characters return /^\d+$/.test(identifier) diff --git a/auth-web/tests/unit/components/AccountInfo.spec.ts b/auth-web/tests/unit/components/AccountInfo.spec.ts index bd3004ac0d..a71bc6711a 100644 --- a/auth-web/tests/unit/components/AccountInfo.spec.ts +++ b/auth-web/tests/unit/components/AccountInfo.spec.ts @@ -2,6 +2,7 @@ import { AccountStatus, Role } from '@/util/constants' import { createLocalVue, mount, shallowMount } from '@vue/test-utils' import AccountInfo from '@/components/auth/account-settings/account-info/AccountInfo.vue' +import OrgService from '@/services/org.services' import Steppable from '@/components/auth/common/stepper/Steppable.vue' import Vuetify from 'vuetify' import can from '@/directives/can' @@ -35,6 +36,12 @@ describe('AccountInfo.vue', () => { orgStore.currentMembership = {} as any orgStore.permissions = ['CHANGE_ADDRESS', 'CHANGE_ORG_NAME', 'VIEW_ADDRESS', 'VIEW_ADMIN_CONTACT'] + OrgService.getContactForOrg = vi.fn().mockResolvedValue({ + data: { + contacts: [] + } + }) + userStore.currentUser = { roles: [Role.Staff, Role.StaffSuspendAccounts] } as any diff --git a/auth-web/tests/unit/components/ProductPayment.spec.ts b/auth-web/tests/unit/components/ProductPayment.spec.ts index 9b6716fe02..828e2cd9a6 100644 --- a/auth-web/tests/unit/components/ProductPayment.spec.ts +++ b/auth-web/tests/unit/components/ProductPayment.spec.ts @@ -1,5 +1,6 @@ import { LoginSource, Permission } from '@/util/constants' import { createLocalVue, mount } from '@vue/test-utils' +import CodesService from '@/services/codes.service' import ProductPackage from '@/components/auth/account-settings/product/ProductPayment.vue' import VueRouter from 'vue-router' import Vuetify from 'vuetify' @@ -50,6 +51,9 @@ describe('Account settings ProductPackage.vue', () => { orgStore.addOrgProducts = () => { return Promise.resolve() as any } + CodesService.getProductPaymentMethods = vi.fn().mockResolvedValue({ + data: [] + }) wrapperFactory = (propsData) => { return mount(ProductPackage, { localVue, @@ -87,7 +91,9 @@ describe('Account settings ProductPackage.vue', () => { it('handles modal dialog add product correctly', async () => { const orgStore = useOrgStore() - + orgStore.addOrgProducts = () => { + return Promise.resolve() as any + } await wrapper.vm.$nextTick() orgStore.currentSelectedProducts = [{ code: 'TEST_PRODUCT' }] wrapper.vm.addProductOnAccountAdmin = true diff --git a/auth-web/tests/unit/components/Transactions.spec.ts b/auth-web/tests/unit/components/Transactions.spec.ts index 3a35d0cc2c..86fa98ecc7 100644 --- a/auth-web/tests/unit/components/Transactions.spec.ts +++ b/auth-web/tests/unit/components/Transactions.spec.ts @@ -1,6 +1,6 @@ import '../test-utils/composition-api-setup' // important to import this first +import { Account, Permission } from '@/util/constants' import { Wrapper, createLocalVue, mount } from '@vue/test-utils' -import { Account } from '@/util/constants' import { MembershipType } from '@/models/Organization' import { Transactions } from '@/components/auth/account-settings/transaction' import TransactionsDataTable from '@/components/auth/account-settings/transaction/TransactionsDataTable.vue' @@ -26,6 +26,7 @@ async function beforeEachSetup (wrapper: any, sandbox: any, accountType: Account orgStore.currentOrganization = { id: 123, orgType: accountType } as any orgStore.getOrgPayments = vi.fn(() => { return { credit: 0 } }) as any orgStore.currentMembership = { membershipTypeCode: MembershipType.Admin } as any + orgStore.permissions = [Permission.TRANSACTION_HISTORY] // stub get transactions get call sandbox = sinon.createSandbox() diff --git a/auth-web/tests/unit/test-utils/test-data/permissions.ts b/auth-web/tests/unit/test-utils/test-data/permissions.ts new file mode 100644 index 0000000000..9b39863b3e --- /dev/null +++ b/auth-web/tests/unit/test-utils/test-data/permissions.ts @@ -0,0 +1,27 @@ +import { Permission } from '@/util/constants' + +export const staffPermissions = [ + Permission.CHANGE_ADDRESS, + Permission.CHANGE_ORG_NAME, + Permission.CHANGE_ROLE, + Permission.EDIT_REQUEST_PRODUCT_PACKAGE, + Permission.DEACTIVATE_ACCOUNT, + Permission.GENERATE_INVOICE, + Permission.INVITE_MEMBERS, + Permission.MAKE_PAYMENT, + Permission.MANAGE_STATEMENTS, + Permission.REMOVE_BUSINESS, + Permission.RESET_OTP, + Permission.RESET_PASSWORD, + Permission.TRANSACTION_HISTORY, + Permission.VIEW_ACTIVITYLOG, + Permission.VIEW_ADDRESS, + Permission.VIEW_ADMIN_CONTACT, + Permission.VIEW_AUTH_OPTIONS, + Permission.VIEW_REQUEST_PRODUCT_PACKAGE, + Permission.VIEW_USER_LOGINSOURCE, + Permission.EDIT_USER, + Permission.VIEW_BUSINESS_REGISTRY_DASHBOARD, + Permission.VIEW_LAUNCH_TITLES, + Permission.VIEW_CONTINUATION_AUTHORIZATION_REVIEWS +] diff --git a/auth-web/tests/unit/util/common-util.spec.ts b/auth-web/tests/unit/util/common-util.spec.ts index 1b1a3426ab..582f6b21e9 100644 --- a/auth-web/tests/unit/util/common-util.spec.ts +++ b/auth-web/tests/unit/util/common-util.spec.ts @@ -1,5 +1,4 @@ import CommonUtil from '@/util/common-util' -import { Permission } from '@/util/constants' const dateStr = new Date('2020-10-22 00:00:00 PDT') @@ -147,18 +146,6 @@ describe('Common Util Test', () => { expect(CommonUtil.formatDatePickerDate(dateStr)).toBe('2020-10-22') }) - it('is getAdminPermissions correctly', () => { - expect(CommonUtil.getAdminPermissions().length).toBeGreaterThan(1) - expect(CommonUtil.getAdminPermissions()).toContain(Permission.INVITE_MEMBERS) - expect(CommonUtil.getAdminPermissions()).toContain(Permission.RESET_OTP) - }) - - it('is getViewOnlyPermissions correctly', () => { - expect(CommonUtil.getViewOnlyPermissions().length).toBeGreaterThan(1) - expect(CommonUtil.getViewOnlyPermissions()).toContain(Permission.VIEW_ACCOUNT) - expect(CommonUtil.getViewOnlyPermissions()).not.toContain(Permission.TRANSACTION_HISTORY) - }) - it('is convertAddressForComponent correctly', () => { expect(CommonUtil.convertAddressForComponent(addressComp)).toMatchObject(addressAuth) }) diff --git a/auth-web/tests/unit/views/StaffDashboard/StaffDashboardView.spec.ts b/auth-web/tests/unit/views/StaffDashboard/StaffDashboardView.spec.ts index 1468f4b0ae..b9f67a82a0 100644 --- a/auth-web/tests/unit/views/StaffDashboard/StaffDashboardView.spec.ts +++ b/auth-web/tests/unit/views/StaffDashboard/StaffDashboardView.spec.ts @@ -12,6 +12,8 @@ import StaffDashboardView from '@/views/auth/staff/StaffDashboardView.vue' import { Transactions } from '@/components/auth/account-settings/transaction' import Vue from 'vue' import Vuetify from 'vuetify' +import { createI18n } from 'vue-i18n-composable' +import { staffPermissions } from '../../test-utils/test-data/permissions' const vuetify = new Vuetify({}) @@ -30,6 +32,7 @@ describe('StaffDashboardView tests', () => { orgStore.currentOrgPaymentDetails = { accountId: 123 } as any orgStore.currentOrganization = { id: 123 } as any orgStore.currentMembership = { membershipTypeCode: MembershipType.Admin } as any + orgStore.syncStaffPermissions = vi.fn().mockResolvedValue(staffPermissions) const userStore = useUserStore() userStore.currentUser = { @@ -47,9 +50,20 @@ describe('StaffDashboardView tests', () => { staffStore.pendingInvitationOrgs = [] staffStore.suspendedStaffOrgs = [] + const i18n = createI18n({ + locale: 'en', + messages: { + en: { + viewAllProductsLauncherTitle: 'View All Products', + viewAllProductsLauncherText: 'Click here to view all products' + } + } + }) + wrapper = mount(StaffDashboardView, { localVue, vuetify, + i18n, stubs: ['Transactions', 'StaffAccountManagement', 'ContinuationApplications', 'PPRLauncher', 'GLCodesListView'] }) }) diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index f0aca22bd0..bbd39749ad 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -34,7 +34,8 @@ export default defineConfig({ } }, define: { - 'import.meta.env.ABOUT_TEXT': generateAboutText(aboutText1, aboutText2) + 'import.meta.env.ABOUT_TEXT': generateAboutText(aboutText1, aboutText2), + 'import.meta.env.APP_NAME': JSON.stringify(appName) }, esbuild: { minifySyntax: false, diff --git a/queue_services/account-mailer/src/account_mailer/auth_utils.py b/queue_services/account-mailer/src/account_mailer/auth_utils.py index df742e9ae8..b80f821a44 100644 --- a/queue_services/account-mailer/src/account_mailer/auth_utils.py +++ b/queue_services/account-mailer/src/account_mailer/auth_utils.py @@ -34,6 +34,13 @@ def get_login_url(): return login_url +def get_transaction_url(org_id: str) -> str: + """Get transaction url.""" + web_app_url = current_app.config.get('WEB_APP_URL') + transaction_url = f'{web_app_url}/account/{org_id}/settings/transactions' + return transaction_url + + def get_dashboard_url(): """Get application dashboard url.""" login_url = current_app.config.get('DASHBOARD_URL') diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html b/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html index 1e415648fc..005afb6825 100644 --- a/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html +++ b/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html @@ -1,4 +1,7 @@ -# Your {{ account_number }}: {{ account_name_with_branch }} account completed ${{ invoice_total }} in transactions during business hours on {{ invoice_process_date }}. +# This email confirms recent transaction(s) on you account {{ account_number }}: {{ account_name_with_branch }}. + +Transaction date: ${{ invoice_process_date }} +Invoice reference number: {{ invoice_number }} Transaction amount: ${{ invoice_total }} {% if credit_total != '0.00' %}Account credits: -${{ credit_total }}{% endif %} @@ -8,6 +11,10 @@ Your account will be suspended and charged a ${{ nsf_fee }} dishonoured bank instrument fee for every failed payment. -Log in to BC Registries and Online Services. +[Log in to view transaction details]({{ transaction_url }}) -[Log in]({{ url }}) +**Business Registry** +BC Registries and Online services +Toll Free: 1-877-526-1526 +Victoria Office: 250-387-7848 +Email: [BCRegistries@gov.bc.ca](BCRegistries@gov.bc.ca) diff --git a/queue_services/account-mailer/src/account_mailer/resources/worker.py b/queue_services/account-mailer/src/account_mailer/resources/worker.py index 67bf357f62..db97cb1caf 100644 --- a/queue_services/account-mailer/src/account_mailer/resources/worker.py +++ b/queue_services/account-mailer/src/account_mailer/resources/worker.py @@ -27,7 +27,7 @@ from sbc_common_components.utils.enums import QueueMessageTypes from structured_logging import StructuredLogging -from account_mailer.auth_utils import get_login_url, get_member_emails +from account_mailer.auth_utils import get_login_url, get_member_emails, get_transaction_url from account_mailer.email_processors import ( account_unlock, common_mailer, ejv_failures, pad_confirmation, product_confirmation, refund_requested) from account_mailer.enums import Constants, SubjectType, TemplateType, TitleType @@ -219,7 +219,9 @@ def handle_pad_invoice_created(message_type, email_msg): 'nsf_fee': format_currency(email_msg.get('nsfFee')), 'invoice_total': format_currency(invoice_total), 'invoice_process_date': get_local_formatted_date(invoice_process_date, '%m-%d-%Y'), - 'withdraw_total': format_currency(str(withdraw_total)) + 'withdraw_total': format_currency(str(withdraw_total)), + 'invoice_number': email_msg.get('invoice_number', None), + 'transaction_url': get_transaction_url(org_id) } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, diff --git a/queue_services/account-mailer/tests/unit/test_worker_queue.py b/queue_services/account-mailer/tests/unit/test_worker_queue.py index c6d0b3b0a4..03eba0ecde 100644 --- a/queue_services/account-mailer/tests/unit/test_worker_queue.py +++ b/queue_services/account-mailer/tests/unit/test_worker_queue.py @@ -22,7 +22,6 @@ from account_mailer.enums import SubjectType from account_mailer.services import notification_service from account_mailer.services.minio_service import MinioService -from account_mailer.utils import get_local_formatted_date from . import factory_membership_model, factory_org_model, factory_user_model_with_contact from .utils import helper_add_event_to_queue @@ -228,7 +227,8 @@ def test_account_pad_invoice_mailer_queue(app, session, client): 'nsfFee': '30', 'invoice_total': '100', 'invoice_process_date': f'{datetime.now()}', - 'withdraw_total': '80' + 'withdraw_total': '80', + 'invoice_number': '1234567890' } helper_add_event_to_queue(client, message_type=QueueMessageTypes.PAD_INVOICE_CREATED.value, @@ -238,9 +238,14 @@ def test_account_pad_invoice_mailer_queue(app, session, client): assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.PAD_INVOICE_CREATED.value assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None - assert f'hours on {get_local_formatted_date(datetime.now(), "%m-%d-%Y")}' \ - in mock_send.call_args.args[0].get('content').get('body') + + email_body = mock_send.call_args.args[0].get('content').get('body') + assert email_body is not None + assert 'This email confirms recent transaction(s) on you account' in email_body + assert 'Invoice reference number: 1234567890' in email_body + assert 'Transaction date:' in email_body + assert 'Log in to view transaction details' in email_body + assert '/account/{org_id}/settings/transactions'.format(org_id=org.id) in email_body def test_account_admin_removed(app, session, client): From 0bcd21406f5a33ca4417b908feb98538e45c9da7 Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Thu, 20 Mar 2025 16:12:54 -0700 Subject: [PATCH 05/10] Solve conflict on package version (#3317) --- auth-web/package-lock.json | 4 ++-- auth-web/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index 73851adf88..feeed17d31 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -1,12 +1,12 @@ { "name": "auth-web", - "version": "2.10.0", + "version": "2.9.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "auth-web", - "version": "2.10.0", + "version": "2.9.2", "dependencies": { "@bcrs-shared-components/base-address": "2.0.39", "@bcrs-shared-components/bread-crumb": "1.0.8", diff --git a/auth-web/package.json b/auth-web/package.json index b80c150b65..9b32bfb810 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -1,6 +1,6 @@ { "name": "auth-web", - "version": "2.10.0", + "version": "2.9.2", "appName": "Auth Web", "sbcName": "SBC Common Components", "private": true, From ec563949adb8bceeaef22720ab8fbc35dce071ca Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Thu, 27 Mar 2025 08:27:04 -0700 Subject: [PATCH 06/10] resync (#3332) Signed-off-by: Thayne Werdal <thayne.werdal@gov.bc.ca> Signed-off-by: Qin <Arwen.Qin@gov.bc.ca> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Travis Semple <travis8814@gmail.com> Co-authored-by: Hrvoje Fekete <hrvoje.fekete@gmail.com> Co-authored-by: TVWerdal <58612694+TVWerdal@users.noreply.github.com> Co-authored-by: Odysseus Chiu <odysseus@highwaythreesolutions.com> Co-authored-by: Rodrigo Barraza <rodrigo.barraza@gov.bc.ca> Co-authored-by: Arwen Qin <122495122+ArwenQin@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Bolyachevets <Andriy.Bolyachevets@gov.bc.ca> --- .github/workflows/account-mailer-ci.yml | 112 +- auth-api/poetry.lock | 196 +- auth-api/pyproject.toml | 2 +- auth-api/src/auth_api/models/membership.py | 3 +- auth-api/src/auth_api/models/user.py | 19 + auth-api/src/auth_api/services/api_gateway.py | 34 +- auth-api/src/auth_api/services/keycloak.py | 19 +- auth-api/src/auth_api/services/membership.py | 10 + auth-api/src/auth_api/services/user.py | 3 + auth-api/src/auth_api/utils/api_gateway.py | 20 +- auth-api/tests/docker/docker-compose.yml | 12 +- auth-api/tests/unit/api/test_activity_log.py | 2 +- auth-api/tests/unit/api/test_org.py | 9 +- auth-api/tests/unit/api/test_org_api_keys.py | 4 + auth-api/tests/unit/api/test_task.py | 6 +- auth-api/tests/unit/api/test_user.py | 2 +- auth-api/tests/unit/api/test_user_settings.py | 2 +- .../services/test_affiliation_invitation.py | 8 +- .../tests/unit/services/test_api_gateway.py | 20 + auth-api/tests/unit/services/test_entity.py | 4 +- .../tests/unit/services/test_invitation.py | 10 +- .../unit/services/test_invitation_auth.py | 14 +- auth-api/tests/unit/services/test_keycloak.py | 8 + auth-api/tests/unit/services/test_org.py | 26 +- .../services/test_product_notifications.py | 16 +- auth-api/tests/unit/services/test_task.py | 4 +- auth-api/tests/unit/services/test_user.py | 20 +- .../tests/unit/services/test_user_settings.py | 2 +- auth-api/tests/utilities/factory_scenarios.py | 3 +- auth-api/tests/utilities/factory_utils.py | 4 +- auth-web/.env.example | 3 + auth-web/devops/vaults.env | 3 + auth-web/index.html | 2 +- auth-web/package-lock.json | 29 +- auth-web/package.json | 3 +- auth-web/src/main.ts | 9 + .../tests/unit/services/task.service.spec.ts | 2 + .../unit/views/AccountSuspendedView.spec.ts | 5 + queue_services/account-mailer/Dockerfile | 2 +- queue_services/account-mailer/Makefile | 139 -- queue_services/account-mailer/__init__.py | 1 + queue_services/account-mailer/app.py | 7 +- .../account-mailer/devops/vaults.gcp.env | 2 + .../account-mailer/gunicorn_config.py | 16 +- .../openshift/templates/bc.yaml | 123 -- .../openshift/templates/dc.yaml | 175 -- queue_services/account-mailer/poetry.lock | 1614 ++++++++++------- queue_services/account-mailer/pyproject.toml | 85 +- queue_services/account-mailer/setup.cfg | 120 -- .../src/account_mailer/__init__.py | 28 +- .../src/account_mailer/auth_utils.py | 18 +- .../src/account_mailer/config.py | 146 +- .../email_processors/__init__.py | 28 +- .../email_processors/account_unlock.py | 58 +- .../email_processors/common_mailer.py | 33 +- .../email_processors/ejv_failures.py | 55 +- .../email_processors/pad_confirmation.py | 104 +- .../email_processors/payment_completed.py | 12 +- .../email_processors/product_confirmation.py | 26 +- .../email_processors/refund_requested.py | 26 +- .../common/business-dashboard-link.html | 3 - .../email_templates/common/footer.html | 5 - .../email_templates/common/header.html | 12 - .../common/initiative-notice.html | 38 - .../email_templates/common/logo.html | 3 - .../email_templates/common/style.html | 70 - .../common/whitespace-16px.html | 2 - .../common/whitespace-24px.html | 2 - .../email_templates/pad_invoice_email.html | 6 +- .../src/account_mailer/enums.py | 265 +-- .../pdf_templates/common/fonts.html | 9 +- .../src/account_mailer/resources/worker.py | 426 +++-- .../account_mailer/services/google_store.py | 89 + .../account_mailer/services/minio_service.py | 1 - .../services/notification_service.py | 3 +- .../src/account_mailer/utils.py | 16 +- .../src/account_mailer/version.py | 3 +- .../account-mailer/tests/__init__.py | 1 - .../account-mailer/tests/conftest.py | 113 +- .../tests/docker/docker-compose.yml | 61 +- .../account-mailer/tests/unit/__init__.py | 54 +- .../tests/unit/test_worker_queue.py | 737 ++++---- .../account-mailer/tests/unit/utils.py | 34 +- 83 files changed, 2803 insertions(+), 2618 deletions(-) create mode 100644 auth-api/tests/unit/services/test_api_gateway.py delete mode 100644 queue_services/account-mailer/Makefile create mode 100644 queue_services/account-mailer/__init__.py delete mode 100644 queue_services/account-mailer/openshift/templates/bc.yaml delete mode 100644 queue_services/account-mailer/openshift/templates/dc.yaml delete mode 100644 queue_services/account-mailer/setup.cfg delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/business-dashboard-link.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/footer.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/header.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/initiative-notice.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/logo.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/style.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-16px.html delete mode 100644 queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-24px.html create mode 100644 queue_services/account-mailer/src/account_mailer/services/google_store.py diff --git a/.github/workflows/account-mailer-ci.yml b/.github/workflows/account-mailer-ci.yml index d1eaa12bcc..63be54382b 100644 --- a/.github/workflows/account-mailer-ci.yml +++ b/.github/workflows/account-mailer-ci.yml @@ -12,113 +12,17 @@ on: - "auth-api/src/auth_api/utils/enums.py" - "build-deps/**" + workflow_dispatch: + defaults: run: shell: bash working-directory: ./queue_services/account-mailer jobs: - setup-job: - runs-on: ubuntu-24.04 - - if: github.repository == 'bcgov/sbc-auth' - - steps: - - uses: actions/checkout@v4 - - run: "true" - - linting: - needs: setup-job - runs-on: ubuntu-24.04 - - strategy: - matrix: - python-version: [3.12] - - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - make setup - - name: Lint with pylint - id: pylint - run: | - make pylint - - name: Lint with flake8 - id: flake8 - run: | - make flake8 - - testing: - needs: setup-job - env: - DATABASE_TEST_URL: "postgresql://postgres:postgres@localhost:5432/postgres" - USE_TEST_KEYCLOAK_DOCKER: "YES" - USE_DOCKER_MOCK: "YES" - JWT_OIDC_ISSUER: "http://localhost:8081/auth/realms/demo" - SBC_AUTH_ADMIN_CLIENT_ID: "sbc-auth-admin" - SBC_AUTH_ADMIN_CLIENT_SECRET: "2222222222" - MINIO_ENDPOINT: "localhost:9000" - MINIO_ACCESS_KEY: "minio" - MINIO_ACCESS_SECRET: "minio123" - MINIO_BUCKET_NAME: "payment-sftp" - MINIO_SECURE: False - BCOL_ADMIN_EMAIL: "test@test.com" - - runs-on: ubuntu-24.04 - strategy: - matrix: - python-version: [3.12] - - services: - postgres: - image: postgres:12 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - ports: - - 5432:5432 - # needed because the postgres container does not provide a healthcheck - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install docker-compose - run: | - sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - docker-compose version - - name: Install dependencies - run: | - make setup - - name: Test with pytest - id: test - run: | - make test - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - file: ./queue_services/account-mailer/coverage.xml - flags: accountmailerqueue - name: codecov-account-mailer - fail_ci_if_error: false - - build-check: - needs: setup-job - runs-on: ubuntu-24.04 - - steps: - - uses: actions/checkout@v4 - - name: build to check strictness - id: build - run: | - make build-nc + account-mailer-ci: + uses: bcgov/bcregistry-sre/.github/workflows/backend-ci.yaml@main + with: + app_name: "account-mailer" + working_directory: "./queue_services/account-mailer" + codecov_flag: "accountmailerqueue" diff --git a/auth-api/poetry.lock b/auth-api/poetry.lock index 0252e872a1..a5da2b3e8a 100644 --- a/auth-api/poetry.lock +++ b/auth-api/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -6,6 +6,7 @@ version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, @@ -17,6 +18,7 @@ version = "3.11.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, @@ -106,7 +108,7 @@ propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""] [[package]] name = "aiosignal" @@ -114,6 +116,7 @@ version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, @@ -128,6 +131,7 @@ version = "1.14.1" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "alembic-1.14.1-py3-none-any.whl", hash = "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5"}, {file = "alembic-1.14.1.tar.gz", hash = "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213"}, @@ -139,7 +143,7 @@ SQLAlchemy = ">=1.3.0" typing-extensions = ">=4" [package.extras] -tz = ["backports.zoneinfo", "tzdata"] +tz = ["backports.zoneinfo ; python_version < \"3.9\"", "tzdata"] [[package]] name = "argon2-cffi" @@ -147,6 +151,7 @@ version = "23.1.0" description = "Argon2 for Python" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, @@ -167,6 +172,7 @@ version = "21.2.0" description = "Low-level CFFI bindings for Argon2" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, @@ -204,6 +210,7 @@ version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, @@ -215,6 +222,7 @@ version = "3.3.8" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" +groups = ["dev"] files = [ {file = "astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c"}, {file = "astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b"}, @@ -226,18 +234,19 @@ version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\""] [[package]] name = "bandit" @@ -245,6 +254,7 @@ version = "1.8.2" description = "Security oriented static analyser for python code." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "bandit-1.8.2-py3-none-any.whl", hash = "sha256:df6146ad73dd30e8cbda4e29689ddda48364e36ff655dbfc86998401fcf1721f"}, {file = "bandit-1.8.2.tar.gz", hash = "sha256:e00ad5a6bc676c0954669fe13818024d66b70e42cf5adb971480cf3b671e835f"}, @@ -260,7 +270,7 @@ stevedore = ">=1.20.0" baseline = ["GitPython (>=3.1.30)"] sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] -toml = ["tomli (>=1.1.0)"] +toml = ["tomli (>=1.1.0) ; python_version < \"3.11\""] yaml = ["PyYAML"] [[package]] @@ -269,6 +279,7 @@ version = "4.2.1" description = "Modern password hashing for your software and your servers" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "bcrypt-4.2.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:1340411a0894b7d3ef562fb233e4b6ed58add185228650942bdc885362f32c17"}, {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ee315739bc8387aa36ff127afc99120ee452924e0df517a8f3e4c0187a0f5f"}, @@ -307,6 +318,7 @@ version = "24.10.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, @@ -351,6 +363,7 @@ version = "1.9.0" description = "Fast, simple object-to-object and broadcast signaling" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"}, {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"}, @@ -362,6 +375,7 @@ version = "1.0.0" description = "common dependencies for all auth tools" optional = false python-versions = "^3.12" +groups = ["main"] files = [] develop = false @@ -397,6 +411,7 @@ version = "0.14.0" description = "httplib2 caching for requests" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0"}, {file = "cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938"}, @@ -417,6 +432,7 @@ version = "0.13.0" description = "A collection of cache libraries in the same API interface." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cachelib-0.13.0-py3-none-any.whl", hash = "sha256:8c8019e53b6302967d4e8329a504acf75e7bc46130291d30188a6e4e58162516"}, {file = "cachelib-0.13.0.tar.gz", hash = "sha256:209d8996e3c57595bee274ff97116d1d73c4980b2fd9a34c7846cd07fd2e1a48"}, @@ -428,6 +444,7 @@ version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, @@ -439,6 +456,7 @@ version = "23.2.3" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, @@ -451,7 +469,7 @@ attrs = ">=23.1.0" bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] -orjson = ["orjson (>=3.9.2)"] +orjson = ["orjson (>=3.9.2) ; implementation_name == \"cpython\""] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] ujson = ["ujson (>=5.7.0)"] @@ -462,6 +480,7 @@ version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main", "test"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -473,6 +492,7 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -552,6 +572,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" +groups = ["main", "test"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -653,6 +674,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -667,10 +689,12 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev", "test"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +markers = {main = "platform_system == \"Windows\"", dev = "platform_system == \"Windows\" or sys_platform == \"win32\"", test = "sys_platform == \"win32\""} [[package]] name = "coverage" @@ -678,6 +702,7 @@ version = "7.6.10" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" +groups = ["test"] files = [ {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, @@ -744,7 +769,7 @@ files = [ ] [package.extras] -toml = ["tomli"] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "cryptography" @@ -752,6 +777,7 @@ version = "44.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" +groups = ["main"] files = [ {file = "cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f"}, @@ -790,10 +816,10 @@ files = [ cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] +pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] test = ["certifi (>=2024)", "cryptography-vectors (==44.0.1)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] @@ -805,6 +831,7 @@ version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] files = [ {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, @@ -814,7 +841,7 @@ files = [ wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "dill" @@ -822,6 +849,7 @@ version = "0.3.9" description = "serialize all of Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, @@ -837,6 +865,7 @@ version = "1.2.2" description = "Dictionary with auto-expiring values for caching purposes" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "expiringdict-1.2.2-py3-none-any.whl", hash = "sha256:09a5d20bc361163e6432a874edd3179676e935eb81b925eccef48d409a8a45e8"}, {file = "expiringdict-1.2.2.tar.gz", hash = "sha256:300fb92a7e98f15b05cf9a856c1415b3bc4f2e132be07daa326da6414c23ee09"}, @@ -851,6 +880,7 @@ version = "25.9.2" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "Faker-25.9.2-py3-none-any.whl", hash = "sha256:7f8cbd179a7351648bea31f53d021a2bdfdeb59e9b830e121a635916615e0ecd"}, {file = "Faker-25.9.2.tar.gz", hash = "sha256:ca94843600a4089a91394023fef014bb41fee509f8c4beef1530018373e770fb"}, @@ -865,6 +895,7 @@ version = "7.1.1" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" +groups = ["dev"] files = [ {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, @@ -881,6 +912,7 @@ version = "1.2.3" description = "Flake8 plug-in loading the configuration from pyproject.toml" optional = false python-versions = ">= 3.6" +groups = ["dev"] files = [ {file = "flake8_pyproject-1.2.3-py3-none-any.whl", hash = "sha256:6249fe53545205af5e76837644dc80b4c10037e73a0e5db87ff562d75fb5bd4a"}, ] @@ -897,6 +929,7 @@ version = "3.0.2" description = "A simple framework for building complex web applications." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e"}, {file = "flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d"}, @@ -919,6 +952,7 @@ version = "2.3.0" description = "Adds caching support to Flask applications." optional = false python-versions = ">=3.8" +groups = ["main"] files = [] develop = false @@ -938,6 +972,7 @@ version = "5.0.0" description = "A Flask extension adding a decorator for CORS support" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "Flask_Cors-5.0.0-py2.py3-none-any.whl", hash = "sha256:b9e307d082a9261c100d8fb0ba909eec6a228ed1b60a8315fd85f783d61910bc"}, {file = "flask_cors-5.0.0.tar.gz", hash = "sha256:5aadb4b950c4e93745034594d9f3ea6591f734bb3662e16e255ffbf5e89c88ef"}, @@ -952,6 +987,7 @@ version = "0.8.1" description = "Opinionated flask oidc client" optional = false python-versions = ">=3.9,<4" +groups = ["main"] files = [] develop = false @@ -974,6 +1010,7 @@ version = "0.10.0" description = "Flask extension for sending email" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask_mail-0.10.0-py3-none-any.whl", hash = "sha256:a451e490931bb3441d9b11ebab6812a16bfa81855792ae1bf9c1e1e22c4e51e7"}, {file = "flask_mail-0.10.0.tar.gz", hash = "sha256:44083e7b02bbcce792209c06252f8569dd5a325a7aaa76afe7330422bd97881d"}, @@ -989,6 +1026,7 @@ version = "1.3.0" description = "Flask + marshmallow for beautiful APIs" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "flask_marshmallow-1.3.0-py3-none-any.whl", hash = "sha256:c0a0644b46406851873ab41c1e8a7de3ef27fa69b00b89bf630f1696ec0813a0"}, {file = "flask_marshmallow-1.3.0.tar.gz", hash = "sha256:27a35d0ce5dcba161cc5f2f4764afbc2536c93fa439a793250b827835e3f3be6"}, @@ -1010,6 +1048,7 @@ version = "4.1.0" description = "SQLAlchemy database migrations for Flask applications using Alembic." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "Flask_Migrate-4.1.0-py3-none-any.whl", hash = "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d"}, {file = "flask_migrate-4.1.0.tar.gz", hash = "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d"}, @@ -1030,6 +1069,7 @@ version = "1.0.6" description = "Formatting of dates and times in Flask templates using moment.js." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "Flask_Moment-1.0.6-py3-none-any.whl", hash = "sha256:3ae8baea20a41e99f457b9710ecd1368911dd5133f09a27583eb0dcb3491e31d"}, {file = "flask_moment-1.0.6.tar.gz", hash = "sha256:2f8969907cbacde4a88319792e8f920ba5c9dd9d99ced2346cad563795302b88"}, @@ -1048,6 +1088,7 @@ version = "1.1.0" description = "OpenTracing support for Flask applications" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "Flask-OpenTracing-1.1.0.tar.gz", hash = "sha256:a9a39d367fbe7e9ed9c77b90ac48159c1a3e82982a5abf84d3f4d710d24580ac"}, ] @@ -1065,6 +1106,7 @@ version = "3.1.1" description = "Add SQLAlchemy support to your Flask application." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask_sqlalchemy-3.1.1-py3-none-any.whl", hash = "sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0"}, {file = "flask_sqlalchemy-3.1.1.tar.gz", hash = "sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312"}, @@ -1080,6 +1122,7 @@ version = "1.5.1" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" +groups = ["test"] files = [ {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, @@ -1094,6 +1137,7 @@ version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, @@ -1195,6 +1239,7 @@ version = "0.3.0" description = "" optional = false python-versions = "^3.8" +groups = ["main"] files = [] develop = false @@ -1217,6 +1262,7 @@ version = "2.24.1" description = "Google API client core library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google_api_core-2.24.1-py3-none-any.whl", hash = "sha256:bc78d608f5a5bf853b80bd70a795f703294de656c096c0968320830a4bc280f1"}, {file = "google_api_core-2.24.1.tar.gz", hash = "sha256:f8b36f5456ab0dd99a1b693a40a31d1e7757beea380ad1b38faaf8941eae9d8a"}, @@ -1229,14 +1275,14 @@ grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_versi grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} proto-plus = [ {version = ">=1.25.0,<2.0.0dev", markers = "python_version >= \"3.13\""}, - {version = ">=1.22.3,<2.0.0dev", markers = "python_version < \"3.13\""}, + {version = ">=1.22.3,<2.0.0dev"}, ] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" [package.extras] async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.dev0)"] -grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"] +grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev) ; python_version >= \"3.11\"", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0) ; python_version >= \"3.11\""] grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] @@ -1246,6 +1292,7 @@ version = "2.38.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a"}, {file = "google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4"}, @@ -1270,6 +1317,7 @@ version = "2.27.3" description = "Google Cloud Pub/Sub API client library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google_cloud_pubsub-2.27.3-py2.py3-none-any.whl", hash = "sha256:6e294b063d6c6bf44d7b1ca99721ae6137930df3fdf7b91e44d280dd84b9410c"}, {file = "google_cloud_pubsub-2.27.3.tar.gz", hash = "sha256:daa03d16552c34240774307fc69ceebb991a94d70d0d6f208179e375f503f532"}, @@ -1298,6 +1346,7 @@ version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, @@ -1316,6 +1365,8 @@ version = "3.1.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" files = [ {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, @@ -1402,6 +1453,7 @@ version = "0.14.0" description = "IAM API client library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "grpc_google_iam_v1-0.14.0-py2.py3-none-any.whl", hash = "sha256:fb4a084b30099ba3ab07d61d620a0d4429570b13ff53bd37bac75235f98b7da4"}, {file = "grpc_google_iam_v1-0.14.0.tar.gz", hash = "sha256:c66e07aa642e39bb37950f9e7f491f70dad150ac9801263b42b2814307c2df99"}, @@ -1418,6 +1470,7 @@ version = "1.70.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "grpcio-1.70.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:95469d1977429f45fe7df441f586521361e235982a0b39e33841549143ae2851"}, {file = "grpcio-1.70.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:ed9718f17fbdb472e33b869c77a16d0b55e166b100ec57b016dc7de9c8d236bf"}, @@ -1485,6 +1538,7 @@ version = "1.70.0" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "grpcio_status-1.70.0-py3-none-any.whl", hash = "sha256:fc5a2ae2b9b1c1969cc49f3262676e6854aa2398ec69cb5bd6c47cd501904a85"}, {file = "grpcio_status-1.70.0.tar.gz", hash = "sha256:0e7b42816512433b18b9d764285ff029bde059e9d41f8fe10a60631bd8348101"}, @@ -1497,13 +1551,14 @@ protobuf = ">=5.26.1,<6.0dev" [[package]] name = "gunicorn" -version = "22.0.0" +version = "23.0.0" description = "WSGI HTTP Server for UNIX" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"}, - {file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"}, + {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, + {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, ] [package.dependencies] @@ -1522,6 +1577,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main", "test"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -1536,6 +1592,7 @@ version = "8.5.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, @@ -1545,12 +1602,12 @@ files = [ zipp = ">=3.20" [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] 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)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] @@ -1559,6 +1616,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" +groups = ["test"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -1570,6 +1628,7 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -1584,6 +1643,7 @@ version = "2.1.2" description = "Safely pass data to untrusted environments and back." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, @@ -1595,6 +1655,7 @@ version = "4.8.0" description = "Jaeger Python OpenTracing Tracer implementation" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"}, ] @@ -1614,6 +1675,7 @@ version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, @@ -1631,6 +1693,7 @@ version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, @@ -1650,6 +1713,7 @@ version = "1.2.1" description = "LaunchDarkly SSE Client" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "launchdarkly_eventsource-1.2.1-py3-none-any.whl", hash = "sha256:0fa935b7692555455ac8b44b845cdc16738bd9b2e9ce89ee19b3f8b4adafe3f1"}, {file = "launchdarkly_eventsource-1.2.1.tar.gz", hash = "sha256:99c29fa9a570aa8d49c9804bcc401028cab8a8954ccbf4a68c3116933301ec33"}, @@ -1664,6 +1728,7 @@ version = "9.5.0" description = "LaunchDarkly SDK for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "launchdarkly_server_sdk-9.5.0-py3-none-any.whl", hash = "sha256:bf2cf213f9eb71cd43d5f20f2ac9ec9235c693036459e5038a69015a6648c035"}, {file = "launchdarkly_server_sdk-9.5.0.tar.gz", hash = "sha256:af64d985621a03257107210266c563c5e268ca8320d1d71b5c18d9592d14fef7"}, @@ -1689,6 +1754,7 @@ version = "0.3.1" description = "Pytest testing utilities with docker containers." optional = false python-versions = "*" +groups = ["test"] files = [ {file = "lovely-pytest-docker-0.3.1.tar.gz", hash = "sha256:4326a180bfd4dd4ad69c2ef3e3643c41075d965f40068488b40204602e6df85e"}, ] @@ -1703,6 +1769,7 @@ version = "1.3.8" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627"}, {file = "mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8"}, @@ -1722,6 +1789,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, @@ -1746,6 +1814,7 @@ version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, @@ -1795,6 +1864,7 @@ version = "3.26.0" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "marshmallow-3.26.0-py3-none-any.whl", hash = "sha256:1287bca04e6a5f4094822ac153c03da5e214a0a60bcd557b140f3e66991b8ca1"}, {file = "marshmallow-3.26.0.tar.gz", hash = "sha256:eb36762a1cc76d7abf831e18a3a1b26d3d481bbc74581b8e532a3d3a8115e1cb"}, @@ -1814,6 +1884,7 @@ version = "1.4.0" description = "SQLAlchemy integration with the marshmallow (de)serialization library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "marshmallow_sqlalchemy-1.4.0-py3-none-any.whl", hash = "sha256:92f389f95f21f6038e5e8be16e6fb89a1d0e25e2fe6ba661fa34b955fac20422"}, {file = "marshmallow_sqlalchemy-1.4.0.tar.gz", hash = "sha256:ca169a26171077af8afa25789e9781680de0e9187563c422f1f67d0a0133433a"}, @@ -1834,6 +1905,7 @@ version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -1845,6 +1917,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -1856,6 +1929,7 @@ version = "7.2.15" description = "MinIO Python SDK for Amazon S3 Compatible Cloud Storage" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "minio-7.2.15-py3-none-any.whl", hash = "sha256:c06ef7a43e5d67107067f77b6c07ebdd68733e5aa7eed03076472410ca19d876"}, {file = "minio-7.2.15.tar.gz", hash = "sha256:5247df5d4dca7bfa4c9b20093acd5ad43e82d8710ceb059d79c6eea970f49f79"}, @@ -1874,6 +1948,7 @@ version = "1.1.0" description = "MessagePack serializer" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd"}, {file = "msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d"}, @@ -1947,6 +2022,7 @@ version = "6.1.0" description = "multidict implementation" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, @@ -2048,6 +2124,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -2059,6 +2136,7 @@ version = "1.29.0" description = "OpenTelemetry Python API" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_api-1.29.0-py3-none-any.whl", hash = "sha256:5fcd94c4141cc49c736271f3e1efb777bebe9cc535759c54c936cca4f1b312b8"}, {file = "opentelemetry_api-1.29.0.tar.gz", hash = "sha256:d04a6cf78aad09614f52964ecb38021e248f5714dc32c2e0d8fd99517b4d69cf"}, @@ -2074,6 +2152,7 @@ version = "1.29.0" description = "OpenTelemetry Python SDK" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_sdk-1.29.0-py3-none-any.whl", hash = "sha256:173be3b5d3f8f7d671f20ea37056710217959e774e2749d984355d1f9391a30a"}, {file = "opentelemetry_sdk-1.29.0.tar.gz", hash = "sha256:b0787ce6aade6ab84315302e72bd7a7f2f014b0fb1b7c3295b88afe014ed0643"}, @@ -2090,6 +2169,7 @@ version = "0.50b0" description = "OpenTelemetry Semantic Conventions" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_semantic_conventions-0.50b0-py3-none-any.whl", hash = "sha256:e87efba8fdb67fb38113efea6a349531e75ed7ffc01562f65b802fcecb5e115e"}, {file = "opentelemetry_semantic_conventions-0.50b0.tar.gz", hash = "sha256:02dc6dbcb62f082de9b877ff19a3f1ffaa3c306300fa53bfac761c4567c83d38"}, @@ -2105,6 +2185,7 @@ version = "2.4.0" description = "OpenTracing API for Python. See documentation at http://opentracing.io" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"}, ] @@ -2118,6 +2199,7 @@ version = "3.10.15" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"}, {file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"}, @@ -2206,6 +2288,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "test"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -2217,6 +2300,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -2228,6 +2312,7 @@ version = "6.1.0" description = "Python Build Reasonableness" optional = false python-versions = ">=2.6" +groups = ["dev"] files = [ {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"}, {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"}, @@ -2239,6 +2324,7 @@ version = "1.31.2" description = "PostgreSQL interface library" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pg8000-1.31.2-py3-none-any.whl", hash = "sha256:436c771ede71af4d4c22ba867a30add0bc5c942d7ab27fadbb6934a487ecc8f6"}, {file = "pg8000-1.31.2.tar.gz", hash = "sha256:1ea46cf09d8eca07fe7eaadefd7951e37bee7fabe675df164f1a572ffb300876"}, @@ -2254,6 +2340,7 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -2270,6 +2357,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -2285,6 +2373,7 @@ version = "0.2.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, @@ -2376,6 +2465,7 @@ version = "1.26.0" description = "Beautiful, Pythonic protocol buffers" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "proto_plus-1.26.0-py3-none-any.whl", hash = "sha256:bf2dfaa3da281fc3187d12d224c707cb57214fb2c22ba854eb0c105a3fb2d4d7"}, {file = "proto_plus-1.26.0.tar.gz", hash = "sha256:6e93d5f5ca267b54300880fff156b6a3386b3fa3f43b1da62e680fc0c586ef22"}, @@ -2393,6 +2483,7 @@ version = "5.29.3" description = "" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888"}, {file = "protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a"}, @@ -2413,6 +2504,7 @@ version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false python-versions = ">=3.8" +groups = ["main", "test"] files = [ {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, @@ -2432,6 +2524,7 @@ version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -2443,6 +2536,7 @@ version = "0.4.1" description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, @@ -2457,6 +2551,7 @@ version = "2.12.1" description = "Python style guide checker" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, @@ -2468,6 +2563,7 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -2479,6 +2575,7 @@ version = "3.21.0" description = "Cryptographic library for Python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] files = [ {file = "pycryptodome-3.21.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:dad9bf36eda068e89059d1f07408e397856be9511d7113ea4b586642a429a4fd"}, {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a1752eca64c60852f38bb29e2c86fca30d7672c024128ef5d70cc15868fa10f4"}, @@ -2520,6 +2617,7 @@ version = "3.2.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, @@ -2531,6 +2629,7 @@ version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, @@ -2545,6 +2644,7 @@ version = "3.8.0" description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"}, {file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"}, @@ -2556,6 +2656,7 @@ version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, @@ -2573,6 +2674,7 @@ version = "3.3.4" description = "python code static checker" optional = false python-versions = ">=3.9.0" +groups = ["dev"] files = [ {file = "pylint-3.3.4-py3-none-any.whl", hash = "sha256:289e6a1eb27b453b08436478391a48cd53bb0efb824873f949e709350f3de018"}, {file = "pylint-3.3.4.tar.gz", hash = "sha256:74ae7a38b177e69a9b525d0794bd8183820bfa7eb68cc1bee6e8ed22a42be4ce"}, @@ -2597,6 +2699,7 @@ version = "2.0.1" description = "Generate and parse RFC 3339 timestamps" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyRFC3339-2.0.1-py3-none-any.whl", hash = "sha256:30b70a366acac3df7386b558c21af871522560ed7f3f73cf344b8c2cbb8b0c9d"}, {file = "pyrfc3339-2.0.1.tar.gz", hash = "sha256:e47843379ea35c1296c3b6c67a948a1a490ae0584edfcbdea0eaffb5dd29960b"}, @@ -2608,6 +2711,7 @@ version = "0.20.0" description = "Persistent/Functional/Immutable data structures" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, @@ -2649,6 +2753,7 @@ version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -2669,6 +2774,7 @@ version = "0.23.8" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, @@ -2687,6 +2793,7 @@ version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, @@ -2705,6 +2812,7 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" +groups = ["test"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -2722,6 +2830,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "test"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -2736,6 +2845,7 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -2750,6 +2860,7 @@ version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -2761,6 +2872,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -2823,6 +2935,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["main", "test"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -2844,6 +2957,7 @@ version = "1.12.1" description = "Mock out responses from the requests package" optional = false python-versions = ">=3.5" +groups = ["test"] files = [ {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, @@ -2861,6 +2975,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -2879,6 +2994,7 @@ version = "4.9" description = "Pure-Python RSA implementation" optional = false python-versions = ">=3.6,<4" +groups = ["main"] files = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -2893,6 +3009,7 @@ version = "0.0.0" description = "" optional = false python-versions = "*" +groups = ["main"] files = [] develop = false @@ -2916,6 +3033,7 @@ version = "1.4.5" description = "An implementation of the SCRAM protocol." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "scramp-1.4.5-py3-none-any.whl", hash = "sha256:50e37c464fc67f37994e35bee4151e3d8f9320e9c204fca83a5d313c121bbbe7"}, {file = "scramp-1.4.5.tar.gz", hash = "sha256:be3fbe774ca577a7a658117dca014e5d254d158cecae3dd60332dfe33ce6d78e"}, @@ -2930,6 +3048,7 @@ version = "3.0.4" description = "Python helper for Semantic Versioning (https://semver.org)" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746"}, {file = "semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602"}, @@ -2941,6 +3060,7 @@ version = "0.0.2" description = "A short description of the project" optional = false python-versions = ">=3.8" +groups = ["main"] files = [] develop = false @@ -2959,6 +3079,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "test"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -2970,6 +3091,7 @@ version = "0.1.0" description = "" optional = false python-versions = "^3.10" +groups = ["main"] files = [] develop = false @@ -2986,6 +3108,7 @@ version = "2.0.37" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da36c3b0e891808a7542c5c89f224520b9a16c7f5e4d6a1156955605e54aef0e"}, {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e7402ff96e2b073a98ef6d6142796426d705addd27b9d26c3b32dbaa06d7d069"}, @@ -3081,6 +3204,7 @@ version = "0.41.2" description = "Various utility functions for SQLAlchemy." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, @@ -3098,8 +3222,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo ; python_version < \"3.9\"", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo ; python_version < \"3.9\"", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -3109,6 +3233,7 @@ version = "5.4.0" description = "Manage dynamic plugins for Python applications" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "stevedore-5.4.0-py3-none-any.whl", hash = "sha256:b0be3c4748b3ea7b854b265dcb4caa891015e442416422be16f8b31756107857"}, {file = "stevedore-5.4.0.tar.gz", hash = "sha256:79e92235ecb828fe952b6b8b0c6c87863248631922c8e8e0fa5b17b232c4514d"}, @@ -3123,6 +3248,7 @@ version = "0.7" description = "Strict, simple, lightweight RFC3339 functions" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "strict-rfc3339-0.7.tar.gz", hash = "sha256:5cad17bedfc3af57b399db0fed32771f18fc54bbd917e85546088607ac5e1277"}, ] @@ -3133,6 +3259,7 @@ version = "24.4.0" description = "Structured Logging for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "structlog-24.4.0-py3-none-any.whl", hash = "sha256:597f61e80a91cc0749a9fd2a098ed76715a1c8a01f73e336b746504d1aad7610"}, {file = "structlog-24.4.0.tar.gz", hash = "sha256:b27bfecede327a6d2da5fbc96bd859f114ecc398a6389d664f62085ee7ae6fc4"}, @@ -3150,6 +3277,7 @@ version = "0.4.0" description = "" optional = false python-versions = "^3.9" +groups = ["main"] files = [] develop = false @@ -3170,6 +3298,7 @@ version = "1.0.2" description = "Tornado IOLoop Backed Concurrent Futures" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"}, {file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"}, @@ -3184,6 +3313,7 @@ version = "0.21.0" description = "Python bindings for the Apache Thrift RPC system" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "thrift-0.21.0.tar.gz", hash = "sha256:5e6f7c50f936ebfa23e924229afc95eb219f8c8e5a83202dd4a391244803e402"}, ] @@ -3202,6 +3332,7 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -3213,6 +3344,7 @@ 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" +groups = ["main"] files = [ {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"}, @@ -3233,6 +3365,7 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -3244,13 +3377,14 @@ version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" +groups = ["main", "test"] files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -3261,6 +3395,7 @@ version = "3.1.3" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, @@ -3278,6 +3413,7 @@ version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, @@ -3366,6 +3502,7 @@ version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, @@ -3462,20 +3599,21 @@ version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] 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 = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = "^3.12" -content-hash = "87d09f9c4b2c86a5ab9b176aff394930c3f413d385dab6bbb12dfdeb1d7377f8" +content-hash = "35a412b05aa303b29460a35fa4b168a7edfe14cce0cf1225134ac1842dd27bee" diff --git a/auth-api/pyproject.toml b/auth-api/pyproject.toml index 3bd235533b..be41fa1635 100644 --- a/auth-api/pyproject.toml +++ b/auth-api/pyproject.toml @@ -12,7 +12,7 @@ flask-migrate = "^4.0.7" flask-moment = "^1.0.6" flask-sqlalchemy = "^3.1.1" flask-marshmallow = "^1.2.1" -gunicorn = "^22.0.0" +gunicorn = "^23.0.0" pg8000 = "^1.31.2" flask-mail = "^0.10.0" bcrypt = "^4.2.0" diff --git a/auth-api/src/auth_api/models/membership.py b/auth-api/src/auth_api/models/membership.py index 0089606cd2..6207f251d8 100644 --- a/auth-api/src/auth_api/models/membership.py +++ b/auth-api/src/auth_api/models/membership.py @@ -24,7 +24,7 @@ from sqlalchemy import Column, ForeignKey, Integer, and_, desc, func from sqlalchemy.orm import relationship -from auth_api.utils.enums import OrgType, Status +from auth_api.utils.enums import LoginSource, OrgType, Status from auth_api.utils.roles import ADMIN, COORDINATOR, USER, VALID_ORG_STATUSES, VALID_STATUSES from .base_model import BaseModel @@ -101,6 +101,7 @@ def find_members_by_org_id_by_status_by_roles( .filter(and_(Membership.status == status, Membership.membership_type_code.in_(roles))) .join(OrgModel) .filter(OrgModel.id == int(org_id or -1)) + .filter(~Membership.user.has(login_source=LoginSource.API_GW.value)) .all() ) diff --git a/auth-api/src/auth_api/models/user.py b/auth-api/src/auth_api/models/user.py index b23cd8bfad..9c61605553 100644 --- a/auth-api/src/auth_api/models/user.py +++ b/auth-api/src/auth_api/models/user.py @@ -144,6 +144,25 @@ def create_from_jwt_token(cls, first_name: str, last_name: str, **kwargs): return user return None + @staticmethod + def create_user_for_api_user(username, keycloak_guid): + """Create user for API user.""" + api_user = User( + username=username, + firstname=None, + lastname=username, + email=None, + keycloak_guid=keycloak_guid, + created=datetime.datetime.now(tz=datetime.timezone.utc), + login_source=LoginSource.API_GW.value, + status=UserStatusCode.get_default_type(), + idp_userid=username, + login_time=datetime.datetime.now(tz=datetime.timezone.utc), + type=Role.PUBLIC_USER.name, + verified=True, + ).save() + return api_user + @classmethod @user_context def update_from_jwt_token( diff --git a/auth-api/src/auth_api/services/api_gateway.py b/auth-api/src/auth_api/services/api_gateway.py index 28c9fbd5dc..c27ff97209 100644 --- a/auth-api/src/auth_api/services/api_gateway.py +++ b/auth-api/src/auth_api/services/api_gateway.py @@ -21,12 +21,17 @@ from structured_logging import StructuredLogging from auth_api.exceptions import BusinessException, Error +from auth_api.models.membership import Membership as MembershipModel from auth_api.models.org import Org as OrgModel +from auth_api.models.user import User as UserModel from auth_api.services.authorization import check_auth +from auth_api.services.flags import flags from auth_api.services.keycloak import KeycloakService +from auth_api.services.membership import Membership as MembershipService from auth_api.services.rest_service import RestService from auth_api.utils.api_gateway import generate_client_representation from auth_api.utils.constants import GROUP_ACCOUNT_HOLDERS, GROUP_API_GW_SANDBOX_USERS, GROUP_API_GW_USERS +from auth_api.utils.enums import Status from auth_api.utils.roles import ADMIN, STAFF from auth_api.utils.user_context import UserContext, user_context @@ -60,6 +65,8 @@ def create_key(cls, org_id: int, request_json: Dict[str, str]): # If env is sandbox; then create a sandbox payment account. if env != "prod": cls._create_payment_account(org) + # Future - if PROD and target is SANDBOX - Call into AUTH-API to create an org, this will call PAY-API + # to create payment account cls._create_consumer(name, org, env=env) org.has_api_access = True org.save() @@ -74,20 +81,41 @@ def create_key(cls, org_id: int, request_json: Dict[str, str]): ) response = api_key_response.json() + cls._create_user_and_membership_for_api_user(org_id, env) return response + @classmethod + def _create_user_and_membership_for_api_user(cls, org_id: int, env: str): + """Create a user and membership for the api user.""" + if flags.is_on("enable-api-gw-user-membership-creation", False) is True: + client_name = ApiGateway.get_api_client_id(org_id, env) + client = KeycloakService.get_service_account_by_client_name(client_name) + if (api_user := UserModel.find_by_username(client_name)) is None: + api_user = UserModel.create_user_for_api_user(client_name, client.get("id")) + if MembershipModel.find_membership_by_user_and_org(api_user.id, org_id) is None: + MembershipService.create_admin_membership_for_api_user(org_id, api_user.id) + @classmethod def _get_api_gw_key(cls, env): + """Get the api gateway key.""" logger.info("_get_api_gw_key %s", env) return current_app.config.get("API_GW_KEY") if env == "prod" else current_app.config.get("API_GW_NON_PROD_KEY") + @staticmethod + def get_api_client_id(org_id, env): + """Get the client id for the org.""" + client_id_pattern = current_app.config.get("API_GW_KC_CLIENT_ID_PATTERN") + suffix = "-sandbox" if env != "prod" else "" + client_id = f"{client_id_pattern}{suffix}".format(account_id=org_id) + return client_id + @classmethod def _create_consumer(cls, name, org, env): """Create an API Gateway consumer.""" consumer_endpoint: str = cls._get_api_consumer_endpoint(env) gw_api_key = cls._get_api_gw_key(env) email = cls._get_email_id(org.id, env) - client_rep = generate_client_representation(org.id, current_app.config.get("API_GW_KC_CLIENT_ID_PATTERN"), env) + client_rep = generate_client_representation(org.id, ApiGateway.get_api_client_id(org.id, env)) KeycloakService.create_client(client_rep) service_account = KeycloakService.get_service_account_user(client_rep.get("id")) @@ -184,6 +212,7 @@ def _add_key_to_response(_key): @classmethod def _get_email_id(cls, org_id, env) -> str: + """Get the email id for the org.""" if current_app.config.get("API_GW_CONSUMER_EMAIL", None) is not None: return current_app.config.get("API_GW_CONSUMER_EMAIL") @@ -243,6 +272,7 @@ def _create_payment_account(cls, org: OrgModel, **kwargs): @classmethod def _create_sandbox_pay_account(cls, pay_request, user): + """Create a sandbox payment account.""" logger.info("Creating Sandbox Payload %s", pay_request) pay_sandbox_accounts_endpoint = f"{current_app.config.get('PAY_API_SANDBOX_URL')}/accounts?sandbox=true" RestService.post( @@ -251,12 +281,14 @@ def _create_sandbox_pay_account(cls, pay_request, user): @classmethod def _get_pay_account(cls, org, user): + """Get the payment account for the org.""" pay_accounts_endpoint = f"{current_app.config.get('PAY_API_URL')}/accounts/{org.id}" pay_account = RestService.get(endpoint=pay_accounts_endpoint, token=user.bearer_token).json() return pay_account @classmethod def _get_api_consumer_endpoint(cls, env): + """Get the consumer endpoint for the environment.""" logger.info("_get_api_consumer_endpoint %s", env) return ( current_app.config.get("API_GW_CONSUMERS_API_URL") diff --git a/auth-api/src/auth_api/services/keycloak.py b/auth-api/src/auth_api/services/keycloak.py index 8bf23ec05b..f89c702a93 100644 --- a/auth-api/src/auth_api/services/keycloak.py +++ b/auth-api/src/auth_api/services/keycloak.py @@ -446,6 +446,24 @@ def create_client(client_representation: Dict[str, any]): ) response.raise_for_status() + @staticmethod + def get_service_account_by_client_name(client_name: str): + """Get client by name.""" + config = current_app.config + base_url = config.get("KEYCLOAK_BASE_URL") + realm = config.get("KEYCLOAK_REALMNAME") + timeout = config.get("CONNECT_TIMEOUT", 60) + admin_token = KeycloakService._get_admin_token() + headers = {"Content-Type": ContentType.JSON.value, "Authorization": f"Bearer {admin_token}"} + response = requests.get( + f"{base_url}/auth/admin/realms/{realm}/clients?clientId={client_name}", + headers=headers, + timeout=timeout, + ) + response.raise_for_status() + client_id = response.json()[0]["id"] + return KeycloakService.get_service_account_user(client_id) + @staticmethod def get_service_account_user(client_identifier: str): """Return service account user.""" @@ -454,7 +472,6 @@ def get_service_account_user(client_identifier: str): realm = config.get("KEYCLOAK_REALMNAME") timeout = config.get("CONNECT_TIMEOUT", 60) admin_token = KeycloakService._get_admin_token() - headers = {"Content-Type": ContentType.JSON.value, "Authorization": f"Bearer {admin_token}"} response = requests.get( f"{base_url}/auth/admin/realms/{realm}/clients/{client_identifier}/service-account-user", diff --git a/auth-api/src/auth_api/services/membership.py b/auth-api/src/auth_api/services/membership.py index 36e8591190..ef3e468d95 100644 --- a/auth-api/src/auth_api/services/membership.py +++ b/auth-api/src/auth_api/services/membership.py @@ -18,6 +18,7 @@ import json +from flask import current_app from jinja2 import Environment, FileSystemLoader from sbc_common_components.utils.enums import QueueMessageTypes from structured_logging import StructuredLogging @@ -338,6 +339,7 @@ def _add_or_remove_group(model: MembershipModel): @staticmethod def add_or_remove_group_for_staff(model: MembershipModel): + """Add or remove the user from/to various staff keycloak groups.""" mapping_group = org_type_to_group_mapping.get(model.org.type_code) if not mapping_group: return @@ -383,3 +385,11 @@ def add_staff_membership(user_id): def remove_staff_membership(user_id): """Remove staff membership for the specified user.""" MembershipModel.remove_membership_for_staff(user_id) + + @staticmethod + def create_admin_membership_for_api_user(org_id, user_id): + """Create a membership for an api user.""" + current_app.logger.info(f"Creating membership in {org_id} for API user {user_id}") + return MembershipModel( + org_id=org_id, user_id=user_id, membership_type_code=ADMIN, status=Status.ACTIVE.value + ).save() diff --git a/auth-api/src/auth_api/services/user.py b/auth-api/src/auth_api/services/user.py index 1d760694f8..99561645e9 100644 --- a/auth-api/src/auth_api/services/user.py +++ b/auth-api/src/auth_api/services/user.py @@ -17,9 +17,11 @@ """ import json +from datetime import datetime, timezone from http import HTTPStatus from typing import Dict, List +from flask import current_app from jinja2 import Environment, FileSystemLoader from requests import HTTPError from sbc_common_components.utils.enums import QueueMessageTypes @@ -34,6 +36,7 @@ from auth_api.models import User as UserModel from auth_api.models import db from auth_api.models.dataclass import Activity +from auth_api.models.user import UserStatusCode from auth_api.schemas import UserSchema from auth_api.services.authorization import check_auth from auth_api.services.keycloak_user import KeycloakUser diff --git a/auth-api/src/auth_api/utils/api_gateway.py b/auth-api/src/auth_api/utils/api_gateway.py index f8359e3d05..b2332475fc 100644 --- a/auth-api/src/auth_api/utils/api_gateway.py +++ b/auth-api/src/auth_api/utils/api_gateway.py @@ -16,17 +16,13 @@ import uuid -def generate_client_representation(account_id: int, client_id_pattern: str, env: str) -> dict: +def generate_client_representation(account_id: int, client_id: str) -> dict: """Return dictionary for api gateway client user.""" _id = str(uuid.uuid4()) _secret = secrets.token_urlsafe(36) - if env != "prod": - client_id_pattern += "-sandbox" - _client_id = client_id_pattern.format(account_id=account_id) - client_json: dict = { "id": _id, - "clientId": _client_id, + "clientId": client_id, "rootUrl": "", "adminUrl": "", "baseUrl": "", @@ -86,7 +82,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", @@ -114,7 +110,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", @@ -128,7 +124,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", @@ -142,7 +138,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", @@ -156,7 +152,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", @@ -215,7 +211,7 @@ def generate_client_representation(account_id: int, client_id_pattern: str, env: "protocolMapper": "oidc-hardcoded-claim-mapper", "consentRequired": False, "config": { - "claim.value": _client_id, + "claim.value": client_id, "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", diff --git a/auth-api/tests/docker/docker-compose.yml b/auth-api/tests/docker/docker-compose.yml index 72dc850cee..03089c27ff 100755 --- a/auth-api/tests/docker/docker-compose.yml +++ b/auth-api/tests/docker/docker-compose.yml @@ -2,13 +2,15 @@ version: "3" services: keycloak: - image: quay.io/keycloak/keycloak:12.0.2 + image: quay.io/keycloak/keycloak:26.0 ports: - "8081:8081" environment: - - KEYCLOAK_USER=admin - - KEYCLOAK_PASSWORD=admin - command: -b 0.0.0.0 -Djboss.http.port=8081 -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/tmp/keycloak/test -Dkeycloak.migration.strategy=OVERWRITE_EXISTING + - KEYCLOAK_ADMIN=admin + - KEYCLOAK_ADMIN_PASSWORD=admin + volumes: + - ./setup:/opt/keycloak/data/import + command: ["start-dev", "--import-realm", "--http-port=8081", "--http-relative-path=/auth"] healthcheck: test: [ @@ -20,8 +22,6 @@ services: interval: 30s timeout: 10s retries: 10 - volumes: - - ./setup:/tmp/keycloak/test/ nats: image: nats-streaming restart: always diff --git a/auth-api/tests/unit/api/test_activity_log.py b/auth-api/tests/unit/api/test_activity_log.py index ca7291f81a..6c4b07709f 100644 --- a/auth-api/tests/unit/api/test_activity_log.py +++ b/auth-api/tests/unit/api/test_activity_log.py @@ -83,7 +83,7 @@ def test_fetch_activity_log_masking(client, jwt, session): # pylint:disable=unu factory_activity_log_model(actor=user.id, action=ActivityAction.CREATE_AFFILIATION.value, org_id=org.id) - user_with_token = TestUserInfo.user_staff_admin + user_with_token = dict(TestUserInfo.user_staff_admin) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] staff_user = factory_user_model(TestUserInfo.user_staff_admin) factory_activity_log_model(actor=staff_user.id, action=ActivityAction.REMOVE_AFFILIATION.value, org_id=org.id) diff --git a/auth-api/tests/unit/api/test_org.py b/auth-api/tests/unit/api/test_org.py index cea72cbb2b..3250f53596 100644 --- a/auth-api/tests/unit/api/test_org.py +++ b/auth-api/tests/unit/api/test_org.py @@ -43,6 +43,7 @@ AccessType, AffidavitStatus, CorpType, + LoginSource, NRActionCodes, NRStatus, OrgStatus, @@ -66,6 +67,7 @@ TestJwtClaims, TestOrgInfo, TestPaymentMethodInfo, + TestUserInfo, ) from tests.utilities.factory_utils import ( convert_org_to_staff_org, @@ -1276,6 +1278,11 @@ def test_get_members(client, jwt, session, keycloak_mock): # pylint:disable=unu ) dictionary = json.loads(rv.data) org_id = dictionary["id"] + # Create API_GW user, this shouldn't show up in the users list + user_dict = dict(TestUserInfo.user1) + user_dict["login_source"] = LoginSource.API_GW.value + api_user = factory_user_model(user_dict) + factory_membership_model(api_user.id, org_id=org_id) rv = client.get("/api/v1/orgs/{}/members".format(org_id), headers=headers, content_type="application/json") @@ -2936,7 +2943,7 @@ def test_update_org_api_access(client, jwt, session, keycloak_mock): # pylint:d def test_search_org_members(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that a list of members for an org search can be retrieved.""" - user_info = TestJwtClaims.public_user_role + user_info = dict(TestJwtClaims.public_user_role) headers = factory_auth_header(jwt=jwt, claims=user_info) client.post("/api/v1/users", headers=headers, content_type="application/json") client.post("/api/v1/orgs", data=json.dumps(TestOrgInfo.org1), headers=headers, content_type="application/json") diff --git a/auth-api/tests/unit/api/test_org_api_keys.py b/auth-api/tests/unit/api/test_org_api_keys.py index ae1f47b5ca..179c972a8d 100644 --- a/auth-api/tests/unit/api/test_org_api_keys.py +++ b/auth-api/tests/unit/api/test_org_api_keys.py @@ -18,8 +18,12 @@ """ import json +from contextlib import suppress from http import HTTPStatus +from auth_api.services.api_gateway import ApiGateway +from auth_api.services.keycloak import KeycloakService +from auth_api.utils.api_gateway import generate_client_representation from tests.utilities.factory_scenarios import TestJwtClaims, TestOrgInfo from tests.utilities.factory_utils import factory_auth_header diff --git a/auth-api/tests/unit/api/test_task.py b/auth-api/tests/unit/api/test_task.py index 8158ebee9e..5534178ccd 100644 --- a/auth-api/tests/unit/api/test_task.py +++ b/auth-api/tests/unit/api/test_task.py @@ -161,7 +161,7 @@ def test_put_task_org(client, jwt, session, keycloak_mock, monkeypatch): # pyli # 4. Create Org # 5. Update the created task and the relationship monkeypatch.setattr("auth_api.utils.user_context._get_token_info", lambda: TestJwtClaims.public_bceid_user) - user_with_token = TestUserInfo.user_staff_admin + user_with_token = dict(TestUserInfo.user_staff_admin) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -217,7 +217,7 @@ def test_put_task_org_on_hold(client, jwt, session, keycloak_mock, monkeypatch): # 4. Create Org # 5. Update the created task and the relationship monkeypatch.setattr("auth_api.utils.user_context._get_token_info", lambda: TestJwtClaims.public_bceid_user) - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -275,7 +275,7 @@ def test_put_task_product(client, jwt, session, keycloak_mock, monkeypatch): # # Post user, org and product subscription headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_admin_role) - user_with_token = TestUserInfo.user_staff_admin + user_with_token = dict(TestUserInfo.user_staff_admin) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model_with_contact(user_with_token) diff --git a/auth-api/tests/unit/api/test_user.py b/auth-api/tests/unit/api/test_user.py index 34b6140220..61f622eb34 100644 --- a/auth-api/tests/unit/api/test_user.py +++ b/auth-api/tests/unit/api/test_user.py @@ -110,7 +110,7 @@ def test_add_user_staff_org(client, jwt, session, keycloak_mock, monkeypatch): def test_delete_bcros_valdiations(client, jwt, session, keycloak_mock, monkeypatch): """Assert different conditions of user deletion.""" - admin_user = TestUserInfo.user_bcros_active + admin_user = dict(TestUserInfo.user_bcros_active) org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model(user_info=TestUserInfo.user_bcros_active) factory_membership_model(user.id, org.id) diff --git a/auth-api/tests/unit/api/test_user_settings.py b/auth-api/tests/unit/api/test_user_settings.py index 845ae35330..1ae2b0dec5 100644 --- a/auth-api/tests/unit/api/test_user_settings.py +++ b/auth-api/tests/unit/api/test_user_settings.py @@ -62,7 +62,7 @@ def test_get_user_settings(client, jwt, session, keycloak_mock, monkeypatch): # assert schema_utils.validate(item_list, "user_settings_response")[0] assert account["productSettings"] == f'/account/{account["id"]}/restricted-product' - kc_id_no_user = TestUserInfo.user1.get("keycloak_guid") + kc_id_no_user = dict(TestUserInfo.user1).get("keycloak_guid") claims = copy.deepcopy(TestJwtClaims.updated_test.value) claims["sub"] = str(kc_id_no_user) patch_token_info(claims, monkeypatch) diff --git a/auth-api/tests/unit/services/test_affiliation_invitation.py b/auth-api/tests/unit/services/test_affiliation_invitation.py index 564b4a9428..57307674d3 100644 --- a/auth-api/tests/unit/services/test_affiliation_invitation.py +++ b/auth-api/tests/unit/services/test_affiliation_invitation.py @@ -350,7 +350,7 @@ def test_accept_affiliation_invitation( """Accept the affiliation invitation and add the affiliation from the invitation.""" with patch.object(AffiliationInvitationService, "send_affiliation_invitation", return_value=None): with patch.object(auth, "check_auth", return_value=True): - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_with_token) @@ -364,7 +364,7 @@ def test_accept_affiliation_invitation( business_identifier=entity_dictionary["business_identifier"], ) - user_with_token_invitee = TestUserInfo.user1 + user_with_token_invitee = dict(TestUserInfo.user1) user_with_token_invitee["keycloak_guid"] = TestJwtClaims.edit_role_2["sub"] user_invitee = factory_user_model(user_with_token_invitee) @@ -447,7 +447,7 @@ def test_get_invitations_by_from_org_id( """Find an existing invitation with the provided from org id.""" with patch.object(AffiliationInvitationService, "send_affiliation_invitation", return_value=None): patch_token_info(TestJwtClaims.public_user_role, monkeypatch) - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -478,7 +478,7 @@ def test_get_invitations_by_to_org_id( """Find an existing invitation with the provided to org id.""" with patch.object(AffiliationInvitationService, "send_affiliation_invitation", return_value=None): patch_token_info(TestJwtClaims.public_user_role, monkeypatch) - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) diff --git a/auth-api/tests/unit/services/test_api_gateway.py b/auth-api/tests/unit/services/test_api_gateway.py new file mode 100644 index 0000000000..f7d6579b3d --- /dev/null +++ b/auth-api/tests/unit/services/test_api_gateway.py @@ -0,0 +1,20 @@ +import os + +import pytest +from flask import current_app + +from auth_api.services.api_gateway import ApiGateway +from auth_api.services.keycloak import KeycloakService + + +@pytest.mark.skip(reason="ADHOC Test for API users creation and Gateway") +def test_keycloak_test_environment(): + """Adhoc test with test secrets that can be run to test the functionality of the api gateway code.""" + current_app.config["KEYCLOAK_BASE_URL"] = os.getenv("KEYCLOAK_BASE_URL") + current_app.config["KEYCLOAK_REALMNAME"] = os.getenv("KEYCLOAK_REALMNAME") + current_app.config["KEYCLOAK_ADMIN_USERNAME"] = os.getenv("SBC_AUTH_ADMIN_CLIENT_ID") + current_app.config["KEYCLOAK_ADMIN_SECRET"] = os.getenv("SBC_AUTH_ADMIN_CLIENT_SECRET") + current_app.config["API_GW_KC_CLIENT_ID_PATTERN"] = os.getenv("API_GW_KC_CLIENT_ID_PATTERN") + KeycloakService.get_service_account_by_client_name(ApiGateway.get_api_client_id(2758, "sandbox")) + ApiGateway._create_user_and_membership_for_api_user(2758, "sandbox") + assert True diff --git a/auth-api/tests/unit/services/test_entity.py b/auth-api/tests/unit/services/test_entity.py index 060ad0b067..ab09c317ef 100644 --- a/auth-api/tests/unit/services/test_entity.py +++ b/auth-api/tests/unit/services/test_entity.py @@ -106,7 +106,7 @@ def test_update_entity_existing_success(session, monkeypatch): # pylint:disable "name": TestEntityInfo.bc_entity_passcode4["name"], "corpTypeCode": TestEntityInfo.bc_entity_passcode4["corpTypeCode"], } - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] patch_token_info({"loginSource": "", "realm_access": {"roles": ["system"]}, "corp_type": "BC"}, monkeypatch) @@ -138,7 +138,7 @@ def test_update_entity_existing_failures(session, monkeypatch): # pylint:disabl "name": TestEntityInfo.bc_entity_passcode4["name"], "corpTypeCode": TestEntityInfo.bc_entity_passcode4["corpTypeCode"], } - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] with pytest.raises(BusinessException) as exception: diff --git a/auth-api/tests/unit/services/test_invitation.py b/auth-api/tests/unit/services/test_invitation.py index a1e757c44b..40cdfaa233 100644 --- a/auth-api/tests/unit/services/test_invitation.py +++ b/auth-api/tests/unit/services/test_invitation.py @@ -216,7 +216,7 @@ def test_accept_invitation(session, auth_mock, keycloak_mock, monkeypatch): # p with patch.object(InvitationService, "send_invitation", return_value=None): with patch.object(auth, "check_auth", return_value=True): with patch.object(InvitationService, "notify_admin", return_value=None): - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_with_token) @@ -225,7 +225,7 @@ def test_accept_invitation(session, auth_mock, keycloak_mock, monkeypatch): # p org = OrgService.create_org(TestOrgInfo.org1, user_id=user.id) org_dictionary = org.as_dict() invitation_info = factory_invitation(org_dictionary["id"]) - user_with_token_invitee = TestUserInfo.user1 + user_with_token_invitee = dict(TestUserInfo.user1) user_with_token_invitee["keycloak_guid"] = TestJwtClaims.edit_role_2["sub"] user_invitee = factory_user_model(user_with_token_invitee) new_invitation = InvitationService.create_invitation(invitation_info, User(user_invitee), "") @@ -243,7 +243,7 @@ def test_accept_invitation_for_govm(session, auth_mock, keycloak_mock, monkeypat with patch.object(InvitationService, "send_invitation", return_value=None): with patch.object(auth, "check_auth", return_value=True): with patch.object(InvitationService, "notify_admin", return_value=None): - user_with_token = TestUserInfo.user_staff_admin + user_with_token = dict(TestUserInfo.user_staff_admin) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_with_token) @@ -252,7 +252,7 @@ def test_accept_invitation_for_govm(session, auth_mock, keycloak_mock, monkeypat org = OrgService.create_org(TestOrgInfo.org_govm, user_id=user.id) org_dictionary = org.as_dict() invitation_info = factory_invitation(org_dictionary["id"]) - user_with_token_invitee = TestUserInfo.user1 + user_with_token_invitee = dict(TestUserInfo.user1) user_with_token_invitee["keycloak_guid"] = TestJwtClaims.edit_role_2["sub"] user_invitee = factory_user_model(user_with_token_invitee) new_invitation = InvitationService.create_invitation(invitation_info, User(user_invitee), "") @@ -314,7 +314,7 @@ def test_get_invitations_by_org_id(session, auth_mock, keycloak_mock, monkeypatc """Find an existing invitation with the provided org id.""" with patch.object(InvitationService, "send_invitation", return_value=None): patch_token_info(TestJwtClaims.public_user_role, monkeypatch) - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) diff --git a/auth-api/tests/unit/services/test_invitation_auth.py b/auth-api/tests/unit/services/test_invitation_auth.py index 9bad174c3f..9eb9b1183d 100644 --- a/auth-api/tests/unit/services/test_invitation_auth.py +++ b/auth-api/tests/unit/services/test_invitation_auth.py @@ -90,7 +90,7 @@ def test_token_user_context(session, auth_mock, monkeypatch): @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_change_authentication_subsequent_invites(session, auth_mock, keycloak_mock, monkeypatch): """Assert that changing org authentication method changes new invitation required login source.""" - user_with_token = TestUserInfo.user_tester + user_with_token = dict(TestUserInfo.user_tester) user_with_token["keycloak_guid"] = TestJwtClaims.tester_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.tester_role["idp_userid"] inviter_user = factory_user_model(user_info=user_with_token) @@ -176,7 +176,7 @@ def test_change_authentication_non_govm(session, auth_mock, keycloak_mock, monke invitee_bcsc_user = factory_user_model(TestUserInfo.user1) invitee_bceid_user = factory_user_model(TestUserInfo.user2) - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) org = OrgService.create_org(TestOrgInfo.org1, user_id=inviter_user.id) org_dictionary = org.as_dict() @@ -219,14 +219,14 @@ def test_change_authentication_non_govm(session, auth_mock, keycloak_mock, monke assert invitation_model.login_source == LoginSource.BCSC.value assert invitation_model.invitation_status_code == InvitationStatus.ACCEPTED.value - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) members = MembershipService.get_members_for_org(org_dictionary["id"], "PENDING_APPROVAL") assert members assert len(members) == 1 # Confirm that an invitation with BCSC login source can be accepted as another user login source and # updates the invitation login source based on the accepting user login source - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) with patch.object(InvitationService, "send_invitation", return_value=None): # Create invitation with BCSC login source with patch.object(ActivityLogPublisher, "publish_activity", return_value=None) as mock_alp: @@ -265,7 +265,7 @@ def test_change_authentication_non_govm(session, auth_mock, keycloak_mock, monke assert invitation_model.login_source == LoginSource.BCEID.value assert invitation_model.invitation_status_code == InvitationStatus.ACCEPTED.value - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) members = MembershipService.get_members_for_org(org_dictionary["id"], "PENDING_APPROVAL") assert members assert len(members) == 2 @@ -362,7 +362,7 @@ def test_invitation_anonymous(session, auth_mock, keycloak_mock, monkeypatch): inviter_user = factory_user_model(TestUserInfo.user_tester) invitee_bcsc_user = factory_user_model(TestUserInfo.user1) - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) org = OrgService.create_org(TestOrgInfo.org1, user_id=inviter_user.id) org_dictionary = org.as_dict() @@ -400,7 +400,7 @@ def test_invitation_anonymous(session, auth_mock, keycloak_mock, monkeypatch): assert invitation_model.login_source is None assert invitation_model.invitation_status_code == InvitationStatus.ACCEPTED.value - patch_token_info(TestJwtClaims.tester_role, monkeypatch) + patch_token_info(TestJwtClaims.user_test, monkeypatch) members = MembershipService.get_members_for_org(org_dictionary["id"], "PENDING_APPROVAL") assert members assert len(members) == 1 diff --git a/auth-api/tests/unit/services/test_keycloak.py b/auth-api/tests/unit/services/test_keycloak.py index c67b927b37..c85243c3d0 100644 --- a/auth-api/tests/unit/services/test_keycloak.py +++ b/auth-api/tests/unit/services/test_keycloak.py @@ -271,3 +271,11 @@ def test_add_remove_group_bulk(session): user2_groups = KEYCLOAK_SERVICE.get_user_groups(user_id=user2.id) assert "ppr" in ["ppr" for user_group in user1_groups if user_group.get("name") == "ppr"] assert "bca" not in ["bca" for user_group in user2_groups if user_group.get("name") == "bca"] + + +def test_service_account_by_client_name(session): + """Test keycloak service account by client name.""" + result = KeycloakService.get_service_account_by_client_name("sbc-auth-admin") + assert result is not None + assert result.get("username") == "service-account-sbc-auth-admin" + assert result.get("id") is not None diff --git a/auth-api/tests/unit/services/test_org.py b/auth-api/tests/unit/services/test_org.py index bd5a7202b1..7a5f6c5efb 100644 --- a/auth-api/tests/unit/services/test_org.py +++ b/auth-api/tests/unit/services/test_org.py @@ -189,7 +189,7 @@ def test_pay_request_is_correct_with_branch_name(session, keycloak_mock, monkeyp @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_update_basic_org_assert_pay_request_activity(session, keycloak_mock, monkeypatch): """Assert that while org payment update touches activity log.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -220,7 +220,7 @@ def test_update_basic_org_assert_pay_request_is_correct( session, keycloak_mock, monkeypatch ): # pylint:disable=unused-argument """Assert that while org updation , pay-api gets called with proper data for basic accounts.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -402,7 +402,7 @@ def test_create_org_assert_payment_types(session, keycloak_mock, monkeypatch): @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_create_product_single_subscription(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an Org can be created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user = factory_user_model(user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -426,7 +426,7 @@ def test_create_product_single_subscription_duplicate_error( session, keycloak_mock, monkeypatch ): # pylint:disable=unused-argument """Assert that an Org can be created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user = factory_user_model(user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -455,7 +455,7 @@ def test_create_product_single_subscription_duplicate_error( @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_create_product_multiple_subscription(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an Org can be created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model(user_with_token) @@ -776,7 +776,7 @@ def test_update_contact_no_contact(session): # pylint:disable=unused-argument @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_get_members(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that members for an org can be retrieved.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_info=user_with_token) @@ -795,7 +795,7 @@ def test_get_members(session, keycloak_mock, monkeypatch): # pylint:disable=unu def test_get_invitations(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that invitations for an org can be retrieved.""" with patch.object(InvitationService, "send_invitation", return_value=None): - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_info=user_with_token) @@ -818,7 +818,7 @@ def test_get_invitations(session, auth_mock, keycloak_mock, monkeypatch): # pyl @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_get_owner_count_one_owner(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that count of owners is correct.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -829,7 +829,7 @@ def test_get_owner_count_one_owner(session, keycloak_mock, monkeypatch): # pyli @pytest.mark.parametrize("staff_org", [(TestOrgInfo.staff_org), (TestOrgInfo.sbc_staff_org)]) def test_create_staff_org_failure(session, keycloak_mock, staff_org, monkeypatch): # pylint:disable=unused-argument """Assert that staff org cannot be created.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) patch_token_info({"sub": user.keycloak_guid, "idp_userid": user.idp_userid}, monkeypatch) @@ -841,7 +841,7 @@ def test_create_staff_org_failure(session, keycloak_mock, staff_org, monkeypatch @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_get_owner_count_two_owner_with_admins(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert wrong org cannot be created.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) @@ -858,7 +858,7 @@ def test_get_owner_count_two_owner_with_admins(session, keycloak_mock, monkeypat @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_delete_org_with_members(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an org can be deleted.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_info=user_with_token) @@ -881,7 +881,7 @@ def test_delete_org_with_members(session, auth_mock, keycloak_mock, monkeypatch) @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_delete_org_with_affiliation(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an org cannot be deleted.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user = factory_user_model(user_info=user_with_token) @@ -908,7 +908,7 @@ def test_delete_org_with_members_success( session, auth_mock, keycloak_mock, monkeypatch ): # pylint:disable=unused-argument """Assert that an org can be deleted.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user = factory_user_model(user_info=user_with_token) diff --git a/auth-api/tests/unit/services/test_product_notifications.py b/auth-api/tests/unit/services/test_product_notifications.py index 1b3e95e2f2..b57547b80e 100644 --- a/auth-api/tests/unit/services/test_product_notifications.py +++ b/auth-api/tests/unit/services/test_product_notifications.py @@ -47,7 +47,7 @@ @patch.object(auth_api.services.products, "publish_to_mailer") def test_default_approved_notification(mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info): """Assert product approved notification default is created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -108,7 +108,7 @@ def test_default_approved_notification(mock_mailer, session, auth_mock, keycloak @patch.object(auth_api.services.products, "publish_to_mailer") def test_default_rejected_notification(mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info): """Assert product rejected notification default is created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -176,7 +176,7 @@ def test_default_rejected_notification(mock_mailer, session, auth_mock, keycloak @patch.object(auth_api.services.products, "publish_to_mailer") def test_detailed_approved_notification(mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info): """Assert product approved notification with details is created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -264,7 +264,7 @@ def test_detailed_rejected_notification( mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info, contact_type ): """Assert product rejected notification with details is created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -353,7 +353,7 @@ def test_detailed_rejected_notification( @patch.object(auth_api.services.products, "publish_to_mailer") def test_hold_notification(mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info): """Assert product notification is not created for on hold state.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -431,7 +431,7 @@ def test_confirmation_notification( mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info, contact_type ): """Assert product confirmation notification is properly created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -479,7 +479,7 @@ def test_confirmation_notification( @patch.object(auth_api.services.products, "publish_to_mailer") def test_no_confirmation_notification(mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info): """Assert product confirmation notification not created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -524,7 +524,7 @@ def test_resubmission_notification( mock_mailer, session, auth_mock, keycloak_mock, monkeypatch, org_product_info, contact_type ): """Assert product resubmission notifications are created.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) diff --git a/auth-api/tests/unit/services/test_task.py b/auth-api/tests/unit/services/test_task.py index 06fe3b9f9a..0be01e0522 100644 --- a/auth-api/tests/unit/services/test_task.py +++ b/auth-api/tests/unit/services/test_task.py @@ -132,7 +132,7 @@ def test_create_task_product(session, keycloak_mock): # pylint:disable=unused-a @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_update_task(session, keycloak_mock, monkeypatch, test_name, rmv_contact): # pylint:disable=unused-argument """Assert that a task can be updated.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) @@ -174,7 +174,7 @@ def test_update_task(session, keycloak_mock, monkeypatch, test_name, rmv_contact @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_hold_task(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that a task can be updated.""" - user_with_token = TestUserInfo.user_bceid_tester + user_with_token = dict(TestUserInfo.user_bceid_tester) user_with_token["keycloak_guid"] = TestJwtClaims.public_bceid_user["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_bceid_user["idp_userid"] user = factory_user_model_with_contact(user_with_token) diff --git a/auth-api/tests/unit/services/test_user.py b/auth-api/tests/unit/services/test_user.py index ece0913bf2..174b38cbfb 100644 --- a/auth-api/tests/unit/services/test_user.py +++ b/auth-api/tests/unit/services/test_user.py @@ -63,7 +63,7 @@ def test_as_dict(session): # pylint: disable=unused-argument user = UserService(user_model) dictionary = user.as_dict() - assert dictionary["username"] == TestUserInfo.user1["username"] + assert dictionary["username"] == dict(TestUserInfo.user1)["username"] def test_user_save_by_token(session, monkeypatch): # pylint: disable=unused-argument @@ -444,7 +444,7 @@ def test_user_save_by_token_fail(session, monkeypatch): # pylint: disable=unuse def test_add_contact_to_user(session, monkeypatch): # pylint: disable=unused-argument """Assert that a contact can be added to a user.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] factory_user_model(user_info=user_with_token) @@ -467,7 +467,7 @@ def test_add_contact_user_no_user(session, monkeypatch): # pylint: disable=unus def test_add_contact_to_user_already_exists(session, monkeypatch): # pylint: disable=unused-argument """Assert that a contact cannot be added to a user that already has a contact.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] factory_user_model(user_info=user_with_token) @@ -482,7 +482,7 @@ def test_add_contact_to_user_already_exists(session, monkeypatch): # pylint: di def test_update_contact_for_user(session, monkeypatch): # pylint: disable=unused-argument """Assert that a contact can be updated for a user.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] factory_user_model(user_info=user_with_token) @@ -555,7 +555,7 @@ def test_update_contact_for_user_no_contact(session, monkeypatch): # pylint: di @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_delete_contact_for_user(session, monkeypatch): # pylint: disable=unused-argument """Assert that a contact can be deleted for a user.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] factory_user_model(user_info=user_with_token) @@ -604,7 +604,7 @@ def test_find_users(session): # pylint: disable=unused-argument def test_user_find_by_token(session, monkeypatch): # pylint: disable=unused-argument """Assert that a user can be found by token.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] factory_user_model(user_info=user_with_token) @@ -640,12 +640,12 @@ def test_user_find_by_username(session): # pylint: disable=unused-argument user = UserService.find_by_username(TestUserInfo.user1["username"]) assert user is not None dictionary = user.as_dict() - assert dictionary["username"] == TestUserInfo.user1["username"] + assert dictionary["username"] == dict(TestUserInfo.user1)["username"] def test_user_find_by_username_no_model_object(session): # pylint: disable=unused-argument """Assert that the business can't be found with no model.""" - username = TestUserInfo.user_test["username"] + username = dict(TestUserInfo.user_test)["username"] user = UserService.find_by_username(username) @@ -665,7 +665,7 @@ def test_user_find_by_username_missing_username(session): # pylint: disable=unu @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_delete_contact_user_link(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that a contact can not be deleted if contact link exists.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user_model = factory_user_model(user_info=user_with_token) @@ -700,7 +700,7 @@ def test_delete_contact_user_link(session, auth_mock, keycloak_mock, monkeypatch @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_delete_user(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that a user can be deleted.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.user_test["sub"] user_with_token["idp_userid"] = TestJwtClaims.user_test["idp_userid"] user_model = factory_user_model(user_info=user_with_token) diff --git a/auth-api/tests/unit/services/test_user_settings.py b/auth-api/tests/unit/services/test_user_settings.py index 944038f3f2..f5e34fed3d 100644 --- a/auth-api/tests/unit/services/test_user_settings.py +++ b/auth-api/tests/unit/services/test_user_settings.py @@ -30,7 +30,7 @@ @mock.patch("auth_api.services.affiliation_invitation.RestService.get_service_account_token", mock_token) def test_user_settings(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that a contact can not be deleted if contact link exists.""" - user_with_token = TestUserInfo.user_test + user_with_token = dict(TestUserInfo.user_test) user_with_token["keycloak_guid"] = TestJwtClaims.public_user_role["sub"] user_with_token["idp_userid"] = TestJwtClaims.public_user_role["idp_userid"] user_model = factory_user_model(user_info=user_with_token) diff --git a/auth-api/tests/utilities/factory_scenarios.py b/auth-api/tests/utilities/factory_scenarios.py index 3f48eb9899..6ac1a4b8e3 100644 --- a/auth-api/tests/utilities/factory_scenarios.py +++ b/auth-api/tests/utilities/factory_scenarios.py @@ -13,7 +13,8 @@ # limitations under the License. """Test Utils. -Test Utility for creating test scenarios. +Test Utility for creating test scenarios. NOTE IF USING THIS, MAKE SURE YOU CLONE (EG. wrap it with DICT) +THE OBJECTS OTHERWISE THEY WILL BLEED BETWEEN UNIT TESTS. """ import uuid from enum import Enum diff --git a/auth-api/tests/utilities/factory_utils.py b/auth-api/tests/utilities/factory_utils.py index e3c2912f9b..8f4eae42fa 100644 --- a/auth-api/tests/utilities/factory_utils.py +++ b/auth-api/tests/utilities/factory_utils.py @@ -85,7 +85,7 @@ def factory_entity_service(entity_info: dict = TestEntityInfo.entity1): return entity_service -def factory_user_model(user_info: dict = TestUserInfo.user1): +def factory_user_model(user_info: dict = dict(TestUserInfo.user1)): """Produce a user model.""" roles = user_info.get("roles", None) if user_info.get("access_type", None) == AccessType.ANONYMOUS.value: @@ -110,7 +110,7 @@ def factory_user_model(user_info: dict = TestUserInfo.user1): return user -def factory_user_model_with_contact(user_info: dict = TestUserInfo.user1, keycloak_guid=None): +def factory_user_model_with_contact(user_info: dict = dict(TestUserInfo.user1), keycloak_guid=None): """Produce a user model.""" user_type = Role.ANONYMOUS_USER.name if user_info.get("access_type", None) == AccessType.ANONYMOUS.value else None user = UserModel( diff --git a/auth-web/.env.example b/auth-web/.env.example index b042fb3481..c85d22c1e8 100644 --- a/auth-web/.env.example +++ b/auth-web/.env.example @@ -73,3 +73,6 @@ VUE_APP_SENTRY_DSN= #vaults hotjar VUE_APP_HOTJAR_ID= + +# Google Analytics +VUE_APP_GTAG_ID= diff --git a/auth-web/devops/vaults.env b/auth-web/devops/vaults.env index f3b63b6827..8c36316825 100644 --- a/auth-web/devops/vaults.env +++ b/auth-web/devops/vaults.env @@ -73,3 +73,6 @@ VUE_APP_SENTRY_DSN="op://sentry/$APP_ENV/relationship-web/SENTRY_DSN" #vaults hotjar VUE_APP_HOTJAR_ID="op://hotjar/$APP_ENV/auth-web/HOTJAR_ID" + +# Google Analytics +VUE_APP_GTAG_ID="op://google-analytics/$APP_ENV/developer/GTAG" diff --git a/auth-web/index.html b/auth-web/index.html index bde636a0ee..6830819c54 100644 --- a/auth-web/index.html +++ b/auth-web/index.html @@ -4,7 +4,7 @@ <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> - <title>BC Business Registry</title> + <title>BC Business Registry - Accounts</title> <meta name="Description" content="File your BC cooperative association's annual reports and maintain your registered office addresses and director information."> <link rel="icon" href="/favicon.png"> <link rel="stylesheet" href="/css/addresscomplete-2.30.min.css"> diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index feeed17d31..1a5a486d88 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -33,6 +33,7 @@ "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", + "vue-gtag": "^1.16.1", "vue-hotjar": "^1.4.0", "vue-i18n": "8.28.2", "vue-i18n-composable": "^1.0.0", @@ -73,7 +74,7 @@ "stylus": "^0.54.7", "typescript": "^4.9.5", "unplugin-vue2-script-setup": "^0.11.4", - "vite": "^4.5.9", + "vite": "^4.5.10", "vite-plugin-environment": "^1.1.3", "vite-plugin-rewrite-all": "^1.0.1", "vite-plugin-vue2": "^2.0.3", @@ -10224,9 +10225,9 @@ "dev": true }, "node_modules/vite": { - "version": "4.5.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", - "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.10.tgz", + "integrity": "sha512-f2ueoukYTMI/5kMMT7wW+ol3zL6z6PjN28zYrGKAjnbzXhRXWXPThD3uN6muCp+TbfXaDgGvRuPsg6mwVLaWwQ==", "license": "MIT", "dependencies": { "esbuild": "^0.18.10", @@ -12216,6 +12217,14 @@ "eslint": ">=5.0.0" } }, + "node_modules/vue-gtag": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/vue-gtag/-/vue-gtag-1.16.1.tgz", + "integrity": "sha512-5vs0pSGxdqrfXqN1Qwt0ZFXG0iTYjRMu/saddc7QIC5yp+DKgjWQRpGYVa7Pq+KbThxwzzMfo0sGi7ISa6NowA==", + "peerDependencies": { + "vue": "^2.0.0" + } + }, "node_modules/vue-hot-reload-api": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", @@ -20170,9 +20179,9 @@ "dev": true }, "vite": { - "version": "4.5.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", - "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.10.tgz", + "integrity": "sha512-f2ueoukYTMI/5kMMT7wW+ol3zL6z6PjN28zYrGKAjnbzXhRXWXPThD3uN6muCp+TbfXaDgGvRuPsg6mwVLaWwQ==", "requires": { "esbuild": "^0.18.10", "fsevents": "~2.3.2", @@ -21328,6 +21337,12 @@ "semver": "^6.3.0" } }, + "vue-gtag": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/vue-gtag/-/vue-gtag-1.16.1.tgz", + "integrity": "sha512-5vs0pSGxdqrfXqN1Qwt0ZFXG0iTYjRMu/saddc7QIC5yp+DKgjWQRpGYVa7Pq+KbThxwzzMfo0sGi7ISa6NowA==", + "requires": {} + }, "vue-hot-reload-api": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", diff --git a/auth-web/package.json b/auth-web/package.json index 9b32bfb810..1664eb39bf 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -42,6 +42,7 @@ "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", + "vue-gtag": "^1.16.1", "vue-hotjar": "^1.4.0", "vue-i18n": "8.28.2", "vue-i18n-composable": "^1.0.0", @@ -82,7 +83,7 @@ "stylus": "^0.54.7", "typescript": "^4.9.5", "unplugin-vue2-script-setup": "^0.11.4", - "vite": "^4.5.9", + "vite": "^4.5.10", "vite-plugin-environment": "^1.1.3", "vite-plugin-rewrite-all": "^1.0.1", "vite-plugin-vue2": "^2.0.3", diff --git a/auth-web/src/main.ts b/auth-web/src/main.ts index f2ac53f051..22d37ae8b0 100644 --- a/auth-web/src/main.ts +++ b/auth-web/src/main.ts @@ -12,6 +12,7 @@ import LaunchDarklyService from 'sbc-common-components/src/services/launchdarkly import './routes/componentHooks' import Vue from 'vue' import VueCompositionAPI from '@vue/composition-api' +import VueGtag from 'vue-gtag' import VueSanitize from 'vue-sanitize-directive' import Vuelidate from 'vuelidate' import can from '@/directives/can' @@ -33,6 +34,14 @@ Vue.use(VueSanitize) const i18n = initializeI18n(Vue) +if (import.meta.env.VUE_APP_GTAG_ID) { + Vue.use(VueGtag, { + config: { + id: import.meta.env.VUE_APP_GTAG_ID + } + }, router) +} + /** * The server side configs are necessary for app to work , since they are reference in templates and all * Two ways , either reload Vue after we get the settings or load vue after we get the configs..going for second diff --git a/auth-web/tests/unit/services/task.service.spec.ts b/auth-web/tests/unit/services/task.service.spec.ts index d97d0ac617..f08f67e1ab 100644 --- a/auth-web/tests/unit/services/task.service.spec.ts +++ b/auth-web/tests/unit/services/task.service.spec.ts @@ -30,6 +30,8 @@ const mocks = vi.hoisted(() => ({ describe('Task service', () => { beforeEach(() => { + TaskService.getTaskById = vi.fn().mockResolvedValue(mockTask) + TaskService.fetchTasks = vi.fn().mockResolvedValue(mockTask) sessionStorage['AUTH_API_CONFIG'] = JSON.stringify(mockob) vi.doMock('axios', () => { return { diff --git a/auth-web/tests/unit/views/AccountSuspendedView.spec.ts b/auth-web/tests/unit/views/AccountSuspendedView.spec.ts index 64b50e0c77..ceea8ba84d 100644 --- a/auth-web/tests/unit/views/AccountSuspendedView.spec.ts +++ b/auth-web/tests/unit/views/AccountSuspendedView.spec.ts @@ -28,6 +28,11 @@ describe('AccountSuspendedView.vue', () => { name: 'testOrg', suspendedOn: 'January 12, 2021' } + orgStore.getAccountAdministrator = vi.fn().mockResolvedValue({ 'user': { 'contacts': [ + { + 'email': 'heyhey@haha.com' + } + ] } }) sessionStorage['AUTH_API_CONFIG'] = JSON.stringify(mockSession) const localVue = createLocalVue() wrapper = shallowMount(AccountSuspendedView, { diff --git a/queue_services/account-mailer/Dockerfile b/queue_services/account-mailer/Dockerfile index c6fb0a9caf..ebf3a08211 100644 --- a/queue_services/account-mailer/Dockerfile +++ b/queue_services/account-mailer/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12.5-bullseye as development_build +FROM python:3.12.9-bullseye as development_build USER root ARG VCS_REF="missing" diff --git a/queue_services/account-mailer/Makefile b/queue_services/account-mailer/Makefile deleted file mode 100644 index 0c8220463a..0000000000 --- a/queue_services/account-mailer/Makefile +++ /dev/null @@ -1,139 +0,0 @@ -.PHONY: license -.PHONY: setup -.PHONY: ci cd -.PHONY: run - -MKFILE_PATH:=$(abspath $(lastword $(MAKEFILE_LIST))) -CURRENT_ABS_DIR:=$(patsubst %/,%,$(dir $(MKFILE_PATH))) - -PROJECT_NAME:=account_mailer -DOCKER_NAME:=account-mailer - -################################################################################# -# COMMANDS -- Setup # -################################################################################# -setup: clean install install-dev ## Setup the project - -clean: clean-build clean-pyc clean-test ## Clean the project - rm -rf .venv/ - rm -rf poetry.lock - -clean-build: ## Clean build files - rm -fr build/ - rm -fr dist/ - rm -fr .eggs/ - find . -name '*.egg-info' -exec rm -fr {} + - find . -name '*.egg' -exec rm -fr {} + - -clean-pyc: ## Clean cache files - find . -name '*.pyc' -exec rm -f {} + - find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + - find . -name '__pycache__' -exec rm -fr {} + - -clean-test: ## clean test files - find . -name '.pytest_cache' -exec rm -fr {} + - rm -fr .tox/ - rm -f .coverage - rm -fr htmlcov/ - -build-req: clean ## Upgrade requirements - update: ## Upgrade lock - poetry update - -install: clean ## Install python virtrual environment - unset HOME ## unset HOME because it's in the DEV .env file, will cause permissions issues - pip install poetry ;\ - poetry config virtualenvs.in-project true ;\ - poetry install - -install-dev: ## Install local application - poetry add --dev pylint astroid - poetry install --with dev - -################################################################################# -# COMMANDS - CI # -################################################################################# -ci: lint flake8 test ## CI flow - -pylint: ## Linting with pylint - poetry run pylint --rcfile=setup.cfg src/$(PROJECT_NAME) - -flake8: ## Linting with flake8 - poetry run flake8 src/$(PROJECT_NAME) tests - -lint: pylint flake8 ## run all lint type scripts - -test: ## Unit testing - poetry run pytest - -mac-cov: test ## Run the coverage report and display in a browser window (mac) - @open -a "Google Chrome" htmlcov/index.html - -################################################################################# -# COMMANDS - CD -# expects the terminal to be openshift login -# expects export OPENSHIFT_DOCKER_REGISTRY="" -# expects export OPENSHIFT_SA_NAME="$(oc whoami)" -# expects export OPENSHIFT_SA_TOKEN="$(oc whoami -t)" -# expects export OPENSHIFT_REPOSITORY="" -# expects export TAG_NAME="dev/test/prod" -# expects export OPS_REPOSITORY="" # -################################################################################# -cd: ## CD flow -ifeq ($(TAG_NAME), test) -cd: update-env - oc -n "$(OPENSHIFT_REPOSITORY)-tools" tag $(DOCKER_NAME):dev $(DOCKER_NAME):$(TAG_NAME) -else ifeq ($(TAG_NAME), prod) -cd: update-env - oc -n "$(OPENSHIFT_REPOSITORY)-tools" tag $(DOCKER_NAME):$(TAG_NAME) $(DOCKER_NAME):$(TAG_NAME)-$(shell date +%F) - oc -n "$(OPENSHIFT_REPOSITORY)-tools" tag $(DOCKER_NAME):test $(DOCKER_NAME):$(TAG_NAME) -else -TAG_NAME=dev -cd: build update-env tag -endif - -build: ## Build the docker container - docker build . -t $(DOCKER_NAME) \ - --build-arg VCS_REF=$(shell git rev-parse --short HEAD) \ - --build-arg BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") \ - -build-nc: ## Build the docker container without caching - docker build --no-cache -t $(DOCKER_NAME) . - -REGISTRY_IMAGE=$(OPENSHIFT_DOCKER_REGISTRY)/$(OPENSHIFT_REPOSITORY)-tools/$(DOCKER_NAME) -push: #build ## Push the docker container to the registry & tag latest - @echo "$(OPENSHIFT_SA_TOKEN)" | docker login $(OPENSHIFT_DOCKER_REGISTRY) -u $(OPENSHIFT_SA_NAME) --password-stdin ;\ - docker tag $(DOCKER_NAME) $(REGISTRY_IMAGE):latest ;\ - docker push $(REGISTRY_IMAGE):latest - -VAULTS=`cat devops/vaults.json` -update-env: ## Update env from 1pass - oc -n "$(OPS_REPOSITORY)-$(TAG_NAME)" exec "dc/vault-service-$(TAG_NAME)" -- ./scripts/1pass.sh \ - -m "secret" \ - -e "$(TAG_NAME)" \ - -a "$(DOCKER_NAME)-$(TAG_NAME)" \ - -n "$(OPENSHIFT_REPOSITORY)-$(TAG_NAME)" \ - -v "$(VAULTS)" \ - -r "true" \ - -f "false" - -tag: push ## tag image - oc -n "$(OPENSHIFT_REPOSITORY)-tools" tag $(DOCKER_NAME):latest $(DOCKER_NAME):$(TAG_NAME) - -################################################################################# -# COMMANDS - Local # -################################################################################# - -run: ## Run the project in local - poetry run flask run -p 5000 - -################################################################################# -# Self Documenting Commands # -################################################################################# -.PHONY: help - -.DEFAULT_GOAL := help - -help: - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/queue_services/account-mailer/__init__.py b/queue_services/account-mailer/__init__.py new file mode 100644 index 0000000000..40f70a1cd0 --- /dev/null +++ b/queue_services/account-mailer/__init__.py @@ -0,0 +1 @@ +"""Account mailer package.""" diff --git a/queue_services/account-mailer/app.py b/queue_services/account-mailer/app.py index 724562ebb4..7af45d5e0c 100755 --- a/queue_services/account-mailer/app.py +++ b/queue_services/account-mailer/app.py @@ -19,9 +19,8 @@ from account_mailer import create_app - app = create_app() -if __name__ == '__main__': - server_port = os.environ.get('PORT', '8080') - app.run(debug=False, port=server_port, host='0.0.0.0') +if __name__ == "__main__": + server_port = os.environ.get("PORT", "8080") + app.run(debug=False, port=server_port, host="0.0.0.0") diff --git a/queue_services/account-mailer/devops/vaults.gcp.env b/queue_services/account-mailer/devops/vaults.gcp.env index cf18056a7e..298d129887 100644 --- a/queue_services/account-mailer/devops/vaults.gcp.env +++ b/queue_services/account-mailer/devops/vaults.gcp.env @@ -20,6 +20,8 @@ MINIO_ENDPOINT="op://minio/$APP_ENV/base/MINIO_ENDPOINT" MINIO_ACCESS_KEY="op://minio/$APP_ENV/base/MINIO_ACCESS_KEY" MINIO_ACCESS_SECRET="op://minio/$APP_ENV/base/MINIO_ACCESS_SECRET" MINIO_BUCKET="op://minio/$APP_ENV/account-mailer/MINIO_BUCKET" +ACCOUNT_MAILER_BUCKET="op://buckets/$APP_ENV/auth/ACCOUNT_MAILER_BUCKET" +STATIC_RESOURCES_BUCKET_URL="op://buckets/$APP_ENV/auth/STATIC_RESOURCES_BUCKET_URL" REFUND_REQUEST_RECIPIENTS="op://relationship/$APP_ENV/account-mailer/REFUND_REQUEST_RECIPIENTS" BCOL_REFUND_REQUEST_RECIPIENTS="op://relationship/$APP_ENV/account-mailer/BCOL_REFUND_REQUEST_RECIPIENTS" PDF_TEMPLATE_PATH="op://relationship/$APP_ENV/account-mailer/PDF_TEMPLATE_PATH" diff --git a/queue_services/account-mailer/gunicorn_config.py b/queue_services/account-mailer/gunicorn_config.py index 7428d67daf..81f6279584 100644 --- a/queue_services/account-mailer/gunicorn_config.py +++ b/queue_services/account-mailer/gunicorn_config.py @@ -11,16 +11,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""The configuration for gunicorn, which picks up the - runtime options from environment variables -""" -import os +"""The configuration for gunicorn.""" +import os -workers = int(os.environ.get('GUNICORN_PROCESSES', '1')) # pylint: disable=invalid-name -timeout = int(os.environ.get('GUNICORN_TIMEOUT', '0')) # pylint: disable=invalid-name -threads = int(os.environ.get('GUNICORN_THREADS', '1')) # pylint: disable=invalid-name +workers = int(os.environ.get("GUNICORN_PROCESSES", "1")) # pylint: disable=invalid-name +timeout = int(os.environ.get("GUNICORN_TIMEOUT", "0")) # pylint: disable=invalid-name +threads = int(os.environ.get("GUNICORN_THREADS", "1")) # pylint: disable=invalid-name -forwarded_allow_ips = '*' # pylint: disable=invalid-name -secure_scheme_headers = {'X-Forwarded-Proto': 'https'} # pylint: disable=invalid-name +forwarded_allow_ips = "*" # pylint: disable=invalid-name +secure_scheme_headers = {"X-Forwarded-Proto": "https"} # pylint: disable=invalid-name diff --git a/queue_services/account-mailer/openshift/templates/bc.yaml b/queue_services/account-mailer/openshift/templates/bc.yaml deleted file mode 100644 index c9596f4a8f..0000000000 --- a/queue_services/account-mailer/openshift/templates/bc.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: template.openshift.io/v1 -kind: Template -metadata: - labels: - name: ${NAME} - name: ${NAME}-build -objects: -- apiVersion: v1 - kind: ImageStream - metadata: - name: ${NAME} - labels: - name: ${NAME} -- apiVersion: v1 - kind: BuildConfig - metadata: - name: ${NAME} - labels: - name: ${NAME} - spec: - output: - to: - kind: ImageStreamTag - name: ${NAME}:${OUTPUT_IMAGE_TAG} - resources: - limits: - cpu: ${CPU_LIMIT} - memory: ${MEMORY_LIMIT} - requests: - cpu: ${CPU_REQUEST} - memory: ${MEMORY_REQUEST} - runPolicy: Serial - source: - contextDir: ${SOURCE_CONTEXT_DIR} - git: - ref: ${GIT_REF} - uri: ${GIT_REPO_URL} - dockerfile: | - FROM docker-remote.artifacts.developer.gov.bc.ca/python:3.8.5-buster - USER root - - # Create working directory - RUN mkdir /opt/app-root && chmod 755 /opt/app-root - WORKDIR /opt/app-root - - # Install the requirements - COPY ./requirements.txt . - - RUN pip install --upgrade pip - RUN pip install --no-cache-dir -r requirements.txt - - COPY . . - - RUN pip install . - - USER 1001 - - # Set Python path - ENV PYTHONPATH=/opt/app-root/src - - #EXPOSE 8080 - - CMD [ "python", "/opt/app-root/app.py" ] - - type: Git - strategy: - type: Docker - dockerStrategy: - pullSecret: - name: artifactory-creds - - triggers: - - type: ConfigChange -parameters: -- description: | - The name assigned to all of the objects defined in this template. - You should keep this as default unless your know what your doing. - displayName: Name - name: NAME - required: true - value: account-mailer -- description: | - The URL to your GIT repo, don't use the this default unless - your just experimenting. - displayName: Git Repo URL - name: GIT_REPO_URL - required: true - value: https://github.com/bcgov/sbc-auth.git -- description: The git reference or branch. - displayName: Git Reference - name: GIT_REF - required: true - value: development -- description: The source context directory. - displayName: Source Context Directory - name: SOURCE_CONTEXT_DIR - required: false - value: queue_services/account-mailer -- description: The tag given to the built image. - displayName: Output Image Tag - name: OUTPUT_IMAGE_TAG - required: true - value: latest -- description: The resources CPU limit (in cores) for this build. - displayName: Resources CPU Limit - name: CPU_LIMIT - required: true - value: "2" -- description: The resources Memory limit (in Mi, Gi, etc) for this build. - displayName: Resources Memory Limit - name: MEMORY_LIMIT - required: true - value: 2Gi -- description: The resources CPU request (in cores) for this build. - displayName: Resources CPU Request - name: CPU_REQUEST - required: true - value: "1" -- description: The resources Memory request (in Mi, Gi, etc) for this build. - displayName: Resources Memory Request - name: MEMORY_REQUEST - required: true - value: 2Gi diff --git a/queue_services/account-mailer/openshift/templates/dc.yaml b/queue_services/account-mailer/openshift/templates/dc.yaml deleted file mode 100644 index 012a58594b..0000000000 --- a/queue_services/account-mailer/openshift/templates/dc.yaml +++ /dev/null @@ -1,175 +0,0 @@ ---- -kind: Template -apiVersion: v1 -metadata: - name: ${NAME}-${TAG}-deployment-template - annotations: - description: - Deployment template for an API application and connect to database. - tags: Flask - iconClass: icon-python -objects: - - kind: Service - apiVersion: v1 - metadata: - name: ${NAME}-${TAG} - labels: - name: ${NAME} - environment: ${TAG} - role: ${ROLE} - spec: - ports: - - name: ${NAME}-${TAG}-tcp - port: 8080 - targetPort: 8080 - selector: - name: ${NAME} - environment: ${TAG} - - - kind: DeploymentConfig - apiVersion: v1 - metadata: - name: ${NAME}-${TAG} - labels: - name: ${NAME} - environment: ${TAG} - role: ${ROLE} - annotations: - description: Defines how to deploy the application server - spec: - strategy: - rollingParams: - intervalSeconds: 1 - maxSurge: 25% - maxUnavailable: 25% - timeoutSeconds: 600 - updatePeriodSeconds: 1 - type: Rolling - triggers: - - type: ImageChange - imageChangeParams: - automatic: true - containerNames: - - ${NAME}-${TAG} - from: - kind: ImageStreamTag - namespace: ${NAMESPACE}-${IMAGE_NAMESPACE} - name: ${NAME}:${TAG} - replicas: 1 - selector: - name: ${NAME} - environment: ${TAG} - template: - metadata: - name: ${NAME}-${TAG} - labels: - name: ${NAME} - environment: ${TAG} - role: ${ROLE} - spec: - containers: - - name: ${NAME}-${TAG} - image: ${IMAGE_REGISTRY}/${NAMESPACE}-${IMAGE_NAMESPACE}/${NAME}:${TAG} - ports: - - containerPort: 8080 - protocol: TCP - readinessProbe: - initialDelaySeconds: 3 - timeoutSeconds: 30 - httpGet: - path: /readyz - port: 7070 - livenessProbe: - initialDelaySeconds: 120 - timeoutSeconds: 30 - httpGet: - path: /healthz - port: 7070 - - - kind: HorizontalPodAutoscaler - apiVersion: autoscaling/v1 - metadata: - name: ${NAME}-${TAG} - labels: - name: ${NAME} - environment: ${TAG} - role: ${ROLE} - spec: - scaleTargetRef: - kind: DeploymentConfig - name: ${NAME}-${TAG} - minReplicas: ${{MIN_REPLICAS}} - maxReplicas: ${{MAX_REPLICAS}} - -parameters: - - name: NAME - displayName: Name - description: The name assigned to all of the OpenShift resources associated to the server instance. - required: true - value: account-mailer - - - name: TAG - displayName: Environment TAG name - description: The TAG name for this environment, e.g., dev, test, prod - value: dev - required: true - - - name: ROLE - displayName: Role - description: Role - required: true - value: queue - - - name: NAMESPACE - displayName: Namespace Name - description: The base namespace name for the project. - required: true - value: 6e0e49 - - - name: IMAGE_NAMESPACE - displayName: Image Namespace - required: true - description: The namespace of the OpenShift project containing the imagestream for the application. - value: tools - - - name: IMAGE_REGISTRY - displayName: Image Registry - required: true - description: The image registry of the OpenShift project. - value: image-registry.openshift-image-registry.svc:5000 - - - name: MIN_REPLICAS - displayName: Minimum Replicas - description: The minimum number of pods to have running. - required: true - value: "1" - - - name: MAX_REPLICAS - displayName: Maximum Replicas - description: The maximum number of pods to have running. - required: true - value: "1" - - - name: CPU_REQUEST - displayName: Resources CPU Request - description: The resources CPU request (in cores) for this build. - required: true - value: 10m - - - name: CPU_LIMIT - displayName: Resources CPU Limit - description: The resources CPU limit (in cores) for this build. - required: true - value: 500m - - - name: MEMORY_REQUEST - displayName: Resources Memory Request - description: The resources Memory request (in Mi, Gi, etc) for this build. - required: true - value: 10Mi - - - name: MEMORY_LIMIT - displayName: Resources Memory Limit - description: The resources Memory limit (in Mi, Gi, etc) for this build. - required: true - value: 1Gi diff --git a/queue_services/account-mailer/poetry.lock b/queue_services/account-mailer/poetry.lock index 1869223080..415b9307fc 100644 --- a/queue_services/account-mailer/poetry.lock +++ b/queue_services/account-mailer/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "aiofiles" @@ -6,6 +6,7 @@ version = "24.1.0" description = "File support for asyncio." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, @@ -13,98 +14,105 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.4" +version = "2.6.1" description = "Happy Eyeballs for asyncio" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, - {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, + {file = "aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8"}, + {file = "aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558"}, ] [[package]] name = "aiohttp" -version = "3.11.11" +version = "3.11.14" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" -files = [ - {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, - {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, - {file = "aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c"}, - {file = "aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745"}, - {file = "aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773"}, - {file = "aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62"}, - {file = "aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, - {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, - {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5"}, - {file = "aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d"}, - {file = "aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226"}, - {file = "aiohttp-3.11.11-cp39-cp39-win32.whl", hash = "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3"}, - {file = "aiohttp-3.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1"}, - {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, +groups = ["main"] +files = [ + {file = "aiohttp-3.11.14-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e2bc827c01f75803de77b134afdbf74fa74b62970eafdf190f3244931d7a5c0d"}, + {file = "aiohttp-3.11.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e365034c5cf6cf74f57420b57682ea79e19eb29033399dd3f40de4d0171998fa"}, + {file = "aiohttp-3.11.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c32593ead1a8c6aabd58f9d7ee706e48beac796bb0cb71d6b60f2c1056f0a65f"}, + {file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4e7c7ec4146a94a307ca4f112802a8e26d969018fabed526efc340d21d3e7d0"}, + {file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8b2df9feac55043759aa89f722a967d977d80f8b5865a4153fc41c93b957efc"}, + {file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7571f99525c76a6280f5fe8e194eeb8cb4da55586c3c61c59c33a33f10cfce7"}, + {file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b59d096b5537ec7c85954cb97d821aae35cfccce3357a2cafe85660cc6295628"}, + {file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b42dbd097abb44b3f1156b4bf978ec5853840802d6eee2784857be11ee82c6a0"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b05774864c87210c531b48dfeb2f7659407c2dda8643104fb4ae5e2c311d12d9"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4e2e8ef37d4bc110917d038807ee3af82700a93ab2ba5687afae5271b8bc50ff"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e9faafa74dbb906b2b6f3eb9942352e9e9db8d583ffed4be618a89bd71a4e914"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7e7abe865504f41b10777ac162c727af14e9f4db9262e3ed8254179053f63e6d"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4848ae31ad44330b30f16c71e4f586cd5402a846b11264c412de99fa768f00f3"}, + {file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d0b46abee5b5737cb479cc9139b29f010a37b1875ee56d142aefc10686a390b"}, + {file = "aiohttp-3.11.14-cp310-cp310-win32.whl", hash = "sha256:a0d2c04a623ab83963576548ce098baf711a18e2c32c542b62322a0b4584b990"}, + {file = "aiohttp-3.11.14-cp310-cp310-win_amd64.whl", hash = "sha256:5409a59d5057f2386bb8b8f8bbcfb6e15505cedd8b2445db510563b5d7ea1186"}, + {file = "aiohttp-3.11.14-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f296d637a50bb15fb6a229fbb0eb053080e703b53dbfe55b1e4bb1c5ed25d325"}, + {file = "aiohttp-3.11.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ec6cd1954ca2bbf0970f531a628da1b1338f594bf5da7e361e19ba163ecc4f3b"}, + {file = "aiohttp-3.11.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:572def4aad0a4775af66d5a2b5923c7de0820ecaeeb7987dcbccda2a735a993f"}, + {file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c68e41c4d576cd6aa6c6d2eddfb32b2acfb07ebfbb4f9da991da26633a3db1a"}, + {file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b8bbfc8111826aa8363442c0fc1f5751456b008737ff053570f06a151650b3"}, + {file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b0a200e85da5c966277a402736a96457b882360aa15416bf104ca81e6f5807b"}, + {file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173c0ac508a2175f7c9a115a50db5fd3e35190d96fdd1a17f9cb10a6ab09aa1"}, + {file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:413fe39fd929329f697f41ad67936f379cba06fcd4c462b62e5b0f8061ee4a77"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65c75b14ee74e8eeff2886321e76188cbe938d18c85cff349d948430179ad02c"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:321238a42ed463848f06e291c4bbfb3d15ba5a79221a82c502da3e23d7525d06"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:59a05cdc636431f7ce843c7c2f04772437dd816a5289f16440b19441be6511f1"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:daf20d9c3b12ae0fdf15ed92235e190f8284945563c4b8ad95b2d7a31f331cd3"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:05582cb2d156ac7506e68b5eac83179faedad74522ed88f88e5861b78740dc0e"}, + {file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:12c5869e7ddf6b4b1f2109702b3cd7515667b437da90a5a4a50ba1354fe41881"}, + {file = "aiohttp-3.11.14-cp311-cp311-win32.whl", hash = "sha256:92868f6512714efd4a6d6cb2bfc4903b997b36b97baea85f744229f18d12755e"}, + {file = "aiohttp-3.11.14-cp311-cp311-win_amd64.whl", hash = "sha256:bccd2cb7aa5a3bfada72681bdb91637094d81639e116eac368f8b3874620a654"}, + {file = "aiohttp-3.11.14-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:70ab0f61c1a73d3e0342cedd9a7321425c27a7067bebeeacd509f96695b875fc"}, + {file = "aiohttp-3.11.14-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:602d4db80daf4497de93cb1ce00b8fc79969c0a7cf5b67bec96fa939268d806a"}, + {file = "aiohttp-3.11.14-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a8a0d127c10b8d89e69bbd3430da0f73946d839e65fec00ae48ca7916a31948"}, + {file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9f835cdfedcb3f5947304e85b8ca3ace31eef6346d8027a97f4de5fb687534"}, + {file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aa5c68e1e68fff7cd3142288101deb4316b51f03d50c92de6ea5ce646e6c71f"}, + {file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b512f1de1c688f88dbe1b8bb1283f7fbeb7a2b2b26e743bb2193cbadfa6f307"}, + {file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc9253069158d57e27d47a8453d8a2c5a370dc461374111b5184cf2f147a3cc3"}, + {file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b2501f1b981e70932b4a552fc9b3c942991c7ae429ea117e8fba57718cdeed0"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:28a3d083819741592685762d51d789e6155411277050d08066537c5edc4066e6"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0df3788187559c262922846087e36228b75987f3ae31dd0a1e5ee1034090d42f"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e73fa341d8b308bb799cf0ab6f55fc0461d27a9fa3e4582755a3d81a6af8c09"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51ba80d473eb780a329d73ac8afa44aa71dfb521693ccea1dea8b9b5c4df45ce"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8d1dd75aa4d855c7debaf1ef830ff2dfcc33f893c7db0af2423ee761ebffd22b"}, + {file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41cf0cefd9e7b5c646c2ef529c8335e7eafd326f444cc1cdb0c47b6bc836f9be"}, + {file = "aiohttp-3.11.14-cp312-cp312-win32.whl", hash = "sha256:948abc8952aff63de7b2c83bfe3f211c727da3a33c3a5866a0e2cf1ee1aa950f"}, + {file = "aiohttp-3.11.14-cp312-cp312-win_amd64.whl", hash = "sha256:3b420d076a46f41ea48e5fcccb996f517af0d406267e31e6716f480a3d50d65c"}, + {file = "aiohttp-3.11.14-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d14e274828561db91e4178f0057a915f3af1757b94c2ca283cb34cbb6e00b50"}, + {file = "aiohttp-3.11.14-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f30fc72daf85486cdcdfc3f5e0aea9255493ef499e31582b34abadbfaafb0965"}, + {file = "aiohttp-3.11.14-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4edcbe34e6dba0136e4cabf7568f5a434d89cc9de5d5155371acda275353d228"}, + {file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a7169ded15505f55a87f8f0812c94c9412623c744227b9e51083a72a48b68a5"}, + {file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad1f2fb9fe9b585ea4b436d6e998e71b50d2b087b694ab277b30e060c434e5db"}, + {file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20412c7cc3720e47a47e63c0005f78c0c2370020f9f4770d7fc0075f397a9fb0"}, + {file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dd9766da617855f7e85f27d2bf9a565ace04ba7c387323cd3e651ac4329db91"}, + {file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:599b66582f7276ebefbaa38adf37585e636b6a7a73382eb412f7bc0fc55fb73d"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b41693b7388324b80f9acfabd479bd1c84f0bc7e8f17bab4ecd9675e9ff9c734"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:86135c32d06927339c8c5e64f96e4eee8825d928374b9b71a3c42379d7437058"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:04eb541ce1e03edc1e3be1917a0f45ac703e913c21a940111df73a2c2db11d73"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dc311634f6f28661a76cbc1c28ecf3b3a70a8edd67b69288ab7ca91058eb5a33"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69bb252bfdca385ccabfd55f4cd740d421dd8c8ad438ded9637d81c228d0da49"}, + {file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2b86efe23684b58a88e530c4ab5b20145f102916bbb2d82942cafec7bd36a647"}, + {file = "aiohttp-3.11.14-cp313-cp313-win32.whl", hash = "sha256:b9c60d1de973ca94af02053d9b5111c4fbf97158e139b14f1be68337be267be6"}, + {file = "aiohttp-3.11.14-cp313-cp313-win_amd64.whl", hash = "sha256:0a29be28e60e5610d2437b5b2fed61d6f3dcde898b57fb048aa5079271e7f6f3"}, + {file = "aiohttp-3.11.14-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:14fc03508359334edc76d35b2821832f092c8f092e4b356e74e38419dfe7b6de"}, + {file = "aiohttp-3.11.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92007c89a8cb7be35befa2732b0b32bf3a394c1b22ef2dff0ef12537d98a7bda"}, + {file = "aiohttp-3.11.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6d3986112e34eaa36e280dc8286b9dd4cc1a5bcf328a7f147453e188f6fe148f"}, + {file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:749f1eb10e51dbbcdba9df2ef457ec060554842eea4d23874a3e26495f9e87b1"}, + {file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:781c8bd423dcc4641298c8c5a2a125c8b1c31e11f828e8d35c1d3a722af4c15a"}, + {file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:997b57e38aa7dc6caab843c5e042ab557bc83a2f91b7bd302e3c3aebbb9042a1"}, + {file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a8b0321e40a833e381d127be993b7349d1564b756910b28b5f6588a159afef3"}, + {file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8778620396e554b758b59773ab29c03b55047841d8894c5e335f12bfc45ebd28"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e906da0f2bcbf9b26cc2b144929e88cb3bf943dd1942b4e5af066056875c7618"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:87f0e003fb4dd5810c7fbf47a1239eaa34cd929ef160e0a54c570883125c4831"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7f2dadece8b85596ac3ab1ec04b00694bdd62abc31e5618f524648d18d9dd7fa"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:fe846f0a98aa9913c2852b630cd39b4098f296e0907dd05f6c7b30d911afa4c3"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ced66c5c6ad5bcaf9be54560398654779ec1c3695f1a9cf0ae5e3606694a000a"}, + {file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a40087b82f83bd671cbeb5f582c233d196e9653220404a798798bfc0ee189fff"}, + {file = "aiohttp-3.11.14-cp39-cp39-win32.whl", hash = "sha256:95d7787f2bcbf7cb46823036a8d64ccfbc2ffc7d52016b4044d901abceeba3db"}, + {file = "aiohttp-3.11.14-cp39-cp39-win_amd64.whl", hash = "sha256:22a8107896877212130c58f74e64b77f7007cb03cea8698be317272643602d45"}, + {file = "aiohttp-3.11.14.tar.gz", hash = "sha256:d6edc538c7480fa0a3b2bdd705f8010062d74700198da55d16498e1b49549b9c"}, ] [package.dependencies] @@ -117,7 +125,7 @@ propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""] [[package]] name = "aiosignal" @@ -125,6 +133,7 @@ version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, @@ -135,22 +144,23 @@ frozenlist = ">=1.1.0" [[package]] name = "alembic" -version = "1.14.1" +version = "1.15.1" description = "A database migration tool for SQLAlchemy." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "alembic-1.14.1-py3-none-any.whl", hash = "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5"}, - {file = "alembic-1.14.1.tar.gz", hash = "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213"}, + {file = "alembic-1.15.1-py3-none-any.whl", hash = "sha256:197de710da4b3e91cf66a826a5b31b5d59a127ab41bd0fc42863e2902ce2bbbe"}, + {file = "alembic-1.15.1.tar.gz", hash = "sha256:e1a1c738577bca1f27e68728c910cd389b9a92152ff91d902da649c192e30c49"}, ] [package.dependencies] Mako = "*" -SQLAlchemy = ">=1.3.0" -typing-extensions = ">=4" +SQLAlchemy = ">=1.4.0" +typing-extensions = ">=4.12" [package.extras] -tz = ["backports.zoneinfo", "tzdata"] +tz = ["tzdata"] [[package]] name = "argon2-cffi" @@ -158,6 +168,7 @@ version = "23.1.0" description = "Argon2 for Python" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, @@ -178,6 +189,7 @@ version = "21.2.0" description = "Low-level CFFI bindings for Argon2" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, @@ -215,6 +227,7 @@ version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, @@ -226,6 +239,7 @@ version = "3.2.4" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "astroid-3.2.4-py3-none-any.whl", hash = "sha256:413658a61eeca6202a59231abb473f932038fbcbf1666587f66d482083413a25"}, {file = "astroid-3.2.4.tar.gz", hash = "sha256:0e14202810b30da1b735827f78f5157be2bbd4a7a59b7707ca0bfc2fb4c0063a"}, @@ -237,18 +251,19 @@ version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\""] [[package]] name = "auth-api" @@ -256,6 +271,7 @@ version = "3.0.6" description = "" optional = false python-versions = "^3.12" +groups = ["main"] files = [] develop = false @@ -288,41 +304,68 @@ sqlalchemy-utils = "^0.41.2" type = "git" url = "https://github.com/bcgov/sbc-auth.git" reference = "dependency_upgrades_p2" -resolved_reference = "b6e525630b83878263c1486aa54dfb1f231bc01e" +resolved_reference = "883845769d4f3f7749ca861a3038b539299dfeb5" subdirectory = "auth-api" [[package]] name = "bcrypt" -version = "4.2.1" +version = "4.3.0" description = "Modern password hashing for your software and your servers" optional = false -python-versions = ">=3.7" -files = [ - {file = "bcrypt-4.2.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:1340411a0894b7d3ef562fb233e4b6ed58add185228650942bdc885362f32c17"}, - {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ee315739bc8387aa36ff127afc99120ee452924e0df517a8f3e4c0187a0f5f"}, - {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dbd0747208912b1e4ce730c6725cb56c07ac734b3629b60d4398f082ea718ad"}, - {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:aaa2e285be097050dba798d537b6efd9b698aa88eef52ec98d23dcd6d7cf6fea"}, - {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:76d3e352b32f4eeb34703370e370997065d28a561e4a18afe4fef07249cb4396"}, - {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7703ede632dc945ed1172d6f24e9f30f27b1b1a067f32f68bf169c5f08d0425"}, - {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:89df2aea2c43be1e1fa066df5f86c8ce822ab70a30e4c210968669565c0f4685"}, - {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:04e56e3fe8308a88b77e0afd20bec516f74aecf391cdd6e374f15cbed32783d6"}, - {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cfdf3d7530c790432046c40cda41dfee8c83e29482e6a604f8930b9930e94139"}, - {file = "bcrypt-4.2.1-cp37-abi3-win32.whl", hash = "sha256:adadd36274510a01f33e6dc08f5824b97c9580583bd4487c564fc4617b328005"}, - {file = "bcrypt-4.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:8c458cd103e6c5d1d85cf600e546a639f234964d0228909d8f8dbeebff82d526"}, - {file = "bcrypt-4.2.1-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:8ad2f4528cbf0febe80e5a3a57d7a74e6635e41af1ea5675282a33d769fba413"}, - {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909faa1027900f2252a9ca5dfebd25fc0ef1417943824783d1c8418dd7d6df4a"}, - {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cde78d385d5e93ece5479a0a87f73cd6fa26b171c786a884f955e165032b262c"}, - {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:533e7f3bcf2f07caee7ad98124fab7499cb3333ba2274f7a36cf1daee7409d99"}, - {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:687cf30e6681eeda39548a93ce9bfbb300e48b4d445a43db4298d2474d2a1e54"}, - {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:041fa0155c9004eb98a232d54da05c0b41d4b8e66b6fc3cb71b4b3f6144ba837"}, - {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f85b1ffa09240c89aa2e1ae9f3b1c687104f7b2b9d2098da4e923f1b7082d331"}, - {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c6f5fa3775966cca251848d4d5393ab016b3afed251163c1436fefdec3b02c84"}, - {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:807261df60a8b1ccd13e6599c779014a362ae4e795f5c59747f60208daddd96d"}, - {file = "bcrypt-4.2.1-cp39-abi3-win32.whl", hash = "sha256:b588af02b89d9fad33e5f98f7838bf590d6d692df7153647724a7f20c186f6bf"}, - {file = "bcrypt-4.2.1-cp39-abi3-win_amd64.whl", hash = "sha256:e84e0e6f8e40a242b11bce56c313edc2be121cec3e0ec2d76fce01f6af33c07c"}, - {file = "bcrypt-4.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76132c176a6d9953cdc83c296aeaed65e1a708485fd55abf163e0d9f8f16ce0e"}, - {file = "bcrypt-4.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e158009a54c4c8bc91d5e0da80920d048f918c61a581f0a63e4e93bb556d362f"}, - {file = "bcrypt-4.2.1.tar.gz", hash = "sha256:6765386e3ab87f569b276988742039baab087b2cdb01e809d74e74503c2faafe"}, +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d"}, + {file = "bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4"}, + {file = "bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669"}, + {file = "bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304"}, + {file = "bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51"}, + {file = "bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62"}, + {file = "bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505"}, + {file = "bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a"}, + {file = "bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938"}, + {file = "bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18"}, ] [package.extras] @@ -335,6 +378,7 @@ version = "1.8.2" description = "Fast, simple object-to-object and broadcast signaling" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, @@ -346,6 +390,7 @@ version = "1.0.0" description = "common dependencies for all auth tools" optional = false python-versions = "^3.12" +groups = ["main"] files = [] develop = false @@ -371,8 +416,8 @@ Werkzeug = "^3.0.0" [package.source] type = "git" url = "https://github.com/bcgov/sbc-auth.git" -reference = "dependency_upgrades" -resolved_reference = "a202363e5dd2e3b4770b1666ce43960eb02f8e4d" +reference = "dependency_upgrades_p2" +resolved_reference = "883845769d4f3f7749ca861a3038b539299dfeb5" subdirectory = "build-deps" [[package]] @@ -381,6 +426,7 @@ version = "0.14.0" description = "httplib2 caching for requests" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0"}, {file = "cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938"}, @@ -401,6 +447,7 @@ version = "0.13.0" description = "A collection of cache libraries in the same API interface." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cachelib-0.13.0-py3-none-any.whl", hash = "sha256:8c8019e53b6302967d4e8329a504acf75e7bc46130291d30188a6e4e58162516"}, {file = "cachelib-0.13.0.tar.gz", hash = "sha256:209d8996e3c57595bee274ff97116d1d73c4980b2fd9a34c7846cd07fd2e1a48"}, @@ -412,6 +459,7 @@ version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, @@ -423,6 +471,7 @@ version = "23.2.3" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, @@ -435,7 +484,7 @@ attrs = ">=23.1.0" bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] -orjson = ["orjson (>=3.9.2)"] +orjson = ["orjson (>=3.9.2) ; implementation_name == \"cpython\""] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] ujson = ["ujson (>=5.7.0)"] @@ -446,6 +495,7 @@ version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -457,6 +507,7 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -536,6 +587,7 @@ version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, @@ -635,6 +687,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -645,13 +698,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "cloud-sql-python-connector" -version = "1.16.0" -description = "The Cloud SQL Python Connector is a library that can be used alongside a database driver to allow users with sufficient permissions to connect to a Cloud SQL database without having to manually allowlist IPs or manage SSL certificates." +version = "1.17.0" +description = "Google Cloud SQL Python Connector library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "cloud_sql_python_connector-1.16.0-py2.py3-none-any.whl", hash = "sha256:13dbe54a376824f30bbafefd5cd8265ee9f2f7faa26b337779060ee85a3b5ed6"}, - {file = "cloud_sql_python_connector-1.16.0.tar.gz", hash = "sha256:4082d305e22253affbc8f91f8b213a66f8dc26b3aa78169f1f79bbb5b6855188"}, + {file = "cloud_sql_python_connector-1.17.0-py3-none-any.whl", hash = "sha256:b83ab9a586baec0f5da4bf914773567ad2a50f2318ab05b0ca8266e282f6e94e"}, ] [package.dependencies] @@ -674,136 +727,145 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +markers = {main = "platform_system == \"Windows\"", dev = "sys_platform == \"win32\""} [[package]] name = "coverage" -version = "7.6.10" +version = "7.7.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" -files = [ - {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, - {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, - {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, - {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, - {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, - {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, - {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, - {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, - {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, - {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, - {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, - {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, - {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, - {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, - {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, - {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, - {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, - {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, - {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, - {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, - {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, - {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, - {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, - {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, - {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, - {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, -] - -[package.extras] -toml = ["tomli"] +groups = ["dev"] +files = [ + {file = "coverage-7.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a538a23119d1e2e2ce077e902d02ea3d8e0641786ef6e0faf11ce82324743944"}, + {file = "coverage-7.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1586ad158523f4133499a4f322b230e2cfef9cc724820dbd58595a5a236186f4"}, + {file = "coverage-7.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6c96d69928a3a6767fab8dc1ce8a02cf0156836ccb1e820c7f45a423570d98"}, + {file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f18d47641282664276977c604b5a261e51fefc2980f5271d547d706b06a837f"}, + {file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a1e18a85bd066c7c556d85277a7adf4651f259b2579113844835ba1a74aafd"}, + {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:70f0925c4e2bfc965369f417e7cc72538fd1ba91639cf1e4ef4b1a6b50439b3b"}, + {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b0fac2088ec4aaeb5468b814bd3ff5e5978364bfbce5e567c44c9e2854469f6c"}, + {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3e212a894d8ae07fde2ca8b43d666a6d49bbbddb10da0f6a74ca7bd31f20054"}, + {file = "coverage-7.7.0-cp310-cp310-win32.whl", hash = "sha256:f32b165bf6dfea0846a9c9c38b7e1d68f313956d60a15cde5d1709fddcaf3bee"}, + {file = "coverage-7.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:a2454b12a3f12cc4698f3508912e6225ec63682e2ca5a96f80a2b93cef9e63f3"}, + {file = "coverage-7.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a0a207c87a9f743c8072d059b4711f8d13c456eb42dac778a7d2e5d4f3c253a7"}, + {file = "coverage-7.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d673e3add00048215c2cc507f1228a7523fd8bf34f279ac98334c9b07bd2656"}, + {file = "coverage-7.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f81fe93dc1b8e5673f33443c0786c14b77e36f1025973b85e07c70353e46882b"}, + {file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8c7524779003d59948c51b4fcbf1ca4e27c26a7d75984f63488f3625c328b9b"}, + {file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c124025430249118d018dcedc8b7426f39373527c845093132196f2a483b6dd"}, + {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e7f559c36d5cdc448ee13e7e56ed7b6b5d44a40a511d584d388a0f5d940977ba"}, + {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:37cbc7b0d93dfd133e33c7ec01123fbb90401dce174c3b6661d8d36fb1e30608"}, + {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7d2a65876274acf544703e943c010b60bd79404e3623a1e5d52b64a6e2728de5"}, + {file = "coverage-7.7.0-cp311-cp311-win32.whl", hash = "sha256:f5a2f71d6a91238e7628f23538c26aa464d390cbdedf12ee2a7a0fb92a24482a"}, + {file = "coverage-7.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:ae8006772c6b0fa53c33747913473e064985dac4d65f77fd2fdc6474e7cd54e4"}, + {file = "coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94"}, + {file = "coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db"}, + {file = "coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe"}, + {file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8"}, + {file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135"}, + {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705"}, + {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0"}, + {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd"}, + {file = "coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d"}, + {file = "coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92"}, + {file = "coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072"}, + {file = "coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82"}, + {file = "coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa"}, + {file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f"}, + {file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265"}, + {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2"}, + {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d"}, + {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39"}, + {file = "coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68"}, + {file = "coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573"}, + {file = "coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322"}, + {file = "coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce"}, + {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816"}, + {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf"}, + {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57"}, + {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4"}, + {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c"}, + {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463"}, + {file = "coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90"}, + {file = "coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07"}, + {file = "coverage-7.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c8fbce80b2b8bf135d105aa8f5b36eae0c57d702a1cc3ebdea2a6f03f6cdde5"}, + {file = "coverage-7.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9710521f07f526de30ccdead67e6b236fe996d214e1a7fba8b36e2ba2cd8261"}, + {file = "coverage-7.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7789e700f33f2b133adae582c9f437523cd5db8de845774988a58c360fc88253"}, + {file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c36093aca722db73633cf2359026ed7782a239eb1c6db2abcff876012dc4cf"}, + {file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c075d167a6ec99b798c1fdf6e391a1d5a2d054caffe9593ba0f97e3df2c04f0e"}, + {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d013c07061751ae81861cae6ec3a4fe04e84781b11fd4b6b4201590234b25c7b"}, + {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:104bf640f408f4e115b85110047c7f27377e1a8b7ba86f7db4fa47aa49dc9a8e"}, + {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39abcacd1ed54e2c33c54bdc488b310e8ef6705833f7148b6eb9a547199d375d"}, + {file = "coverage-7.7.0-cp39-cp39-win32.whl", hash = "sha256:8e336b56301774ace6be0017ff85c3566c556d938359b61b840796a0202f805c"}, + {file = "coverage-7.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:8c938c6ae59be67ac19a7204e079efc94b38222cd7d0269f96e45e18cddeaa59"}, + {file = "coverage-7.7.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:3b0e6e54591ae0d7427def8a4d40fca99df6b899d10354bab73cd5609807261c"}, + {file = "coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a"}, + {file = "coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166"}, +] + +[package.extras] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "cryptography" -version = "44.0.1" +version = "44.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" -files = [ - {file = "cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0"}, - {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf"}, - {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864"}, - {file = "cryptography-44.0.1-cp37-abi3-win32.whl", hash = "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a"}, - {file = "cryptography-44.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00"}, - {file = "cryptography-44.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41"}, - {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b"}, - {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7"}, - {file = "cryptography-44.0.1-cp39-abi3-win32.whl", hash = "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9"}, - {file = "cryptography-44.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7"}, - {file = "cryptography-44.0.1.tar.gz", hash = "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14"}, +groups = ["main"] +files = [ + {file = "cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7"}, + {file = "cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79"}, + {file = "cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa"}, + {file = "cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4"}, + {file = "cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5"}, + {file = "cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390"}, + {file = "cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] +pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi (>=2024)", "cryptography-vectors (==44.0.1)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.2)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] @@ -812,6 +874,7 @@ version = "0.3.9" description = "serialize all of Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, @@ -827,6 +890,7 @@ version = "2.7.0" description = "DNS toolkit" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, @@ -847,6 +911,7 @@ version = "1.2.2" description = "Dictionary with auto-expiring values for caching purposes" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "expiringdict-1.2.2-py3-none-any.whl", hash = "sha256:09a5d20bc361163e6432a874edd3179676e935eb81b925eccef48d409a8a45e8"}, {file = "expiringdict-1.2.2.tar.gz", hash = "sha256:300fb92a7e98f15b05cf9a856c1415b3bc4f2e132be07daa326da6414c23ee09"}, @@ -861,6 +926,7 @@ version = "5.0.4" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.6.1" +groups = ["dev"] files = [ {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, @@ -877,6 +943,7 @@ version = "0.2.1" description = "A flake8 extension that checks for blind except: statements" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "flake8-blind-except-0.2.1.tar.gz", hash = "sha256:f25a575a9dcb3eeb3c760bf9c22db60b8b5a23120224ed1faa9a43f75dd7dd16"}, ] @@ -887,6 +954,7 @@ version = "4.1.2" description = "ipdb/pdb statement checker plugin for flake8" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "flake8-debugger-4.1.2.tar.gz", hash = "sha256:52b002560941e36d9bf806fca2523dc7fb8560a295d5f1a6e15ac2ded7a73840"}, {file = "flake8_debugger-4.1.2-py3-none-any.whl", hash = "sha256:0a5e55aeddcc81da631ad9c8c366e7318998f83ff00985a49e6b3ecf61e571bf"}, @@ -902,6 +970,7 @@ version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, @@ -913,18 +982,19 @@ pydocstyle = ">=2.1" [[package]] name = "flake8-isort" -version = "6.1.1" +version = "6.1.2" description = "flake8 plugin that integrates isort" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "flake8_isort-6.1.1-py3-none-any.whl", hash = "sha256:0fec4dc3a15aefbdbe4012e51d5531a2eb5fa8b981cdfbc882296a59b54ede12"}, - {file = "flake8_isort-6.1.1.tar.gz", hash = "sha256:c1f82f3cf06a80c13e1d09bfae460e9666255d5c780b859f19f8318d420370b3"}, + {file = "flake8_isort-6.1.2-py3-none-any.whl", hash = "sha256:549197dedf0273502fb74f04c080beed9e62a7eb70244610413d27052e78bd3b"}, + {file = "flake8_isort-6.1.2.tar.gz", hash = "sha256:9d0452acdf0e1cd6f2d6848e3605e66b54d920e73471fb4744eef0f93df62d5d"}, ] [package.dependencies] flake8 = "*" -isort = ">=5.0.0,<6" +isort = ">=5.0.0,<7" [package.extras] test = ["pytest"] @@ -935,6 +1005,7 @@ version = "5.0.0" description = "print statement checker plugin for flake8" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "flake8-print-5.0.0.tar.gz", hash = "sha256:76915a2a389cc1c0879636c219eb909c38501d3a43cc8dae542081c9ba48bdf9"}, {file = "flake8_print-5.0.0-py3-none-any.whl", hash = "sha256:84a1a6ea10d7056b804221ac5e62b1cee1aefc897ce16f2e5c42d3046068f5d8"}, @@ -944,12 +1015,30 @@ files = [ flake8 = ">=3.0" pycodestyle = "*" +[[package]] +name = "flake8-pyproject" +version = "1.2.3" +description = "Flake8 plug-in loading the configuration from pyproject.toml" +optional = false +python-versions = ">= 3.6" +groups = ["dev"] +files = [ + {file = "flake8_pyproject-1.2.3-py3-none-any.whl", hash = "sha256:6249fe53545205af5e76837644dc80b4c10037e73a0e5db87ff562d75fb5bd4a"}, +] + +[package.dependencies] +Flake8 = ">=5" + +[package.extras] +dev = ["pyTest", "pyTest-cov"] + [[package]] name = "flake8-quotes" version = "3.4.0" description = "Flake8 lint for quotes." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "flake8-quotes-3.4.0.tar.gz", hash = "sha256:aad8492fb710a2d3eabe68c5f86a1428de650c8484127e14c43d0504ba30276c"}, ] @@ -964,6 +1053,7 @@ version = "3.0.2" description = "A simple framework for building complex web applications." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e"}, {file = "flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d"}, @@ -986,6 +1076,7 @@ version = "2.3.0" description = "Adds caching support to Flask applications." optional = false python-versions = ">=3.8" +groups = ["main"] files = [] develop = false @@ -997,21 +1088,23 @@ Flask = "*" type = "git" url = "https://github.com/pallets-eco/flask-caching.git" reference = "master" -resolved_reference = "494d49882537a6cbcfe3cb41c4df05ae8acf60ce" +resolved_reference = "e59bc040cd47cd2b43e501d636d43d442c50b3ff" [[package]] name = "flask-cors" -version = "5.0.0" -description = "A Flask extension adding a decorator for CORS support" +version = "5.0.1" +description = "A Flask extension simplifying CORS support" optional = false -python-versions = "*" +python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ - {file = "Flask_Cors-5.0.0-py2.py3-none-any.whl", hash = "sha256:b9e307d082a9261c100d8fb0ba909eec6a228ed1b60a8315fd85f783d61910bc"}, - {file = "flask_cors-5.0.0.tar.gz", hash = "sha256:5aadb4b950c4e93745034594d9f3ea6591f734bb3662e16e255ffbf5e89c88ef"}, + {file = "flask_cors-5.0.1-py3-none-any.whl", hash = "sha256:fa5cb364ead54bbf401a26dbf03030c6b18fb2fcaf70408096a572b409586b0c"}, + {file = "flask_cors-5.0.1.tar.gz", hash = "sha256:6ccb38d16d6b72bbc156c1c3f192bc435bfcc3c2bc864b2df1eb9b2d97b2403c"}, ] [package.dependencies] -Flask = ">=0.9" +flask = ">=0.9" +Werkzeug = ">=0.7" [[package]] name = "flask-jwt-oidc" @@ -1019,6 +1112,7 @@ version = "0.8.1" description = "Opinionated flask oidc client" optional = false python-versions = ">=3.9,<4" +groups = ["main"] files = [] develop = false @@ -1041,6 +1135,7 @@ version = "0.10.0" description = "Flask extension for sending email" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask_mail-0.10.0-py3-none-any.whl", hash = "sha256:a451e490931bb3441d9b11ebab6812a16bfa81855792ae1bf9c1e1e22c4e51e7"}, {file = "flask_mail-0.10.0.tar.gz", hash = "sha256:44083e7b02bbcce792209c06252f8569dd5a325a7aaa76afe7330422bd97881d"}, @@ -1056,6 +1151,7 @@ version = "1.3.0" description = "Flask + marshmallow for beautiful APIs" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "flask_marshmallow-1.3.0-py3-none-any.whl", hash = "sha256:c0a0644b46406851873ab41c1e8a7de3ef27fa69b00b89bf630f1696ec0813a0"}, {file = "flask_marshmallow-1.3.0.tar.gz", hash = "sha256:27a35d0ce5dcba161cc5f2f4764afbc2536c93fa439a793250b827835e3f3be6"}, @@ -1077,6 +1173,7 @@ version = "4.1.0" description = "SQLAlchemy database migrations for Flask applications using Alembic." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "Flask_Migrate-4.1.0-py3-none-any.whl", hash = "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d"}, {file = "flask_migrate-4.1.0.tar.gz", hash = "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d"}, @@ -1097,6 +1194,7 @@ version = "1.0.6" description = "Formatting of dates and times in Flask templates using moment.js." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "Flask_Moment-1.0.6-py3-none-any.whl", hash = "sha256:3ae8baea20a41e99f457b9710ecd1368911dd5133f09a27583eb0dcb3491e31d"}, {file = "flask_moment-1.0.6.tar.gz", hash = "sha256:2f8969907cbacde4a88319792e8f920ba5c9dd9d99ced2346cad563795302b88"}, @@ -1115,6 +1213,7 @@ version = "1.1.0" description = "OpenTracing support for Flask applications" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "Flask-OpenTracing-1.1.0.tar.gz", hash = "sha256:a9a39d367fbe7e9ed9c77b90ac48159c1a3e82982a5abf84d3f4d710d24580ac"}, ] @@ -1132,6 +1231,7 @@ version = "3.1.1" description = "Add SQLAlchemy support to your Flask application." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask_sqlalchemy-3.1.1-py3-none-any.whl", hash = "sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0"}, {file = "flask_sqlalchemy-3.1.1.tar.gz", hash = "sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312"}, @@ -1147,6 +1247,7 @@ version = "1.5.1" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, @@ -1161,6 +1262,7 @@ version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, @@ -1262,6 +1364,7 @@ version = "0.3.0" description = "" optional = false python-versions = "^3.8" +groups = ["main"] files = [] develop = false @@ -1275,7 +1378,7 @@ simple-cloudevent = {git = "https://github.com/daxiom/simple-cloudevent.py.git"} type = "git" url = "https://github.com/bcgov/sbc-connect-common.git" reference = "main" -resolved_reference = "dcfd4fb0cc5d25a2d74f99cad8f6d661c1880117" +resolved_reference = "7f1cc0ea4a374310ac558ff435fa6b7ea7bb2f8b" subdirectory = "python/gcp-queue" [[package]] @@ -1284,6 +1387,7 @@ version = "1.34.1" description = "Google API client core library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google-api-core-1.34.1.tar.gz", hash = "sha256:3399c92887a97d33038baa4bfd3bf07acc05d474b0171f333e1f641c1364e552"}, {file = "google_api_core-1.34.1-py3-none-any.whl", hash = "sha256:52bcc9d9937735f8a3986fa0bbf9135ae9cf5393a722387e5eced520e39c774a"}, @@ -1308,6 +1412,7 @@ version = "2.28.2" description = "Google Authentication Library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google-auth-2.28.2.tar.gz", hash = "sha256:80b8b4969aa9ed5938c7828308f20f035bc79f9d8fb8120bf9dc8db20b41ba30"}, {file = "google_auth-2.28.2-py2.py3-none-any.whl", hash = "sha256:9fd67bbcd40f16d9d42f950228e9cf02a2ded4ae49198b27432d0cded5a74c38"}, @@ -1325,12 +1430,32 @@ pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] +[[package]] +name = "google-cloud-core" +version = "2.4.3" +description = "Google Cloud API client core library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_core-2.4.3-py2.py3-none-any.whl", hash = "sha256:5130f9f4c14b4fafdff75c79448f9495cfade0d8775facf1b09c3bf67e027f6e"}, + {file = "google_cloud_core-2.4.3.tar.gz", hash = "sha256:1fab62d7102844b278fe6dead3af32408b1df3eb06f5c7e8634cbd40edc4da53"}, +] + +[package.dependencies] +google-api-core = ">=1.31.6,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-auth = ">=1.25.0,<3.0dev" + +[package.extras] +grpc = ["grpcio (>=1.38.0,<2.0dev)", "grpcio-status (>=1.38.0,<2.0.dev0)"] + [[package]] name = "google-cloud-pubsub" version = "2.20.2" description = "Google Cloud Pub/Sub API client library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "google-cloud-pubsub-2.20.2.tar.gz", hash = "sha256:236046ea860230c788e4d4ea2d0f12299cdf1d94ac71ec42ed1a0ce1ba28d66f"}, {file = "google_cloud_pubsub-2.20.2-py2.py3-none-any.whl", hash = "sha256:9607bb8f973cbd123b5fa2db9c0aa38501a1a42f18593739067cd307263d090f"}, @@ -1348,12 +1473,101 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4 [package.extras] libcst = ["libcst (>=0.3.10)"] +[[package]] +name = "google-cloud-storage" +version = "2.14.0" +description = "Google Cloud Storage API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google-cloud-storage-2.14.0.tar.gz", hash = "sha256:2d23fcf59b55e7b45336729c148bb1c464468c69d5efbaee30f7201dd90eb97e"}, + {file = "google_cloud_storage-2.14.0-py2.py3-none-any.whl", hash = "sha256:8641243bbf2a2042c16a6399551fbb13f062cbc9a2de38d6c0bb5426962e9dbd"}, +] + +[package.dependencies] +google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-auth = ">=2.23.3,<3.0dev" +google-cloud-core = ">=2.3.0,<3.0dev" +google-crc32c = ">=1.0,<2.0dev" +google-resumable-media = ">=2.6.0" +requests = ">=2.18.0,<3.0.0dev" + +[package.extras] +protobuf = ["protobuf (<5.0.0dev)"] + +[[package]] +name = "google-crc32c" +version = "1.7.0" +description = "A python wrapper of the C library 'Google CRC32C'" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "google_crc32c-1.7.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:18f1dfc6baeb3b28b1537d54b3622363352f75fcb2d4b6ffcc37584fe431f122"}, + {file = "google_crc32c-1.7.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:732378dc4ca08953eac0d13d1c312d99a54d5b483c90b4a5a536132669ed1c24"}, + {file = "google_crc32c-1.7.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14fdac94aa60d5794652f8ea6c2fcc532032e31f9050698b7ecdc6d4c3a61784"}, + {file = "google_crc32c-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bc14187a7fe5c61024c0dd1b578d7f9391df55459bf373c07f66426e09353b6"}, + {file = "google_crc32c-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54af59a98a427d0f98b6b0446df52ad286948ab7745da80a1edeb32ad633b3ae"}, + {file = "google_crc32c-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:2515aa89e46c6fa99190ec29bf27f33457ff98e5ca5c6c05602f74e0fb005752"}, + {file = "google_crc32c-1.7.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:96e33b249776f5aa7017a494b78994cf3cc8461291d460b46e75f6bc6cc40dc8"}, + {file = "google_crc32c-1.7.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:c2dc799827990dd06b777067e27f57c2a552ddde4c4cd2d883b1b615ee92f9cf"}, + {file = "google_crc32c-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c29f7718f48e32810a41b17126e0ca588a0ae6158b4da2926d8074241a155d"}, + {file = "google_crc32c-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f30548e65291a4658c9e56f6f516159663f2b4a2c991b9af5846f0084ea25d4"}, + {file = "google_crc32c-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:9754f9eaa5ff82166512908f02745d5e883650d7b04d1732b5df3335986ad359"}, + {file = "google_crc32c-1.7.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:11b3b2f16a534c76ce3c9503800c7c2578c13a56e8e409eac273330e25b5c521"}, + {file = "google_crc32c-1.7.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:fd3afea81a7c7b95f98c065edc5a0fdb58f1fea5960e166962b142ec037fe5e0"}, + {file = "google_crc32c-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d07ad3ff51f26cef5bbad66622004eca3639271230cfc2443845ec4650e1c57"}, + {file = "google_crc32c-1.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af6e80f83d882b247eef2c0366ec72b1ffb89433b9f35dc621d79190840f1ea6"}, + {file = "google_crc32c-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:10721764a9434546b7961194fbb1f80efbcaf45b8498ed379d64f8891d4c155b"}, + {file = "google_crc32c-1.7.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:76bb19d182b999f9c9d580b1d7ab6e9334ab23dd669bf91f501812103408c85b"}, + {file = "google_crc32c-1.7.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:6a40522958040051c755a173eb98c05ad4d64a6dd898888c3e5ccca2d1cbdcdc"}, + {file = "google_crc32c-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f714fe5cdf5007d7064c57cf7471a99e0cbafda24ddfa829117fc3baafa424f7"}, + {file = "google_crc32c-1.7.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f04e58dbe1bf0c9398e603a9be5aaa09e0ba7eb022a3293195d8749459a01069"}, + {file = "google_crc32c-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:364067b063664dd8d1fec75a3fe85edf05c46f688365269beccaf42ef5dfe889"}, + {file = "google_crc32c-1.7.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1b0d6044799f6ac51d1cc2decb997280a83c448b3bef517a54b57a3b71921c0"}, + {file = "google_crc32c-1.7.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:02bc3295d26cd7666521fd6d5b7b93923ae1eb4417ddd3bc57185a5881ad7b96"}, + {file = "google_crc32c-1.7.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:807503eedd7bf9bfded2776e0bcd0b017998f45b8b1e813cde3b9bf8f7593313"}, + {file = "google_crc32c-1.7.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ff62f4959fabc8e5e90af920cc2fb0a9ccf1e74fd6da8a56d8ef04a600a68f97"}, + {file = "google_crc32c-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2daec556d537b07af25fa3f91841f022dd6869a648ca4aea1add56f87b80647"}, + {file = "google_crc32c-1.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dc17abb62bd7c7a33da307f24ae05cd6e36c24e847a67e3e2165cba23a06dd4"}, + {file = "google_crc32c-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:a79f7e486756385c4309d7815ede53a72f6cbab12ddf140c5f5b335caf08edfb"}, + {file = "google_crc32c-1.7.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8f48dddd1451026a517d7eb1f8c4ee2491998bfa383abb5fdebf32b0aa333e"}, + {file = "google_crc32c-1.7.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60f89e06ce462a65dd4d14a97bd29d92730713316b8b89720f9b2bb1aef270f7"}, + {file = "google_crc32c-1.7.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1277c27428a6cc89a51f5afbc04b81fae0288fb631117383f0de4f2bf78ffad6"}, + {file = "google_crc32c-1.7.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:731921158ef113bf157b8e65f13303d627fb540f173a410260f2fb7570af644c"}, + {file = "google_crc32c-1.7.0.tar.gz", hash = "sha256:c8c15a04b290c7556f277acc55ad98503a8bc0893ea6860fd5b5d210f3f558ce"}, +] + +[package.extras] +testing = ["pytest"] + +[[package]] +name = "google-resumable-media" +version = "2.7.2" +description = "Utilities for Google Media Downloads and Resumable Uploads" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_resumable_media-2.7.2-py2.py3-none-any.whl", hash = "sha256:3ce7551e9fe6d99e9a126101d2536612bb73486721951e9562fee0f90c6ababa"}, + {file = "google_resumable_media-2.7.2.tar.gz", hash = "sha256:5280aed4629f2b60b847b0d42f9857fd4935c11af266744df33d8074cae92fe0"}, +] + +[package.dependencies] +google-crc32c = ">=1.0,<2.0dev" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "google-auth (>=1.22.0,<2.0dev)"] +requests = ["requests (>=2.18.0,<3.0.0dev)"] + [[package]] name = "googleapis-common-protos" version = "1.63.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "googleapis-common-protos-1.63.0.tar.gz", hash = "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e"}, {file = "googleapis_common_protos-1.63.0-py2.py3-none-any.whl", hash = "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632"}, @@ -1372,6 +1586,8 @@ version = "3.1.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" files = [ {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, @@ -1458,6 +1674,7 @@ version = "0.13.0" description = "IAM API client library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "grpc-google-iam-v1-0.13.0.tar.gz", hash = "sha256:fad318608b9e093258fbf12529180f400d1c44453698a33509cc6ecf005b294e"}, {file = "grpc_google_iam_v1-0.13.0-py2.py3-none-any.whl", hash = "sha256:53902e2af7de8df8c1bd91373d9be55b0743ec267a7428ea638db3775becae89"}, @@ -1470,61 +1687,67 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [[package]] name = "grpcio" -version = "1.64.0" +version = "1.71.0" description = "HTTP/2-based RPC framework" optional = false -python-versions = ">=3.8" -files = [ - {file = "grpcio-1.64.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:3b09c3d9de95461214a11d82cc0e6a46a6f4e1f91834b50782f932895215e5db"}, - {file = "grpcio-1.64.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:7e013428ab472892830287dd082b7d129f4d8afef49227a28223a77337555eaa"}, - {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:02cc9cc3f816d30f7993d0d408043b4a7d6a02346d251694d8ab1f78cc723e7e"}, - {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f5de082d936e0208ce8db9095821361dfa97af8767a6607ae71425ac8ace15c"}, - {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b7bf346391dffa182fba42506adf3a84f4a718a05e445b37824136047686a1"}, - {file = "grpcio-1.64.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b2cbdfba18408389a1371f8c2af1659119e1831e5ed24c240cae9e27b4abc38d"}, - {file = "grpcio-1.64.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca4f15427d2df592e0c8f3d38847e25135e4092d7f70f02452c0e90d6a02d6d"}, - {file = "grpcio-1.64.0-cp310-cp310-win32.whl", hash = "sha256:7c1f5b2298244472bcda49b599be04579f26425af0fd80d3f2eb5fd8bc84d106"}, - {file = "grpcio-1.64.0-cp310-cp310-win_amd64.whl", hash = "sha256:73f84f9e5985a532e47880b3924867de16fa1aa513fff9b26106220c253c70c5"}, - {file = "grpcio-1.64.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2a18090371d138a57714ee9bffd6c9c9cb2e02ce42c681aac093ae1e7189ed21"}, - {file = "grpcio-1.64.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:59c68df3a934a586c3473d15956d23a618b8f05b5e7a3a904d40300e9c69cbf0"}, - {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:b52e1ec7185512103dd47d41cf34ea78e7a7361ba460187ddd2416b480e0938c"}, - {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d598b5d5e2c9115d7fb7e2cb5508d14286af506a75950762aa1372d60e41851"}, - {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01615bbcae6875eee8091e6b9414072f4e4b00d8b7e141f89635bdae7cf784e5"}, - {file = "grpcio-1.64.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0b2dfe6dcace264807d9123d483d4c43274e3f8c39f90ff51de538245d7a4145"}, - {file = "grpcio-1.64.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f17572dc9acd5e6dfd3014d10c0b533e9f79cd9517fc10b0225746f4c24b58e"}, - {file = "grpcio-1.64.0-cp311-cp311-win32.whl", hash = "sha256:6ec5ed15b4ffe56e2c6bc76af45e6b591c9be0224b3fb090adfb205c9012367d"}, - {file = "grpcio-1.64.0-cp311-cp311-win_amd64.whl", hash = "sha256:597191370951b477b7a1441e1aaa5cacebeb46a3b0bd240ec3bb2f28298c7553"}, - {file = "grpcio-1.64.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:1ce4cd5a61d4532651079e7aae0fedf9a80e613eed895d5b9743e66b52d15812"}, - {file = "grpcio-1.64.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:650a8150a9b288f40d5b7c1d5400cc11724eae50bd1f501a66e1ea949173649b"}, - {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:8de0399b983f8676a7ccfdd45e5b2caec74a7e3cc576c6b1eecf3b3680deda5e"}, - {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46b8b43ba6a2a8f3103f103f97996cad507bcfd72359af6516363c48793d5a7b"}, - {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a54362f03d4dcfae63be455d0a7d4c1403673498b92c6bfe22157d935b57c7a9"}, - {file = "grpcio-1.64.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1f8ea18b928e539046bb5f9c124d717fbf00cc4b2d960ae0b8468562846f5aa1"}, - {file = "grpcio-1.64.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c56c91bd2923ddb6e7ed28ebb66d15633b03e0df22206f22dfcdde08047e0a48"}, - {file = "grpcio-1.64.0-cp312-cp312-win32.whl", hash = "sha256:874c741c8a66f0834f653a69e7e64b4e67fcd4a8d40296919b93bab2ccc780ba"}, - {file = "grpcio-1.64.0-cp312-cp312-win_amd64.whl", hash = "sha256:0da1d921f8e4bcee307aeef6c7095eb26e617c471f8cb1c454fd389c5c296d1e"}, - {file = "grpcio-1.64.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:c46fb6bfca17bfc49f011eb53416e61472fa96caa0979b4329176bdd38cbbf2a"}, - {file = "grpcio-1.64.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3d2004e85cf5213995d09408501f82c8534700d2babeb81dfdba2a3bff0bb396"}, - {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:6d5541eb460d73a07418524fb64dcfe0adfbcd32e2dac0f8f90ce5b9dd6c046c"}, - {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f279ad72dd7d64412e10f2443f9f34872a938c67387863c4cd2fb837f53e7d2"}, - {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85fda90b81da25993aa47fae66cae747b921f8f6777550895fb62375b776a231"}, - {file = "grpcio-1.64.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a053584079b793a54bece4a7d1d1b5c0645bdbee729215cd433703dc2532f72b"}, - {file = "grpcio-1.64.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:579dd9fb11bc73f0de061cab5f8b2def21480fd99eb3743ed041ad6a1913ee2f"}, - {file = "grpcio-1.64.0-cp38-cp38-win32.whl", hash = "sha256:23b6887bb21d77649d022fa1859e05853fdc2e60682fd86c3db652a555a282e0"}, - {file = "grpcio-1.64.0-cp38-cp38-win_amd64.whl", hash = "sha256:753cb58683ba0c545306f4e17dabf468d29cb6f6b11832e1e432160bb3f8403c"}, - {file = "grpcio-1.64.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:2186d76a7e383e1466e0ea2b0febc343ffeae13928c63c6ec6826533c2d69590"}, - {file = "grpcio-1.64.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0f30596cdcbed3c98024fb4f1d91745146385b3f9fd10c9f2270cbfe2ed7ed91"}, - {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:d9171f025a196f5bcfec7e8e7ffb7c3535f7d60aecd3503f9e250296c7cfc150"}, - {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf4c8daed18ae2be2f1fc7d613a76ee2a2e28fdf2412d5c128be23144d28283d"}, - {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3550493ac1d23198d46dc9c9b24b411cef613798dc31160c7138568ec26bc9b4"}, - {file = "grpcio-1.64.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3161a8f8bb38077a6470508c1a7301cd54301c53b8a34bb83e3c9764874ecabd"}, - {file = "grpcio-1.64.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8fabe2cc57a369638ab1ad8e6043721014fdf9a13baa7c0e35995d3a4a7618"}, - {file = "grpcio-1.64.0-cp39-cp39-win32.whl", hash = "sha256:31890b24d47b62cc27da49a462efe3d02f3c120edb0e6c46dcc0025506acf004"}, - {file = "grpcio-1.64.0-cp39-cp39-win_amd64.whl", hash = "sha256:5a56797dea8c02e7d3a85dfea879f286175cf4d14fbd9ab3ef2477277b927baa"}, - {file = "grpcio-1.64.0.tar.gz", hash = "sha256:257baf07f53a571c215eebe9679c3058a313fd1d1f7c4eede5a8660108c52d9c"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.64.0)"] +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "grpcio-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:c200cb6f2393468142eb50ab19613229dcc7829b5ccee8b658a36005f6669fdd"}, + {file = "grpcio-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b2266862c5ad664a380fbbcdbdb8289d71464c42a8c29053820ee78ba0119e5d"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0ab8b2864396663a5b0b0d6d79495657ae85fa37dcb6498a2669d067c65c11ea"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c30f393f9d5ff00a71bb56de4aa75b8fe91b161aeb61d39528db6b768d7eac69"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f250ff44843d9a0615e350c77f890082102a0318d66a99540f54769c8766ab73"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6d8de076528f7c43a2f576bc311799f89d795aa6c9b637377cc2b1616473804"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9b91879d6da1605811ebc60d21ab6a7e4bae6c35f6b63a061d61eb818c8168f6"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f71574afdf944e6652203cd1badcda195b2a27d9c83e6d88dc1ce3cfb73b31a5"}, + {file = "grpcio-1.71.0-cp310-cp310-win32.whl", hash = "sha256:8997d6785e93308f277884ee6899ba63baafa0dfb4729748200fcc537858a509"}, + {file = "grpcio-1.71.0-cp310-cp310-win_amd64.whl", hash = "sha256:7d6ac9481d9d0d129224f6d5934d5832c4b1cddb96b59e7eba8416868909786a"}, + {file = "grpcio-1.71.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:d6aa986318c36508dc1d5001a3ff169a15b99b9f96ef5e98e13522c506b37eef"}, + {file = "grpcio-1.71.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:d2c170247315f2d7e5798a22358e982ad6eeb68fa20cf7a820bb74c11f0736e7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:e6f83a583ed0a5b08c5bc7a3fe860bb3c2eac1f03f1f63e0bc2091325605d2b7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be74ddeeb92cc87190e0e376dbc8fc7736dbb6d3d454f2fa1f5be1dee26b9d7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd0dfbe4d5eb1fcfec9490ca13f82b089a309dc3678e2edabc144051270a66e"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a2242d6950dc892afdf9e951ed7ff89473aaf744b7d5727ad56bdaace363722b"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0fa05ee31a20456b13ae49ad2e5d585265f71dd19fbd9ef983c28f926d45d0a7"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3d081e859fb1ebe176de33fc3adb26c7d46b8812f906042705346b314bde32c3"}, + {file = "grpcio-1.71.0-cp311-cp311-win32.whl", hash = "sha256:d6de81c9c00c8a23047136b11794b3584cdc1460ed7cbc10eada50614baa1444"}, + {file = "grpcio-1.71.0-cp311-cp311-win_amd64.whl", hash = "sha256:24e867651fc67717b6f896d5f0cac0ec863a8b5fb7d6441c2ab428f52c651c6b"}, + {file = "grpcio-1.71.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:0ff35c8d807c1c7531d3002be03221ff9ae15712b53ab46e2a0b4bb271f38537"}, + {file = "grpcio-1.71.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:b78a99cd1ece4be92ab7c07765a0b038194ded2e0a26fd654591ee136088d8d7"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc1a1231ed23caac1de9f943d031f1bc38d0f69d2a3b243ea0d664fc1fbd7fec"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6beeea5566092c5e3c4896c6d1d307fb46b1d4bdf3e70c8340b190a69198594"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5170929109450a2c031cfe87d6716f2fae39695ad5335d9106ae88cc32dc84c"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5b08d03ace7aca7b2fadd4baf291139b4a5f058805a8327bfe9aece7253b6d67"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f903017db76bf9cc2b2d8bdd37bf04b505bbccad6be8a81e1542206875d0e9db"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:469f42a0b410883185eab4689060a20488a1a0a00f8bbb3cbc1061197b4c5a79"}, + {file = "grpcio-1.71.0-cp312-cp312-win32.whl", hash = "sha256:ad9f30838550695b5eb302add33f21f7301b882937460dd24f24b3cc5a95067a"}, + {file = "grpcio-1.71.0-cp312-cp312-win_amd64.whl", hash = "sha256:652350609332de6dac4ece254e5d7e1ff834e203d6afb769601f286886f6f3a8"}, + {file = "grpcio-1.71.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:cebc1b34ba40a312ab480ccdb396ff3c529377a2fce72c45a741f7215bfe8379"}, + {file = "grpcio-1.71.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:85da336e3649a3d2171e82f696b5cad2c6231fdd5bad52616476235681bee5b3"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f9a412f55bb6e8f3bb000e020dbc1e709627dcb3a56f6431fa7076b4c1aab0db"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47be9584729534660416f6d2a3108aaeac1122f6b5bdbf9fd823e11fe6fbaa29"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9c80ac6091c916db81131d50926a93ab162a7e97e4428ffc186b6e80d6dda4"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:789d5e2a3a15419374b7b45cd680b1e83bbc1e52b9086e49308e2c0b5bbae6e3"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1be857615e26a86d7363e8a163fade914595c81fec962b3d514a4b1e8760467b"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a76d39b5fafd79ed604c4be0a869ec3581a172a707e2a8d7a4858cb05a5a7637"}, + {file = "grpcio-1.71.0-cp313-cp313-win32.whl", hash = "sha256:74258dce215cb1995083daa17b379a1a5a87d275387b7ffe137f1d5131e2cfbb"}, + {file = "grpcio-1.71.0-cp313-cp313-win_amd64.whl", hash = "sha256:22c3bc8d488c039a199f7a003a38cb7635db6656fa96437a8accde8322ce2366"}, + {file = "grpcio-1.71.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c6a0a28450c16809f94e0b5bfe52cabff63e7e4b97b44123ebf77f448534d07d"}, + {file = "grpcio-1.71.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:a371e6b6a5379d3692cc4ea1cb92754d2a47bdddeee755d3203d1f84ae08e03e"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:39983a9245d37394fd59de71e88c4b295eb510a3555e0a847d9965088cdbd033"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9182e0063112e55e74ee7584769ec5a0b4f18252c35787f48738627e23a62b97"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693bc706c031aeb848849b9d1c6b63ae6bcc64057984bb91a542332b75aa4c3d"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:20e8f653abd5ec606be69540f57289274c9ca503ed38388481e98fa396ed0b41"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8700a2a57771cc43ea295296330daaddc0d93c088f0a35cc969292b6db959bf3"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d35a95f05a8a2cbe8e02be137740138b3b2ea5f80bd004444e4f9a1ffc511e32"}, + {file = "grpcio-1.71.0-cp39-cp39-win32.whl", hash = "sha256:f9c30c464cb2ddfbc2ddf9400287701270fdc0f14be5f08a1e3939f1e749b455"}, + {file = "grpcio-1.71.0-cp39-cp39-win_amd64.whl", hash = "sha256:63e41b91032f298b3e973b3fa4093cbbc620c875e2da7b93e249d4728b54559a"}, + {file = "grpcio-1.71.0.tar.gz", hash = "sha256:2b85f7820475ad3edec209d3d89a7909ada16caab05d3f2e08a7e8ae3200a55c"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.71.0)"] [[package]] name = "grpcio-status" @@ -1532,6 +1755,7 @@ version = "1.48.2" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "grpcio-status-1.48.2.tar.gz", hash = "sha256:53695f45da07437b7c344ee4ef60d370fd2850179f5a28bb26d8e2aa1102ec11"}, {file = "grpcio_status-1.48.2-py3-none-any.whl", hash = "sha256:2c33bbdbe20188b2953f46f31af669263b6ee2a9b2d38fa0d36ee091532e21bf"}, @@ -1548,6 +1772,7 @@ version = "22.0.0" description = "WSGI HTTP Server for UNIX" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"}, {file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"}, @@ -1569,6 +1794,7 @@ version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, @@ -1580,6 +1806,7 @@ version = "5.13.0" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "importlib_resources-5.13.0-py3-none-any.whl", hash = "sha256:9f7bd0c97b79972a6cce36a366356d16d5e13b09679c11a58f1014bfdf8e64b2"}, {file = "importlib_resources-5.13.0.tar.gz", hash = "sha256:82d5c6cca930697dbbd86c93333bb2c2e72861d4789a11c2662b933e5ad2b528"}, @@ -1587,17 +1814,18 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-ruff"] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["dev"] files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] @@ -1606,6 +1834,7 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -1620,6 +1849,7 @@ version = "2.1.2" description = "Safely pass data to untrusted environments and back." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, @@ -1631,6 +1861,7 @@ version = "4.8.0" description = "Jaeger Python OpenTracing Tracer implementation" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"}, ] @@ -1646,13 +1877,14 @@ tests = ["codecov", "coverage", "flake8", "flake8-quotes", "flake8-typing-import [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -1667,6 +1899,7 @@ version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, @@ -1682,13 +1915,14 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "launchdarkly-eventsource" -version = "1.2.1" +version = "1.2.2" description = "LaunchDarkly SSE Client" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "launchdarkly_eventsource-1.2.1-py3-none-any.whl", hash = "sha256:0fa935b7692555455ac8b44b845cdc16738bd9b2e9ce89ee19b3f8b4adafe3f1"}, - {file = "launchdarkly_eventsource-1.2.1.tar.gz", hash = "sha256:99c29fa9a570aa8d49c9804bcc401028cab8a8954ccbf4a68c3116933301ec33"}, + {file = "launchdarkly_eventsource-1.2.2-py3-none-any.whl", hash = "sha256:3c47c1ce77418d978ca4753bc3ff61eaf5c4191088376c0584c70d1571eb2aaf"}, + {file = "launchdarkly_eventsource-1.2.2.tar.gz", hash = "sha256:6f7cc74c1dc01ac3fe1cec09d71a7f46c2da92ab3051c0d3406d90311a64d963"}, ] [package.dependencies] @@ -1700,6 +1934,7 @@ version = "9.5.0" description = "LaunchDarkly SDK for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "launchdarkly_server_sdk-9.5.0-py3-none-any.whl", hash = "sha256:bf2cf213f9eb71cd43d5f20f2ac9ec9235c693036459e5038a69015a6648c035"}, {file = "launchdarkly_server_sdk-9.5.0.tar.gz", hash = "sha256:af64d985621a03257107210266c563c5e268ca8320d1d71b5c18d9592d14fef7"}, @@ -1725,6 +1960,7 @@ version = "1.0.0" description = "Pytest testing utilities with docker containers." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "lovely_pytest_docker-1.0.0.tar.gz", hash = "sha256:7283abfe400c31ecc7155f9338c6f5af476f2ab506e1aadb9f7e9a5005e491d6"}, ] @@ -1735,13 +1971,14 @@ six = "*" [[package]] name = "mako" -version = "1.3.8" +version = "1.3.9" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627"}, - {file = "mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8"}, + {file = "Mako-1.3.9-py3-none-any.whl", hash = "sha256:95920acccb578427a9aa38e37a186b1e43156c87260d7ba18ca63aa4c7cbd3a1"}, + {file = "mako-1.3.9.tar.gz", hash = "sha256:b5d65ff3462870feec922dbccf38f6efb44e5714d7b593a656be86663d8600ac"}, ] [package.dependencies] @@ -1758,6 +1995,7 @@ version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, @@ -1803,13 +2041,14 @@ files = [ [[package]] name = "marshmallow" -version = "3.26.0" +version = "3.26.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "marshmallow-3.26.0-py3-none-any.whl", hash = "sha256:1287bca04e6a5f4094822ac153c03da5e214a0a60bcd557b140f3e66991b8ca1"}, - {file = "marshmallow-3.26.0.tar.gz", hash = "sha256:eb36762a1cc76d7abf831e18a3a1b26d3d481bbc74581b8e532a3d3a8115e1cb"}, + {file = "marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c"}, + {file = "marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6"}, ] [package.dependencies] @@ -1822,13 +2061,14 @@ tests = ["pytest", "simplejson"] [[package]] name = "marshmallow-sqlalchemy" -version = "1.4.0" +version = "1.4.1" description = "SQLAlchemy integration with the marshmallow (de)serialization library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "marshmallow_sqlalchemy-1.4.0-py3-none-any.whl", hash = "sha256:92f389f95f21f6038e5e8be16e6fb89a1d0e25e2fe6ba661fa34b955fac20422"}, - {file = "marshmallow_sqlalchemy-1.4.0.tar.gz", hash = "sha256:ca169a26171077af8afa25789e9781680de0e9187563c422f1f67d0a0133433a"}, + {file = "marshmallow_sqlalchemy-1.4.1-py3-none-any.whl", hash = "sha256:9a3dd88a2b24f425fbffb3fea8aeb7f424a932fc97372a9f1338b7a379396191"}, + {file = "marshmallow_sqlalchemy-1.4.1.tar.gz", hash = "sha256:b4aa964356d00e178bdb8469a28daa9022b375ff4f5c04f8e2b9aafe1e65c529"}, ] [package.dependencies] @@ -1846,6 +2086,7 @@ version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -1857,6 +2098,7 @@ version = "7.2.15" description = "MinIO Python SDK for Amazon S3 Compatible Cloud Storage" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "minio-7.2.15-py3-none-any.whl", hash = "sha256:c06ef7a43e5d67107067f77b6c07ebdd68733e5aa7eed03076472410ca19d876"}, {file = "minio-7.2.15.tar.gz", hash = "sha256:5247df5d4dca7bfa4c9b20093acd5ad43e82d8710ceb059d79c6eea970f49f79"}, @@ -1875,6 +2117,7 @@ version = "1.0.8" description = "MessagePack serializer" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, @@ -1936,103 +2179,104 @@ files = [ [[package]] name = "multidict" -version = "6.1.0" +version = "6.2.0" description = "multidict implementation" optional = false -python-versions = ">=3.8" -files = [ - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, - {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, - {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, - {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, - {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, - {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, - {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6"}, - {file = "multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81"}, - {file = "multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd"}, - {file = "multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167"}, - {file = "multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43"}, - {file = "multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada"}, - {file = "multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a"}, - {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, - {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "multidict-6.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b9f6392d98c0bd70676ae41474e2eecf4c7150cb419237a41f8f96043fcb81d1"}, + {file = "multidict-6.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3501621d5e86f1a88521ea65d5cad0a0834c77b26f193747615b7c911e5422d2"}, + {file = "multidict-6.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32ed748ff9ac682eae7859790d3044b50e3076c7d80e17a44239683769ff485e"}, + {file = "multidict-6.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc826b9a8176e686b67aa60fd6c6a7047b0461cae5591ea1dc73d28f72332a8a"}, + {file = "multidict-6.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:214207dcc7a6221d9942f23797fe89144128a71c03632bf713d918db99bd36de"}, + {file = "multidict-6.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05fefbc3cddc4e36da209a5e49f1094bbece9a581faa7f3589201fd95df40e5d"}, + {file = "multidict-6.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e851e6363d0dbe515d8de81fd544a2c956fdec6f8a049739562286727d4a00c3"}, + {file = "multidict-6.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32c9b4878f48be3e75808ea7e499d6223b1eea6d54c487a66bc10a1871e3dc6a"}, + {file = "multidict-6.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7243c5a6523c5cfeca76e063efa5f6a656d1d74c8b1fc64b2cd1e84e507f7e2a"}, + {file = "multidict-6.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0e5a644e50ef9fb87878d4d57907f03a12410d2aa3b93b3acdf90a741df52c49"}, + {file = "multidict-6.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0dc25a3293c50744796e87048de5e68996104d86d940bb24bc3ec31df281b191"}, + {file = "multidict-6.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a49994481b99cd7dedde07f2e7e93b1d86c01c0fca1c32aded18f10695ae17eb"}, + {file = "multidict-6.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641cf2e3447c9ecff2f7aa6e9eee9eaa286ea65d57b014543a4911ff2799d08a"}, + {file = "multidict-6.2.0-cp310-cp310-win32.whl", hash = "sha256:0c383d28857f66f5aebe3e91d6cf498da73af75fbd51cedbe1adfb85e90c0460"}, + {file = "multidict-6.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a33273a541f1e1a8219b2a4ed2de355848ecc0254264915b9290c8d2de1c74e1"}, + {file = "multidict-6.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84e87a7d75fa36839a3a432286d719975362d230c70ebfa0948549cc38bd5b46"}, + {file = "multidict-6.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8de4d42dffd5ced9117af2ce66ba8722402541a3aa98ffdf78dde92badb68932"}, + {file = "multidict-6.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7d91a230c7f8af86c904a5a992b8c064b66330544693fd6759c3d6162382ecf"}, + {file = "multidict-6.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f6cad071960ba1914fa231677d21b1b4a3acdcce463cee41ea30bc82e6040cf"}, + {file = "multidict-6.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f74f2fc51555f4b037ef278efc29a870d327053aba5cb7d86ae572426c7cccc"}, + {file = "multidict-6.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14ed9ed1bfedd72a877807c71113deac292bf485159a29025dfdc524c326f3e1"}, + {file = "multidict-6.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac3fcf9a2d369bd075b2c2965544036a27ccd277fc3c04f708338cc57533081"}, + {file = "multidict-6.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fc6af8e39f7496047c7876314f4317736eac82bf85b54c7c76cf1a6f8e35d98"}, + {file = "multidict-6.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f8cb1329f42fadfb40d6211e5ff568d71ab49be36e759345f91c69d1033d633"}, + {file = "multidict-6.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5389445f0173c197f4a3613713b5fb3f3879df1ded2a1a2e4bc4b5b9c5441b7e"}, + {file = "multidict-6.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:94a7bb972178a8bfc4055db80c51efd24baefaced5e51c59b0d598a004e8305d"}, + {file = "multidict-6.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da51d8928ad8b4244926fe862ba1795f0b6e68ed8c42cd2f822d435db9c2a8f4"}, + {file = "multidict-6.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:063be88bd684782a0715641de853e1e58a2f25b76388538bd62d974777ce9bc2"}, + {file = "multidict-6.2.0-cp311-cp311-win32.whl", hash = "sha256:52b05e21ff05729fbea9bc20b3a791c3c11da61649ff64cce8257c82a020466d"}, + {file = "multidict-6.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1e2a2193d3aa5cbf5758f6d5680a52aa848e0cf611da324f71e5e48a9695cc86"}, + {file = "multidict-6.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:437c33561edb6eb504b5a30203daf81d4a9b727e167e78b0854d9a4e18e8950b"}, + {file = "multidict-6.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9f49585f4abadd2283034fc605961f40c638635bc60f5162276fec075f2e37a4"}, + {file = "multidict-6.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5dd7106d064d05896ce28c97da3f46caa442fe5a43bc26dfb258e90853b39b44"}, + {file = "multidict-6.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e25b11a0417475f093d0f0809a149aff3943c2c56da50fdf2c3c88d57fe3dfbd"}, + {file = "multidict-6.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac380cacdd3b183338ba63a144a34e9044520a6fb30c58aa14077157a033c13e"}, + {file = "multidict-6.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61d5541f27533f803a941d3a3f8a3d10ed48c12cf918f557efcbf3cd04ef265c"}, + {file = "multidict-6.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:facaf11f21f3a4c51b62931feb13310e6fe3475f85e20d9c9fdce0d2ea561b87"}, + {file = "multidict-6.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:095a2eabe8c43041d3e6c2cb8287a257b5f1801c2d6ebd1dd877424f1e89cf29"}, + {file = "multidict-6.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a0cc398350ef31167e03f3ca7c19313d4e40a662adcb98a88755e4e861170bdd"}, + {file = "multidict-6.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7c611345bbe7cb44aabb877cb94b63e86f2d0db03e382667dbd037866d44b4f8"}, + {file = "multidict-6.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8cd1a0644ccaf27e9d2f6d9c9474faabee21f0578fe85225cc5af9a61e1653df"}, + {file = "multidict-6.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:89b3857652183b8206a891168af47bac10b970d275bba1f6ee46565a758c078d"}, + {file = "multidict-6.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:125dd82b40f8c06d08d87b3510beaccb88afac94e9ed4a6f6c71362dc7dbb04b"}, + {file = "multidict-6.2.0-cp312-cp312-win32.whl", hash = "sha256:76b34c12b013d813e6cb325e6bd4f9c984db27758b16085926bbe7ceeaace626"}, + {file = "multidict-6.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:0b183a959fb88ad1be201de2c4bdf52fa8e46e6c185d76201286a97b6f5ee65c"}, + {file = "multidict-6.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5c5e7d2e300d5cb3b2693b6d60d3e8c8e7dd4ebe27cd17c9cb57020cac0acb80"}, + {file = "multidict-6.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:256d431fe4583c5f1e0f2e9c4d9c22f3a04ae96009b8cfa096da3a8723db0a16"}, + {file = "multidict-6.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a3c0ff89fe40a152e77b191b83282c9664357dce3004032d42e68c514ceff27e"}, + {file = "multidict-6.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef7d48207926edbf8b16b336f779c557dd8f5a33035a85db9c4b0febb0706817"}, + {file = "multidict-6.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3c099d3899b14e1ce52262eb82a5f5cb92157bb5106bf627b618c090a0eadc"}, + {file = "multidict-6.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e16e7297f29a544f49340012d6fc08cf14de0ab361c9eb7529f6a57a30cbfda1"}, + {file = "multidict-6.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:042028348dc5a1f2be6c666437042a98a5d24cee50380f4c0902215e5ec41844"}, + {file = "multidict-6.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08549895e6a799bd551cf276f6e59820aa084f0f90665c0f03dd3a50db5d3c48"}, + {file = "multidict-6.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ccfd74957ef53fa7380aaa1c961f523d582cd5e85a620880ffabd407f8202c0"}, + {file = "multidict-6.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83b78c680d4b15d33042d330c2fa31813ca3974197bddb3836a5c635a5fd013f"}, + {file = "multidict-6.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b4c153863dd6569f6511845922c53e39c8d61f6e81f228ad5443e690fca403de"}, + {file = "multidict-6.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:98aa8325c7f47183b45588af9c434533196e241be0a4e4ae2190b06d17675c02"}, + {file = "multidict-6.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9e658d1373c424457ddf6d55ec1db93c280b8579276bebd1f72f113072df8a5d"}, + {file = "multidict-6.2.0-cp313-cp313-win32.whl", hash = "sha256:3157126b028c074951839233647bd0e30df77ef1fedd801b48bdcad242a60f4e"}, + {file = "multidict-6.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:2e87f1926e91855ae61769ba3e3f7315120788c099677e0842e697b0bfb659f2"}, + {file = "multidict-6.2.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:2529ddbdaa424b2c6c2eb668ea684dd6b75b839d0ad4b21aad60c168269478d7"}, + {file = "multidict-6.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:13551d0e2d7201f0959725a6a769b6f7b9019a168ed96006479c9ac33fe4096b"}, + {file = "multidict-6.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d1996ee1330e245cd3aeda0887b4409e3930524c27642b046e4fae88ffa66c5e"}, + {file = "multidict-6.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c537da54ce4ff7c15e78ab1292e5799d0d43a2108e006578a57f531866f64025"}, + {file = "multidict-6.2.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f249badb360b0b4d694307ad40f811f83df4da8cef7b68e429e4eea939e49dd"}, + {file = "multidict-6.2.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48d39b1824b8d6ea7de878ef6226efbe0773f9c64333e1125e0efcfdd18a24c7"}, + {file = "multidict-6.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b99aac6bb2c37db336fa03a39b40ed4ef2818bf2dfb9441458165ebe88b793af"}, + {file = "multidict-6.2.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07bfa8bc649783e703263f783f73e27fef8cd37baaad4389816cf6a133141331"}, + {file = "multidict-6.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2c00ad31fbc2cbac85d7d0fcf90853b2ca2e69d825a2d3f3edb842ef1544a2c"}, + {file = "multidict-6.2.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d57a01a2a9fa00234aace434d8c131f0ac6e0ac6ef131eda5962d7e79edfb5b"}, + {file = "multidict-6.2.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:abf5b17bc0cf626a8a497d89ac691308dbd825d2ac372aa990b1ca114e470151"}, + {file = "multidict-6.2.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:f7716f7e7138252d88607228ce40be22660d6608d20fd365d596e7ca0738e019"}, + {file = "multidict-6.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d5a36953389f35f0a4e88dc796048829a2f467c9197265504593f0e420571547"}, + {file = "multidict-6.2.0-cp313-cp313t-win32.whl", hash = "sha256:e653d36b1bf48fa78c7fcebb5fa679342e025121ace8c87ab05c1cefd33b34fc"}, + {file = "multidict-6.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ca23db5fb195b5ef4fd1f77ce26cadefdf13dba71dab14dadd29b34d457d7c44"}, + {file = "multidict-6.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b4f3d66dd0354b79761481fc15bdafaba0b9d9076f1f42cc9ce10d7fcbda205a"}, + {file = "multidict-6.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e2a2d6749e1ff2c9c76a72c6530d5baa601205b14e441e6d98011000f47a7ac"}, + {file = "multidict-6.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cca83a629f77402cfadd58352e394d79a61c8015f1694b83ab72237ec3941f88"}, + {file = "multidict-6.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:781b5dd1db18c9e9eacc419027b0acb5073bdec9de1675c0be25ceb10e2ad133"}, + {file = "multidict-6.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf8d370b2fea27fb300825ec3984334f7dd54a581bde6456799ba3776915a656"}, + {file = "multidict-6.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25bb96338512e2f46f615a2bb7c6012fe92a4a5ebd353e5020836a7e33120349"}, + {file = "multidict-6.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19e2819b0b468174de25c0ceed766606a07cedeab132383f1e83b9a4e96ccb4f"}, + {file = "multidict-6.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aed763b6a1b28c46c055692836879328f0b334a6d61572ee4113a5d0c859872"}, + {file = "multidict-6.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a1133414b771619aa3c3000701c11b2e4624a7f492f12f256aedde97c28331a2"}, + {file = "multidict-6.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:639556758c36093b35e2e368ca485dada6afc2bd6a1b1207d85ea6dfc3deab27"}, + {file = "multidict-6.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:163f4604e76639f728d127293d24c3e208b445b463168af3d031b92b0998bb90"}, + {file = "multidict-6.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2325105e16d434749e1be8022f942876a936f9bece4ec41ae244e3d7fae42aaf"}, + {file = "multidict-6.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e4371591e621579cb6da8401e4ea405b33ff25a755874a3567c4075ca63d56e2"}, + {file = "multidict-6.2.0-cp39-cp39-win32.whl", hash = "sha256:d1175b0e0d6037fab207f05774a176d71210ebd40b1c51f480a04b65ec5c786d"}, + {file = "multidict-6.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad81012b24b88aad4c70b2cbc2dad84018783221b7f923e926f4690ff8569da3"}, + {file = "multidict-6.2.0-py3-none-any.whl", hash = "sha256:5d26547423e5e71dcc562c4acdc134b900640a39abd9066d7326a7cc2324c530"}, + {file = "multidict-6.2.0.tar.gz", hash = "sha256:0085b0afb2446e57050140240a8595846ed64d1cbd26cef936bfab3192c673b8"}, ] [[package]] @@ -2041,6 +2285,7 @@ version = "2.4.0" description = "OpenTracing API for Python. See documentation at http://opentracing.io" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"}, ] @@ -2054,6 +2299,7 @@ version = "3.10.15" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"}, {file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"}, @@ -2142,6 +2388,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -2153,6 +2400,7 @@ version = "0.14.1" description = "Check PEP-8 naming conventions, plugin for flake8" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pep8-naming-0.14.1.tar.gz", hash = "sha256:1ef228ae80875557eb6c1549deafed4dabbf3261cfcafa12f773fe0db9be8a36"}, {file = "pep8_naming-0.14.1-py3-none-any.whl", hash = "sha256:63f514fc777d715f935faf185dedd679ab99526a7f2f503abb61587877f7b1c5"}, @@ -2167,6 +2415,7 @@ version = "1.31.2" description = "PostgreSQL interface library" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pg8000-1.31.2-py3-none-any.whl", hash = "sha256:436c771ede71af4d4c22ba867a30add0bc5c942d7ab27fadbb6934a487ecc8f6"}, {file = "pg8000-1.31.2.tar.gz", hash = "sha256:1ea46cf09d8eca07fe7eaadefd7951e37bee7fabe675df164f1a572ffb300876"}, @@ -2176,12 +2425,28 @@ files = [ python-dateutil = ">=2.8.2" scramp = ">=1.4.5" +[[package]] +name = "pkginfo" +version = "1.12.1.2" +description = "Query metadata from sdists / bdists / installed packages." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pkginfo-1.12.1.2-py3-none-any.whl", hash = "sha256:c783ac885519cab2c34927ccfa6bf64b5a704d7c69afaea583dd9b7afe969343"}, + {file = "pkginfo-1.12.1.2.tar.gz", hash = "sha256:5cd957824ac36f140260964eba3c6be6442a8359b8c48f4adf90210f33a04b7b"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov", "wheel"] + [[package]] name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, @@ -2189,19 +2454,20 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.3.7" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, + {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, + {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, ] [package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] [[package]] name = "pluggy" @@ -2209,6 +2475,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -2220,108 +2487,126 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.2.1" +version = "0.3.0" description = "Accelerated property cache" optional = false python-versions = ">=3.9" -files = [ - {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, - {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, - {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, - {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, - {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, - {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, - {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, - {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, - {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, - {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, - {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, - {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, - {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, - {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, - {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, +groups = ["main"] +files = [ + {file = "propcache-0.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d"}, + {file = "propcache-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c"}, + {file = "propcache-0.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc"}, + {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d"}, + {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f"}, + {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf"}, + {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9"}, + {file = "propcache-0.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25"}, + {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f"}, + {file = "propcache-0.3.0-cp310-cp310-win32.whl", hash = "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c"}, + {file = "propcache-0.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340"}, + {file = "propcache-0.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51"}, + {file = "propcache-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e"}, + {file = "propcache-0.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa"}, + {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf"}, + {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b"}, + {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9"}, + {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6"}, + {file = "propcache-0.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7"}, + {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c"}, + {file = "propcache-0.3.0-cp311-cp311-win32.whl", hash = "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d"}, + {file = "propcache-0.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32"}, + {file = "propcache-0.3.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e"}, + {file = "propcache-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af"}, + {file = "propcache-0.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5"}, + {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b"}, + {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667"}, + {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7"}, + {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7"}, + {file = "propcache-0.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64"}, + {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c"}, + {file = "propcache-0.3.0-cp312-cp312-win32.whl", hash = "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d"}, + {file = "propcache-0.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57"}, + {file = "propcache-0.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a2b9bf8c79b660d0ca1ad95e587818c30ccdb11f787657458d6f26a1ea18c568"}, + {file = "propcache-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b0c1a133d42c6fc1f5fbcf5c91331657a1ff822e87989bf4a6e2e39b818d0ee9"}, + {file = "propcache-0.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bb2f144c6d98bb5cbc94adeb0447cfd4c0f991341baa68eee3f3b0c9c0e83767"}, + {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1323cd04d6e92150bcc79d0174ce347ed4b349d748b9358fd2e497b121e03c8"}, + {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b812b3cb6caacd072276ac0492d249f210006c57726b6484a1e1805b3cfeea0"}, + {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:742840d1d0438eb7ea4280f3347598f507a199a35a08294afdcc560c3739989d"}, + {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c6e7e4f9167fddc438cd653d826f2222222564daed4116a02a184b464d3ef05"}, + {file = "propcache-0.3.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a94ffc66738da99232ddffcf7910e0f69e2bbe3a0802e54426dbf0714e1c2ffe"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c6ec957025bf32b15cbc6b67afe233c65b30005e4c55fe5768e4bb518d712f1"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:549722908de62aa0b47a78b90531c022fa6e139f9166be634f667ff45632cc92"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5d62c4f6706bff5d8a52fd51fec6069bef69e7202ed481486c0bc3874912c787"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:24c04f8fbf60094c531667b8207acbae54146661657a1b1be6d3ca7773b7a545"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7c5f5290799a3f6539cc5e6f474c3e5c5fbeba74a5e1e5be75587746a940d51e"}, + {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4fa0e7c9c3cf7c276d4f6ab9af8adddc127d04e0fcabede315904d2ff76db626"}, + {file = "propcache-0.3.0-cp313-cp313-win32.whl", hash = "sha256:ee0bd3a7b2e184e88d25c9baa6a9dc609ba25b76daae942edfb14499ac7ec374"}, + {file = "propcache-0.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1c8f7d896a16da9455f882870a507567d4f58c53504dc2d4b1e1d386dfe4588a"}, + {file = "propcache-0.3.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e560fd75aaf3e5693b91bcaddd8b314f4d57e99aef8a6c6dc692f935cc1e6bbf"}, + {file = "propcache-0.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:65a37714b8ad9aba5780325228598a5b16c47ba0f8aeb3dc0514701e4413d7c0"}, + {file = "propcache-0.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:07700939b2cbd67bfb3b76a12e1412405d71019df00ca5697ce75e5ef789d829"}, + {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c0fdbdf6983526e269e5a8d53b7ae3622dd6998468821d660d0daf72779aefa"}, + {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:794c3dd744fad478b6232289c866c25406ecdfc47e294618bdf1697e69bd64a6"}, + {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4544699674faf66fb6b4473a1518ae4999c1b614f0b8297b1cef96bac25381db"}, + {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fddb8870bdb83456a489ab67c6b3040a8d5a55069aa6f72f9d872235fbc52f54"}, + {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f857034dc68d5ceb30fb60afb6ff2103087aea10a01b613985610e007053a121"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:02df07041e0820cacc8f739510078f2aadcfd3fc57eaeeb16d5ded85c872c89e"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f47d52fd9b2ac418c4890aad2f6d21a6b96183c98021f0a48497a904199f006e"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9ff4e9ecb6e4b363430edf2c6e50173a63e0820e549918adef70515f87ced19a"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ecc2920630283e0783c22e2ac94427f8cca29a04cfdf331467d4f661f4072dac"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:c441c841e82c5ba7a85ad25986014be8d7849c3cfbdb6004541873505929a74e"}, + {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6c929916cbdb540d3407c66f19f73387f43e7c12fa318a66f64ac99da601bcdf"}, + {file = "propcache-0.3.0-cp313-cp313t-win32.whl", hash = "sha256:0c3e893c4464ebd751b44ae76c12c5f5c1e4f6cbd6fbf67e3783cd93ad221863"}, + {file = "propcache-0.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:75e872573220d1ee2305b35c9813626e620768248425f58798413e9c39741f46"}, + {file = "propcache-0.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:03c091bb752349402f23ee43bb2bff6bd80ccab7c9df6b88ad4322258d6960fc"}, + {file = "propcache-0.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:46ed02532cb66612d42ae5c3929b5e98ae330ea0f3900bc66ec5f4862069519b"}, + {file = "propcache-0.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11ae6a8a01b8a4dc79093b5d3ca2c8a4436f5ee251a9840d7790dccbd96cb649"}, + {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df03cd88f95b1b99052b52b1bb92173229d7a674df0ab06d2b25765ee8404bce"}, + {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03acd9ff19021bd0567582ac88f821b66883e158274183b9e5586f678984f8fe"}, + {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd54895e4ae7d32f1e3dd91261df46ee7483a735017dc6f987904f194aa5fd14"}, + {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a67e5c04e3119594d8cfae517f4b9330c395df07ea65eab16f3d559b7068fe"}, + {file = "propcache-0.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee25f1ac091def37c4b59d192bbe3a206298feeb89132a470325bf76ad122a1e"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:58e6d2a5a7cb3e5f166fd58e71e9a4ff504be9dc61b88167e75f835da5764d07"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:be90c94570840939fecedf99fa72839aed70b0ced449b415c85e01ae67422c90"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:49ea05212a529c2caffe411e25a59308b07d6e10bf2505d77da72891f9a05641"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:119e244ab40f70a98c91906d4c1f4c5f2e68bd0b14e7ab0a06922038fae8a20f"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:507c5357a8d8b4593b97fb669c50598f4e6cccbbf77e22fa9598aba78292b4d7"}, + {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8526b0941ec5a40220fc4dfde76aed58808e2b309c03e9fa8e2260083ef7157f"}, + {file = "propcache-0.3.0-cp39-cp39-win32.whl", hash = "sha256:7cedd25e5f678f7738da38037435b340694ab34d424938041aa630d8bac42663"}, + {file = "propcache-0.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:bf4298f366ca7e1ad1d21bbb58300a6985015909964077afd37559084590c929"}, + {file = "propcache-0.3.0-py3-none-any.whl", hash = "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043"}, + {file = "propcache-0.3.0.tar.gz", hash = "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5"}, ] [[package]] name = "proto-plus" -version = "1.26.0" +version = "1.26.1" description = "Beautiful, Pythonic protocol buffers" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "proto_plus-1.26.0-py3-none-any.whl", hash = "sha256:bf2dfaa3da281fc3187d12d224c707cb57214fb2c22ba854eb0c105a3fb2d4d7"}, - {file = "proto_plus-1.26.0.tar.gz", hash = "sha256:6e93d5f5ca267b54300880fff156b6a3386b3fa3f43b1da62e680fc0c586ef22"}, + {file = "proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66"}, + {file = "proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012"}, ] [package.dependencies] -protobuf = ">=3.19.0,<6.0.0dev" +protobuf = ">=3.19.0,<7.0.0" [package.extras] testing = ["google-api-core (>=1.31.5)"] @@ -2332,6 +2617,7 @@ version = "3.19.6" description = "Protocol Buffers" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "protobuf-3.19.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:010be24d5a44be7b0613750ab40bc8b8cedc796db468eae6c779b395f50d1fa1"}, {file = "protobuf-3.19.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11478547958c2dfea921920617eb457bc26867b0d1aa065ab05f35080c5d9eb6"}, @@ -2362,21 +2648,25 @@ files = [ [[package]] name = "psycopg2" -version = "2.9.10" +version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" +groups = ["main", "dev"] files = [ - {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, - {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, - {file = "psycopg2-2.9.10-cp311-cp311-win32.whl", hash = "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2"}, - {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, - {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, - {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, - {file = "psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2"}, - {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, - {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, - {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, + {file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"}, + {file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"}, + {file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"}, + {file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"}, + {file = "psycopg2-2.9.9-cp312-cp312-win32.whl", hash = "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"}, + {file = "psycopg2-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"}, + {file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"}, + {file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"}, + {file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"}, + {file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"}, + {file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"}, ] [[package]] @@ -2385,6 +2675,7 @@ version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -2396,6 +2687,7 @@ version = "0.4.1" description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, @@ -2410,6 +2702,7 @@ version = "2.9.1" description = "Python style guide checker" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, @@ -2421,6 +2714,7 @@ version = "23.12.11" description = "ISO country, subdivision, language, currency and script definitions and their translations" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pycountry-23.12.11-py3-none-any.whl", hash = "sha256:2ff91cff4f40ff61086e773d61e72005fe95de4a57bfc765509db05695dc50ab"}, {file = "pycountry-23.12.11.tar.gz", hash = "sha256:00569d82eaefbc6a490a311bfa84a9c571cff9ddbf8b0a4f4e7b4f868b4ad925"}, @@ -2432,6 +2726,7 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -2439,43 +2734,41 @@ files = [ [[package]] name = "pycryptodome" -version = "3.21.0" +version = "3.22.0" description = "Cryptographic library for Python" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -files = [ - {file = "pycryptodome-3.21.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:dad9bf36eda068e89059d1f07408e397856be9511d7113ea4b586642a429a4fd"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a1752eca64c60852f38bb29e2c86fca30d7672c024128ef5d70cc15868fa10f4"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3ba4cc304eac4d4d458f508d4955a88ba25026890e8abff9b60404f76a62c55e"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cb087b8612c8a1a14cf37dd754685be9a8d9869bed2ffaaceb04850a8aeef7e"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:26412b21df30b2861424a6c6d5b1d8ca8107612a4cfa4d0183e71c5d200fb34a"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-win32.whl", hash = "sha256:cc2269ab4bce40b027b49663d61d816903a4bd90ad88cb99ed561aadb3888dd3"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-win_amd64.whl", hash = "sha256:0fa0a05a6a697ccbf2a12cec3d6d2650b50881899b845fac6e87416f8cb7e87d"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6cce52e196a5f1d6797ff7946cdff2038d3b5f0aba4a43cb6bf46b575fd1b5bb"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a915597ffccabe902e7090e199a7bf7a381c5506a747d5e9d27ba55197a2c568"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4e74c522d630766b03a836c15bff77cb657c5fdf098abf8b1ada2aebc7d0819"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:a3804675283f4764a02db05f5191eb8fec2bb6ca34d466167fc78a5f05bbe6b3"}, - {file = "pycryptodome-3.21.0-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2480ec2c72438430da9f601ebc12c518c093c13111a5c1644c82cdfc2e50b1e4"}, - {file = "pycryptodome-3.21.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:de18954104667f565e2fbb4783b56667f30fb49c4d79b346f52a29cb198d5b6b"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de4b7263a33947ff440412339cb72b28a5a4c769b5c1ca19e33dd6cd1dcec6e"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0714206d467fc911042d01ea3a1847c847bc10884cf674c82e12915cfe1649f8"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d85c1b613121ed3dbaa5a97369b3b757909531a959d229406a75b912dd51dd1"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8898a66425a57bcf15e25fc19c12490b87bd939800f39a03ea2de2aea5e3611a"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_2_i686.whl", hash = "sha256:932c905b71a56474bff8a9c014030bc3c882cee696b448af920399f730a650c2"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:18caa8cfbc676eaaf28613637a89980ad2fd96e00c564135bf90bc3f0b34dd93"}, - {file = "pycryptodome-3.21.0-cp36-abi3-win32.whl", hash = "sha256:280b67d20e33bb63171d55b1067f61fbd932e0b1ad976b3a184303a3dad22764"}, - {file = "pycryptodome-3.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:b7aa25fc0baa5b1d95b7633af4f5f1838467f1815442b22487426f94e0d66c53"}, - {file = "pycryptodome-3.21.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:2cb635b67011bc147c257e61ce864879ffe6d03342dc74b6045059dfbdedafca"}, - {file = "pycryptodome-3.21.0-pp27-pypy_73-win32.whl", hash = "sha256:4c26a2f0dc15f81ea3afa3b0c87b87e501f235d332b7f27e2225ecb80c0b1cdd"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d5ebe0763c982f069d3877832254f64974139f4f9655058452603ff559c482e8"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee86cbde706be13f2dec5a42b52b1c1d1cbb90c8e405c68d0755134735c8dc6"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fd54003ec3ce4e0f16c484a10bc5d8b9bd77fa662a12b85779a2d2d85d67ee0"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5dfafca172933506773482b0e18f0cd766fd3920bd03ec85a283df90d8a17bc6"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:590ef0898a4b0a15485b05210b4a1c9de8806d3ad3d47f74ab1dc07c67a6827f"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35e442630bc4bc2e1878482d6f59ea22e280d7121d7adeaedba58c23ab6386b"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff99f952db3db2fbe98a0b355175f93ec334ba3d01bbde25ad3a5a33abc02b58"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8acd7d34af70ee63f9a849f957558e49a98f8f1634f86a59d2be62bb8e93f71c"}, - {file = "pycryptodome-3.21.0.tar.gz", hash = "sha256:f7787e0d469bdae763b876174cf2e6c0f7be79808af26b1da96f1a64bcf47297"}, +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +files = [ + {file = "pycryptodome-3.22.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:96e73527c9185a3d9b4c6d1cfb4494f6ced418573150be170f6580cb975a7f5a"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9e1bb165ea1dc83a11e5dbbe00ef2c378d148f3a2d3834fb5ba4e0f6fd0afe4b"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:d4d1174677855c266eed5c4b4e25daa4225ad0c9ffe7584bb1816767892545d0"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-win32.whl", hash = "sha256:9dbb749cef71c28271484cbef684f9b5b19962153487735411e1020ca3f59cb1"}, + {file = "pycryptodome-3.22.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f1ae7beb64d4fc4903a6a6cca80f1f448e7a8a95b77d106f8a29f2eb44d17547"}, + {file = "pycryptodome-3.22.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a26bcfee1293b7257c83b0bd13235a4ee58165352be4f8c45db851ba46996dc6"}, + {file = "pycryptodome-3.22.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:009e1c80eea42401a5bd5983c4bab8d516aef22e014a4705622e24e6d9d703c6"}, + {file = "pycryptodome-3.22.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3b76fa80daeff9519d7e9f6d9e40708f2fce36b9295a847f00624a08293f4f00"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a31fa5914b255ab62aac9265654292ce0404f6b66540a065f538466474baedbc"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0092fd476701eeeb04df5cc509d8b739fa381583cda6a46ff0a60639b7cd70d"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d5b0ddc7cf69231736d778bd3ae2b3efb681ae33b64b0c92fb4626bb48bb89"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f6cf6aa36fcf463e622d2165a5ad9963b2762bebae2f632d719dfb8544903cf5"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:aec7b40a7ea5af7c40f8837adf20a137d5e11a6eb202cde7e588a48fb2d871a8"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d21c1eda2f42211f18a25db4eaf8056c94a8563cd39da3683f89fe0d881fb772"}, + {file = "pycryptodome-3.22.0-cp37-abi3-win32.whl", hash = "sha256:f02baa9f5e35934c6e8dcec91fcde96612bdefef6e442813b8ea34e82c84bbfb"}, + {file = "pycryptodome-3.22.0-cp37-abi3-win_amd64.whl", hash = "sha256:d086aed307e96d40c23c42418cbbca22ecc0ab4a8a0e24f87932eeab26c08627"}, + {file = "pycryptodome-3.22.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:98fd9da809d5675f3a65dcd9ed384b9dc67edab6a4cda150c5870a8122ec961d"}, + {file = "pycryptodome-3.22.0-pp27-pypy_73-win32.whl", hash = "sha256:37ddcd18284e6b36b0a71ea495a4c4dca35bb09ccc9bfd5b91bfaf2321f131c1"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4bdce34af16c1dcc7f8c66185684be15f5818afd2a82b75a4ce6b55f9783e13"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2988ffcd5137dc2d27eb51cd18c0f0f68e5b009d5fec56fbccb638f90934f333"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e653519dedcd1532788547f00eeb6108cc7ce9efdf5cc9996abce0d53f95d5a9"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5810bc7494e4ac12a4afef5a32218129e7d3890ce3f2b5ec520cc69eb1102ad"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7514a1aebee8e85802d154fdb261381f1cb9b7c5a54594545145b8ec3056ae6"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:56c6f9342fcb6c74e205fbd2fee568ec4cdbdaa6165c8fde55dbc4ba5f584464"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87a88dc543b62b5c669895caf6c5a958ac7abc8863919e94b7a6cafd2f64064f"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a683bc9fa585c0dfec7fa4801c96a48d30b30b096e3297f9374f40c2fedafc"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f4f6f47a7f411f2c157e77bbbda289e0c9f9e1e9944caa73c1c2e33f3f92d6e"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6cf9553b29624961cab0785a3177a333e09e37ba62ad22314ebdbb01ca79840"}, + {file = "pycryptodome-3.22.0.tar.gz", hash = "sha256:fd7ab568b3ad7b77c908d7c3f7e167ec5a8f035c64ff74f10d47a4edd043d723"}, ] [[package]] @@ -2484,6 +2777,7 @@ version = "6.3.0" description = "Python docstring style checker" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, @@ -2493,7 +2787,7 @@ files = [ snowballstemmer = ">=2.2.0" [package.extras] -toml = ["tomli (>=1.2.3)"] +toml = ["tomli (>=1.2.3) ; python_version < \"3.11\""] [[package]] name = "pyflakes" @@ -2501,6 +2795,7 @@ version = "2.5.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, @@ -2512,6 +2807,7 @@ version = "2.1.0" description = "Hamcrest framework for matcher objects" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pyhamcrest-2.1.0-py3-none-any.whl", hash = "sha256:f6913d2f392e30e0375b3ecbd7aee79e5d1faa25d345c8f4ff597665dcac2587"}, {file = "pyhamcrest-2.1.0.tar.gz", hash = "sha256:c6acbec0923d0cb7e72c22af1926f3e7c97b8e8d69fc7498eabacaf7c975bd9c"}, @@ -2520,7 +2816,7 @@ files = [ [package.extras] dev = ["black", "doc2dash", "flake8", "pyhamcrest[docs,tests]", "pytest-mypy", "towncrier", "tox", "tox-asdf", "twine"] docs = ["alabaster (>=0.7,<1.0)", "sphinx (>=4.0,<5.0)"] -tests = ["coverage[toml]", "dataclasses", "mypy (!=0.940)", "pytest (>=5.0)", "pytest-mypy-plugins", "pytest-sugar", "pytest-xdist", "pyyaml", "types-dataclasses", "types-mock"] +tests = ["coverage[toml]", "dataclasses ; python_version < \"3.7\"", "mypy (!=0.940) ; platform_python_implementation != \"PyPy\"", "pytest (>=5.0)", "pytest-mypy-plugins ; platform_python_implementation != \"PyPy\"", "pytest-sugar", "pytest-xdist", "pyyaml", "types-dataclasses ; python_version < \"3.7\"", "types-mock"] tests-numpy = ["numpy", "pyhamcrest[tests]"] [[package]] @@ -2529,6 +2825,7 @@ version = "3.8.0" description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"}, {file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"}, @@ -2540,6 +2837,7 @@ version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, @@ -2557,6 +2855,7 @@ version = "3.2.3" description = "python code static checker" optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "pylint-3.2.3-py3-none-any.whl", hash = "sha256:b3d7d2708a3e04b4679e02d99e72329a8b7ee8afb8d04110682278781f889fa8"}, {file = "pylint-3.2.3.tar.gz", hash = "sha256:02f6c562b215582386068d52a30f520d84fdbcf2a95fc7e855b816060d048b60"}, @@ -2581,6 +2880,7 @@ version = "0.6" description = "pylint-flask is a Pylint plugin to aid Pylint in recognizing and understanding errors caused when using Flask" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "pylint-flask-0.6.tar.gz", hash = "sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"}, ] @@ -2594,6 +2894,7 @@ version = "0.8.2" description = "Utilities and helpers for writing Pylint plugins" optional = false python-versions = ">=3.7,<4.0" +groups = ["dev"] files = [ {file = "pylint_plugin_utils-0.8.2-py3-none-any.whl", hash = "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507"}, {file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"}, @@ -2608,6 +2909,7 @@ version = "1.1" description = "Generate and parse RFC 3339 timestamps" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyRFC3339-1.1-py2.py3-none-any.whl", hash = "sha256:67196cb83b470709c580bb4738b83165e67c6cc60e1f2e4f286cfcb402a926f4"}, {file = "pyRFC3339-1.1.tar.gz", hash = "sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a"}, @@ -2622,6 +2924,7 @@ version = "0.20.0" description = "Persistent/Functional/Immutable data structures" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, @@ -2659,13 +2962,14 @@ files = [ [[package]] name = "pytest" -version = "8.3.4" +version = "8.3.5" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ - {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, - {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, + {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, + {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, ] [package.dependencies] @@ -2683,6 +2987,7 @@ version = "0.18.3" description = "Pytest support for asyncio" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "pytest-asyncio-0.18.3.tar.gz", hash = "sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91"}, {file = "pytest_asyncio-0.18.3-1-py3-none-any.whl", hash = "sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213"}, @@ -2701,6 +3006,7 @@ version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, @@ -2719,6 +3025,7 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -2736,6 +3043,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "dev"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -2750,6 +3058,7 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -2764,6 +3073,7 @@ version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -2775,6 +3085,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -2796,6 +3107,7 @@ version = "4.9" description = "Pure-Python RSA implementation" optional = false python-versions = ">=3.6,<4" +groups = ["main"] files = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -2810,6 +3122,7 @@ version = "0.0.0" description = "" optional = false python-versions = "*" +groups = ["main"] files = [] develop = false @@ -2824,7 +3137,7 @@ jaeger-client = "*" type = "git" url = "https://github.com/bcgov/sbc-common-components.git" reference = "master" -resolved_reference = "d640dc75ea51add2d611a30259d15d93d8654381" +resolved_reference = "5570da927853b20bc655bb303c34068aa28d66d7" subdirectory = "python" [[package]] @@ -2833,6 +3146,7 @@ version = "1.4.5" description = "An implementation of the SCRAM protocol." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "scramp-1.4.5-py3-none-any.whl", hash = "sha256:50e37c464fc67f37994e35bee4151e3d8f9320e9c204fca83a5d313c121bbbe7"}, {file = "scramp-1.4.5.tar.gz", hash = "sha256:be3fbe774ca577a7a658117dca014e5d254d158cecae3dd60332dfe33ce6d78e"}, @@ -2847,6 +3161,7 @@ version = "3.0.2" description = "Python helper for Semantic Versioning (https://semver.org)" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "semver-3.0.2-py3-none-any.whl", hash = "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4"}, {file = "semver-3.0.2.tar.gz", hash = "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc"}, @@ -2854,23 +3169,24 @@ files = [ [[package]] name = "setuptools" -version = "75.8.0" +version = "77.0.3" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, - {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, + {file = "setuptools-77.0.3-py3-none-any.whl", hash = "sha256:67122e78221da5cf550ddd04cf8742c8fe12094483749a792d56cd669d6cf58c"}, + {file = "setuptools-77.0.3.tar.gz", hash = "sha256:583b361c8da8de57403743e756609670de6fb2345920e36dc5c2d914c319c945"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.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)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] +core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "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.7.2)", "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.14.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "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) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "simple-cloudevent" @@ -2878,6 +3194,7 @@ version = "0.0.2" description = "A short description of the project" optional = false python-versions = ">=3.8" +groups = ["main"] files = [] develop = false @@ -2896,6 +3213,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main", "dev"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -2907,6 +3225,7 @@ version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, @@ -2918,6 +3237,7 @@ version = "0.1.0" description = "" optional = false python-versions = "^3.10" +groups = ["main"] files = [] develop = false @@ -2925,73 +3245,74 @@ develop = false type = "git" url = "https://github.com/bcgov/sbc-connect-common.git" reference = "main" -resolved_reference = "dcfd4fb0cc5d25a2d74f99cad8f6d661c1880117" +resolved_reference = "7f1cc0ea4a374310ac558ff435fa6b7ea7bb2f8b" subdirectory = "python/sql-versioning" [[package]] name = "sqlalchemy" -version = "2.0.37" +version = "2.0.39" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da36c3b0e891808a7542c5c89f224520b9a16c7f5e4d6a1156955605e54aef0e"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e7402ff96e2b073a98ef6d6142796426d705addd27b9d26c3b32dbaa06d7d069"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6f5d254a22394847245f411a2956976401e84da4288aa70cbcd5190744062c1"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41296bbcaa55ef5fdd32389a35c710133b097f7b2609d8218c0eabded43a1d84"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bedee60385c1c0411378cbd4dc486362f5ee88deceea50002772912d798bb00f"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6c67415258f9f3c69867ec02fea1bf6508153709ecbd731a982442a590f2b7e4"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-win32.whl", hash = "sha256:650dcb70739957a492ad8acff65d099a9586b9b8920e3507ca61ec3ce650bb72"}, - {file = "SQLAlchemy-2.0.37-cp310-cp310-win_amd64.whl", hash = "sha256:93d1543cd8359040c02b6614421c8e10cd7a788c40047dbc507ed46c29ae5636"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:78361be6dc9073ed17ab380985d1e45e48a642313ab68ab6afa2457354ff692c"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b661b49d0cb0ab311a189b31e25576b7ac3e20783beb1e1817d72d9d02508bf5"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d57bafbab289e147d064ffbd5cca2d7b1394b63417c0636cea1f2e93d16eb9e8"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa2c0913f02341d25fb858e4fb2031e6b0813494cca1ba07d417674128ce11b"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9df21b8d9e5c136ea6cde1c50d2b1c29a2b5ff2b1d610165c23ff250e0704087"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db18ff6b8c0f1917f8b20f8eca35c28bbccb9f83afa94743e03d40203ed83de9"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-win32.whl", hash = "sha256:46954173612617a99a64aee103bcd3f078901b9a8dcfc6ae80cbf34ba23df989"}, - {file = "SQLAlchemy-2.0.37-cp311-cp311-win_amd64.whl", hash = "sha256:7b7e772dc4bc507fdec4ee20182f15bd60d2a84f1e087a8accf5b5b7a0dcf2ba"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2952748ecd67ed3b56773c185e85fc084f6bdcdec10e5032a7c25a6bc7d682ef"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3151822aa1db0eb5afd65ccfafebe0ef5cda3a7701a279c8d0bf17781a793bb4"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaa8039b6d20137a4e02603aba37d12cd2dde7887500b8855356682fc33933f4"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cdba1f73b64530c47b27118b7053b8447e6d6f3c8104e3ac59f3d40c33aa9fd"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1b2690456528a87234a75d1a1644cdb330a6926f455403c8e4f6cad6921f9098"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf5ae8a9dcf657fd72144a7fd01f243236ea39e7344e579a121c4205aedf07bb"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-win32.whl", hash = "sha256:ea308cec940905ba008291d93619d92edaf83232ec85fbd514dcb329f3192761"}, - {file = "SQLAlchemy-2.0.37-cp312-cp312-win_amd64.whl", hash = "sha256:635d8a21577341dfe4f7fa59ec394b346da12420b86624a69e466d446de16aff"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8c4096727193762e72ce9437e2a86a110cf081241919ce3fab8e89c02f6b6658"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e4fb5ac86d8fe8151966814f6720996430462e633d225497566b3996966b9bdb"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e56a139bfe136a22c438478a86f8204c1eb5eed36f4e15c4224e4b9db01cb3e4"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f95fc8e3f34b5f6b3effb49d10ac97c569ec8e32f985612d9b25dd12d0d2e94"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c505edd429abdfe3643fa3b2e83efb3445a34a9dc49d5f692dd087be966020e0"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:12b0f1ec623cccf058cf21cb544f0e74656618165b083d78145cafde156ea7b6"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-win32.whl", hash = "sha256:293f9ade06b2e68dd03cfb14d49202fac47b7bb94bffcff174568c951fbc7af2"}, - {file = "SQLAlchemy-2.0.37-cp313-cp313-win_amd64.whl", hash = "sha256:d70f53a0646cc418ca4853da57cf3ddddbccb8c98406791f24426f2dd77fd0e2"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:44f569d0b1eb82301b92b72085583277316e7367e038d97c3a1a899d9a05e342"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2eae3423e538c10d93ae3e87788c6a84658c3ed6db62e6a61bb9495b0ad16bb"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfff7be361048244c3aa0f60b5e63221c5e0f0e509f4e47b8910e22b57d10ae7"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:5bc3339db84c5fb9130ac0e2f20347ee77b5dd2596ba327ce0d399752f4fce39"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:84b9f23b0fa98a6a4b99d73989350a94e4a4ec476b9a7dfe9b79ba5939f5e80b"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-win32.whl", hash = "sha256:51bc9cfef83e0ac84f86bf2b10eaccb27c5a3e66a1212bef676f5bee6ef33ebb"}, - {file = "SQLAlchemy-2.0.37-cp37-cp37m-win_amd64.whl", hash = "sha256:8e47f1af09444f87c67b4f1bb6231e12ba6d4d9f03050d7fc88df6d075231a49"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6b788f14c5bb91db7f468dcf76f8b64423660a05e57fe277d3f4fad7b9dcb7ce"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521ef85c04c33009166777c77e76c8a676e2d8528dc83a57836b63ca9c69dcd1"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75311559f5c9881a9808eadbeb20ed8d8ba3f7225bef3afed2000c2a9f4d49b9"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cce918ada64c956b62ca2c2af59b125767097ec1dca89650a6221e887521bfd7"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9d087663b7e1feabea8c578d6887d59bb00388158e8bff3a76be11aa3f748ca2"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cf95a60b36997dad99692314c4713f141b61c5b0b4cc5c3426faad570b31ca01"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-win32.whl", hash = "sha256:d75ead7dd4d255068ea0f21492ee67937bd7c90964c8f3c2bea83c7b7f81b95f"}, - {file = "SQLAlchemy-2.0.37-cp38-cp38-win_amd64.whl", hash = "sha256:74bbd1d0a9bacf34266a7907d43260c8d65d31d691bb2356f41b17c2dca5b1d0"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:648ec5acf95ad59255452ef759054f2176849662af4521db6cb245263ae4aa33"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:35bd2df269de082065d4b23ae08502a47255832cc3f17619a5cea92ce478b02b"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f581d365af9373a738c49e0c51e8b18e08d8a6b1b15cc556773bcd8a192fa8b"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82df02816c14f8dc9f4d74aea4cb84a92f4b0620235daa76dde002409a3fbb5a"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94b564e38b344d3e67d2e224f0aec6ba09a77e4582ced41e7bfd0f757d926ec9"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:955a2a765aa1bd81aafa69ffda179d4fe3e2a3ad462a736ae5b6f387f78bfeb8"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-win32.whl", hash = "sha256:03f0528c53ca0b67094c4764523c1451ea15959bbf0a8a8a3096900014db0278"}, - {file = "SQLAlchemy-2.0.37-cp39-cp39-win_amd64.whl", hash = "sha256:4b12885dc85a2ab2b7d00995bac6d967bffa8594123b02ed21e8eb2205a7584b"}, - {file = "SQLAlchemy-2.0.37-py3-none-any.whl", hash = "sha256:a8998bf9f8658bd3839cbc44ddbe982955641863da0c1efe5b00c1ab4f5c16b1"}, - {file = "sqlalchemy-2.0.37.tar.gz", hash = "sha256:12b28d99a9c14eaf4055810df1001557176716de0167b91026e648e65229bffb"}, +groups = ["main"] +files = [ + {file = "SQLAlchemy-2.0.39-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:66a40003bc244e4ad86b72abb9965d304726d05a939e8c09ce844d27af9e6d37"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67de057fbcb04a066171bd9ee6bcb58738d89378ee3cabff0bffbf343ae1c787"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:533e0f66c32093a987a30df3ad6ed21170db9d581d0b38e71396c49718fbb1ca"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7399d45b62d755e9ebba94eb89437f80512c08edde8c63716552a3aade61eb42"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:788b6ff6728072b313802be13e88113c33696a9a1f2f6d634a97c20f7ef5ccce"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-win32.whl", hash = "sha256:01da15490c9df352fbc29859d3c7ba9cd1377791faeeb47c100832004c99472c"}, + {file = "SQLAlchemy-2.0.39-cp37-cp37m-win_amd64.whl", hash = "sha256:f2bcb085faffcacf9319b1b1445a7e1cfdc6fb46c03f2dce7bc2d9a4b3c1cdc5"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b761a6847f96fdc2d002e29e9e9ac2439c13b919adfd64e8ef49e75f6355c548"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0d7e3866eb52d914aea50c9be74184a0feb86f9af8aaaa4daefe52b69378db0b"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995c2bacdddcb640c2ca558e6760383dcdd68830160af92b5c6e6928ffd259b4"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344cd1ec2b3c6bdd5dfde7ba7e3b879e0f8dd44181f16b895940be9b842fd2b6"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5dfbc543578058c340360f851ddcecd7a1e26b0d9b5b69259b526da9edfa8875"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3395e7ed89c6d264d38bea3bfb22ffe868f906a7985d03546ec7dc30221ea980"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-win32.whl", hash = "sha256:bf555f3e25ac3a70c67807b2949bfe15f377a40df84b71ab2c58d8593a1e036e"}, + {file = "SQLAlchemy-2.0.39-cp38-cp38-win_amd64.whl", hash = "sha256:463ecfb907b256e94bfe7bcb31a6d8c7bc96eca7cbe39803e448a58bb9fcad02"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6827f8c1b2f13f1420545bd6d5b3f9e0b85fe750388425be53d23c760dcf176b"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9f119e7736967c0ea03aff91ac7d04555ee038caf89bb855d93bbd04ae85b41"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4600c7a659d381146e1160235918826c50c80994e07c5b26946a3e7ec6c99249"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a06e6c8e31c98ddc770734c63903e39f1947c9e3e5e4bef515c5491b7737dde"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c4c433f78c2908ae352848f56589c02b982d0e741b7905228fad628999799de4"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7bd5c5ee1448b6408734eaa29c0d820d061ae18cb17232ce37848376dcfa3e92"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-win32.whl", hash = "sha256:87a1ce1f5e5dc4b6f4e0aac34e7bb535cb23bd4f5d9c799ed1633b65c2bcad8c"}, + {file = "sqlalchemy-2.0.39-cp310-cp310-win_amd64.whl", hash = "sha256:871f55e478b5a648c08dd24af44345406d0e636ffe021d64c9b57a4a11518304"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a28f9c238f1e143ff42ab3ba27990dfb964e5d413c0eb001b88794c5c4a528a9"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:08cf721bbd4391a0e765fe0fe8816e81d9f43cece54fdb5ac465c56efafecb3d"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a8517b6d4005facdbd7eb4e8cf54797dbca100a7df459fdaff4c5123265c1cd"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b2de1523d46e7016afc7e42db239bd41f2163316935de7c84d0e19af7e69538"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:412c6c126369ddae171c13987b38df5122cb92015cba6f9ee1193b867f3f1530"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b35e07f1d57b79b86a7de8ecdcefb78485dab9851b9638c2c793c50203b2ae8"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-win32.whl", hash = "sha256:3eb14ba1a9d07c88669b7faf8f589be67871d6409305e73e036321d89f1d904e"}, + {file = "sqlalchemy-2.0.39-cp311-cp311-win_amd64.whl", hash = "sha256:78f1b79132a69fe8bd6b5d91ef433c8eb40688ba782b26f8c9f3d2d9ca23626f"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c457a38351fb6234781d054260c60e531047e4d07beca1889b558ff73dc2014b"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:018ee97c558b499b58935c5a152aeabf6d36b3d55d91656abeb6d93d663c0c4c"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a8120d6fc185f60e7254fc056a6742f1db68c0f849cfc9ab46163c21df47"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2cf5b5ddb69142511d5559c427ff00ec8c0919a1e6c09486e9c32636ea2b9dd"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f03143f8f851dd8de6b0c10784363712058f38209e926723c80654c1b40327a"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06205eb98cb3dd52133ca6818bf5542397f1dd1b69f7ea28aa84413897380b06"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-win32.whl", hash = "sha256:7f5243357e6da9a90c56282f64b50d29cba2ee1f745381174caacc50d501b109"}, + {file = "sqlalchemy-2.0.39-cp312-cp312-win_amd64.whl", hash = "sha256:2ed107331d188a286611cea9022de0afc437dd2d3c168e368169f27aa0f61338"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe193d3ae297c423e0e567e240b4324d6b6c280a048e64c77a3ea6886cc2aa87"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79f4f502125a41b1b3b34449e747a6abfd52a709d539ea7769101696bdca6716"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a10ca7f8a1ea0fd5630f02feb055b0f5cdfcd07bb3715fc1b6f8cb72bf114e4"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b0a1c7ed54a5361aaebb910c1fa864bae34273662bb4ff788a527eafd6e14d"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52607d0ebea43cf214e2ee84a6a76bc774176f97c5a774ce33277514875a718e"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c08a972cbac2a14810463aec3a47ff218bb00c1a607e6689b531a7c589c50723"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-win32.whl", hash = "sha256:23c5aa33c01bd898f879db158537d7e7568b503b15aad60ea0c8da8109adf3e7"}, + {file = "sqlalchemy-2.0.39-cp313-cp313-win_amd64.whl", hash = "sha256:4dabd775fd66cf17f31f8625fc0e4cfc5765f7982f94dc09b9e5868182cb71c0"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2600a50d590c22d99c424c394236899ba72f849a02b10e65b4c70149606408b5"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4eff9c270afd23e2746e921e80182872058a7a592017b2713f33f96cc5f82e32"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7332868ce891eda48896131991f7f2be572d65b41a4050957242f8e935d5d7"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125a7763b263218a80759ad9ae2f3610aaf2c2fbbd78fff088d584edf81f3782"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:04545042969833cb92e13b0a3019549d284fd2423f318b6ba10e7aa687690a3c"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:805cb481474e111ee3687c9047c5f3286e62496f09c0e82e8853338aaaa348f8"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-win32.whl", hash = "sha256:34d5c49f18778a3665d707e6286545a30339ad545950773d43977e504815fa70"}, + {file = "sqlalchemy-2.0.39-cp39-cp39-win_amd64.whl", hash = "sha256:35e72518615aa5384ef4fae828e3af1b43102458b74a8c481f69af8abf7e802a"}, + {file = "sqlalchemy-2.0.39-py3-none-any.whl", hash = "sha256:a1c6b0a5e3e326a466d809b651c63f278b1256146a377a528b6938a279da334f"}, + {file = "sqlalchemy-2.0.39.tar.gz", hash = "sha256:5d2d1fe548def3267b4c70a8568f108d1fed7cbbeccb9cc166e05af2abc25c22"}, ] [package.dependencies] @@ -3029,6 +3350,7 @@ version = "0.41.2" description = "Various utility functions for SQLAlchemy." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, @@ -3046,8 +3368,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo ; python_version < \"3.9\"", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo ; python_version < \"3.9\"", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -3057,6 +3379,7 @@ version = "0.7" description = "Strict, simple, lightweight RFC3339 functions" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "strict-rfc3339-0.7.tar.gz", hash = "sha256:5cad17bedfc3af57b399db0fed32771f18fc54bbd917e85546088607ac5e1277"}, ] @@ -3067,6 +3390,7 @@ version = "24.4.0" description = "Structured Logging for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "structlog-24.4.0-py3-none-any.whl", hash = "sha256:597f61e80a91cc0749a9fd2a098ed76715a1c8a01f73e336b746504d1aad7610"}, {file = "structlog-24.4.0.tar.gz", hash = "sha256:b27bfecede327a6d2da5fbc96bd859f114ecc398a6389d664f62085ee7ae6fc4"}, @@ -3084,6 +3408,7 @@ version = "0.4.0" description = "" optional = false python-versions = "^3.9" +groups = ["main"] files = [] develop = false @@ -3095,7 +3420,7 @@ structlog = "^24.1.0" type = "git" url = "https://github.com/bcgov/sbc-connect-common.git" reference = "main" -resolved_reference = "dcfd4fb0cc5d25a2d74f99cad8f6d661c1880117" +resolved_reference = "7f1cc0ea4a374310ac558ff435fa6b7ea7bb2f8b" subdirectory = "python/structured-logging" [[package]] @@ -3104,6 +3429,7 @@ version = "1.0.2" description = "Tornado IOLoop Backed Concurrent Futures" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"}, {file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"}, @@ -3118,6 +3444,7 @@ version = "0.20.0" description = "Python bindings for the Apache Thrift RPC system" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "thrift-0.20.0.tar.gz", hash = "sha256:4dd662eadf6b8aebe8a41729527bd69adf6ceaa2a8681cbef64d1273b3e8feba"}, ] @@ -3136,6 +3463,7 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -3147,6 +3475,7 @@ 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" +groups = ["main"] files = [ {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"}, @@ -3167,6 +3496,7 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -3178,13 +3508,14 @@ version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -3195,6 +3526,7 @@ version = "3.1.3" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, @@ -3212,6 +3544,7 @@ version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, @@ -3308,6 +3641,7 @@ version = "3.19.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, @@ -3318,6 +3652,6 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] -lock-version = "2.0" -python-versions = "^3.12" -content-hash = "bff1167417fd5efe916a2b51d0192567faf2bcdd3d23a9609cbc263437c63bf8" +lock-version = "2.1" +python-versions = "3.12.9" +content-hash = "8d92970876177c6837c7c5914b5298d011c918d7e00bcdda15e53c2cad3626b0" diff --git a/queue_services/account-mailer/pyproject.toml b/queue_services/account-mailer/pyproject.toml index 7a43ec686f..a6f8fe9dca 100644 --- a/queue_services/account-mailer/pyproject.toml +++ b/queue_services/account-mailer/pyproject.toml @@ -1,23 +1,22 @@ [tool.poetry] name = "account-mailer" -version = "0.1.0" +version = "0.2.0" description = "" authors = ["Avni Salhotra <avni.salhotra@gov.bc.ca>"] readme = "README.md" [tool.poetry.dependencies] -python = "^3.12" +python = "3.12.9" blinker = "1.8.2" charset-normalizer = "3.3.2" click = "8.1.7" expiringdict = "1.2.2" google-api-core = "1.34.1" google-auth = "2.28.2" +google-cloud-core = "2.4.3" google-cloud-pubsub = "2.20.2" +google-cloud-storage = "2.14.0" googleapis-common-protos = "1.63.0" -grpc-google-iam-v1 = "0.13.0" -grpcio-status = "1.48.2" -grpcio = "1.64.0" idna = "3.7" importlib-resources = "5.13.0" jaeger-client = "4.8.0" @@ -41,9 +40,10 @@ zipp = "3.19.1" auth-api = { git = "https://github.com/bcgov/sbc-auth.git", rev = "dependency_upgrades_p2", subdirectory = "auth-api" } simple-cloudevent = { git = "https://github.com/daxiom/simple-cloudevent.py.git" } cloud-sql-python-connector = "^1.13.0" +pkginfo = "^1.12.1.2" [tool.poetry.group.dev.dependencies] -psycopg2 = "^2.9.9" +psycopg2 = "2.9.9" pytest = "^8.3.2" pytest-mock = "^3.14.0" pyhamcrest = "^2.1.0" @@ -65,7 +65,80 @@ isort = "^5.13.2" lovely-pytest-docker = "^1.0.0" pytest-asyncio = "0.18.3" astroid = "^3.2.3" +flake8-pyproject = "^1.2.3" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.pylint.main] +fail-under = 10 +max-line-length = 120 +ignore = [ "migrations", "devops", "tests"] +disable = ["invalid-name"] + +[tool.black] +target-version = ["py310", "py311", "py312"] +line-length = 120 +include = '\.pyi?$' +extend-exclude = ''' +/( + # The following are specific to Black, you probably don't want those. + migrations + | devops + | .history +)/ +''' + +[tool.isort] +atomic = true +profile = "black" +line_length = 120 +skip_gitignore = true +skip_glob = ["migrations", "devops"] + +[tool.bandit] +exclude_dirs = [".venv","tests"] +skips = ["B104"] + +[tool.flake8] +ignore = "F401,E402,Q000,E203,W503,I004" +exclude = [ + ".venv", + "./venv", + ".git", + ".history", + "devops", + "*migrations*", + "tests" +] +per-file-ignores = [ + "__init__.py:F401", + "*.py:B902" +] +max-line-length = 120 +docstring-min-length=10 +count = true + +[tool.pytest.ini_options] +asyncio_mode = "auto" +minversion = "2.0" +testpaths = [ + "tests", +] +addopts = "--verbose --strict -p no:warnings --cov=src --cov-report html:htmlcov --cov-report xml:coverage.xml" +python_files = [ + "test*.py" +] +norecursedirs = [ + ".git", ".tox", "venv*", "requirements*", "build", +] +log_cli = true +log_cli_level = "1" +filterwarnings = [ + "ignore::UserWarning" +] +markers = [ + "slow", + "serial", +] \ No newline at end of file diff --git a/queue_services/account-mailer/setup.cfg b/queue_services/account-mailer/setup.cfg deleted file mode 100644 index e45a2790b1..0000000000 --- a/queue_services/account-mailer/setup.cfg +++ /dev/null @@ -1,120 +0,0 @@ -[metadata] -name = account_mailer -url = https://github.com/bcgov/sbc-pay/queue_services/account-mailer -author = SBC Relationships team -author_email = -classifiers = - Development Status :: Beta - Intended Audience :: Developers / QA - Topic :: Payments - License :: OSI Approved :: Apache Software License - Natural Language :: English - Programming Language :: Python :: 3.8 -license = Apache Software License Version 2.0 -description = A short description of the project -long_description = file: README.md -keywords = - -[options] -zip_safe = True -python_requires = >=3.6 -include_package_data = True -packages = find: - -[options.package_data] -account_mailer = - -[wheel] -universal = 1 - -[bdist_wheel] -universal = 1 - -[aliases] -test = pytest - -[flake8] -exclude = .git,*migrations* -max-line-length = 120 -docstring-min-length=10 -per-file-ignores = - */__init__.py:F401 - -[pycodestyle] -max_line_length = 120 -ignore = E501 -docstring-min-length=10 -notes=FIXME,XXX # TODO is ignored -match_dir = src/account_mailer -ignored-modules=flask_sqlalchemy - sqlalchemy -per-file-ignores = - */__init__.py:F401 -good-names= - b, - d, - i, - e, - f, - k, - u, - v, - ar, - cb, #common shorthand for callback - nc, - rv, - sc, - event_loop, - logger, - loop, - -[pylint] -ignore=migrations,test -notes=FIXME,XXX,TODO -ignored-modules=flask_sqlalchemy,sqlalchemy,SQLAlchemy,alembic,scoped_session -ignored-classes=scoped_session -disable=C0301,W0511,R0801,R0902 - -[isort] -line_length = 120 -indent = 4 -multi_line_output = 4 -lines_after_imports = 2 - -[tool:pytest] -minversion = 2.0 -testpaths = tests -addopts = --verbose - --strict - -p no:warnings - --cov=src --cov-report html:htmlcov --cov-report xml:coverage.xml -python_files = tests/*/test*.py -norecursedirs = .git .tox venv* requirements* build -log_cli = true -log_cli_level = 1 -filterwarnings = - ignore::UserWarning -markers = - slow - serial - -[coverage:run] -branch = True -source = - src/account_mailer -omit = - src/account_mailer/wsgi.py - src/account_mailer/gunicorn_config.py - -[report:run] -exclude_lines = - pragma: no cover - from - import - def __repr__ - if self.debug: - if settings.DEBUG - raise AssertionError - raise NotImplementedError - if 0: - if __name__ == .__main__.: diff --git a/queue_services/account-mailer/src/account_mailer/__init__.py b/queue_services/account-mailer/src/account_mailer/__init__.py index ca4ecc4a9d..9aa8aeccd8 100644 --- a/queue_services/account-mailer/src/account_mailer/__init__.py +++ b/queue_services/account-mailer/src/account_mailer/__init__.py @@ -55,12 +55,12 @@ def getconn(connector: Connector, db_config: DBConfig) -> object: object: A connection object to the database. """ return connector.connect( - instance_connection_string=db_config.unix_sock.replace('/cloudsql/', ''), - ip_type='private', + instance_connection_string=db_config.unix_sock.replace("/cloudsql/", ""), + ip_type="private", user=db_config.user, password=db_config.password, db=db_config.database, - driver='pg8000', + driver="pg8000", ) @@ -71,11 +71,11 @@ def register_endpoints(app: Flask) -> None: app (Flask): The Flask application instance. """ app.url_map.strict_slashes = False - app.register_blueprint(worker_endpoint, url_prefix='/') + app.register_blueprint(worker_endpoint, url_prefix="/") app.register_blueprint(ops_bp) -def create_app(run_mode=os.getenv('DEPLOYMENT_ENV', 'production')) -> Flask: +def create_app(run_mode=os.getenv("DEPLOYMENT_ENV", "production")) -> Flask: """Return a configured Flask App using the Factory method. Args: @@ -86,19 +86,17 @@ def create_app(run_mode=os.getenv('DEPLOYMENT_ENV', 'production')) -> Flask: """ app = Flask(__name__) app.config.from_object(app_config.get_named_config(run_mode)) - app.config['ENV'] = run_mode + app.config["ENV"] = run_mode - if app.config.get('DB_UNIX_SOCKET'): - connector = Connector(refresh_strategy='lazy') + if app.config.get("DB_UNIX_SOCKET"): + connector = Connector(refresh_strategy="lazy") db_config = DBConfig( - unix_sock=app.config.get('DB_UNIX_SOCKET'), - database=app.config.get('DB_NAME'), - user=app.config.get('DB_USER'), - password=app.config.get('DB_PASSWORD') + unix_sock=app.config.get("DB_UNIX_SOCKET"), + database=app.config.get("DB_NAME"), + user=app.config.get("DB_USER"), + password=app.config.get("DB_PASSWORD"), ) - app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { - 'creator': lambda: getconn(connector, db_config) - } + app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {"creator": lambda: getconn(connector, db_config)} db.init_app(app) flags.init_app(app) diff --git a/queue_services/account-mailer/src/account_mailer/auth_utils.py b/queue_services/account-mailer/src/account_mailer/auth_utils.py index b80f821a44..45f3b0c2c2 100644 --- a/queue_services/account-mailer/src/account_mailer/auth_utils.py +++ b/queue_services/account-mailer/src/account_mailer/auth_utils.py @@ -24,38 +24,38 @@ def get_member_emails(org_id, roles): """Get emails for the user role passed in.""" member_list = UserModel.find_users_by_org_id_by_status_by_roles(org_id, roles, Status.ACTIVE.value) - member_emails = ','.join([str(x.contacts[0].contact.email) for x in member_list if x.contacts]) + member_emails = ",".join([str(x.contacts[0].contact.email) for x in member_list if x.contacts]) return member_emails def get_login_url(): """Get application login url.""" - login_url = current_app.config.get('WEB_APP_URL') + login_url = current_app.config.get("WEB_APP_URL") return login_url def get_transaction_url(org_id: str) -> str: """Get transaction url.""" - web_app_url = current_app.config.get('WEB_APP_URL') - transaction_url = f'{web_app_url}/account/{org_id}/settings/transactions' + web_app_url = current_app.config.get("WEB_APP_URL") + transaction_url = f"{web_app_url}/account/{org_id}/settings/transactions" return transaction_url def get_dashboard_url(): """Get application dashboard url.""" - login_url = current_app.config.get('DASHBOARD_URL') + login_url = current_app.config.get("DASHBOARD_URL") return login_url def get_payment_statements_url(org_id: str) -> str: """Get auth web statement url for an org.""" if not org_id: # Safeguard as this is now part of the common_mailer processing - return '' + return "" - web_app_url = current_app.config.get('WEB_APP_URL') - web_app_statement_path_url = current_app.config.get('WEB_APP_STATEMENT_PATH_URL') + web_app_url = current_app.config.get("WEB_APP_URL") + web_app_statement_path_url = current_app.config.get("WEB_APP_STATEMENT_PATH_URL") - web_app_statement_path_url = web_app_statement_path_url.replace('orgId', str(org_id)) + web_app_statement_path_url = web_app_statement_path_url.replace("orgId", str(org_id)) statement_path_url = web_app_url + web_app_statement_path_url return statement_path_url diff --git a/queue_services/account-mailer/src/account_mailer/config.py b/queue_services/account-mailer/src/account_mailer/config.py index a088bf2970..99730f5945 100644 --- a/queue_services/account-mailer/src/account_mailer/config.py +++ b/queue_services/account-mailer/src/account_mailer/config.py @@ -23,35 +23,34 @@ from dotenv import find_dotenv, load_dotenv - # this will load all the envars from a .env file located in the project root (api) load_dotenv(find_dotenv()) CONFIGURATION = { - 'development': 'account_mailer.config.DevConfig', - 'testing': 'account_mailer.config.TestConfig', - 'production': 'account_mailer.config.ProdConfig', - 'default': 'account_mailer.config.ProdConfig' + "development": "account_mailer.config.DevConfig", + "testing": "account_mailer.config.TestConfig", + "production": "account_mailer.config.ProdConfig", + "default": "account_mailer.config.ProdConfig", } -def get_named_config(config_name: str = 'production'): +def get_named_config(config_name: str = "production"): """Return the configuration object based on the name. :raise: KeyError: if an unknown configuration is requested """ - if config_name in ['production', 'staging', 'default']: + if config_name in ["production", "staging", "default"]: app_config = ProdConfig() - elif config_name == 'testing': + elif config_name == "testing": app_config = TestConfig() - elif config_name == 'development': + elif config_name == "development": app_config = DevConfig() else: - raise KeyError(f'Unknown configuration: {config_name}') + raise KeyError(f"Unknown configuration: {config_name}") return app_config -class _Config(): # pylint: disable=too-few-public-methods +class _Config: # pylint: disable=too-few-public-methods """Base class configuration that should set reasonable defaults. Used as the base for all the other configurations. @@ -64,80 +63,85 @@ class _Config(): # pylint: disable=too-few-public-methods SQLALCHEMY_TRACK_MODIFICATIONS = False - AUTH_LD_SDK_KEY = os.getenv('AUTH_LD_SDK_KEY', None) + AUTH_LD_SDK_KEY = os.getenv("AUTH_LD_SDK_KEY", None) # POSTGRESQL - DB_USER = os.getenv('DATABASE_USERNAME', '') - DB_PASSWORD = os.getenv('DATABASE_PASSWORD', '') - DB_NAME = os.getenv('DATABASE_NAME', '') - DB_HOST = os.getenv('DATABASE_HOST', '') - DB_PORT = os.getenv('DATABASE_PORT', '5432') - if DB_UNIX_SOCKET := os.getenv('DATABASE_UNIX_SOCKET', None): - SQLALCHEMY_DATABASE_URI = 'postgresql+pg8000://' + DB_USER = os.getenv("DATABASE_USERNAME", "") + DB_PASSWORD = os.getenv("DATABASE_PASSWORD", "") + DB_NAME = os.getenv("DATABASE_NAME", "") + DB_HOST = os.getenv("DATABASE_HOST", "") + DB_PORT = os.getenv("DATABASE_PORT", "5432") + if DB_UNIX_SOCKET := os.getenv("DATABASE_UNIX_SOCKET", None): + SQLALCHEMY_DATABASE_URI = "postgresql+pg8000://" else: - SQLALCHEMY_DATABASE_URI = f'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}' # noqa: E231, E501 + SQLALCHEMY_DATABASE_URI = ( + f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}" # noqa: E231, E501 + ) # Keycloak & Jwt - JWT_OIDC_ISSUER = os.getenv('JWT_OIDC_ISSUER') + JWT_OIDC_ISSUER = os.getenv("JWT_OIDC_ISSUER") # Keycloak auth config baseurl - KEYCLOAK_BASE_URL = os.getenv('KEYCLOAK_BASE_URL') - KEYCLOAK_REALMNAME = os.getenv('KEYCLOAK_REALMNAME') - KEYCLOAK_ADMIN_USERNAME = os.getenv('SBC_AUTH_ADMIN_CLIENT_ID') - KEYCLOAK_ADMIN_SECRET = os.getenv('SBC_AUTH_ADMIN_CLIENT_SECRET') + KEYCLOAK_BASE_URL = os.getenv("KEYCLOAK_BASE_URL") + KEYCLOAK_REALMNAME = os.getenv("KEYCLOAK_REALMNAME") + KEYCLOAK_ADMIN_USERNAME = os.getenv("SBC_AUTH_ADMIN_CLIENT_ID") + KEYCLOAK_ADMIN_SECRET = os.getenv("SBC_AUTH_ADMIN_CLIENT_SECRET") # Service account details - KEYCLOAK_SERVICE_ACCOUNT_ID = os.getenv('SBC_AUTH_ADMIN_CLIENT_ID') - KEYCLOAK_SERVICE_ACCOUNT_SECRET = os.getenv('SBC_AUTH_ADMIN_CLIENT_SECRET') + KEYCLOAK_SERVICE_ACCOUNT_ID = os.getenv("SBC_AUTH_ADMIN_CLIENT_ID") + KEYCLOAK_SERVICE_ACCOUNT_SECRET = os.getenv("SBC_AUTH_ADMIN_CLIENT_SECRET") # API endpoints - PAY_API_URL = os.getenv('PAY_API_URL', '') - PAY_API_VERSION = os.getenv('PAY_API_VERSION', '') + PAY_API_URL = os.getenv("PAY_API_URL", "") + PAY_API_VERSION = os.getenv("PAY_API_VERSION", "") PAY_API_URL = PAY_API_URL + PAY_API_VERSION - NOTIFY_API_URL = os.getenv('NOTIFY_API_URL', '') - NOTIFY_API_VERSION = os.getenv('NOTIFY_API_VERSION', '') + NOTIFY_API_URL = os.getenv("NOTIFY_API_URL", "") + NOTIFY_API_VERSION = os.getenv("NOTIFY_API_VERSION", "") NOTIFY_API_URL = NOTIFY_API_URL + NOTIFY_API_VERSION - REPORT_API_URL = os.getenv('REPORT_API_URL', '') - REPORT_API_VERSION = os.getenv('REPORT_API_VERSION', '') + REPORT_API_URL = os.getenv("REPORT_API_URL", "") + REPORT_API_VERSION = os.getenv("REPORT_API_VERSION", "") REPORT_API_URL = REPORT_API_URL + REPORT_API_VERSION - REPORT_API_BASE_URL = f'{REPORT_API_URL}/reports' + REPORT_API_BASE_URL = f"{REPORT_API_URL}/reports" - # Minio configuration values + # TODO remove when cgi_ejv bucket moves to google storage MINIO_ENDPOINT = os.getenv('MINIO_ENDPOINT') MINIO_ACCESS_KEY = os.getenv('MINIO_ACCESS_KEY') MINIO_ACCESS_SECRET = os.getenv('MINIO_ACCESS_SECRET') MINIO_BUCKET = os.getenv('MINIO_BUCKET', 'account-mailer') MINIO_SECURE = os.getenv('MINIO_SECURE', 'true').lower() == 'true' + # GCP Cloud Storage configuration values + ACCOUNT_MAILER_BUCKET = os.getenv("ACCOUNT_MAILER_BUCKET", "auth-account-mailer-dev") + STATIC_RESOURCES_BUCKET_URL = os.getenv( + "STATIC_RESOURCES_BUCKET_URL", + "https://storage.googleapis.com/auth-static-resources-dev/", + ) + REFUND_REQUEST = { - 'creditcard': { - 'recipients': os.getenv('REFUND_REQUEST_RECIPIENTS', '') - }, - 'bcol': { - 'recipients': os.getenv('BCOL_REFUND_REQUEST_RECIPIENTS', '') - } + "creditcard": {"recipients": os.getenv("REFUND_REQUEST_RECIPIENTS", "")}, + "bcol": {"recipients": os.getenv("BCOL_REFUND_REQUEST_RECIPIENTS", "")}, } # application setting - PDF_TEMPLATE_PATH = os.getenv('PDF_TEMPLATE_PATH', 'src/account_mailer/pdf_templates') - TEMPLATE_PATH = os.getenv('TEMPLATE_PATH', 'src/account_mailer/email_templates') - HTTP_ORIGIN = os.getenv('HTTP_ORIGIN', 'localhost') - WEB_APP_URL = os.getenv('WEB_APP_URL', 'localhost') - WEB_APP_STATEMENT_PATH_URL = os.getenv('WEB_APP_STATEMENT_PATH_URL', 'account/orgId/settings/statements') - DASHBOARD_URL = os.getenv('DASHBOARD_URL', 'localhost') + PDF_TEMPLATE_PATH = os.getenv("PDF_TEMPLATE_PATH", "src/account_mailer/pdf_templates") + TEMPLATE_PATH = os.getenv("TEMPLATE_PATH", "src/account_mailer/email_templates") + HTTP_ORIGIN = os.getenv("HTTP_ORIGIN", "localhost") + WEB_APP_URL = os.getenv("WEB_APP_URL", "localhost") + WEB_APP_STATEMENT_PATH_URL = os.getenv("WEB_APP_STATEMENT_PATH_URL", "account/orgId/settings/statements") + DASHBOARD_URL = os.getenv("DASHBOARD_URL", "localhost") # PAD TOS PDF file name. - PAD_TOS_FILE = os.getenv('PAD_TOS_FILE', 'BCROS-Business-Pre-Authorized-Debit-Agreement.pdf') + PAD_TOS_FILE = os.getenv("PAD_TOS_FILE", "BCROS-Business-Pre-Authorized-Debit-Agreement.pdf") # MHR QUALIFIED SUPPLIER PDF File name - MHR_QS_AGREEMENT_FILE = os.getenv('MHR_QS_AGREEMENT_FILE', 'MHR_QualifiedSuppliersAgreement.pdf') + MHR_QS_AGREEMENT_FILE = os.getenv("MHR_QS_AGREEMENT_FILE", "MHR_QualifiedSuppliersAgreement.pdf") # If any value is present in this flag, starts up a keycloak docker - USE_TEST_KEYCLOAK_DOCKER = os.getenv('USE_TEST_KEYCLOAK_DOCKER', None) - USE_DOCKER_MOCK = os.getenv('USE_DOCKER_MOCK', None) + USE_TEST_KEYCLOAK_DOCKER = os.getenv("USE_TEST_KEYCLOAK_DOCKER", None) + USE_DOCKER_MOCK = os.getenv("USE_DOCKER_MOCK", None) # BC online admin email - BCOL_ADMIN_EMAIL = os.getenv('BCOL_ADMIN_EMAIL', 'test@test.com') + BCOL_ADMIN_EMAIL = os.getenv("BCOL_ADMIN_EMAIL", "test@test.com") - LEGISLATIVE_TIMEZONE = os.getenv('LEGISLATIVE_TIMEZONE', 'America/Vancouver') + LEGISLATIVE_TIMEZONE = os.getenv("LEGISLATIVE_TIMEZONE", "America/Vancouver") class DevConfig(_Config): # pylint: disable=too-few-public-methods @@ -148,36 +152,30 @@ class DevConfig(_Config): # pylint: disable=too-few-public-methods class TestConfig(_Config): # pylint: disable=too-few-public-methods - """In support of testing only. + """In support of unit testing only. Used by the py.test suite """ DEBUG = True TESTING = True - # POSTGRESQL - DB_USER = os.getenv('DATABASE_TEST_USERNAME', '') - DB_PASSWORD = os.getenv('DATABASE_TEST_PASSWORD', '') - DB_NAME = os.getenv('DATABASE_TEST_NAME', '') - DB_HOST = os.getenv('DATABASE_TEST_HOST', '') - DB_PORT = os.getenv('DATABASE_TEST_PORT', '5432') + DB_USER = os.getenv("DATABASE_TEST_USERNAME", "postgres") + DB_PASSWORD = os.getenv("DATABASE_TEST_PASSWORD", "postgres") + DB_NAME = os.getenv("DATABASE_TEST_NAME", "postgres") + DB_HOST = os.getenv("DATABASE_TEST_HOST", "localhost") + DB_PORT = os.getenv("DATABASE_TEST_PORT", "5432") + os.environ["CLOUD_STORAGE_EMULATOR_HOST"] = "http://localhost:4443" + os.environ["PUBSUB_EMULATOR_HOST"] = "localhost:8085" + SQLALCHEMY_DATABASE_URI = os.getenv( - 'DATABASE_TEST_URL', - default=f'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}', # noqa: E231 + "DATABASE_TEST_URL", + default=f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}", # noqa: E231 ) - - JWT_OIDC_ISSUER = os.getenv('JWT_OIDC_TEST_ISSUER') + JWT_OIDC_ISSUER = os.getenv("JWT_OIDC_TEST_ISSUER") # Service account details - KEYCLOAK_SERVICE_ACCOUNT_ID = os.getenv('KEYCLOAK_TEST_ADMIN_CLIENTID') - KEYCLOAK_SERVICE_ACCOUNT_SECRET = os.getenv('KEYCLOAK_TEST_ADMIN_SECRET') - BCOL_ADMIN_EMAIL = 'test@test.com' - - # Minio variables - MINIO_ENDPOINT = 'localhost:9000' - MINIO_ACCESS_KEY = 'minio' - MINIO_ACCESS_SECRET = 'minio123' - MINIO_BUCKET_NAME = 'cgi-ejv' - MINIO_SECURE = False + KEYCLOAK_SERVICE_ACCOUNT_ID = os.getenv("KEYCLOAK_TEST_ADMIN_CLIENTID") + KEYCLOAK_SERVICE_ACCOUNT_SECRET = os.getenv("KEYCLOAK_TEST_ADMIN_SECRET") + BCOL_ADMIN_EMAIL = "test@test.com" class ProdConfig(_Config): # pylint: disable=too-few-public-methods diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/__init__.py b/queue_services/account-mailer/src/account_mailer/email_processors/__init__.py index 824a50a538..34070cdf9c 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/__init__.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/__init__.py @@ -30,26 +30,26 @@ def generate_template(template_path: str, template_file_name: str) -> str: parts. There is no recursive search and replace. """ template_parts = [ - 'business-dashboard-link', - 'footer', - 'header', - 'initiative-notice', - 'logo', - 'style', - 'fonts', - 'bc_logo_img', - 'bc_registry_logo_img', - 'whitespace-16px', - 'whitespace-24px' + "business-dashboard-link", + "footer", + "header", + "initiative-notice", + "logo", + "style", + "fonts", + "bc_logo_img", + "bc_registry_logo_img", + "whitespace-16px", + "whitespace-24px", ] - template_code = Path(f'{template_path}/{template_file_name}.html').read_text() # pylint: disable=W1514 + template_code = Path(f"{template_path}/{template_file_name}.html").read_text() # pylint: disable=W1514 # substitute template parts - marked up by [[filename]] for template_part in template_parts: - template_part_path = Path(f'{template_path}/common/{template_part}.html') + template_part_path = Path(f"{template_path}/common/{template_part}.html") if os.path.exists(template_part_path) and os.path.getsize(template_part_path) > 0: template_part_code = template_part_path.read_text() # pylint: disable=W1514 - template_code = template_code.replace(f'[[{template_part}.html]]', template_part_code) + template_code = template_code.replace(f"[[{template_part}.html]]", template_part_code) return template_code diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py index 62889fa789..858f146363 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py @@ -23,60 +23,58 @@ from account_mailer.email_processors import generate_template - logger = StructuredLogging.get_logger() def process(data: dict, token: str) -> dict: """Build the email for Account Unlocked notification.""" - logger.debug('email_msg notification: %s', data) + logger.debug("email_msg notification: %s", data) pdf_attachment = _get_account_unlock_pdf(data, token) html_body = _get_account_unlock_email(data) return { - 'recipients': data.get('admin_coordinator_emails'), - 'content': { - 'subject': data.get('subject'), - 'body': f'{html_body}', - 'attachments': [ + "recipients": data.get("admin_coordinator_emails"), + "content": { + "subject": data.get("subject"), + "body": f"{html_body}", + "attachments": [ { - 'fileName': 'Account_Unlock_Receipt.pdf', - 'fileBytes': pdf_attachment.decode('utf-8'), - 'fileUrl': '', - 'attachOrder': '1' + "fileName": "Account_Unlock_Receipt.pdf", + "fileBytes": pdf_attachment.decode("utf-8"), + "fileUrl": "", + "attachOrder": "1", } - ] - } + ], + }, } def _get_account_unlock_email(email_msg): - filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), email_msg.get('template_name')) + filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), email_msg.get("template_name")) jnja_template = Template(filled_template, autoescape=True) - html_out = jnja_template.render( - account_name=email_msg.get('account_name'), - logo_url=email_msg.get('logo_url') - ) + html_out = jnja_template.render(account_name=email_msg.get("account_name"), logo_url=email_msg.get("logo_url")) return html_out def _get_account_unlock_pdf(data, token): pdf_payload = { - 'reportName': 'NSF_Fee_Receipt', - 'templateVars': data['template_vars'], - 'populatePageNumber': True, - 'templateName': 'payment_receipt', + "reportName": "NSF_Fee_Receipt", + "templateVars": data["template_vars"], + "populatePageNumber": True, + "templateName": "payment_receipt", } - report_response = RestService.post(endpoint=current_app.config.get('REPORT_API_BASE_URL'), - token=token, - auth_header_type=AuthHeaderType.BEARER, - content_type=ContentType.JSON, - data=pdf_payload, - raise_for_status=True, - additional_headers={'Accept': 'application/pdf'}) + report_response = RestService.post( + endpoint=current_app.config.get("REPORT_API_BASE_URL"), + token=token, + auth_header_type=AuthHeaderType.BEARER, + content_type=ContentType.JSON, + data=pdf_payload, + raise_for_status=True, + additional_headers={"Accept": "application/pdf"}, + ) pdf_attachment = None if report_response.status_code != 200: - logger.error('Failed to get pdf') + logger.error("Failed to get pdf") else: pdf_attachment = base64.b64encode(report_response.content) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/common_mailer.py b/queue_services/account-mailer/src/account_mailer/email_processors/common_mailer.py index 95d459342a..fcfb7f3325 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/common_mailer.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/common_mailer.py @@ -20,13 +20,12 @@ from account_mailer.auth_utils import get_dashboard_url, get_login_url, get_payment_statements_url from account_mailer.email_processors import generate_template - logger = StructuredLogging.get_logger() def process(org_id, recipients, template_name, subject, logo_url, **kwargs) -> dict: """Build the email for Account notification.""" - logger.debug('account notification: %s', org_id) + logger.debug("account notification: %s", org_id) account_name: str = None account_name_with_branch: str = None @@ -35,31 +34,27 @@ def process(org_id, recipients, template_name, subject, logo_url, **kwargs) -> d account_name = org.name account_name_with_branch = org.name if org.branch_name: - account_name_with_branch = f'{org.name} - {org.branch_name}' + account_name_with_branch = f"{org.name} - {org.branch_name}" # fill in template - filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), template_name) + filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), template_name) # render template with vars from email msg jnja_template = Template(filled_template, autoescape=True) jinja_kwargs = { - 'account_name': account_name, - 'account_name_with_branch': account_name_with_branch, - 'account_number': org_id, - 'url': get_login_url(), - 'logo_url': logo_url, - 'dashboard_url': get_dashboard_url(), - 'payment_statement_url': get_payment_statements_url(org_id), - **kwargs + "account_name": account_name, + "account_name_with_branch": account_name_with_branch, + "account_number": org_id, + "url": get_login_url(), + "logo_url": logo_url, + "dashboard_url": get_dashboard_url(), + "payment_statement_url": get_payment_statements_url(org_id), + **kwargs, } - logger.debug('notification args: %s', jinja_kwargs) + logger.debug("notification args: %s", jinja_kwargs) html_out = jnja_template.render(jinja_kwargs) return { - 'recipients': recipients, - 'content': { - 'subject': subject, - 'body': html_out, - 'attachments': [] - } + "recipients": recipients, + "content": {"subject": subject, "body": html_out, "attachments": []}, } diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/ejv_failures.py b/queue_services/account-mailer/src/account_mailer/email_processors/ejv_failures.py index 7eef70d91a..3095dcc9b4 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/ejv_failures.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/ejv_failures.py @@ -21,53 +21,60 @@ from account_mailer.email_processors import generate_template from account_mailer.enums import SubjectType, TemplateType -from account_mailer.services import minio_service +# from account_mailer.services import google_store +from account_mailer.services import minio_service logger = StructuredLogging.get_logger() def process(email_msg: dict) -> dict: """Build the email for JV failures.""" - logger.debug('ejv_failures: %s', email_msg) + logger.debug("ejv_failures: %s", email_msg) # fill in template - failed_jv_file_name = email_msg.get('fileName') - file_location = email_msg.get('minioLocation') - bcol_admin_email = current_app.config['BCOL_ADMIN_EMAIL'] + failed_jv_file_name = email_msg.get("fileName") + # TODO update minioLocation + file_location = email_msg.get("minioLocation") + bcol_admin_email = current_app.config["BCOL_ADMIN_EMAIL"] feedback_attachment = _get_jv_file(file_location, failed_jv_file_name) html_body = _get_body(email_msg) return { - 'recipients': bcol_admin_email, - 'content': { - 'subject': SubjectType.EJV_FAILED.value, - 'body': f'{html_body}', - 'attachments': [ + "recipients": bcol_admin_email, + "content": { + "subject": SubjectType.EJV_FAILED.value, + "body": f"{html_body}", + "attachments": [ { - 'fileName': failed_jv_file_name, - 'fileBytes': feedback_attachment.decode('utf-8'), - 'fileUrl': '', - 'attachOrder': '1' + "fileName": failed_jv_file_name, + "fileBytes": feedback_attachment.decode("utf-8"), + "fileUrl": "", + "attachOrder": "1", } - ] - } + ], + }, } def _get_body(email_msg: dict): - filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), - TemplateType.EJV_FAILED_TEMPLATE_NAME.value) + filled_template = generate_template( + current_app.config.get("TEMPLATE_PATH"), + TemplateType.EJV_FAILED_TEMPLATE_NAME.value, + ) # render template with vars from email msg jnja_template = Template(filled_template, autoescape=True) - html_out = jnja_template.render( - logo_url=email_msg.get('logo_url') - ) + html_out = jnja_template.render(logo_url=email_msg.get("logo_url")) return html_out def _get_jv_file(file_location: str, file_name: str): file = None - mino_object = minio_service.MinioService.get_minio_file(file_location, file_name) - if mino_object: - file = base64.b64encode(mino_object.data) + # use this version once cgi-ejv moves to gcs, + # then will also need update name of payload attribute in pay-queue, i.e. minioLocation + # store_blob = google_store.GoogleStoreService.download_file_from_bucket(file_location, file_name) + # if store_blob: + # file = base64.b64encode(store_blob) + minio_object = minio_service.MinioService.get_minio_file(file_location, file_name) + if minio_object: + file = base64.b64encode(minio_object.data) return file diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/pad_confirmation.py b/queue_services/account-mailer/src/account_mailer/email_processors/pad_confirmation.py index 6168305a05..52cc434d10 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/pad_confirmation.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/pad_confirmation.py @@ -25,106 +25,104 @@ from structured_logging import StructuredLogging from account_mailer.email_processors import generate_template -from account_mailer.services import minio_service - +from account_mailer.services import google_store logger = StructuredLogging.get_logger() def process(email_msg: dict, token: str) -> dict: """Build the email for PAD Confirmation notification.""" - logger.debug('email_msg notification: %s', email_msg) + logger.debug("email_msg notification: %s", email_msg) # fill in template - username = email_msg.get('padTosAcceptedBy') - pad_tos_file_name = current_app.config['PAD_TOS_FILE'] + username = email_msg.get("padTosAcceptedBy") + pad_tos_file_name = current_app.config["PAD_TOS_FILE"] admin_emails, admin_name = _get_admin_emails(username) pdf_attachment = _get_pad_confirmation_report_pdf(email_msg, token) tos_attachment = _get_pdf(pad_tos_file_name) html_body = _get_pad_confirmation_email_body(email_msg, admin_name) return { - 'recipients': admin_emails, - 'content': { - 'subject': 'Confirmation of Pre-Authorized Debit (PAD) Sign-up', - 'body': f'{html_body}', - 'attachments': [ + "recipients": admin_emails, + "content": { + "subject": "Confirmation of Pre-Authorized Debit (PAD) Sign-up", + "body": f"{html_body}", + "attachments": [ { - 'fileName': 'PAD_Confirmation_Letter.pdf', - 'fileBytes': pdf_attachment.decode('utf-8'), - 'fileUrl': '', - 'attachOrder': '1' + "fileName": "PAD_Confirmation_Letter.pdf", + "fileBytes": pdf_attachment.decode("utf-8"), + "fileUrl": "", + "attachOrder": "1", }, { - 'fileName': pad_tos_file_name, - 'fileBytes': tos_attachment.decode('utf-8'), - 'fileUrl': '', - 'attachOrder': '2' - } - ] - } + "fileName": pad_tos_file_name, + "fileBytes": tos_attachment.decode("utf-8"), + "fileUrl": "", + "attachOrder": "2", + }, + ], + }, } def _get_admin_emails(username): admin_user = UserModel.find_by_username(username) if admin_user: - admin_name = admin_user.firstname + ' ' + admin_user.lastname + admin_name = admin_user.firstname + " " + admin_user.lastname if admin_user.contacts: admin_emails = admin_user.contacts[0].contact.email else: admin_emails = admin_user.email else: - raise ValueError('Admin user not found, cannot determine email address.') + raise ValueError("Admin user not found, cannot determine email address.") return admin_emails, admin_name def _get_pad_confirmation_email_body(email_msg, admin_name): - filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), 'pad_confirmation_email') + filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), "pad_confirmation_email") # render template with vars from email msg jnja_template = Template(filled_template, autoescape=True) - html_out = jnja_template.render( - request=email_msg, admin_name=admin_name, logo_url=email_msg.get('logo_url') - - ) + html_out = jnja_template.render(request=email_msg, admin_name=admin_name, logo_url=email_msg.get("logo_url")) return html_out def _get_address(account_id: str): mailing_address = OrgService.get_contacts(account_id) - return mailing_address.get('contacts')[0] + return mailing_address.get("contacts")[0] def _get_pad_confirmation_report_pdf(email_msg, token): current_time = datetime.datetime.now() - mailing_address = _get_address(email_msg.get('accountId')) + mailing_address = _get_address(email_msg.get("accountId")) template_vars = { **email_msg, - 'generatedDate': current_time.strftime('%m-%d-%Y'), - 'accountAddress': mailing_address, - 'logo_url': email_msg.get('logo_url'), - 'registry_logo_url': email_msg.get('registry_logo_url') + "generatedDate": current_time.strftime("%m-%d-%Y"), + "accountAddress": mailing_address, + "logo_url": email_msg.get("logo_url"), + "registry_logo_url": email_msg.get("registry_logo_url"), } - filled_template = generate_template(current_app.config.get('PDF_TEMPLATE_PATH'), 'pad_confirmation') - template_b64 = "'" + base64.b64encode(bytes(filled_template, 'utf-8')).decode() + "'" + filled_template = generate_template(current_app.config.get("PDF_TEMPLATE_PATH"), "pad_confirmation") + template_b64 = "'" + base64.b64encode(bytes(filled_template, "utf-8")).decode() + "'" pdf_payload = { - 'reportName': 'PAD_Confirmation_Letter', - 'template': template_b64, - 'templateVars': template_vars, - 'populatePageNumber': True, + "reportName": "PAD_Confirmation_Letter", + "template": template_b64, + "templateVars": template_vars, + "populatePageNumber": True, } - report_response = RestService.post(endpoint=current_app.config.get('REPORT_API_BASE_URL'), - token=token, - auth_header_type=AuthHeaderType.BEARER, - content_type=ContentType.JSON, - data=pdf_payload, - raise_for_status=True, - additional_headers={'Accept': 'application/pdf'}) + report_response = RestService.post( + endpoint=current_app.config.get("REPORT_API_BASE_URL"), + token=token, + auth_header_type=AuthHeaderType.BEARER, + content_type=ContentType.JSON, + data=pdf_payload, + raise_for_status=True, + additional_headers={"Accept": "application/pdf"}, + ) pdf_attachment = None if report_response.status_code != 200: - logger.error('Failed to get pdf') + logger.error("Failed to get pdf") else: pdf_attachment = base64.b64encode(report_response.content) @@ -132,10 +130,12 @@ def _get_pad_confirmation_report_pdf(email_msg, token): def _get_pdf(pad_tos_file_name: str): + read_pdf = None - mino_object = minio_service.MinioService.get_minio_file(current_app.config['MINIO_BUCKET'], - pad_tos_file_name) - if mino_object: - read_pdf = base64.b64encode(mino_object.data) + store_blob = google_store.GoogleStoreService.download_file_from_bucket( + current_app.config["ACCOUNT_MAILER_BUCKET"], pad_tos_file_name + ) + if store_blob: + read_pdf = base64.b64encode(store_blob) return read_pdf diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/payment_completed.py b/queue_services/account-mailer/src/account_mailer/email_processors/payment_completed.py index f2210c0040..0b47e76a3c 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/payment_completed.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/payment_completed.py @@ -19,10 +19,10 @@ def process(email_msg: dict) -> dict: # TODO Replace this file return { - 'recipients': '', - 'content': { - 'subject': 'Payment Complete', - 'body': email_msg.get('body'), - 'attachments': [] - } + "recipients": "", + "content": { + "subject": "Payment Complete", + "body": email_msg.get("body"), + "attachments": [], + }, } diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/product_confirmation.py b/queue_services/account-mailer/src/account_mailer/email_processors/product_confirmation.py index 89dcab4722..35f9f89f23 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/product_confirmation.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/product_confirmation.py @@ -18,7 +18,7 @@ from flask import current_app from account_mailer.enums import AttachmentTypes -from account_mailer.services import minio_service +from account_mailer.services import google_store def process_attachment(email_dict: dict, attachment_type: str) -> dict: @@ -32,12 +32,12 @@ def process_attachment(email_dict: dict, attachment_type: str) -> dict: return email_dict pdf_attachment = _get_pdf(attachment_name) - email_dict['content']['attachments'] = [ + email_dict["content"]["attachments"] = [ { - 'fileName': attachment_name, - 'fileBytes': pdf_attachment.decode('utf-8'), - 'fileUrl': '', - 'attachOrder': '1' + "fileName": attachment_name, + "fileBytes": pdf_attachment.decode("utf-8"), + "fileUrl": "", + "attachOrder": "1", } ] @@ -46,16 +46,18 @@ def process_attachment(email_dict: dict, attachment_type: str) -> dict: def _get_attachment_name(attachment_type: str) -> str: if attachment_type == AttachmentTypes.QUALIFIED_SUPPLIER.value: - return current_app.config['MHR_QS_AGREEMENT_FILE'] + return current_app.config["MHR_QS_AGREEMENT_FILE"] return None -def _get_pdf(file_name: str): +def _get_pdf(pad_tos_file_name: str): + read_pdf = None - mino_object = minio_service.MinioService.get_minio_file(current_app.config['MINIO_BUCKET'], - file_name) - if mino_object: - read_pdf = base64.b64encode(mino_object.data) + store_blob = google_store.GoogleStoreService.download_file_from_bucket( + current_app.config["ACCOUNT_MAILER_BUCKET"], pad_tos_file_name + ) + if store_blob: + read_pdf = base64.b64encode(store_blob) return read_pdf diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/refund_requested.py b/queue_services/account-mailer/src/account_mailer/email_processors/refund_requested.py index b0ea94d6c6..ab96843744 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/refund_requested.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/refund_requested.py @@ -21,32 +21,24 @@ from account_mailer.email_processors import generate_template - logger = StructuredLogging.get_logger() def process(email_msg: dict) -> dict: """Build the email for Payment Completed notification.""" - logger.debug('refund_request notification: %s', email_msg) - template_name = 'bcol_refund_request_email' - recepients = current_app.config.get('REFUND_REQUEST').get('bcol').get('recipients') - refund_date = datetime.strptime(email_msg.get('refundDate'), '%Y%m%d').strftime('%Y-%m-%d') - subject = f'BC Registries and Online Services Refunds for {refund_date}' + logger.debug("refund_request notification: %s", email_msg) + template_name = "bcol_refund_request_email" + recepients = current_app.config.get("REFUND_REQUEST").get("bcol").get("recipients") + refund_date = datetime.strptime(email_msg.get("refundDate"), "%Y%m%d").strftime("%Y-%m-%d") + subject = f"BC Registries and Online Services Refunds for {refund_date}" # fill in template - filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), template_name) + filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), template_name) # render template with vars from email msg jnja_template = Template(filled_template, autoescape=True) - html_out = jnja_template.render( - refund_data=email_msg, - logo_url=email_msg.get('logo_url') - ) + html_out = jnja_template.render(refund_data=email_msg, logo_url=email_msg.get("logo_url")) return { - 'recipients': recepients, - 'content': { - 'subject': subject, - 'body': html_out, - 'attachments': [] - } + "recipients": recepients, + "content": {"subject": subject, "body": html_out, "attachments": []}, } diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/business-dashboard-link.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/business-dashboard-link.html deleted file mode 100644 index 5f7a631dc0..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/business-dashboard-link.html +++ /dev/null @@ -1,3 +0,0 @@ -<p class="business-dashboard-link"> - These documents are also available on the <a style="font-weight: 600" href="{{ entity_dashboard_url }}">Business Dashboard</a>. -</p> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/footer.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/footer.html deleted file mode 100644 index ca8dc8eb66..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/footer.html +++ /dev/null @@ -1,5 +0,0 @@ -<footer> - <div style="font-weight: 600;">Business Registry</div> - <div style="font-size: 13px">BC Registries and Online Services</div> - <div style="font-size: 13px"><a href="tel:1-877-526-1526">+1 (877) 526-1526</a></div> -</footer> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/header.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/header.html deleted file mode 100644 index e84c792134..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/header.html +++ /dev/null @@ -1,12 +0,0 @@ -<header> - <!-- table and cell padding doesn't work consistently -- use cellspacing instead --> - <table class="header-table" cellspacing="10" role="presentation"> - <tr> - <td>[[logo.html]]</td> - <td> - <div class="report-type">{{ email_header }}</div> - <div class="report-type-desc">BC Online Registries</div> - </td> - </tr> - </table> -</header> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/initiative-notice.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/initiative-notice.html deleted file mode 100644 index 509ab14f64..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/initiative-notice.html +++ /dev/null @@ -1,38 +0,0 @@ -<div class="initiative-notice"> - <p> - As part of a provincial and federal partnership, BC Registries and Online - Services, our New West Partners, and other Canadian jurisdictions have - developed an agreement to share company information. - </p> - - <!-- whitespace --> - <p style="margin-top: 16px !important;"> </p> - - <p> - The initiative will facilitate the updating of information to new or existing - extra provincial registrations of your BC company with one or more of the - partner jurisdictions. Select the jurisdictions you wish to be redirected - from the list below. You may want to submit a name search, register extra - provincially or update an existing extra provincial registration. - </p> - - <!-- whitespace --> - <p style="margin-top: 16px !important;"> </p> - - <p>Our Partners:</p> - <ul> - <li><a href="http://www.servicealberta.gov.ab.ca/Provincial-trade-agreement.cfm">Alberta</a></li> - <li><a href="https://companiesoffice.gov.mb.ca">Manitoba</a></li> - <li><a href="http://www.registreentreprises.gouv.qc.ca/en/consulter/rechercher/default.aspx">Quebec</a></li> - <li><a href="https://www.isc.ca/CorporateRegistry/Pages/default.aspx">Saskatchewan</a></li> - </ul> - - <!-- whitespace --> - <p style="margin-top: 16px !important;"> </p> - - <p> - If your jurisdiction is not listed as one of BC's extraprovincial partners, you - must contact the jurisdiction you wish to register in directly in order to submit - a name request or complete an extraprovincial registration. - </p> -</div> diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/logo.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/logo.html deleted file mode 100644 index f8d33bec83..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/logo.html +++ /dev/null @@ -1,3 +0,0 @@ -<div class="logo-container"> - <img alt="Government of British Columbia" src="{{ logo_url }}"> -</div> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/style.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/style.html deleted file mode 100644 index 8bdb5d815a..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/style.html +++ /dev/null @@ -1,70 +0,0 @@ -<style> - /* - * BCSans-Regular font - */ - @font-face { - font-family: 'BCSans-Regular'; - src: url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Regular.woff2') format('woff2'), - url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Regular.woff') format('woff'); - font-weight: normal; - font-style: normal; - } - - /* global resets */ - body, div, td, p { - margin: 0; - padding: 0; - } - - body { - min-width: 650px; - max-width: 1000px; - font-family: 'BCSans-Normal', sans-serif; - font-size: 14px; - tab-internal: 1.5in; /* for Microsoft Outlook */ - } - - table { - width: 100%; - } - - .logo-container { - display: inline-block; - text-align: left; - } - - .logo-container img { - width: 107px !important; - height: 101px !important; - } - - .report-type { - font-weight: bold; - color: #234075; - font-size: 16px; - text-align: right; - } - - .report-type-desc { - color: #1A5A96; - font-size: 14px; - text-align: right; - } - - .business-info-table { - border-top: 1px solid black; - border-bottom: 1px solid black; - } - - .business-info-table .value { - font-weight: bold; - } - - .container { - margin: 16px; - } - - .uppercase { - text-transform: uppercase; - } - </style> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-16px.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-16px.html deleted file mode 100644 index 1ef1ab5b86..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-16px.html +++ /dev/null @@ -1,2 +0,0 @@ - <!-- empty paragraph for spacing --> - <p style="margin-top: 16px !important;"> </p> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-24px.html b/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-24px.html deleted file mode 100644 index ea0a8030fb..0000000000 --- a/queue_services/account-mailer/src/account_mailer/email_templates/common/whitespace-24px.html +++ /dev/null @@ -1,2 +0,0 @@ - <!-- empty paragraph for spacing --> - <p style="margin-top: 24px !important;"> </p> \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html b/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html index 005afb6825..df0d2b6659 100644 --- a/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html +++ b/queue_services/account-mailer/src/account_mailer/email_templates/pad_invoice_email.html @@ -1,6 +1,6 @@ # This email confirms recent transaction(s) on you account {{ account_number }}: {{ account_name_with_branch }}. -Transaction date: ${{ invoice_process_date }} +Transaction date: {{ invoice_process_date }} Invoice reference number: {{ invoice_number }} Transaction amount: ${{ invoice_total }} @@ -15,6 +15,6 @@ **Business Registry** BC Registries and Online services -Toll Free: 1-877-526-1526 -Victoria Office: 250-387-7848 +Toll Free: [1-877-526-1526](1-877-526-1526) +Victoria Office: [250-387-7848](250-387-7848) Email: [BCRegistries@gov.bc.ca](BCRegistries@gov.bc.ca) diff --git a/queue_services/account-mailer/src/account_mailer/enums.py b/queue_services/account-mailer/src/account_mailer/enums.py index 1a5207104a..392e823af3 100644 --- a/queue_services/account-mailer/src/account_mailer/enums.py +++ b/queue_services/account-mailer/src/account_mailer/enums.py @@ -18,147 +18,164 @@ class SubjectType(Enum): """Event Types.""" - NSF_LOCK_ACCOUNT_SUBJECT = '[BC Registries and Online Services] Your account has been suspended' - NSF_UNLOCK_ACCOUNT_SUBJECT = 'Your Account Was Successfully Restored' - ACCOUNT_CONF_OVER_SUBJECT = '[BC Registries and Online Services] Your account is now active' - PAD_INVOICE_CREATED = '[BC Registries and Online Services] Your PAD Transaction Details' - ADMIN_REMOVED_SUBJECT = '[BC Registries and Online Services] You have been removed as an administrator' - TEAM_MODIFIED_SUBJECT = '[BC Registries and Online Services] Change in Team members' - ONLINE_BANKING_PAYMENT_SUBJECT = '[BC Registries and Online Services] Online Banking payment has been received' - PAD_SETUP_FAILED = '[BC Registries and Online Services] Your Account is Temporarily Suspended' - PAYMENT_PENDING = '[BC Registries and Online Services] Payment is now due for pending transaction on your account' - EJV_FAILED = 'GL disbursement failure for EJV' - RESET_PASSCODE = 'BC Registries Account Passcode Reset' - ADMIN_NOTIFICATION = '[BC Registries and Online Services] {user_first_name} {user_last_name} ' \ - 'has responded for the invitation to join the account {account_name}' - AFFILIATION_INVITATION = '[BC Registries and Online Services] Authorise Access to Manage Your Business' - BUSINESS_INVITATION = '[BC Registries and Online Services] {user_first_name} {user_last_name} ' \ - 'has invited you to join an account' - BUSINESS_INVITATION_FOR_BCEID = '[BC Registries and Online Services] {user_first_name} {user_last_name} ' \ - 'has invited you to join an account' - DIRSEARCH_BUSINESS_INVITATION = 'Your BC Registries Account has been created' - GOVM_BUSINESS_INVITATION = '[BC Registries and Online Services] ' \ - 'You’ve been invited to create a BC Registries account' - GOVM_MEMBER_INVITATION = '[BC Registries and Online Services] You have been added as a team member' - MEMBERSHIP_APPROVED_NOTIFICATION = '[BC Registries and Online Services] Welcome to the account {account_name}' - MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID = '[BC Registries and Online Services] Welcome to the account ' \ - '{account_name}' - NON_BCSC_ORG_APPROVED_NOTIFICATION = '[BC Registries and Online Services] APPROVED Business Registry Account' - NON_BCSC_ORG_REJECTED_NOTIFICATION = '[BC Registries and Online Services] YOUR ACTION REQUIRED: ' \ - 'Business Registry Account cannot be approved' - OTP_AUTHENTICATOR_RESET_NOTIFICATION = '[BC Registries and Online Services] Authenticator Has Been Reset' - ROLE_CHANGED_NOTIFICATION = '[BC Registries and Online Services] Your Role Has Been Changed' - STAFF_REVIEW_ACCOUNT = '[BC Registries and Online Services] An out of province account needs to be approved.' - GOVM_APPROVED_NOTIFICATION = '[BC Registries and Online Services] Your BC Registries Account Has Been Approved' - GOVM_REJECTED_NOTIFICATION = '[BC Registries and Online Services] Your BC Registries Account {account_name} ' \ - 'Has Been Rejected' - PROD_PACKAGE_APPROVED_NOTIFICATION = '[BC Registries and Online Services] Your Product Request ' \ - '{product_name} Has Been Approved' - PROD_PACKAGE_REJECTED_NOTIFICATION = '[BC Registries and Online Services] YOUR ACTION REQUIRED: ' \ - 'Your Product Request {product_name} Has Been Rejected' - PRODUCT_APPROVED_NOTIFICATION_DETAILED = '[BC Registries and Online Services] Your {subject_descriptor} ' \ - 'Access Has Been Approved' - PRODUCT_REJECTED_NOTIFICATION_DETAILED = '[BC Registries and Online Services] Your {subject_descriptor} ' \ - 'Access Has Been Rejected' - PRODUCT_CONFIRMATION_NOTIFICATION = '[BC Registries and Online Services] {subject_descriptor} ' \ - 'Application Confirmation' - RESUBMIT_BCEID_ORG_NOTIFICATION = '[BC Registries and Online Services] YOUR ACTION REQUIRED: ' \ - 'Update your information.' - RESUBMIT_BCEID_ADMIN_NOTIFICATION = '[BC Registries and Online Services] YOUR ACTION REQUIRED: ' \ - 'Update your information.' - AFFILIATION_INVITATION_REQUEST = '[BC Registries and Online Services] Request to manage {business_name}' - AFFILIATION_INVITATION_REQUEST_AUTHORIZATION = '[BC Registries and Online Services] ' \ - 'Request to manage {business_name}' - STATEMENT_NOTIFICATION = 'Your BC Registries statement is available' - PAYMENT_REMINDER_NOTIFICATION = 'Your BC Registries payment reminder' - PAYMENT_DUE_NOTIFICATION = 'Your BC Registries payment is due' - EFT_AVAILABLE_NOTIFICATION = 'New Payment Method Available' + NSF_LOCK_ACCOUNT_SUBJECT = "[BC Registries and Online Services] Your account has been suspended" + NSF_UNLOCK_ACCOUNT_SUBJECT = "Your Account Was Successfully Restored" + ACCOUNT_CONF_OVER_SUBJECT = "[BC Registries and Online Services] Your account is now active" + PAD_INVOICE_CREATED = "[BC Registries and Online Services] Your PAD Transaction Details" + ADMIN_REMOVED_SUBJECT = "[BC Registries and Online Services] You have been removed as an administrator" + TEAM_MODIFIED_SUBJECT = "[BC Registries and Online Services] Change in Team members" + ONLINE_BANKING_PAYMENT_SUBJECT = "[BC Registries and Online Services] Online Banking payment has been received" + PAD_SETUP_FAILED = "[BC Registries and Online Services] Your Account is Temporarily Suspended" + PAYMENT_PENDING = "[BC Registries and Online Services] Payment is now due for pending transaction on your account" + EJV_FAILED = "GL disbursement failure for EJV" + RESET_PASSCODE = "BC Registries Account Passcode Reset" + ADMIN_NOTIFICATION = ( + "[BC Registries and Online Services] {user_first_name} {user_last_name} " + "has responded for the invitation to join the account {account_name}" + ) + AFFILIATION_INVITATION = "[BC Registries and Online Services] Authorise Access to Manage Your Business" + BUSINESS_INVITATION = ( + "[BC Registries and Online Services] {user_first_name} {user_last_name} " "has invited you to join an account" + ) + BUSINESS_INVITATION_FOR_BCEID = ( + "[BC Registries and Online Services] {user_first_name} {user_last_name} " "has invited you to join an account" + ) + DIRSEARCH_BUSINESS_INVITATION = "Your BC Registries Account has been created" + GOVM_BUSINESS_INVITATION = ( + "[BC Registries and Online Services] " "You’ve been invited to create a BC Registries account" + ) + GOVM_MEMBER_INVITATION = "[BC Registries and Online Services] You have been added as a team member" + MEMBERSHIP_APPROVED_NOTIFICATION = "[BC Registries and Online Services] Welcome to the account {account_name}" + MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID = ( + "[BC Registries and Online Services] Welcome to the account " "{account_name}" + ) + NON_BCSC_ORG_APPROVED_NOTIFICATION = "[BC Registries and Online Services] APPROVED Business Registry Account" + NON_BCSC_ORG_REJECTED_NOTIFICATION = ( + "[BC Registries and Online Services] YOUR ACTION REQUIRED: " "Business Registry Account cannot be approved" + ) + OTP_AUTHENTICATOR_RESET_NOTIFICATION = "[BC Registries and Online Services] Authenticator Has Been Reset" + ROLE_CHANGED_NOTIFICATION = "[BC Registries and Online Services] Your Role Has Been Changed" + STAFF_REVIEW_ACCOUNT = "[BC Registries and Online Services] An out of province account needs to be approved." + GOVM_APPROVED_NOTIFICATION = "[BC Registries and Online Services] Your BC Registries Account Has Been Approved" + GOVM_REJECTED_NOTIFICATION = ( + "[BC Registries and Online Services] Your BC Registries Account {account_name} " "Has Been Rejected" + ) + PROD_PACKAGE_APPROVED_NOTIFICATION = ( + "[BC Registries and Online Services] Your Product Request " "{product_name} Has Been Approved" + ) + PROD_PACKAGE_REJECTED_NOTIFICATION = ( + "[BC Registries and Online Services] YOUR ACTION REQUIRED: " + "Your Product Request {product_name} Has Been Rejected" + ) + PRODUCT_APPROVED_NOTIFICATION_DETAILED = ( + "[BC Registries and Online Services] Your {subject_descriptor} " "Access Has Been Approved" + ) + PRODUCT_REJECTED_NOTIFICATION_DETAILED = ( + "[BC Registries and Online Services] Your {subject_descriptor} " "Access Has Been Rejected" + ) + PRODUCT_CONFIRMATION_NOTIFICATION = ( + "[BC Registries and Online Services] {subject_descriptor} " "Application Confirmation" + ) + RESUBMIT_BCEID_ORG_NOTIFICATION = ( + "[BC Registries and Online Services] YOUR ACTION REQUIRED: " "Update your information." + ) + RESUBMIT_BCEID_ADMIN_NOTIFICATION = ( + "[BC Registries and Online Services] YOUR ACTION REQUIRED: " "Update your information." + ) + AFFILIATION_INVITATION_REQUEST = "[BC Registries and Online Services] Request to manage {business_name}" + AFFILIATION_INVITATION_REQUEST_AUTHORIZATION = ( + "[BC Registries and Online Services] " "Request to manage {business_name}" + ) + STATEMENT_NOTIFICATION = "Your BC Registries statement is available" + PAYMENT_REMINDER_NOTIFICATION = "Your BC Registries payment reminder" + PAYMENT_DUE_NOTIFICATION = "Your BC Registries payment is due" + EFT_AVAILABLE_NOTIFICATION = "New Payment Method Available" class TitleType(Enum): """Event Title Types.""" - ADMIN_NOTIFICATION = 'Notification from Business Registry' - BUSINESS_INVITATION = 'Invitation to Join an Account at Business Registry' - BUSINESS_INVITATION_FOR_BCEID = 'Invitation to Join an Account at Business Registry' - DIRSEARCH_BUSINESS_INVITATION = 'Invitation to Join an Account at Business Registry' - GOVM_BUSINESS_INVITATION = 'Invitation to Join an Account at Business Registry' - GOVM_MEMBER_INVITATION = 'Invitation to Join an Account at Business Registry' - MEMBERSHIP_APPROVED_NOTIFICATION = 'Your Membership Has Been Approved' - MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID = 'Your Membership Has Been Approved' - NON_BCSC_ORG_APPROVED_NOTIFICATION = 'Your Membership Has Been Approved' - NON_BCSC_ORG_REJECTED_NOTIFICATION = 'Your Membership Has Been Rejected' - OTP_AUTHENTICATOR_RESET_NOTIFICATION = 'Your Authenticator Has Been Reset' - ROLE_CHANGED_NOTIFICATION = 'Your Role Has Been Changed' - STAFF_REVIEW_ACCOUNT = 'Notification from Business Registry' - GOVM_APPROVED_NOTIFICATION = 'Your BC Registries Account Has Been Approved' - GOVM_REJECTED_NOTIFICATION = 'Your BC Registries Account Has Been Rejected' - PROD_PACKAGE_APPROVED_NOTIFICATION = 'Your Product Request Has Been Approved' - PROD_PACKAGE_REJECTED_NOTIFICATION = 'Your Product Request Has Been Rejected' - PRODUCT_APPROVED_NOTIFICATION_DETAILED = 'Your Product Request Has Been Approved' - PRODUCT_REJECTED_NOTIFICATION_DETAILED = 'Your Product Request Has Been Rejected' - PRODUCT_CONFIRMATION_NOTIFICATION = 'Your Product Request Application Has Been Received' - RESUBMIT_BCEID_ORG_NOTIFICATION = 'Your Account Creation Request is On hold ' - RESUBMIT_BCEID_ADMIN_NOTIFICATION = 'Your Team Member Request is On hold ' - AFFILIATION_INVITATION = 'Invitation to manage a business with your account.' - AFFILIATION_INVITATION_REQUEST = 'You have been authorized to manage the business.' - AFFILIATION_INVITATION_REQUEST_AUTHORIZATION = 'You have been authorized to manage the business.' + ADMIN_NOTIFICATION = "Notification from Business Registry" + BUSINESS_INVITATION = "Invitation to Join an Account at Business Registry" + BUSINESS_INVITATION_FOR_BCEID = "Invitation to Join an Account at Business Registry" + DIRSEARCH_BUSINESS_INVITATION = "Invitation to Join an Account at Business Registry" + GOVM_BUSINESS_INVITATION = "Invitation to Join an Account at Business Registry" + GOVM_MEMBER_INVITATION = "Invitation to Join an Account at Business Registry" + MEMBERSHIP_APPROVED_NOTIFICATION = "Your Membership Has Been Approved" + MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID = "Your Membership Has Been Approved" + NON_BCSC_ORG_APPROVED_NOTIFICATION = "Your Membership Has Been Approved" + NON_BCSC_ORG_REJECTED_NOTIFICATION = "Your Membership Has Been Rejected" + OTP_AUTHENTICATOR_RESET_NOTIFICATION = "Your Authenticator Has Been Reset" + ROLE_CHANGED_NOTIFICATION = "Your Role Has Been Changed" + STAFF_REVIEW_ACCOUNT = "Notification from Business Registry" + GOVM_APPROVED_NOTIFICATION = "Your BC Registries Account Has Been Approved" + GOVM_REJECTED_NOTIFICATION = "Your BC Registries Account Has Been Rejected" + PROD_PACKAGE_APPROVED_NOTIFICATION = "Your Product Request Has Been Approved" + PROD_PACKAGE_REJECTED_NOTIFICATION = "Your Product Request Has Been Rejected" + PRODUCT_APPROVED_NOTIFICATION_DETAILED = "Your Product Request Has Been Approved" + PRODUCT_REJECTED_NOTIFICATION_DETAILED = "Your Product Request Has Been Rejected" + PRODUCT_CONFIRMATION_NOTIFICATION = "Your Product Request Application Has Been Received" + RESUBMIT_BCEID_ORG_NOTIFICATION = "Your Account Creation Request is On hold " + RESUBMIT_BCEID_ADMIN_NOTIFICATION = "Your Team Member Request is On hold " + AFFILIATION_INVITATION = "Invitation to manage a business with your account." + AFFILIATION_INVITATION_REQUEST = "You have been authorized to manage the business." + AFFILIATION_INVITATION_REQUEST_AUTHORIZATION = "You have been authorized to manage the business." class TemplateType(Enum): """Template Types.""" - NSF_LOCK_ACCOUNT_TEMPLATE_NAME = 'account_suspended_email' - NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME = 'account_unlocked_email' - ACCOUNT_CONF_OVER_TEMPLATE_NAME = 'account_conf_over_email' - PAD_INVOICE_CREATED_TEMPLATE_NAME = 'pad_invoice_email' - ADMIN_REMOVED_TEMPLATE_NAME = 'admin_removed_email' - TEAM_MODIFIED_TEMPLATE_NAME = 'team_modified_email' - ONLINE_BANKING_PAYMENT_TEMPLATE_NAME = 'online_banking_payment' - ONLINE_BANKING_OVER_PAYMENT_TEMPLATE_NAME = 'online_banking_over_payment' - ONLINE_BANKING_UNDER_PAYMENT_TEMPLATE_NAME = 'online_banking_under_payment' - PAD_SETUP_FAILED_TEMPLATE_NAME = 'pad_setup_failed' - PAYMENT_PENDING_TEMPLATE_NAME = 'paymanet_pending' - EJV_FAILED_TEMPLATE_NAME = 'ejv_failed_email' - RESET_PASSCODE_TEMPLATE_NAME = 'reset_passcode' - ADMIN_NOTIFICATION_TEMPLATE_NAME = 'admin_notification_email' - AFFILIATION_INVITATION_TEMPLATE_NAME = 'affiliation_invitation_email' - BUSINESS_INVITATION_TEMPLATE_NAME = 'business_invitation_email' - BUSINESS_INVITATION_FOR_BCEID_TEMPLATE_NAME = 'business_invitation_email_for_bceid' - DIRSEARCH_BUSINESS_INVITATION_TEMPLATE_NAME = 'dirsearch_business_invitation_email' - GOVM_BUSINESS_INVITATION_TEMPLATE_NAME = 'govm_business_invitation_email' - GOVM_MEMBER_INVITATION_TEMPLATE_NAME = 'govm_member_invitation_email' - MEMBERSHIP_APPROVED_NOTIFICATION_TEMPLATE_NAME = 'membership_approved_notification_email' - MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID_TEMPLATE_NAME = 'membership_approved_notification_email_for_bceid' - NON_BCSC_ORG_APPROVED_NOTIFICATION_TEMPLATE_NAME = 'nonbcsc_org_approved_notification_email' - NON_BCSC_ORG_REJECTED_NOTIFICATION_TEMPLATE_NAME = 'nonbcsc_org_rejected_notification_email' - OTP_AUTHENTICATOR_RESET_NOTIFICATION_TEMPLATE_NAME = 'otp_authenticator_reset_notification_email' - ROLE_CHANGED_NOTIFICATION_TEMPLATE_NAME = 'role_changed_notification_email' - STAFF_REVIEW_ACCOUNT_TEMPLATE_NAME = 'staff_review_account_email' - GOVM_APPROVED_NOTIFICATION_TEMPLATE_NAME = 'govm_approved_notification' - GOVM_REJECTED_NOTIFICATION_TEMPLATE_NAME = 'govm_rejected_notification' - PROD_PACKAGE_APPROVED_NOTIFICATION_TEMPLATE_NAME = 'prod_package_approved_notification' - PROD_PACKAGE_REJECTED_NOTIFICATION_TEMPLATE_NAME = 'prod_package_rejected_notification' - PRODUCT_APPROVED_NOTIFICATION_DETAILED_TEMPLATE_NAME = 'product_approved_notification_detailed' - PRODUCT_REJECTED_NOTIFICATION_DETAILED_TEMPLATE_NAME = 'product_rejected_notification_detailed' - PRODUCT_CONFIRMATION_NOTIFICATION_TEMPLATE_NAME = 'product_confirmation_notification' - RESUBMIT_BCEID_ORG_NOTIFICATION_TEMPLATE_NAME = 'resubmit_bceid_org' - RESUBMIT_BCEID_ADMIN_NOTIFICATION_TEMPLATE_NAME = 'resubmit_bceid_admin' - AFFILIATION_INVITATION_REQUEST_TEMPLATE_NAME = 'affiliation_invitation_request' - AFFILIATION_INVITATION_REQUEST_AUTHORIZATION_TEMPLATE_NAME = 'affiliation_invitation_request_authorization' - STATEMENT_NOTIFICATION_TEMPLATE_NAME = 'statement_notification' - PAYMENT_REMINDER_NOTIFICATION_TEMPLATE_NAME = 'payment_reminder_notification' - PAYMENT_DUE_NOTIFICATION_TEMPLATE_NAME = 'payment_due_notification' - EFT_AVAILABLE_NOTIFICATION_TEMPLATE_NAME = 'eft_available_notification' + NSF_LOCK_ACCOUNT_TEMPLATE_NAME = "account_suspended_email" + NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME = "account_unlocked_email" + ACCOUNT_CONF_OVER_TEMPLATE_NAME = "account_conf_over_email" + PAD_INVOICE_CREATED_TEMPLATE_NAME = "pad_invoice_email" + ADMIN_REMOVED_TEMPLATE_NAME = "admin_removed_email" + TEAM_MODIFIED_TEMPLATE_NAME = "team_modified_email" + ONLINE_BANKING_PAYMENT_TEMPLATE_NAME = "online_banking_payment" + ONLINE_BANKING_OVER_PAYMENT_TEMPLATE_NAME = "online_banking_over_payment" + ONLINE_BANKING_UNDER_PAYMENT_TEMPLATE_NAME = "online_banking_under_payment" + PAD_SETUP_FAILED_TEMPLATE_NAME = "pad_setup_failed" + PAYMENT_PENDING_TEMPLATE_NAME = "paymanet_pending" + EJV_FAILED_TEMPLATE_NAME = "ejv_failed_email" + RESET_PASSCODE_TEMPLATE_NAME = "reset_passcode" + ADMIN_NOTIFICATION_TEMPLATE_NAME = "admin_notification_email" + AFFILIATION_INVITATION_TEMPLATE_NAME = "affiliation_invitation_email" + BUSINESS_INVITATION_TEMPLATE_NAME = "business_invitation_email" + BUSINESS_INVITATION_FOR_BCEID_TEMPLATE_NAME = "business_invitation_email_for_bceid" + DIRSEARCH_BUSINESS_INVITATION_TEMPLATE_NAME = "dirsearch_business_invitation_email" + GOVM_BUSINESS_INVITATION_TEMPLATE_NAME = "govm_business_invitation_email" + GOVM_MEMBER_INVITATION_TEMPLATE_NAME = "govm_member_invitation_email" + MEMBERSHIP_APPROVED_NOTIFICATION_TEMPLATE_NAME = "membership_approved_notification_email" + MEMBERSHIP_APPROVED_NOTIFICATION_FOR_BCEID_TEMPLATE_NAME = "membership_approved_notification_email_for_bceid" + NON_BCSC_ORG_APPROVED_NOTIFICATION_TEMPLATE_NAME = "nonbcsc_org_approved_notification_email" + NON_BCSC_ORG_REJECTED_NOTIFICATION_TEMPLATE_NAME = "nonbcsc_org_rejected_notification_email" + OTP_AUTHENTICATOR_RESET_NOTIFICATION_TEMPLATE_NAME = "otp_authenticator_reset_notification_email" + ROLE_CHANGED_NOTIFICATION_TEMPLATE_NAME = "role_changed_notification_email" + STAFF_REVIEW_ACCOUNT_TEMPLATE_NAME = "staff_review_account_email" + GOVM_APPROVED_NOTIFICATION_TEMPLATE_NAME = "govm_approved_notification" + GOVM_REJECTED_NOTIFICATION_TEMPLATE_NAME = "govm_rejected_notification" + PROD_PACKAGE_APPROVED_NOTIFICATION_TEMPLATE_NAME = "prod_package_approved_notification" + PROD_PACKAGE_REJECTED_NOTIFICATION_TEMPLATE_NAME = "prod_package_rejected_notification" + PRODUCT_APPROVED_NOTIFICATION_DETAILED_TEMPLATE_NAME = "product_approved_notification_detailed" + PRODUCT_REJECTED_NOTIFICATION_DETAILED_TEMPLATE_NAME = "product_rejected_notification_detailed" + PRODUCT_CONFIRMATION_NOTIFICATION_TEMPLATE_NAME = "product_confirmation_notification" + RESUBMIT_BCEID_ORG_NOTIFICATION_TEMPLATE_NAME = "resubmit_bceid_org" + RESUBMIT_BCEID_ADMIN_NOTIFICATION_TEMPLATE_NAME = "resubmit_bceid_admin" + AFFILIATION_INVITATION_REQUEST_TEMPLATE_NAME = "affiliation_invitation_request" + AFFILIATION_INVITATION_REQUEST_AUTHORIZATION_TEMPLATE_NAME = "affiliation_invitation_request_authorization" + STATEMENT_NOTIFICATION_TEMPLATE_NAME = "statement_notification" + PAYMENT_REMINDER_NOTIFICATION_TEMPLATE_NAME = "payment_reminder_notification" + PAYMENT_DUE_NOTIFICATION_TEMPLATE_NAME = "payment_due_notification" + EFT_AVAILABLE_NOTIFICATION_TEMPLATE_NAME = "eft_available_notification" class Constants(Enum): """Constants.""" - RESET_PASSCODE_HEADER = 'BC Registries have generated a new passcode for your business.' + RESET_PASSCODE_HEADER = "BC Registries have generated a new passcode for your business." class AttachmentTypes(Enum): """Notification Attachment Types.""" - QUALIFIED_SUPPLIER = 'QUALIFIED_SUPPLIER' + QUALIFIED_SUPPLIER = "QUALIFIED_SUPPLIER" diff --git a/queue_services/account-mailer/src/account_mailer/pdf_templates/common/fonts.html b/queue_services/account-mailer/src/account_mailer/pdf_templates/common/fonts.html index b8368ca04b..d03083add5 100644 --- a/queue_services/account-mailer/src/account_mailer/pdf_templates/common/fonts.html +++ b/queue_services/account-mailer/src/account_mailer/pdf_templates/common/fonts.html @@ -1,8 +1,7 @@ /* BCSans-Bold */ @font-face { font-family: 'BCSans-Bold'; - src: url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Bold.woff2') format('woff2'), - url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Bold.woff') format('woff'); + src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); font-weight: normal; font-style: normal; } @@ -10,8 +9,7 @@ /* BCSans-Regular */ @font-face { font-family: 'BCSans-Regular'; - src: url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Regular.woff2') format('woff2'), - url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Regular.woff') format('woff'); + src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); font-weight: normal; font-style: normal; } @@ -19,8 +17,7 @@ /* BCSans-Italic */ @font-face { font-family: 'BCSans-Italic'; - src: url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Italic.woff2') format('woff2'), - url('https://minio.apps.silver.devops.gov.bc.ca/public/BCSans-Italic.woff') format('woff'); + src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAHKsABIAAAABA3QAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABlAAAABwAAAAcjN2FC0dERUYAAAGwAAAAIgAAACQBHAHPR1BPUwAAAdQAAAfcAAA+8lfSas9HU1VCAAAJsAAAAZMAAAQGjFKFW09TLzIAAAtEAAAAWgAAAGCWGaQ7Y21hcAAAC6AAAAGIAAAB4uXMQipjdnQgAAANKAAAAFYAAABWFbwPyWZwZ20AAA2AAAABsQAAAmVTtC+nZ2FzcAAADzQAAAAIAAAACAAAABBnbHlmAAAPPAAAWTIAAKhA5A4d8mhlYWQAAGhwAAAANgAAADYX2GB8aGhlYQAAaKgAAAAiAAAAJA7xBedobXR4AABozAAAAk4AAAOmpww7kWxvY2EAAGscAAABygAAAdbrq8MIbWF4cAAAbOgAAAAgAAAAIAIHAc1uYW1lAABtCAAAAysAAAgyvzn0QnBvc3QAAHA0AAAB7wAAAt17hIzucHJlcAAAciQAAACHAAAAr/MTFqYAAAABAAAAANqHb48AAAAA0w+ShgAAAADfRoL1eNpjYGRgYOABYhkgZgJCRoanQPyM4SWQzQIWYwAAKkMC7AAAeNrtW1tsFFUY/rZplUtjaVosMdEQgoVBi5ZbacsSqpXL0m3pghRkNRhCfeCSLDFG0/AgsNyUYAgqWVQI3pO6D8QHookIwyuPOlQaAi8kJvvsAw+u35zd2Z3ZnZmd3ZntTon75cyenTnnzH++85///P+ZWQQAzML7OI76/vUD2/DMng8O7Uf7O4f27sPq/W+/exD9qGcZpNPIlA1sjbwyn9/aGf3VBWh4tW/bfCwI921Uj0MDPA72becxMhTmMVcysG/voYOYoeZEqkcdf9VhVuAhAoH3RKud2E+5PsFnGMdVXOPxEcYD9YGnAvOI53A8sFjk5jHXwys7WDaPqzmM68F6j0Sdq8yN4wl0pePoTivoYVqTlnGJ6RZTHTp4zzAilK4Do2hAUzqFZqYJpkmme0wB9LKeWmIMc9AIiaXiLBVnXyUs5LV1/N7NdIT5o0zHmOJMx5lOME2w7CTTPaY6zGSbaot1OMDcfSb1nCJaC4ij+lsWuXrKJHEkJNxhusv0pJC0i+W7WbOHSd8j9eptXk3yqsyrMq8meTXJq0m23omZmI2FeB6LsJitLcNyrMBKdKEbPViDtViPnXgDUbyFPTiMD3EER3EMcY7SCZzEaXyEj3EG53Aen3LUPscFJHAJl3EdN3ATt/AAdb331bHtbu3ZzrYimBYf8pnLcZSsy8UKa5BjFOaYT3gjTcF5WZVOfx9L6eLpZEYGTRL+jlYuVTrBukHtDvn7FPdYld1MfmqqP0c+5XPNTApGU5y/ViU0fZWy5eO2rSWtRs5aB/UlrLQvq21J6qhceM/SfRTzTpmaseadUv4bdfPek82oXv5///HsfnZakijPLhmvmcnozh7y01oJj9aaVyijnXxGpjLtu+6Pw5GwKpOZLWLeGDREZ4OjnmqnXGkZdaZxvsmVtlr5aul76342++21jxT0sC1NtjF7nqfIRsq52SeZ6wD9FEW3FiZM5pZkXHVMVzHFmU0pWukULzRZ54tWrL1azQokOltrf0fnc2a9TXqzcXt7qZYxjiK93STPJtS6pv5o3IKxhMGKpqzWB9djnTKOsHtLZdUC1wo5y5FcuCKa9csQxwhvTvXqStnv6lqH2ttxa//Uwn8u6VW7X92czKJyy2Tijam26576ivmWbleuT7kVxTRWcMJv7SPHx19Gd3ZBv94Wa71FRKZ4ZU+m2j93V7+0vFwrYsLbjxn3IMRqHCvVniiVsLSxytRooHdzxma/JuVudLzjovKWbONlG1/J4EnL1Z0j5dWuhofh0jr5fGcy41OW1hKjR+01F1b74emNBaWSxRGgacwl5yIKpcCOJbUem/u9vEdM3WPXdsBFyaQmoxqLZOtL5vMlI6Muko2ZRJzJ3NVokQWNl4xdY2azVPcEQ3G2D5aTMWkaCSSqNa89j68Vt7bFwK7Btmm6rz2HsVsZjBJlRsE8aq1+pJXf93GyL+mFxTLnkAym7LWwslihMO7OnbFZr9WYKB8HWPiF+WdvUXXv1cwqsaaUtQuxoj0pKWsDFK1utoVWXcv53akxwy5WnNLF9FG6bq4m8hG9tReWKz+atQOx8tZ+c10xsOxaa13HCtWeN1LNV+OoxVoYKz1WtjtIqg4pxTufwk7JFqtynLXk3FqYKKcXduOWXeVya53pPJPLsVSe6MVZJ1cMdxpz6vuLHbjUFOlw8Wc0d5RMznv9GSub4TH3s79cVqsxCrV/ugLtaU+kemNtHeF7tk8xrWMuJ+z4YS/cdt/M0c53rWIA//kUvpj5LqX2cE8qVQ3NnxZ7KbY+UuZZhi7iVnzAheQn77fUvPbbW4m+f/OwpvJl3mGyedc1rs9pbx/mfOZ45ZZdeNyjxbuX9l5IdjWUnT0vNO556N80MLesbqyik3Gs2hokOR1rB6ViZYxhvHYzxWavOlXevKrSDIxMj2fDfrBT5c0787d5nL9rUPWPj9ZrgwVM2b1VV5pJp2xXi2fv3tt7zOdbpNCGF+xMJvPjL/a1U24tu59jq2kRk/hRxuDjM2csnnGlvNyj+F+Xa77S1WElGogOzCI60ES0YA4xD81ECxYSw2gnJCwiBrGYGMJSohkvEcsEBrGcmIEVxCC6iHasJtaKf3C+iF6iGWuITs6TIFrRT4xgE9GEzcQItvBOI3ideIHfI3hZ/OczhF3EDkSJEA4QjThMzMYRnGCNk8QQThESTuMM8+eIQZzHBR4TxCAu4itKconoxGViBq7ge97hOhHCDSKEm8QQbhGd+AN/kgEFd8jJBNGCv3CX+UmiBfeJRjwgZpPBPsHgXMHgXJ5vZD9VHtt0PLYJHkOCxzCWEGHBWljwFRZ8PSv42iD4WiKYWiWYehrriGbB12a8RgSxHhvZc5W7XrYaIlMqg0H2dIhHlccBetMRfm8lBrCNGBbMDmA7sVzwu5qs7uCZnWS2H28Sy7CbaBYs1wuWGwTLIcFyk2A5LJgNC2bDgtkNgtlV5PQK7/I1fqAsP+In5n/GNR5/IYbxK37jvVTG+/E7ERS89wvew5CJYcH+qiz7d4i5gv02cn+XeZX9Ntwj2sQY1IsxaMBD/E0eAux7A8egiaw3k+128V/ipUJD1X8Td7G/Kre9ZDbI+26ilFsEKyNCz3aRhQPssfGfxacs/lt8EV/gS/Zd/Y/xFfb5G3yL76hT2v+N1T6o+jMhNGeS0j74DyKZsPd42qWS0UoCURCG/zm2FhESZhFLF0sIQQSJhN0kZIl1oQm2bDcVxJZBbSqrBlJP4CN01WWP0VXPEdED9AY1O3uwMtOgizNnZr5/h5mzAwIwiXu8YCxfKNow3Y7vYeXcP7tE3jtp1eBgjDV4f5ebEOF7ErRf2bL4/p7/qVyEsZ2zLaRKuV0Li6Vyke1ezmFbKZfY9umDyJBISWy47lUDVtU/cbHs1V0Pqbp/WkOm2W40scHKiNYG30TFhtXGxRqYQBwmkshgFzYOUQUJORa1QgNd8aL8Co94JpBFm2GG9sijLj3QE71KJkJvKq7WwgqqEFZQtrrQ3rW644ox7sDDrZygmyTSyKOie4zxmdMTFlGSWiGZ5sw8FvoY6RkToiCeBTpPWBKbHcGPfuU7I/i62MwI7vzKD3pcMTdFgS88q6cbTI/+QTNDqfMnGmzHNP8r0v+EUBbb0f4gxeoXxWpPkeh7l454ClOsuEELbdn+BGa5VvCWcdmTz54wJGsKCeNwc5K8bYq9GelqsCbN+9jTfAAXy0SDAHjaY2Bh4WWcwMDKwMJqzHL2/32GWSCaYQbTWYY0pskMSOABA9N/BwYGaQ4GBUUGAQYGd39/dwZGBt7fLBy9f1cwMHD0MkUoMDDOB6ll8WLdBqQUGJgBgGMRfwAAeNpjYGBgZoBgGQZGBhC4A+QxgvksDAeAtA6DApDFA2TxMtQx/GcMZqxgOsZ0R4FLQURBSkFOQUlBTUFfwUohXmGNopLqn98s//+DzeEF6lvAGARVzaAgoCChIANVbQlXzQhUzfj/6//H/w/9L/jv8/f/31cPjj849GD/g30Pdj/Y8WDDg+UPmh+Y3z906yXrU6gLiQaMbAxwLYxMQIIJXQHQ6yysbOwcnFzcPLx8/AKCQsIiomLiEpJS0jKycvIKikrKKqpq6hqaWto6unr6BoZGxiamZuYWllbWNrZ29g6OTs4urm7uHp5e3j6+fv4BgUHBIaFh4RGRUdExsXHxCYkMbe2d3ZNnzFu8aMmypctXrl61Zu36dRs2bt66ZduO7Xt2793HUJSSmnm3YmFB9pOyLIaOWQzFDAzp5WDX5dQwrNjVmJwHYufW3ktqap1+6PDVa7duX7+xk+HgEYbHDx4+e85QefMOQ0tPc29X/4SJfVOnMUyZM3c2w9FjhUBNVUAMAB66irUAAARKBbYAogBmAIcAkACVAJ0A4wC2ALYAwwCFAJMAvACxAKwAmACzAKgArwClAHoAjgCfAKoAgwC4AHEAcwB3AG8ATABPALoAmgCLAIkAgAB8AEQFEQAAeNpdUbtOW0EQ3Q0PA4HE2CA52hSzmZDGe6EFCcTVjWJkO4XlCGk3cpGLcQEfQIFEDdqvGaChpEibBiEXSHxCPiESM2uIojQ7O7NzzpkzS8qRqnfpa89T5ySQwt0GzTb9Tki1swD3pOvrjYy0gwdabGb0ynX7/gsGm9GUO2oA5T1vKQ8ZTTuBWrSn/tH8Cob7/B/zOxi0NNP01DoJ6SEE5ptxS4PvGc26yw/6gtXhYjAwpJim4i4/plL+tzTnasuwtZHRvIMzEfnJNEBTa20Emv7UIdXzcRRLkMumsTaYmLL+JBPBhcl0VVO1zPjawV2ys+hggyrNgQfYw1Z5DB4ODyYU0rckyiwNEfZiq8QIEZMcCjnl3Mn+pED5SBLGvElKO+OGtQbGkdfAoDZPs/88m01tbx3C+FkcwXe/GUs6+MiG2hgRYjtiKYAJREJGVfmGGs+9LAbkUvvPQJSA5fGPf50ItO7YRDyXtXUOMVYIen7b3PLLirtWuc6LQndvqmqo0inN+17OvscDnh4Lw0FjwZvP+/5Kgfo8LK40aA4EQ3o3ev+iteqIq7wXPrIn07+xWgAAAAABAAH//wAPeNrEvQl8VOXVP36fe++smZnMPtm3STIJIRkyk2QyLAlLZBcREAERWUJYZAvIJiAgIkZUNkVFRESklFJ678wQFdFGKW5oLbVirbX+1Ne29EXflva1guTyP+d57kwmEKK2bz//9uPNnZmQec7+Pec5z7kczzVwHN+ouYkTOB1XIRPO3zeiE0u/DMhaze/7RgQebjlZwLc1+HZEp+1xqW+E4PtBW76tKN+W38DnKYXkMWW25qaLP2kQ3+HgT3Kllz/ng5pWLoVL5aq5iJnnyiSjPyYYuFSxjEhWv8SdiWlNnFUsk22kTNZyNrtkCnOyWaA3vSpDVTXBgNvl1Gm9BZkkSEpvGNGrtsg3bP7SYx8pl8YMua13dd+qGvKCmPHtHzn6nZ8IB4SR8J1IS4CDRcJ3aoIxzsDpxTJJDBBJH/9aHXytQf1amRfDYa5XJXyJEHQEhU+Gntz1JfwnHOCt7X/F/+Bv9+M4TR/425lcLhnGRTI4rizicqcHg8GIDr4nok8xwX2MIxk6c1mUt2VlF3qCMqc5G3V60jILPYGYRqQfCdacXPxIAx9pDUYzfESkPL+UcSaWbuSyYaHpVllHymJ6I1cCr1wBSW+NudkLtx9eyCnwqYn+rpxPyqSajGP9bvqylXOVGY/12/HVg3gjZVijfIbOAd9Hr1q8wl+OGtL1cOO2Ro3uFLhxWaNmlwl+wUqvNnp14hV/x0N/B/5VGv1X8Dcz438nK/53svF3ojnx38zF94X+Vl5A4qw2pD4rOye34or/Sf0zgOWOUL4jH/4LCvQ/XT79z+vA//CjfmaSNUP50kzK7nx4DfGt3byKaC3KJ1NJplk5tWrHeuXDNQ+ueIH4JisfkcObyMiNJKKMwv82KrFNyjhyGP+D91E/BG7w5RYxqLVyeVwxV05WcVKuXxZ1ZyVfIJIrGsui/XOzDWVSTkAq9EuOoJwCH1lAOBXA9DNyvvGslG+VsvPO2GI5TFA5/lg2vYvkZOM/z+Hgn+db5R6gWB7j2ajZ00Mfl5Rk8sfMTGZ+JrO6JecJikqUcqySqU3KtkrmNg28iIo5wP9jdY+dPwSfp0Q1+FITTcEf8FtRS7YZOO7Aa8cvOembWXilfyO389/wsr9RGP8bvs7/uhxfRuCL8u7Pu9+rtdjsYckbjsCfw7vysOQMc60ak9mZ5S1XBUj6m0RNisXhzMr1FvrKr5At4WQxFwyZC0uFtijR2zyFnrCUYpeN1jDadnUO8TgqSHVVTT0J6tweXbFPyCEup4VPJd5QscPpcViIow5+odg3eNRLN07dtOmL530bC59eOWjZusnbNg1Y9vjkyo2Vx0+3jJ55x5YZdw0aLu0v6cWT54Pb7nz2JesRydR/20C9Mq76wSU3b761d8onHxuFexZVkTUp8y/9xLzk1tCNOagTGm7/5XNao+YU5+TSOB/XhxtO8riIC607DBe5TnM24qb2DRfZqzkbs2eG9eYy2Q63FYPpbYXmLJFGUM+SzswULBgMM5bCXqVY5RJ41Ze96muVG0ABBgVileyNQEAeqWrEqb8/zTRiUIVFGtAmygHLBYtU1SZVWaPBqgCIboA1OnDAIJAVXDtkFYEP4Qd3NBCsGjBwkCqgKL6Iy0NORwfrCkv5tog9TR8Oh+WGvjZ7xB2ugHup0iZ5wPna68AdlvSFNzJtcmUD/FLFYHgnnYN3vDY5JR+F56iq01DPbBG9BcUOcM2CMxioE6qrvAUWnlTVCexTDXwaSvpkvzG9uG7UwgFLV1m99WNXD2u+c5BYt/fbV0fPCo6rLDDPrpta6eEnO0PjHpq4bFVKZmn/GxbUN6/a2RgcFygwz6mb0ssjTKlounPx/Bsqt28KrNpxX3PDY+0QYy4OF6buH7v8oQWFexfuf7R92XWP/qzllm339pi1ennzTVWP7cDP5hfuXfDsTvABAy+f05Rq3uFyuZ5cLbeYi6SjrLNR1l7dWSbmGi0INIwClfPA6vOssgYsuhxuy61yEG5TjGfl3viWBjgoZHuRg0FbVF/sszE1j9o96RmFyNEar83eymlSPBk+P7yB3KsJFVersc0i6EhNKKjVObw+C6H8cgcDNSFiEYnTUxOqAf33FmgHvvTGzN+0PiL1HNDcOIJYll0fm/rSqfeb5/9u66FfRtbPnvHkFOWD4PDRlXkkY1RL1dxxIxubyYQnz0zdt2Xv6T2b+s654cbaImVT44m/RZW/7p0w+eVjs1aPHE6ezejZf9At/C+WLxhSMnba8JuXcxzBGErO0RhawCKoGj6JJFIN51nIBoaoEfOTRKTk8N+PUY7zf6VxH+xIhH9PwPMhJ3XAM/Djsg710Ijx1mF12ENBzmZ1ePkxG+778oBiWfLADmIlS0gmKfp7+x/a71IiyjfEAH/38nTlOFHg7xo7/m6KX+LZ3zXh3+Xh72rw7wrwJ4Wg3WbldXvIX5sf2Nb+LSwqj7+HjCGi8g+lVXmy/SUF1voe3ySu12ZyFo5zhDQOj1CkK3LoUoiPvBcmzaWRlWSfXlkVObzw0hoSEA/sfY484FU2OA/2UjbWkK3KkTUkjdK8hftcHCOeAJpv4iTOL+mCMtGelTSBCEcwLnBGQ1mEcHhLBAPjiPGMxAdiBuYCxEDEYMSPDTr4TaMBb40QTJBhyKjqfBuALVe+zWvbQh7bgVhrB9+ynRxUJmxXJpEDwJ+DwKh67itOD/yBNcREA2dAqRniiCcFpGakf04AvQoFPVphQlVtVdkv9I2HlG9W3L9+ieeM8k9KTzU5zffjl4MO5OPfkolwFv9LUgF9QgUgTOuqi8jnheT0AVgH4j54/xuQUwUHX64CvgTuS0nCfXH4Z6J/KA73AO2V3nh9Rc0Nw+aOGjattvq6Gbimy/sggG+ieunmIhzaLKFKIPrVhXjBD00Ryp+/9D56BIoHl14+Jw4GW3dyXu4QF7GjkXviRp6rB4IKqWq6wLJdVjkbvHBWQDbCq5SAXKT65Mjfi5hPzgKfnAE+OSUVfLK5TTJboyZzShwWZYFPhmuST4YPqU9OMZkzMrPiPhlfJHxytgucqx2cMSfneuDWyCX8a56NOlA+ZKUO1AoOlPBLneWDGlfuu5U0u3tdN/POpyZFX2x9Z9SmWwflvXrrvlm9yccTXnyt9ZkVg5XS20//8ujuRfWE+5tycH70T1+vIOF97coHGPMIKQJePkhtaSzYEnBFEoIMLfNBKiLxjCwws6IseOT8LmSBRRKtkgYgimCV+DaBkzQVROY1DMvJRKR23avSAILwOmpC2lT4JnLqSeX11ldr8gI3x8QdxAu+uuXCrOpQM+qZluPEMMTebG4gk6mcKZyN2FA6KSidHAq8nLCSXDBwpx44lJWNzMpEH0LA0YLPtaQ6qV8NhgjqteoxdT7VwfI64srXafPJ6RN9Z7v1S5rGPTxm/Gt/aD1VseKp+5WD/O7cXeSZyMAlc3w9pywZ2G/VnucenbTjmT0rlPf1+3GN5aBDQVhjKTeVi5TgGgExRtJwjQ7d2ZgppSQNIIBJB8vtAZZ/Ri4wnY1aC3R6IAYWXga6KYslDAml2GRSAKHCZJdzcuGnwya7MuFnml1yq6AInD8QUEZC7MZbECdEq3NRfCR4C8qvPz1zX+Txhzbkbtz78ZIpzzw77rU/xk6+GVmxo3jcnbH5Z/oc6dl796a77nnkRw9Oblq+dmtk++4P8wyuA+sGr7/jpgDYhQn4PpzK387dzUUMqAH6YISn3j7FwANBImQzMgd2rzMGAAI7/JLhjKwHgpyqTjx7/r+YThgYbNVbJbEtqtOLYBAGyC4MCEdNeAVFMVeQmKgzmswJ6C/zYBwySaX6HsLES+cFzF+U76hxeLU6U64QfvfUZ97Phx4ZqlxP3h9um64vbiIj9wuvXarZq8TIyL1kynAyt34dymgkyAjpycV4noMyEkBGqSgju3A25krJSQWSXBjV86hKpQEh8cxp+VdlNGFKBfO2tGngX4B5O9o42eJAe7Wk2h0dmFbIiUsyQsxpYQZlIWLX8aqwHJi/xGO7t2Dkj5+dvWdy+fZ1kx8a+Tq/z9t+cdWsEc+d8Y6/+5d3v9HnSFO4cfWw1VuK+vDSfmWC693YqK0PzKqnvms90DQF9C4X/OhcjgGUQqAKk03ZpD8bc/bIhnRSdiJV/mSsUsKyD7kX/CzJA4DizLYiQPHYQE3RenoU2uxRzuaxgt3IJic1W0lnkwzU99jRiPIDgMiBHq0QrCMJagCdoIYiKkcT065vGDR43nOkcva4ouHTT+x4dLC+7qezdkWKxyz9SVPk3UiPOaOmbR/ywcxDWenk8A4ycMv2eS95nkjbdJ/y9uhJr/5s7NMPLxr02a+vXz3ujqO3/8/dw/rS2HMAdHMtyFKL+IP6eQEp5tEf6PyyHu1JYKEebJ5A8qgjB/hL7eF8YUNmu6jxPLXl4ocQJSYD/yaA78/myrgQcjATOZgPHDTg36tGg62lbMsBtuVYZS2wqyfc9rTKhXDrhvwt4C4EM7YAL8P4oRa+VcB8ptWQme/w+aspwIPYbD/KaS3uJHxHE5tgIIenDojlNQlwhymNRXA43R6a3gAnJ598+aaJXx+f9vD4HjUzm4cvuaPPshNr3vr1ixsXbNs5a97Iebf1envcqO2bF05ZcA+ZtOuDIXXb58q/qrl10YDr19/WkDP0x3eN27604d0fz7lz17xp2/ql14xawD9988pe4ZY5E5rWgC5NBV6Ugy5lcj24max2IQv6sxIHuSwG9ogdWeIDd2bMzbCDUhlRqcr8kvmMnAUsyWIsgTAp94SfWZAUykJGGFkRMdq1YVQqH2R7UZ3ZpaVMoEZhd3gppq2uquOpDvHghwscDOEy72YhUzc2v/V1nbFq/9SfHB26/tUlra8/suqI8vmDT82bNe2JsuxFM2c8MtxyoJx4SN7wm157aeEbj0360+//n2Lb/Krw8oq7Z00ZOXX1znkSF685kXfEJvBrLm5EEvqQnP6YRQUg7iQAEk3RcpCg2xgM8SCwx3KQYIC8xwbSli1OWhhKgiaOq1HKvtHXV4RuHBJHK8IHw6fX1DQ0cvzl3YDJcD16zgGcl+z+mEldhRP9aSyVfbELvjjVAF+n0dKvS+CzpC9rrKotCp8EqHZA/TaEbJMfQ8gmvqp+oYpFvxLHiR9jbHVUE5eBuLYIJy9dEkR+ZxP5dK/ysHL8KeTVbnJcHCx8QWtlGQzlAWRFNIWy1/uxOsagp4vAf7uFQ5fGC4fI8e3byWPbtl31XaFqA6nG7xLhu05+9RQZSBbsVXKbqFz2XP5c2Af6Z+SKuDtYLVD2gv4ZOuqBxUlikdwBSWuNeRg29vjhhZwHPLKC/vnQuaGQUopA/7Q2Kiwpzx4zO5wZXmqQXgF8ntVdhD7PbJNSwp0FGA+nFqLz1pFQB2bQ7VFZW3TyuWdffujRO29K2+6avcTgWOAbMmPKconKt6FRs37W/j13/3LRhHlzNjx7qy51nH9s0y3TxiGd8y8P1u7QxLg+3HXc2xxkkHKVBpClX0oNYiFBKgxIg/xyNtyV+2UtVg0GU7LVQkClVU5jdYIgqxOUJGoI8hA1Wv35f06wsFtvlQa0yXn2C1JuG7yI9q8fAAgUrh0IlIvm5vUfwGBn/I7CzhJI/J9LdWVry6tqwpRnVWHwbaGw5LJJNWF5UB3krCmcI81eUqn6NHsdKQwGRA9aMXCx2OfVJizbI2hdThYWKsDNibzLyuUHQi6tN48j8IEjhE5u/rhn/4sEfnqaeAbVL3pj9eLJBv3tsaUbxj740uwtm6fmT7/x7oE1zb/Y+F/KEz+H9M/45sef/EF5XdnOp62P3txQ12/rL8g3j5CMv7bO2r9t04GY8odnFgxtfeT+O3+9ZUxfZfuy3s2P/GH57MMtI3+nbPlM+Ub5YPzGSWQhufEwCSmev4Etboa4kglxRcelcitVtCmIwQTujWn1HDEDdgnKWgFzN1qjVoGwjXG/bdk3YxJA2BgHwpLRGtUYAfdEDXgFuGMEhvMagzEBdoherWlDkuLwCvkCyReQhbqlQmbb0aMhxfEVGUw25Ht4bWghpi/kdSXMzyVVXzXec4bVLkHBxFZYfyqXBpHxcZUCq/4sJUAuAESQnoYUyOkY2rx+yXlGTjFBKgPADP18Dtzn+AHYnUVnTjHcrvMxCn24CqmgQuKsstV6QSqwygR+WK3RNGsBEJWOV+EoR6xp6QUdtVs5zQo0pYSldJusB1ghFdglkYVkSF3iaJV4ffkdiJbGuzIyDjzFKhKRHp+7fsfF/ZcI/9OXN239Iu+vt+6YvHbzu5pWRdp+PMeY9eiy7b+auXv3lrlrHwvdeXPjTOZzdlw+p7HQnKGfGsmcEMC0NGcQWM4AMd1mojkDJzszYJUeCtg4gxtdgtYu6ZNUmuIci+DCqBRyYbzyFe/oe3cr0T/x7iPDWrYve6NlavnPf7Q9ctPTC/7R8gCfeS8x/O/xRWMeGzr58bd+13zst3335uY88hj1cyAjjYfiahd3KxcxIq7mgpjLMCG5EMRAALKdkTWwQI8qhsfP/ywuBhcVQwrw30XFIEQ5kuJK8NyV0gF88jgbDag+5Ks9wdhJxEKK33zphPLVtt1PfLvv5nePHQGO/l75+LJyR/OSPQt/QXSP/+6XjJeoUwtprWaOqk8GQV2qCLhZQy1C1iBbTX6sRVy5XJEu1wDLFZnWAPLXGNAU9HhFrRE1ekNyxR9Wrlb583WwXv6P3vbT0/iU3PZ/NPOVXk3rPqV2b/vX+zqtz4C5F64PrLNjeXoNXZ4el2ekUjeAqaaoq9xz/hdslVaJtGGSAtlJ8tKiuLKulkUXld/+7nzeVND+9w2wovZv9rXvjOveaKp7d6l4EtILWoySjbAgtydTBA+SFpTd4EFcgbgyWpgy0mW1nG+ky3JBtuGEbCPNCtlGOmQbznR0005XWnpHtuG2IwbhAI0YPSB4XVgSbZIWlddqp6pbQai7pag8hBspAvrcHSfJ3D/+90uDpz07Zb/ytydHHVm7YeUU5VMveX/3B+8p7cpveTsxkkj7+L0lPV9Xdn18hzy/iEh726tHkALK9/GgxyupXuxVMbhOnxJUfWWE12hxp0swxv2lANTi5hqr86Vg+QS0AQI1D7e8FTE7VukkHaujalkhkLLjqfOv022rut3nX6R8SbFGhRQecki9NSrqNehU8YrvG/F9ISqIHY4V5Ua3jghuGY0n1c/dw9+zIaacOrq1fc1WTWv7Tn7uxeH8ofbxtIb0AThSE6VrvKrvRDwrGQMRDdUpuNcFOqn6U+ffZP6et0pCG1V0fRsX5QWm0yRxR+UF7r2eOHyh/FQieHSlriMXnnDynFO6uMfVWCru9jU1+b5tLGU4TXlFWcUPhLWYuIkcTeogA5dS/MhMIplpJQHTbUvCVctsJTqrpG3DbNsASqOFLyf0qqanKSw9hWSOgJqQECsmBwmfX6C8ou0zftq96ST4nPLWWOWZJmXHHueytZr9F4cqaxL+QFNN17RJ5Y/epEpd5jXBIF0YiNgEwjQlRJxY497z7zJhMttLgd+JCiYQWjQFrxG4Jm0vCWFcL64frxSX8ISVhmXCqbUkFC+s30C8RIeW2froWr7y4/aNZNIbyueHVoGEe2/i69vXXHqHP7mm/XlGgzAZaNAABlOjvOrTaHFL65fIGbpq3RWOglglro0JWpA5IUnBCPVUrco56qAufkXrQmM4TvsKfI+De4d9T1SntzgKPXF2aZFdTsouB7DLkTADhPtXeygL/IZkbzvWtuSbZnxXI1nAQ6S2yYL9ggZAxrG6H5+/wDQAZJ8C2IMqwrG6ded7U16DvRj0KcBluCZBQADYKal2dcPOQHBXNsWivpHAg3oH+BnRTJMPoBbMKR8Myh7yEq8AIEUYA3GFf0jPt5B05VfPPz+gQGyv37Zbb6s8pmn9drx46OJwoZH4Vl68pOEPfHlpG6fyRxOheGVtPLakxnVJp0fm0BYAORWYk0o3vKm+2xLMOZnMnFSrZAFif/J3gb5LadcwKxDADCxoi0RrsHQgLprIpYSZDpFgTQidBPFqUwhQc4K0aa21h48op04ofbXW3geBjqG7LghFF4eLx5++zF36gsZz9PcbNe9wdi6Pa+AiqUgFuHbmLrLRUPOZgE1UwBlAgwF8fQH8zECWalIxM852wy1nYJXdDIo53BC6Lbw3z1fMsmE7qwPwO2a9SDIOfrN5c+8Vh85tVi7c/9CJ4wf2nF/1/NN7/3ct730JIjz/6K4nlX8+rpw7+5Opjz9KUl797Qdk8ulXf3taeSaOQcQW6uOc3BI1aqaofHcCSDSaaNQ0IhRxJTtsq+qa3V0GUECRzjZwwU6s6uEVAqjR5Ezw22kCi9UyZBLALIHL9wqOeDUTgcnwL2c2Ks8pr21YuWvtqU/ve/AJTevsuT/5RrnYfpJ//3BkxQKWw+9Q9lOeuzgvd71as0+P8zxPSNTs3cBzN63ZU54XwU9kdFRjsZtpSpMOwVMyQ25ou5r5RqID1dZ2I4ClZ/cSx18+tjhUITx9fsVVQvgNJNP/rFF2kuF8XBK3/JpJgsnhQVUOm1UL0KUEv68kxCRJPH3+/e8tCdmKdVWtPkyxgg74YDJSyUhOWwc+t2ogC7lCPgPJq8rDf3vj9F/X7t178tX7UT7KQ8qPmtpX8ZPb9/Pf/OThlbPArn2Xz4k+wEC9uClcxK9WkiIuJCoDpVNJ4W02SCebWXUZSCeA0rGhRfrDGJ2iJldGIZWS4GcRK8MWJba0Mtw9dSFgj9dVIWPwFfsqRMg0iQrWIdnMETw5WtYZ5NsfmbpzanXlA8ERQ8oy7vntxrefGfzwI+uftGf2rQ6Uhwb3KE+zbtv6zxPlsfGhuyaN6VN1Y3Z1w/Dbau85MW387tEblxb37VnpzcksDPbo3WdE2YdLFgGNz6u5lo4bzkW0HO0iYnLDirioC7BOIi3AeBCTQRXTE+ePUjFprZKuTdIg4hTgl5NaXXTgVsnzXuGjPGWBcu4F4tA49+27eE7jhO/cB75mPXyni1vORRwcg5Ss9mlJRXfpju+iIo4SmIog7LZg9cjYkU3ccV5gccKChXn0nFZACmYrRlq8Uo9vEXG3yYHuSTBSCaB9gI/EVJ6CBrzl8guK96W91PqyZ8v9UqzsVOs7VcqflMuffUbWj1ghLL60YdYNS9dH24TWS33blX++S/3+cfD7PqDDzN3IRcyIHTmkgRiRBgulgcBqU9WMevSFQ3HdNoOfJ5hQcxKPG0vmOKrhzKpvcQQd4FlcQQppvMePTraL1XPIR6cufX1C03ppxs4HnM617whPXBwO6/iI43Sb6Z7Aei6SizJ0B9lSjE5cSl58KfidmCDHclkVJtcfE9kdsSJTYxbWvwPsTMFfy2AvM/xYmlFbsGSRMHyeYZONOchVLtdmj2itGXSLgK1bR9fdcQceqLgawivxfhTLJgbtuMFk27FSI9EO7kfWvto+58VyvdYzXRl9HGjbmF9w1+NfPCxMvnTwiQfLepzeKtwBQffIimeH/P7SBIptIUERP6H+plj1+uqODuhuHNNyMo9hUTTiorwGWAyFVgKZy49VLr3wGom+0f4Bcb1yWikStLzUfpr3tw9t5/mV7ZvishUhP+f03BrArPgdWpWnRECeGihshSACsRg3wDjgLhYWQd5GVTuP/N2ewLH6NrQVTduxV178Wy2+C8BAj5qgT2gCJBuYpBH1pwqzHUHadOJ1HH/uCPnk3fYHF72wHKCgl//40pz2T/ki5Mc5WOtOmjtWxL1vPFcTWMaIqSLH2hFIGDJKVcm8IbapkK9zZglb2+/0CtMyLzXzR/K3iBv2b/t27X6KlS9/pRznv6Y+YiSn5qQ6ME0/JvwaXaKESomOJzeJjFnjZhmzmyb4oqYjnxHge70kqLOT1eSB/E+VX3yWrxzXXtxxsfxhhtE/hiA5ie6D13MRgaOwlspAApawDXpVq6mTQKSrUW0t8vUTuAyBqA4p6PB+vP/D/ep2OdA0H2haQmm6iaMBF+RLyRIC8bYGeMEHOhEXR2p8haStwHRPB8Rp4duROMCbuiTiQqD0oXyyI+cz0ufTPPKAskE5/rDmvR0XtJS2UbxXHKx5hdNyNk7d3le3fGC1aDAGMopEmsj/26tsUV7gvcKeS9P5T9rzce0NsPYtl4cCXzzxajb+l9QgIIBUj+cI5TnK8QceoPvgZeKH/CptPuhzEQeZQYw3cGa1ZwKTBBNVWzAaLVURyKeqg26Py1sB//KV0qaF4RatybXxUHr4ReD/dIiLTeIUwIr53HQuYkLPZ6WAEbecCLwS4SLnoGoUJKcFpo4irxcEZgLgGBWt7pxCVrUyWzLp/koOgJsYp9dZzPGKLBayPcFQUPCGaDE2lLyxouWn33fx8ZmbC1MGtJzdkqGXf9Gy94WJYxeeDmTePmn24alk+tvk1vduH3vo29ZTn7wiz1/0ZXTxxOkrjyhfAC1hoKWfFjviirnX1QoADUlZQEsKklEAekD8NKPyxTMqlD2W6XG/rOQKzafJFU2ji9ukYkgLizEtFOlVQ69FeI3ANSlFFMOShiaKMUHUFBWzLOYo1/GiI22E7MuRhSwDuJdSgAwryAKG6Sxuj561B0AmaeF18e1Mnu5M+by6BP7DDrUwGR4bZS7y8Prxh+be/8yIe99eOWuL1zho09xZcw9NODJo6+LhWqeytW77OGHu0ldijyhf/mbtnLEHyZSm5UeJZ/cfZv/oC9Rj0AVBAl1Ixxqlh9aJgHFaZFwKyj8jnvnImahfdg/rzKM1SmenGiW20jHQw6sVSpT09GBjy3Oztq4LLp7TfHTaXUuWbV/7xPHfk41LP2rdNLJ6Z9Ue5cITa1oaHhvwa4apUTdfV+X5Wy5iQ69hDUbctOMCVqYhrPsN43MqEymsLx1Emm7FjCxmZQHR2oE24gLedP6WBNrIacPG05QcCyJTejXTay5eI3BNEm1KWDKFAZ5zMXOKSe0OJkn3VLC2dAT07kzc15GstojdkYfcsSB3ONmbiRZh0DvsHXsU1CTqeJrshbxqR11iex6MYmTLOytntRSmCLZU44io0vqwRz/uyO1gG0cGPbR4+MzZcw7dQqbvJI737poz1n7XmJ6k6cK5U3OWtUU+bjrwx2Wzlh9V/pTgqfAKyDgDeDqHi6R1knIhdoZkpmmxMwR9kC851UW8YGAslPNTgQat2Y4d4mHJYJOdLtRdexrTCBPkLqAQciGQqm7Pq82VYr5Xm1SzLnZ0EDm919S75em79iptyssF4qrVGw9M2jb1pdPvp0576u6hw4fNbCUts391bMu4jasOfxDIWPfQuF0lvo/J/rTgpLraAS+iL81UnMJmbS5XwO3nIulIUJbmrGQIUK8GyAkDHKQsspXtNCT2E9REhZYozG1ytvWClEbT9KhBT9tB8Irdx+nZabRZOQ23S6J6c1o2lf9zeoPJnJaelZ3cJC5r8oD4grCUZcNEIZ1uOrhskgNUwi7ZgSlCjkARq7ee70gSUgl2lNB6/heGIlde6pBxGZ/+PPVtT8+f7l402j+qz9hb09P+O+PcF76nHuo9THmFT9FoliwTK0Y0TP/lU76WrCmrZrd8+3LsORfIOqg4xdkg6wLIesardYAikHUmunUP8qccGAJ8EXQsA7Kfkb1GmvYAvlaXnwqy1IL2FtnZfkm57WiKyZ6eYWTaS1t/6kkdr4tvmlN1pg6eUuFI1uNg7+fG3r3H69Bl2ol+7JG5LftQsV+aaBjUcqHXN2+90vLnIw1bFg2dNnvO4Vsuc97gXQ+MKmzqT2YvfzX2CHH+Zu3Lh75d/tmpwYL48ZyDXyyevQzVmnBhwEx+8BMZ6CWo17ekZmDdV480Ojt8fibV5wzQ54xOlV47642NWlLs+jKm734aD7ISYOEEKxFuPb+BqQrNT9RcJQMCQwYNCfSajtcIXJP8RjweaMzWdNVpdNx3FBG1YdkOpiXrcQNfdiLq1caLQQBJgurJEoCQNczz6wT0/RMMtcafvHH3dvfW2DbH1trFzVOzGsHhzy//4JMtLcV3tzfy0rTiraFFr61XfBgnwRGUaj4HzGHBKi4X76QjFJUh6NYZQCFSKbcE4IbQwS26J4eVC2sifXwugc5kHvMznYlV5CAVo50AdP+6OPyX2NnGgaEpQyrKQuLwb1s1U2tHTO47oorjFUVx8j5Yjwkw0BKOunVAcAh1edVgcTlpfklDUbpkxjXYYQ3p6ho2nh/NpEKzV5bJcjSHJfFMlshabP+wUj/FG+m+pqSx0QySoD8CnEb1lXQsWVFGlq3uSbQR5euCJ7aNqOLHDQxNHlLRo0Z5xfOm+MG3afsPuXQhlQzQwxDoYRD00MJtV7G70YLnbJAeVQMZT0G1QHUSheg4K4/+vTpeiD5Bi6MWUCwLqpQZr4CpripEm2khWk05ZWJRuzEk3kYPJWGWIGtMcQ0CHMEyJ50QIsNbN4ZKRV7/vlJKil7/08M3ap3tOxWlmXcope0P8vxSZQmjiQ8BTQJiAlVT4sSIXShIHLXHt9viqB2rmSEyMqYc1TovnGM5Aeih9kHwT+Xcp2ot2u3JL6C1aPRQiD4h3mODj5TNzrPA16nt7PB1MZ6FdzBgLF2ygy60mgkQNep2ZOhpQ5nk8WNXVOL4yiPndzNlKbBK3jY8G5PXdqzuj/+ooIjPYwXfL7mtkquNi7rS8rxswyR+lzBVWRAhwOUXwJ3Bp3apmeFnBugY7fX0AesB/5nMDobjHEEAcQIL9CTZjGnbZyeL/ssOtzG/buK8vgvuMumH/nzxuvvdD7U+bL9u8MKPKufEtts3Vs27fXJWozj8VPmgob71S+ZsfuDum29FK59b1H/o+S8UKy9NLovbO+EqL18Uq8VGLotbqMrQorKYOkg35pXZlLlZJto1pTI3yJjrRO9oQu/oRO9oYt4RzC8HRU5od5nspG7LjZS7O2rYHqBajfxIIsYBRmPluafc3oG33lG/4VH39rYdgkn7QE1z85TMJq04/lTPhqG+7XcPn9c+lX/e3c9nu6dm4cl1ilfFL38V88UJkGnlJmrbrjh+ydKdjVdI7CB4O21MoaAFwUsabktqaW07y5VU246f+xDiyYjdVoU7lAC7et6y7uictt+V3bK2de7Lv39udfPOt0tnj5p/aCLZ2fRm6+Yxn5+c+Xrr5rGfH1+7mfQm2oELRu26THHW5fcg9vYTJ4NHK+Ke51hKhZiVsh09Avb0YXbqCapdRExXr9Rs7CA2sgYidWvvLaa9oKiFbWAwhZiE4DUC90nuoSjMRdyFRbQKwX4yF4Gg3YEOIiKI2Akq5UISYs3Mp2XNfMSmotHhFKjSCiSo69RIib0fQqfUo5yM3pGmHyMDFvVPXndo2qzNPqPG3XiiI/NQnNqad2Yvf6V1xWc/33Lj7HGTpirFwnA185h1QD0DOR34hXmoC9DKT9RKYpqagkrGIMtCc4FlJr+UEqSNIlhNN9Jqukk921KYSN+OMSaZrFIqILkUbHs5Vjf7b7+K7++ZTanoUE2pSXtOsjkVmWXEH4xZJtwCcQCXMMcRrbk0o81NwzZUvc56ZUJLu8c7wHuiOD993bf7ZgJ2H7RJORKZIdQy4PPCkYnP3zmzEYAOmf4mmfi7ueMOXXiLvGf9DbBK/vgIKXhs2hqK2qmfFBZS3twQP0OA3EjVno0Y6Y0AMTEQL7WqpwI61Ih2CCZ8Fiencupt3CuJcfCp06reJ6/sun7jygdX+morp+8Nhx1zwdf0CAwqyrTsM61b2NyoGHFdRsglRsK6SrgmLuKL95jbCBMdkUr9kuUMtpNLmaymXggywkOGmcDviEn0hVlVPcWWlot5RKFdyoP1iT5WW0+zRYnFifV2iepsUqc51tZZr6pHh71bkFN43J4cgcZtY3j/6OXrfeWNq5p/+aPDe3tX1M+vnTi7yDu/btjwgs9fj1YeKKyaPLqfr7xm8ObGzYdHbnGlecYOqiop7VNYNWJi7TNHkLZJl8/xZzUNgCnv5SJOpM0Szzj1kFRkBCIaPR530QiGsgjPYc0H0KWHboYkYKOqh1JGBTZLaGQ9dk3gBriBdk3oDekZiaCSgobJA/kW7Gy2hSW9TbZ6gEEaVsRx1PNBHTZ6dMqfqqtCjknWF9bODRFnlvLlWnuops/4zFk9VjxkXyO8cuOo/7rY0v7jG8oC9Zn3mz3Ndw26gR/HYm8zrfsM53K4n6vnBrOQSFPclersWBnNpRoF/ieqNXJ61g5htOJWcMzJXJSToWeIuFhEoVRvP/8gsz4tbkqrFVPBGhUFLWJkvEbgvhM65qIavSCyWBu/o2zRAVSTTVkQa53os90e1GCtCfSHw3vaJEkTZ7WZj95iDo3uqlkjpvBbIXRuqVmyZHpWY+Tswx4jhJ3F9Wt3XHJX5va18HvaR00IPFi76PX15MNvW2noeZDWQgDL5QJ/TNwytSrGIVuIoaOdgHT0ELTdeGF/fD/AxKrAYluUJ9i3I+A1AvedsVuEp1SSKG/qIJeTOZPaKuUIQm4V3zOYfrSf3qKbV0cGvdJ+5Jw4vP3JwX+pOL+En/xtKyxrKeAoD6y1iGvmIkXxPQOS2DMovmrPoIgJryh5zyBLrYH51H0BWYvpXpYtYswvZOUL0FG6R1BE9wjyutgj0NE7B9sjqPJVhWrYTsFSyUoM+p4TSf4Jr0iIvn7KX3+uiB/mCgRelI9XPn0faGot77GreW0bP789dnhyXcbx9/nMb1v5MYFeVkdxr2HFd8fad7F6bwxk4wR6O+8ZkG72DIhAS+8Or0BGko++bD1EBv5Kqb303DHlCF/Nu5S5ZGf75+3vkUPKePj79RCLUPZp2A1HY7U+NRgE94r5CJHSE10uGar07/9n7Ht0ufAQTaQ09HgyR9GR4Ka5s4AsDNppBgJa63tlcN0Ny2uHHDg6JFO7IZvUv9I+pHz0tCVD+45Rjtmnz1orTmr/VP4TKanmJ11Ubpw3psgFa/4UYsQGWLOB6xnfN9CcZVFT0Fy9byAJtit2DXLT+UNKaRa/K7t9Bm/MXCUM3bT90rub0BY8ynEBZyL4uM84dgwBj5jn+uVsHdsoQa6U+KViGnwirmJ0jK4cAx7TlzIwWaPY3I+Zt1ya8I0vMZ55cS9FThMuSJY2eBEVvdg4lWaNpqZhFc6DV3y/EN+PwLVTpTUCn+Ndaph7TtRYUj1p3sJ4GYZc9Q51KRnFeHqNbiJy2XDrygftJjb6Fu53Yk2mBvwo0SEwtxCdCzQ8lVC/6/LmVVfVEwhBnoJVDzgbCsbf+NOi3GkzHEPS72x+3F6eesOITOUDV6WFKI9MmkkGPDOg/pGBk5VXFtzjEMsPVl1/emBWbc+dn+Xd/sGIwi3AW96p2PmDNL/K4yCvip9VFKhZqj/UjQBiC9p458OKXc//U6F2oBznT4BcirGXx8GzSh5Yu8zpaM9sto7V8IxnYpkMzaeiMNxJddCV59OZFARa+ipwY+mLOWta+cIrJErR9AKsfOXjFXy3OUkEpnAE3sa7dBABJjxp6fkFHSK48h0qgkyaLdBTPdk56q1kt8lGN4pAhxKoI6HqYpXXxd5QME+VQVCVShkZOXuee0j68jsetftTb74lx0zKXZXW0/l33u8ZVPhTKfXIwMmkfuE6h7bnj6quf29gVrjnI5/Wj/xwvGfLzglNyssHV7GzAPxIcZwwAbBVkKP7vEFYzNmoQ2/R0+NYUgoFVoihONlhoXUDWdCrOyuOagr+6AYGLXH7EEZtmbGjfvmEdTf1vqtq5ra6ZZPW3Rxax4/cOy/DVzuoZs+CrKLaBpojnFM2k68BPwlcKloteprEeQ/axI29FvFBI0YsrRCenbQgwcQhC2wmcBL78iP+0SMqQt7i6+cqm8XMb7/QlA6dHq7uW13N4v1HEO/LNKcg3v+J9YBKGcH4Xlks3ZmpYR3YUWOmRl8WE030Dbo1GIjDABsYsc2KtX91MzmSkYmWnuEx4GFS1NKYlu0tx6HAO39n2+SZoFCZGnbmVJehpUUyLQ5yeOHvgykkh1/Iwl+IwDUJkktZECBFXXpWQnM02BjtxCMUtMDhTGd90kZbhLNhn7QsmhI1Z3tiSAPFtvGdCJzUUEE+WvWnnfnri+66Nbjo9sXRYGD9kqXb7n2sdEPZuh38qOdJ7TtpBw8aSnYGd927cdeazdc9Xi+89kH+WzT+nIX4s1fzJmSgT6q+NhsQOAlETGiDNt3ZmEbLmYB/OneQDkyRxfQAnZYSP71Xd+/5mxN2p2+TM2wXJBdtzAfD0wN7dII6uMSd4aLcctGSs6B3ZcTNSqd3uRl+TJSc8fAPeELJZJMs1LkDA8B00JsF4yfjdNgtjKdI8nWe7F9Wlb+R9ebQnkuXPfHyzsE71o4dMiKzgczPVnaUp00bwr/rfazXV6c3kfFvXD96/EOj/L3uU17d9O7iNUX7ac62n2SLdnEzl8mVcndyLNj4ABzb/XKuhh0sTT8Ty2KNB1lW3CeMNx+U4Xks3CZxEQ/dQ/DaorzW6lTHEOgM5lSakOZCzh61WJ1u/MBnixrM7NdFSMF4Ldsic4Q8SF7Io0Nz8Oh82F6j8+G0gpCHypxmDKAD+6eunb1wyfT109c3NKyduv62ZUunr52ytqHhugcaZw8eOnTw7MYHxFL8cP3U9bMWwYdT1w6EX1x764plt73f+MDgodObhg6me7AceA/xK/C9bq6V4WfJySbqQLIa44gLzzjy1iAdpSM73IFATNTgm5IpKIvwlpCKGuHxSy56Ujiqd7pUfI1bx+Ch01RNOXD+L6zzmoJpJya0OP2GdwkORN9RqzMVp6rgFd934/vCUV5ItTrcCdWgh5Ah4EP818TNIwSBPxRkwIhmFnSCzapckpOvfJL7yVvSYfLpyfb/+a9s5aN8UpSt/KH3gVqibdnTInDYstDOwa1ykWhp/p4Ux3QQjySNn7YaCWckMRCvZmjjd+oZLRK0edMJjWkPP0xyL/1d/FowXfoHqweELn8t/EmLp0j7cru4SDnNLkG3MsEVo271w1N+MT8Na1GH3wzMywXm+a1yDahWEXC0R1FNB0d7AEfr4AO/g53+yLVFRaOtHFVJZ4+4g2FEuDW2SGZBCd71sEvesFTEhouI5SwfzbQdJY70HkE8eiR5EMoln32mCWmIzsgI1eSx4xkEXI4HD5RodeopLkxT2XQYcEih8DM3rL9/wsK7Vg8ecuvSxpnkjpbQljW1UwaMW7Rq7eo5zZ+9F32yOrRp6NTZawb07lO9K98/YYx/RFXtvfOXDRtSNnz9ynHjBq+vy7qusmpIZe2GpsZnaoYv3RER8hv8lX1LVgytvzXoCvXheHJCYxLOaz7gjKCt1RzKxRnEE2wBbA8KqHdUGTl6wkPS0FlN9DRKGhNVR1G8qONMWjE50adyTL9SXyVZ1LeypEf/0uJemumVDWNqBlWUVDb0LIafeAao8fI5bQPEHitXwNVyLay/SnaLal9Lrng2VlNpFsFiajRnY8Vl9LZYEx9mErMZORss1cY8SAWDMhW01IvTpuAzOtUko8Jm728wmd1ibnFJsIb6j8oakF1VWCqzteptGV6uNIjCK7ZLJSxC4OEwO54NE/MKi/mQM4cPBgrt8QNhmqqajua9xDZ24ytkwgfvkAmnml9T/qy8rPz5teYlUw/8z30/JQWHpx748r5W5eP9RP/hiQ0r+865acW9K+6Ztmzu0td+yX/0AZnwSpvy7PtPK38+2dx8kqQ9veHLnzY9Q0qfw5/PKr97/p1LdWtqfvrovmf8GwJfUzs4KFgFp+Z1zg7RZjabIALZjpwlngWIILvEeMEz5mBMcrAxW0bGFix7prDODBdtM4A4aTKn0zqWy4rHEY0sx+PMJtR7UW1Yq0rs4XXajibq4deDw3bNWlCmL5r84FSLtqyxYVTTyulD5vWqra2fERS+XvGrllmT2mcs7jto5apNq3YP6dcw+wlKy3huoXBcOMlpOTM95ekhDp36YzxpmaB8eHDNEbJkqvLHJ1bzZZlk7QTleWVtNdmRTZ64XnlE2VeNeI1oxTFCJqdBvMb6ZeLTSkQcUaKluInhZkCq+IGIE0l0iYkkXtsW4cQ2vmV7+3+TDf/m3BCxk2734sLcz7rSbj/Tbj9kZP5KXJLfC5CpZyBWFKYfFKGu9+5C13sxXa8MSL2scjW8UcLeKOmk/H1Ayr28rG242hZz54oVtCO1xC6bynFPwib1RFvw2+wxsAKOfhi2fT8bILZ8dvAUW2/TE4MevpcRNBLds3smDf5Kemdt0w23jJnU+D1soP0+Ye3GeyYtyVKWkOnKHvLpDQOHDmQY9l2tU0zX7unolYI4SjTJvVIonXfzhVKv1nn//VTnmoXx/CWQj5lL50ZztDE15tFweSId62ejd2pnS0fHJG55xHQMqWTiCA/cVzMKaDUeGxY/dBwrflD/4LbSht6OY/LgLpp/tnPbLZMm3bJtx4RJG6dNu23qjMnTpolbHjoyYZJy7uYJE26+f+KsWRMnz5mNa4REUBwnvknzgMb4CR96qllKCeLBZuxhEDVUly2GsoiGDn3T6AwsT7CcwdBqZkFWH4iYLfixOQVUjA9ELGZ8ZQHjkLgAZhK4GcdOR3cM5xFOXuoTH9CzbRu/JWlED/B9mzBO8GvfA64Po3x3aegZaIvKvDRsKUbFxdCejnFDm6jUudRyg8EW0abY1C4YE4UfRYkDzPFRIakkX7ctnejXhHr3q72tsf6uJ5ctnb/lfbIpQxjX/OmCgYNHV/UdPa1p1fiZ+5dF1LM/B4TBQpn2fbC+xZyU748JIjcR2GDwQ8KELjLmUlfppavMYVzKsUppWAeLS9wfS2PSLqStD/ks4BtsMsmBJRvtcgbOO7HaIhY73TNxsXq0o5pJPD73RJeY38LOkYJaHLhrcWPT4SnpU6Y2b2icGG5+avna09fdIB++W1izcejE6zc0jxqyQhD6T5+wZPLPavW2mdet3kXpOid+yO+hPX4ldC6S0NHjB5qqMXFGNhdJ1iCHRTqXqromFHQBsj83b+U75e8MFT/MXHHU1fu1IOYsuB+1hNZ7/8B2o1iDl07dkpJ5czCI21E5iaqvOl8iqU3CClaRyhiYaqVDsSxJZV8VqB6r23l+D83pcqxRIQd3rzPpNYtes/EagWtSCSETQhCtiUaFbDZxiCTu2KYVji9Jx00rWQdqJadi6IJ/iXjWyj4iNvoGy42vLgX7IIrphHIyGhskqhcvnp41R8KNjuJ+t87v11ypF/PFgbhR1T7q1tJtoYWvrSMff9t6qlf98OIp2SfTlF9QmZxQLomtgHEd3EgOC2oa/dmIkZqlMdWAVxMYGebLTr9kOoOpjo2O0YtxdHAnsjeFnqdC32JjExQ4Gm35IJoh/h9UpoI/Ub/qqTl85fJfLa8bN+OR5t6ifcupO6q++bN25YVNQtBetYSt5wA/lBwUJv/wmVVJAxoOqNMg+MiwaSE6tIpcHqM4ORy5ZOWq1H5pi1/mEWrYaHRV2z5p1wxWJfQGKgmeQmtW1oSEKxRUQa/vSGHxwftnLO6zYc/migqlRT//eltsadGK21alsLlOfmEMf1r7MpfC3cDR45iJCJ440bj7/AtsmpVYYZE0baIspF2wYKd1lBdYH3JipBORBZHmOIhbi4K4sx6ykFT4GuJde2z7/NQehn7227X88UsP8/yIh3Uhy3XggyH15r8BnJUK2exQ1kUsp4MHMftlB1KeRZlpZSK1sg57NfziWR4PaqQGj6LJ6XiESh+fiMWr45zie8vqEBqpbMw9N66+0zfqnpsWbl45dNCAqT03NC0Us2/ceeewB1feuPOukZvvvfGmKQ+N3XuU5UNOwE6r4tgpRISQw0WK2A8nydy95gPlIXjtO7jmC2X566SJTK9R5uYqt48k15ENNcqAbOVe/Dsi+BJOs4P2YadyGVwBMavxJi09yOpBEHmCwZgVEBZO6cnCe+pBZU9GIBDJtKK6Z9pB0R0B6lT1Z1Cb0SforOj9kzwpldy+8x8wyekrcO9LlHVpFzT0COBj53/MaiDpVim3TSOlWSVHW9SZ5qBVXweby5qRnou+A6/H6u45P4KO/czGlxG4Jp8Y1OkN2bnxE4NaA6RaGVnZuZ1PDOpwFpeAfRrptpgmxWrLpFlCppVuubEuFSFZZ9QRTzpvyBcM4Xs6Sax7+tsT00nB2mPb5pnLDXX2ueRjD/l024rV7vWlLaUnPi7NSzUPc2N7uniRKlm/fahkl/xz+YHt76x8/fWVx7eG3DPS6XyEGMdp01V5FOPOd0IG9KBhUC6EYJvmj2WrYcx3BcfdwPE8Zisl38FxAYyZHvtNbEok8cNta9WQFGtmNt1vzbNH+KJimiYUMt5IabaIK4P2sWbbwWN3xauiOv6qeB6j7GpKZhc/Jo0YJk6p6Vc7pbE/xPhlNMZnXsWwb2c3f3r9tMbZV8R8kWsGntkB0/UAvxfmhpABXKQMdThUCzrcE896ZyDMc1CWsS1yA8BxnLAV8/cuM4JiB/uAYvuZYteEQbF7+1Gxe1cacLBpTCjB30IwMRiZPpRiBy8DC1YEDtlMAF6rXAsCCDGVH6YKYMf5HUyxa61SHSh2yCoF2qLBUAA0uQav8EE0XFsHL/vgFf/FVqrYffFlBK7JbQl960BkrYFgTbgP3nZoc202YFF/r94olJBNHtiA8uqNJ9N6hWWhBPdI8T2Kvoi3f5hBmdw8NsLNkw0/e7IyRicgw7o1tVeCGerDsFhUdIVR1IToVBqtrnnVHbcsOjwl7TbfdfVFAwcE/SWB8IJ9cx84fd2ocOOKIeH126gykCNoLivXxM3FTYwWk0WXreOL+CUbh95w84bm1Lx+pfU1Qmqqd8aE2bOO9NanNg4ZvrB/Tk77j1BNXkdLenvF66+veOk2XWUvp8tQYhB60pr6+8pS/kNxMvi2Im4BF8nBmrqXTVNKA1eOhxbZdqgVMI2VVrMRPeexKMnsim6Bok+IiUbBkUaLRKD9OXReah4OveNkB7Y6u7FuGeG0LpoN6KpqQnXAQMqLRL3ZQwslHfWTssSEnsU507Sk8dbl0oATx559iedvHDIXg/HwDfEhPROzpsw3GG6ZPq6l6Rlxd0PjXAjR4DPYTBjdg3QmTBq3+/tNhUmnBxztJtoWJQKBQtIG5r82IEa249lIYmaHNoEZgl1tBL/m4BhH/ChKVxNkUttKZi8Mt1w5SEb43Ln+SFr4RS5Oe1OC9vXfm3Z1Is6/STBFFo7uCVRBeFcErlm4/O2Kt4dcSSAvZayWnb1fD6j0DVfpy+c2fD/6ChL0ef99+mRXdrciFKpRyXNEECNWMbuis6mhteiIKbcsK6hrbpiyYnkXBPd5IZwzYGj5DcaMvnfNG8UlZHtEN4rSXsid+D60464ybnpmBKIee76+jG5JW4ElRX7JeiZWyPBaYULjsVMVKyeZDLoV/3vsEnEiITHbsXlOEsBFoE/tlnd2nK6Hu4VB8Ka0ybBLBi7u+7OSiXXXecoCGfMGHuk1+7ai0mrX1VwkWm+ZN9hfuVhbG+pDYyPl4ShdA+UhnvGQvxcXIYUvDMYcrCScE6Aww3pGdploKxmWQPJNau+30LF7/K+yjVYezQQSOSET7nIKu+dZ17XnrtiWdnU5+kpfEr6yPK3yLFN3nvIsE3j21vfiWbofa3tSoZogUI7hZpeNbXYVgJa52Su3NWpzCxb16LP//4KFWVZWVxFtMbMjPZcdSldZKBfmYv3FGu7KPSVxkNWraLmqK2Z61k5pXLV6RuPKeX2rg/37B3sNuIqZm6bd0Ty9acnimVX96pr61WH8bQFsdpbOz3Bwj7DOKUSxiQFNDjyJbgeIZbGakJ+2oGyh7Ysxjd6UGNvk9CfGjWw+P4/uf5noIVSTVTY46CFUu+PKsU2sr9OOj4PAq/AcznAymW32zs9u8CZNcsp35BtIvsO7XDgoPJ/X/u4M3pzb/o+FvN/bnj5VGa58TjaShdvGJcY7Mer5Q+pML8VJZ3qV4Z5GujrTC7fo3GgoHiC5FAst8SFf2DFTiKrSMz7rC8u84IJQa7BcnUUbZ7I8hjK5HEyuGKJrNDe/pBS9S5Ytku7MoN4lvRAHCpeA+aS4EeMZaF1Na+tmPhhAcTUXr1aT82K+y2lhew5X0iwdMvaWSb/8oquxYX34aTR3n4t5/IEM4k3M71gIcQvnRiz6rqlcLjqiE1vI3f/nw7kSh12vntJ1mXultGlB7/sT4tStdG48lNb7xSvWP+e71/8fWLgQRw5XL3zbvJXvUNygrls7OGPFUQoYruB99nevPcefGOr1f8n0TpjgagqUBwYlIMGihilLVyXTkowF5o7umBu4EOJYCufmChJ9FtegCgtuecFYKotfGawwYUqYGPY/ZyfND/w36Kb1f7Zrlm2Tddr47KEOTnQdrbrgyId9K8fUYbBq7ghWcZ68e0WU4tkMMFU/Z3UzBexq0/pBw8BkC56SMqZQupLHgglxs+o0H2wjQ+zJY8LAphhaZ2teoq55fLdr/tcWe9USVQPqtEQ3K4YnL1E1n9eC6hrHq7bT3RqTzObfW2MnQ+m00otJqHnA1KWrrlhyh5WE16OVCHTtkxI28uA1V9+deRgDXVnID9MZm4lWfuVsfBaAahOdiO7aJjoRf7hv5Y0UujX3AWuoB2voRP67V8E2jj4DjM6ttIDsdqlYwxyUU/XqAJp0/dkYR0wCtuJkYCuO/qxsyQ6wAYeuM7IuacCheipMMldI6RWS2SqnAr5It8oC/DBbo7xZAJ9gwauUao1mpKbjXgZehed4wWxJTc/ofPo3HTuodS7WURp0sLGXWtGbn0k6Bl+iz2go2Pkgm365+APlhVPKYxvHxAdg3k4GepWX+Y17+B04CfPnys//+x5+o5KuDsNUjHsYH+jMMsibUrki7nCXU8sgQ8Sx/1JmIJrmKNDTeQ40TSruYpiZlIkVLoZkE+eO/r3BZqzh00pHzHQz4oxg28GV+VFXc89IU/aKm0sm1DdghjQ/KUO6YhyadvC6e5NTJIHNRgN7x9lopdxtXU5H65E8HQ2PFnrh1tsxKA2b1wqwyp/qZs8X0mSzk39Fvh84OC0BVrqdoEZ2MNzynZPUxNUqnrmSztHfTWcycTgFLqZJzS8sVY/3Yy34BxKm+uLuR8PxDNh8J2HCsA7A00GblcvheiFtlvg8XUpbpjrPqwNj4ylAvTrPK82GtFlyC3sibXqb3KOMPprDibTpk2jjVNK4Kynr5MEZfV+TNEbfJeWLZMHlAur5WVIhJE6ockr5X0YoqSDmzoReWRmJ0zuKyrKGm9eFLKWgH4c3SD0D0dLCINi3H17kg32HuhBxtKchQ18WK2cGXpsk71I/zSN/iJy7stjuldmOpkuLG5VJpvs9VKCzKXOiypcGyhd8WsLdXXGm1C9VB2OFLPb5A/GnJ6gswQapYrgt7uBOALkj94Q3e/rlgIk9RCE/Ye7FzNzljJ7wjr/6h9pF16Gwe47Nv6qs8d3c+vVVAZNwh4lFrBYfA7zAOUIG4jEQnYH4yOHbIf5MaVL2k0lNyj7lELwUy29Xnia3zVH2K/vnkEnKgTlkMsPlSy8f1rRqRS4dEEdPrLDTaSxFQvzpRGh75dj4KWeY6JgFPO9nBS5WoJ4JWC9OxwZL21GjPs2dzUakAKKmW6dFlJF43jLXdpSYBWsWM1JApPQMez0prlYZHPLQ51Mgkwt8OofTQyh/HW41uvqWbppDmfpyy/rlO/xBytjXN6y93ce/d/ODe79et35Sy4o37hmWazz4wBeMmbfvmxKrf/F2xs8pe/hVd98ktIz7tbKv/czgNb8hnt1zJrB4S2fegf9xgf95oOupd7nXmHqHQCsNGJPWMZIm74cMwPPEB+DJljS4y8j6HqPwEkGmy5l4fAYLLl3PxtO+rEaUK+ne8MPo/peIxWl/MaPDnU6HSqXaaBfO9yBXDT1dk9vCQk7X5Go2d8SZZHqLsb+9K3p930FvyQ+lNwr05rERk99FJo1DghqHup53eACzbkswd7jQjEn3NYmGmFM0JbhYE0/ABZX2BqA9D+z8ya6oRxTdIxhLZ661MEANv0tuuHE/zUSPAaPD9cGtr4NHFT+ER+7vPQHyGq62a0b94yoXew17cF7lV3k2XxD0RM/ZrjFh0H7tCYOO/8SEwcyEESSNGnw/XkXqmDgo5ifrO9ZcxtMZmO747FfIpxIVcJOF1lvwIU6Cm94KuJ3K2sbNOJflqqE6yQcZ4oN5IZsSzNgKZqJXC726zWxIusniTqRQbjxtpWdpgi7Y5XTe1uqHv5zZpMSUk+sbZqw/9emmh/ZoWpXZcw5/o1xUTpAPfyKvnM/OjHI4C0mbyw3GaQz5HHtukNTARsz08+OhLyIN8Uu9EgPuMHCxpwjRAZpyb7jv7afnu4deOXeGPmBOHuC+IPWHNFnUxB9fEr+jquvoBead7yvvh96shy1q1Vdjk7rU2y6n0akUfAMQPBgfdYrdhz56BqGfLZKSVUj3l9mYmvjwEHWLGUfKqpvzvs5nEer4ED7BlJ59YqNtLnO9q9f1JO6yP53c93K//sNmZPeweTPKtRPGDVyydaw0pdd9/Zet6z1y/LCcgYFePSt6Z8yesHRjpvJX355tw6qUE543NRlvvbZ1/bzBw2qH5JX3tHm9nnzNiHWTbtsxoeeQA4U1d9wyYHzfgQvqA2OHlBbkFvbuWzBg6Jq1F88ffd5FfQqdNajNp7MGe6BH7XbaYFnytEEcMVgIbqOw0+BBfKqTF5GZ1U2f6iTniPQxdVIJTmyImS2ZxT7qS3/wFMLEPnX34wg/Z/Wva08lFC2u9UfS2d71FfQ3/RD6ryAapy224rTFAm8PNnAxCsQW/Wu0JnzFd4xeHMMqadcmlv8o3nDamdYgViy7pbXqGrRWd6K1OMhoRcH6Kv9VwXZK37onecEVFbluSU/kbZlqfY7xQPMp5UEIKzPd8ABY0JHBVakZXEFHumKMFyOw2Qg3FUPJjMK+UtALNaeTjAGatIQK4qZhskXFnMIAO11H2YeZntTTFtEZSv+1OZ2OzlvZOITjO7g5PXlT+6fFY/sOz4HErzueEq23hzcAGR8kfqG+tPeL8fQDylN8EvKPuudqD79UE4wVMYjSKxB/PHIHO+NgBDfcgpD9pQTL2bPPS9izz1VF7B0v+VB2+pinkctNuJFtofNhsIs5iCcXe9X8i5rZNV7pnqfHE5sI8bLptfkpNF69963a6UbKz3LgZ2v3/Czzy5XiWanGLxeJZ6/mJh7OsrHDWVUQIzMDeGDFhk+sK6n6TrbKpgqb/aiYU1RWSeNilY3yVi7B0fA6/VVaKtdU4lO/C8Lfn71X73x3z97/XjulcfWaGY0r5/dhe+D9u2FvJHk3vK6ei/t87XQ646wvN5STuEgxchfbFaWCoFwJLM0K0DFclMdYvg7De4MDMXe/Mjwa5MY5nMMomyuAzRVsw7iIsbnIKg/C8xYASYZjIaMCT3qVVdIDikW2iK+kBneGB9lbtWZPelYBBR42G+0A5OTKYhvO25HctqNcbqGvpAJZGu4HItBpbTXGQUlqi2zV0SNhtJe5jMSxtosete04I9aJ40VJsz1bzm/90ZiUQUuyqw/ePm/MmOE7Lz5bKt51V8PGqT965osx2SvS9Lf8aM7KLS8MHTTv7UDmxOunH5zKH7NP3bt+6JDei18gU98hU0+/fOihETf3679hbMvtfXEAaGnZnhFPbDq1cNEJeeGi/4kuvnn6yp8qXyxIC07sU1+Hz1SZrjjpPNtS7r6kebY+uievDrWVsv1ygZiohaqF8EJ2xB335DMK6RF3l4GdWcbZSZHs3IIwwxvFPlr4jdg9adSLetDjZhTTYQZ0NK49MRrX1s1oXN0Vm/MAO64elfsM7sz76c78lJZdXUzNTdqWP5zzFtM94RWIwdgH5Ofu+a5pr72SWYBTXkvBNZZ2DH6txAezYh3fjIdhSm1RbVohzrCV8u1SOZaJo05XWU/q/P6tQbAd2Ou7JsLOVOFXd4NheUVFYIwff0rwY8EP4kcyE3D67XN0+q2vxM8q5BGnq0c4/O9THkdi30X5e6yTsFvKyanM1bKLJneM9lMq7bU4B7B72sNd0d67M+1lNYx2EHvPqn9f7FdsjX4nC6xXNBl+Fy868Bmrq9PYJ7wLWAJ5Usn1w6cTdscVfFxxn2CsBwMT1QAm6pK5hE3DtGpMGSYFAsgzqTYg1yPKSNhNT5uMZ8jAaGRtYVjlX3Wf/wOzuQZ++C4+1l1d+ujWnsZd2ZtA58laQbcEzsRNumqebHxc1hWDZHmrpMW0mp4398taU8cDuTqPlNWyh2vRYXUpiVomjpMtbyttWhBuwWmyiYn2nLqeT9X1jPie67nGlxNw9yIOUE1MtI2bKC5gAKuo4ALUw3avB9TvP0m/34VPJLjq+91dfb+nq+8XOPr92F/OJvjpHeEOVnSyF1zPviu2m9SFXan56A9wjW+C7uMM4AxuaVdTgKW0YEzHlN0eiA9P7rzqqIEnenzqOu1rNJho4ScVn7ls6piC14kiInSaEJxyjSodUjPuKsWkc4OnX6V/EwDDLtHmAoKt5kaxp6bgnGup0s8eaVFDV14AKy+w4uyJWLqRqwP0GUK/BhG7VWOyOD25LHRVFuF4R0O6Po5/QhRYhmqKfRpfqNgXcnuKPDq3LWleaJ3IDktrddoJ65fesXfhVgju9WOUr/v+ZWJo2v01hB94bn/hzRveXvf86edvbx6waGSfAmtG9ZT6ZbuKisjyp4hl7Jhbh/Frfz1jx4L1I72rpvTeOn/Dr5Xfrfri432N777cvKnn8MlNt5T6bxpWtnr+TLYHgTNdl0NumcUF8NRQl1NdwWHJecAHXyBamOcHOfVQJ+kGf/iw16gP31DhPIJ7daIk7nyn2iJ5/gCiHKc9oneX02O+NqkHrWEVfs+JsA66k0g6J5TXHBP7RPaKm4MLJ2ex7X+WS1a5uhkeK36y7t7a2uRcUmCzZMFOcZZsCXquLqbJliZPk8VAWGCiahQfLItVwoJ8UBltapYL42GaTS4s/gEzZjvQzjWHzb7MntrR3cxZ4fOE/7uSrtHfTVcyMTglN6ZNzfOWqHv/hUU/gJqOWtK1R+eWq3WkbsjhpcTR5SvoqbwGPYGu6Akm0VOkIjW5rPwHSaczKLkmVcOuLBV1T90VxSJGYz3YM9JYza3ogkYgkT7sokcg6vMG9Orw/kDcvXUmHZ8cW4ZtPD1YptjDHytjphtK4omvnLq878uLriz02hzp12GiiXJPlat7vlxpoyKTPcQp5EsPrgazmKs5U+KXqoJ4zAtjVUWi7UFlCT7cpQistqgTdyoRfJSZWEkDohX2QRTl4S4/RFupzCZrcehoJe6yVlT9EI25Bgy7Jp8evbqE052hh6+er7OF+0YcJx6isTwdLESd4K+OR8H553YDe3yLeEZKDcQMJi4TR7cG6HNc6FQUV1IctnXcbhFOth+qr1pUFwj2V3/wLdu3K+cG9F5VX1fHX2A/4Zv7XI6IY8Qd8P1ergw7wGlfQLGWFZBwcjPtexcSj18oxb4AsNFytS8gQtJwLg3mlQY3O4VqtUdSTBaaVhV36gywWIUsOsTEwDoH1M4AmlqzMWD0zH+iLUCnxb4A7Aros3Bwz1vWHp29Y1bj/CV1ZRPvis3Z2jh9ro18UztpwSF/r1trb3v012Zty8x9VAQDVt+49rZnZr314tab6teQv95QwS8pf3Td3cq6MhL4dmgRzhdR69w5nA+nMF5zkm5J15N089SjNfnXGqpb+p8fqht1e7xs6+D7ztVNoPDuBuySx1ljQTeDdjU7MGrR/vtkPr73w/n4/wfzJJctkpvnU3GP24NFIdmBQ+a9heEfxE01ZnbHTV7PomY33BSnJoJmMj97cR92w8/KH8LPwH+Kn1FTVm4efYimTfb2ogzF0fZYksRKWs+w5LCrjXrfn6udIne3mlp0xeGE7pmcnE7R2N2s7knkcKUQu7+9JrexWyQYjBWwOFWeCN1XcT+3Y7ezS0HgQ5d7YfzqYcItDrkXxK/Qf9ZR9IhP35btOJ88GJZ62aTyHyKPruNit3JZnHxEohRDY3eSOdtFjzib5Qx2kAbZYZfTnAsS05y9/5FpzgnrvvZYZ34vq+Zda7yzVooX8tTnSqjPRPsFeyYafbydIf54Ow7z9qSH3IF+pRlpw1lSbwaGHVNSe5L6VIn4g+9ScPyykMbTQRz0KXd4jcB9pwdM0DHmgoc9Y+L/K+3qY6I4ovjO7n3BXe+4Dzg5POR6nldEUDhkIRZRih9ouSpVWwmmCFgUBD8rWBAFqRSIoZGY0kat2jQlNCZcOUJT0g8UpI21xFgxpk0a0/oHLaVNYypqWDtvZu8LEDXkcrdzt7O3b96+2X3z5s3vR7cUrgecJkM4oaHplMq0lOBOh8faXoI7mcoQKvVwTACz0QR+u0CaCfwAj0UdbueiCMXGC8WN59Ycu3KwqNkeLNMXXtq+A4gmSn+NDRMMCkY4MZiz48DFrpPC6PXDO17dng1cE0UHCNfE/a4Cus6Y2ATur7Owr7KQaZlsFcCPHetwz6Yd1Z5AYsHUSrA5EIyrSBVBR5qLi7gTQlj4qW3HFRlO12nOn0vgWp/BlqbuQ9NYlnJSDOVxRiZPmRRXaXk0Io+XXmWMWE8nRU5rDTdM6RAicEHOijlhHpZrt1JtANwYpY/wehZlufa/N3Vo4tQAwaUJcZn196Wgx2D9fVhXodQEQ0oQfHIADQ28icFKtQZK3rwgtUb0BX3ptn4rOn3s2Lzejxu7cSs7aBkfzGdVlvG7ZWy8dXxT/lIx0TZ9yb+vvelHkm0Ul2EZaFKtXrLfSGnKxfm8DsJ5kcSkw6qTKIi82BwuE5m8Jzd7QG1z4K/LEtx8aBREj3mIqb9E9BEdTCZVFuH7upFGXYwhrlQRSysDkPyicfNsMsoppLDibaquU2mK4qEXqbVYK9CLTEDPFgkPzE7GbIU8fZeDB6zcRYpUMXKF3eEoo5e9JXDSbp7dD7JOJ8I6+k/YLcit+XIn4vLW/lDRdH5B/okbdTGS6rdX1OWdba/pXtAkdO8s7a4o2d+WvWc3HsNwCsPWj2oz01PLv8aDl++6m7J/LjlQW52+N3+lPcF0uBmm6nYV39i7r/9Y8weI/aS8/sOHaeGJW9ISlrupXmkOXQajYPR4pOeeIosOwKfMDreKdkojwVN+XFZdZxD5QY07qYzGtEyqYS/48sxT7VxqgLhTaSEP3EAIkAKS76bupn6peGkvkm6Z4L/2zy8rr33ik4zgwXGFJAYSA3hwHSqHWyJCwukINJWKYIxBOiHjkjDkxgIjuwAnaGSCnzMhNkzXXiLmDj7XoPQ2E8rEMgDmTGHQOxUcsOOp4RlDyWaUQzCjr6UMM6CAqRYD3Jky3V9y68gxMbcjJZkM9QNwOJlAmM0Z7bvOtbAHffu4lOfRde8+ebH/PnmId18l18uGEM5oRp+kd0C2nbXyjQsNickxjn7u5jWkrmgsbqByQ12dpy6PG2+UcZWGnKVz+hQFn3G9cT+15IXdEh6QPMRTwhhyMKNQl/PULUxMtqX0KwrbhbGKxtxW45Bwj8R48f9yDfh/KV4qkcJqwxuWirI7px/t2dhTX7eqjwj08EFYD5orDF3xHNvkPVZHzuOgm8r3loBg/5SvH1Cs/4brRRkuEA8p/wjrEX7BPgaWkW3HMpJjOXxC37GFZbkg6F9HV/cr1lwUxu4xj0BcZB80fiz0YV0MoFH2ODdM1hj42f5AVdG26uptRVXsSG1lVc2R6kNY69GPfpOuZMaYYJJlzPC++rYpi9EerDo1FJyZJexz67LiePyLM3Nr8uIVBSUBG3JtNjG7WJ7gpjEToGZZmxkdfV34XHgHcGUNzC50l9bjPbBq9rZDvwsHB1AWqkwSMk1CJa6Xin39m9LvGRvYjCOJt/IOHQMTBBRkHh5A8BFioWDBrDY1ojUo9KT59Ba0bCjveMaG3W813M5A50yCM1yByucIZ1Fk1bt1rT/+jf6rf2V9A2KRZWHsCeflrxqynfXC+8lnliAZkhB7sLJ3pKcIz/VsaI0lFAADkdYRAUja2kTeyuFXJBuqtbKWazWo7dveyz1HZYrB0r4gxLHS1WVl46fZAvy+Nn6DjRlfiM7PK4CSJm2+XBB5gSDotloCfNRMvNaihfLDL7DPFIF9JjfhVoW5UuZJ3KUokPzxKahMufZhH0HkNLym6GYAeyT4+CDbJVG2J0oWhO/RTyNOG1rbJbinFYQyGRLdyDPw+ZdijyDrsRJY+CnlWUyT1i3T6C09J3ySoOjWrPhPT+9bl+BM2bDZHD5qxnKfac5KfNm+bHP4bcFOWyFL+bNrpGg5v2VV3AvJtC3FhwPaUnz1DC7kHhIb1WosrZLETVb0YlHP8myxnTNqpe8azKRpaI3bc4GeoVFw0f4HnHK3OgAAAAEAAAACAACd4pmhXw889QAfCAAAAAAA0w+ShgAAAADfRoL1/sH+EgeLB/IAAgAIAAIAAAAAAAB42mNgZGDg6P27goGB/dO/g/8Z2LsZUhhEGZDBSwCuFgfnAAB42m2TT0hUURTGv3fufXdAZhExFGSr/ovEECGDhAghtTACbRgkWsTgYhCNEXIlCLMUF0MM6SJJMhldiEhIRMymDHIhFEqIiEhEi2AKCloENafvPrUGceDHd9+Zc9677/vukyo6wJ8k9jiGJnMKO2Ez2mwO11wvZsIsrgavsSNd6JYuzbK+bksoSlznpIAWiaNJNnWa9SGbC85SHblI4uQGKZAyuUPuRv1xnfT3IJGaPB67FQzYER2zq0jbZyiFGepJpM17pMN+XueRkQndkGTtlR1hfQ1p9xLd4Sx5g5IdZZ/Xh5xrwHkreBH2Ydr2oeI2sWVTOm6PomLbtcr3+Cab2KYO8Pk3zQXtkNag2Y4ha5+g1UxFmjV/kJUxbeT6sq/LEU+tZn4ixXUqBrSyfskWfL+uRzNJzt9Hg8ziNq8HTQXZcAVDZluXTEXbTVE/yiqO25wkZFWXIi8j77VKf7ZsTr9QZ8iw7zGfkLL3gmU3i155jjn6kYlm6L2vmTN4Z/oxGNXW8ICU5QSqdkHXwzYs0+9y8FS7ZS1Icn6R84lwC4sujyXXw/3l9UPk+yG4CR31Wfgc6olyqINZdezncBDua5465LOoJ8qCmdl5ReT7Ibgi/ZzazaGe3Rz+Y4vo+ZfDQfw5K+CKz6Ien4XPzKvbQcl9ZS/3xPNfNRl8Nr+A2A9gX6UMBL/JrV1Qo45TB/mf/w72MBtoiS2gJejFcMR3nZRtDHtMTieN4K07hyY/K508051I+Psy7zaXxGl7netHPHMk1qyN2vgXwLoHjAAAeNpjYGDQgcI0himMZUwNzBUsHCwaLCEsdSyLWJ6wcrFqsIaw5rH+YrNjm8D2iz2J/QyHB0cOxyfONM51nC84/3DJcRlxLeMu4b7CE8GzjOcfrx/vND4uvjK+Pfxs/Bn8cwR0BPoEXgh6CK4RkhDqEjoirCGcI/xEREwkR2SOyA1RNlE30RTROtElYlxiq8Q+ic+R4JKYJMkmOU/ymZSX1BapR9LTpP/IBMi8kC2TPSRnILdA3kC+Tf6fgp5Ch8I2xRTFJiUVpSQgnKFsp3xIxUHlhMoH1Wmq19RK1G6p/VFXU3dR/6UhopGmsU2TRbNAc4aWlVaT1jqtZ9oa2hXac3RSdP7p8ejV6f3Rz9F/ZdBjqGZ4xsjJ6ISxhnGb8QeTCpNLpiqmTWZMZm3mMuYTzP9ZlFkyWc6y3GNlZ7XL2sh6g42bzSpbCdtbdlF2F+yD7P84LHEMcRJymuQs5TzDRcnlmCufq5/rAjc2twZ3Jfc+928eGR5fPNs8T3i5eL3wnuDj5iviW+Mn57fJ38b/RUBFwLqAVzjgj0C2QJFApUCDQLfAmMCiwAmB6wLPBD4KEgFCjSAbIKwKWhO0I5gt2C14V4gCAJE8nNoAAAABAAAA6gBOAAUAAAAAAAIAAQACABYAAAEAAXsAAAAAeNrFVU1PE1EUPZ1iEUQWhrggLiYsDbSUL20xJnwINiI1FCVuTIbOUBqnndqZqiQuXRqXLvwJ/ARXLhX3Rvf+BuPS8+5cWqYBAyvzMu+d9+6795378d4AGMNvpJEaGAJwxC/GKYxyFmMLI/ihOI1D/FI8gBup94ovYT91qDiDceua4kGsWpOKL+Om1VI8hGfWR8XDeGv9UXwFd9NvFI/gTvqT4qvWh/Qxz1HMZd4p/oLrmc+Kv2I6813xEUYHM4q/EY/F+Gca44MTWEGAFg7QRh017COCjRlMI495onVKA6778DgroYkqskRLXPE5bnW1Qpl5HD3aesne5c7hU+0/4izgnrrYM5YD7LFfpsaK2I8ZFC501jJ1bVTg0GpIrhGRT50qnsi+kDigzFjP0r5pi/SwzLZO1KQ04jfFnQE61DDcisrlFvuCRKXIcZqSPY4FzLLdprTaZ82wOeYylWCzqBYXiNawQXYl7ljgylyfD/Z/8eJs5ptq2+bMsHP4RTzBYfw9NDi28bybzdNr56GwN3YOWBexxGjWpBpq/9y5Kjk3VWD83+bMoe5wYt3EqHiOGkvquJTs8hz7lFPdxKmRnmpq2+x1Kdnjd9JGxCr1zsHB1HLEU4rIsb2SluU5vbhlqRfwtBznHvfmuvnNnaHd6OPfsxByrSN8A8ZuX3O4JvsjqTrDLqIVk0evm+U4957UQ+xlh9iVSPd8rTBvGxzLcmozYXkjYWGSK/21nCfPvNz2izBzZYzkbdklq0j5xTYd6Sf4flSkqirEJvZLwrUiPHaItnGfrB9zNPMlvixb7Dc5L+Ge6Ja5YjNjZa6uikZJcCxbkzdqE085PqDE7DG2PbKKo9OW2WtGpi21FArHtvjR4Kqv9ZMVXz3x8OJxtRmjIJGTUHSqWqFVyaUjt6wjNy7ORUsYNiSWxxkJNX6u5r8hvjj8evKa1LbRbXbv7oG+OaZGwhMVH50jq/33ISRjk9mWvPhZ4eZzND7WKC/L67lDzV3xPLaal1dxm+d7Gs2WrM5KP0fb83xrTT+r/5kZNldeQodavjCIq9MTL04yfsGVOmWGr/8X8EhN8gB42m3QV0zTcRDA8e9BaaHsvXHv9f//2zLcLVD33uJCgbaKgMWquNC4ZzQm+qRxvahxz2jUBzVu1DiiPvjsjg/oq/6xP9+85PLJXXKXyxEBv1vNdFLD/+IzSIREEomFKKzYiCYGO7HEEU8CiSSRTAqppJFOBplkkU0OueSRTwHtaE8HOtKJznShK93oTg960ove9KEv/dDQMXDgxEUhRRRTQn8GMJBBDGYIQ3HjoZQyyvEyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAmFcxiNnOYyzwqxcIxNrKJm+znI5vZzQ4OcoLjEsV23rOBfWIVG7s4wFbu8EGiOcRJftLKL45ymofc5wzzWcAeqnhMNQ94xDOe8JQWPpnfe8lzXnAWHz/Yyxte8Ro/X/jGNhYSYBGLqaWOw9SzhAaCNBJiKctYbn55BStpYhVrWM01jtDMWtaxnq985zrnOM8N3vJOYsQusRIn8ZIgiZIkyZIiqZIm6ZLBBS5yhavc5RKXuccWTkkmt7gtWZLNTsmRXMmTfCmw+mqbGvy6LVQX0DStLKxbU6raYygdypI2DXNAqSsNpUPpVLqUhcoiZbHy3z53WF3t1XV7TcAXClZXVTb6wy3DG9bltZSHgvV/C5e3tE2vJ3yHqaF0KJ1/AAdKnvAAeNrbwfi/dQNjL4P3Bo6AiI2MjH2RG93YtCMUNwhEem8QCQIyGiJlN7Bpx0QwbGBWcN3ArO2ygUPBdRPzKyZtMIcdyOGIh3LYgBx2SyiHFchh04VyWIAcVmEohxNkgBCEw7iBC2ost4LrLgau+v8MTNobmd3KgCI8QHXcITBu5AYRbQBBvDKfAA==) format('woff'); font-weight: normal; font-style: normal; } \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/resources/worker.py b/queue_services/account-mailer/src/account_mailer/resources/worker.py index db97cb1caf..43ebafc6f7 100644 --- a/queue_services/account-mailer/src/account_mailer/resources/worker.py +++ b/queue_services/account-mailer/src/account_mailer/resources/worker.py @@ -29,19 +29,24 @@ from account_mailer.auth_utils import get_login_url, get_member_emails, get_transaction_url from account_mailer.email_processors import ( - account_unlock, common_mailer, ejv_failures, pad_confirmation, product_confirmation, refund_requested) + account_unlock, + common_mailer, + ejv_failures, + pad_confirmation, + product_confirmation, + refund_requested, +) from account_mailer.enums import Constants, SubjectType, TemplateType, TitleType -from account_mailer.services import minio_service, notification_service +from account_mailer.services import google_store, notification_service from account_mailer.utils import format_currency, format_day_with_suffix, get_local_formatted_date - -bp = Blueprint('worker', __name__) +bp = Blueprint("worker", __name__) logger = StructuredLogging.get_logger() -@bp.route('/', methods=('POST',)) +@bp.route("/", methods=("POST",)) def worker(): """Worker to handle incoming queue pushes.""" if not (event_message := queue.get_simple_cloud_event(request, wrapped=True)): @@ -49,12 +54,12 @@ def worker(): return {}, HTTPStatus.OK try: - logger.info('Event message received: %s', json.dumps(dataclasses.asdict(event_message))) + logger.info("Event message received: %s", json.dumps(dataclasses.asdict(event_message))) if is_message_processed(event_message): - logger.info('Event message already processed, skipping.') + logger.info("Event message already processed, skipping.") return {}, HTTPStatus.OK message_type, email_msg = event_message.type, event_message.data - email_msg['logo_url'] = minio_service.MinioService.get_minio_public_url('bc_logo_for_email.png') + email_msg["logo_url"] = google_store.GoogleStoreService.get_static_resource_url("bc_logo_for_email.png") handle_drawdown_request(message_type, email_msg) handle_pad_account_create(message_type, email_msg) @@ -75,7 +80,7 @@ def worker(): # Note if you're extending above, make sure to include the new type in handle_other_messages below. handle_other_messages(message_type, email_msg) - except Exception as e: # NOQA # pylint: disable=broad-except + except Exception as e: # NOQA # pylint: disable=broad-except raise e return {}, HTTPStatus.OK @@ -105,7 +110,7 @@ def handle_pad_account_create(message_type, email_msg): """Handle the pad account create message.""" if message_type != QueueMessageTypes.PAD_ACCOUNT_CREATE.value: return - email_msg['registry_logo_url'] = minio_service.MinioService.get_minio_public_url('bc_registry_logo_pdf.svg') + email_msg["registry_logo_url"] = google_store.GoogleStoreService.get_static_resource_url("bc_registry_logo_pdf.svg") token = RestService.get_service_account_token() email_dict = pad_confirmation.process(email_msg, token) process_email(email_dict, token) @@ -116,46 +121,51 @@ def handle_eft_available_notification(message_type, email_msg): if message_type != QueueMessageTypes.EFT_AVAILABLE_NOTIFICATION.value: return template_name = TemplateType.EFT_AVAILABLE_NOTIFICATION_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.EFT_AVAILABLE_NOTIFICATION.value - context_url = f'{get_login_url()}/account/{org_id}/settings/payment-option' - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_emails, template_name, subject, - logo_url=logo_url, context_url=context_url) + context_url = f"{get_login_url()}/account/{org_id}/settings/payment-option" + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process( + org_id, + admin_emails, + template_name, + subject, + logo_url=logo_url, + context_url=context_url, + ) process_email(email_dict) def handle_nsf_lock_unlock_account(message_type, email_msg): """Handle the NSF lock/unlock account message.""" if message_type == QueueMessageTypes.NSF_LOCK_ACCOUNT.value: - logger.debug('Lock account message received') + logger.debug("Lock account message received") template_name = TemplateType.NSF_LOCK_ACCOUNT_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) - if additional_emails := email_msg.get('additionalEmails'): - emails += ',' + additional_emails + if additional_emails := email_msg.get("additionalEmails"): + emails += "," + additional_emails subject = SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, emails, template_name, - subject, logo_url=logo_url) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process(org_id, emails, template_name, subject, logo_url=logo_url) process_email(email_dict) elif message_type == QueueMessageTypes.NSF_UNLOCK_ACCOUNT.value: - logger.debug('Unlock account message received') + logger.debug("Unlock account message received") template_name = TemplateType.NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value - logo_url = email_msg.get('logo_url') + logo_url = email_msg.get("logo_url") email_dict = { - 'template_vars': email_msg, - 'logo_url': logo_url, - 'template_name': template_name, - 'subject': subject, - 'org_id': org_id, - 'admin_coordinator_emails': admin_coordinator_emails, - 'account_name': email_msg.get('accountName') + "template_vars": email_msg, + "logo_url": logo_url, + "template_name": template_name, + "subject": subject, + "org_id": org_id, + "admin_coordinator_emails": admin_coordinator_emails, + "account_name": email_msg.get("accountName"), } token = RestService.get_service_account_token() @@ -168,37 +178,44 @@ def handle_account_confirmation_period_over(message_type, email_msg): if message_type != QueueMessageTypes.CONFIRMATION_PERIOD_OVER.value: return template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') - nsf_fee = format_currency(email_msg.get('nsfFee')) + org_id = email_msg.get("accountId") + nsf_fee = format_currency(email_msg.get("nsfFee")) admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.ACCOUNT_CONF_OVER_SUBJECT.value - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, - nsf_fee=nsf_fee, logo_url=logo_url) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process( + org_id, + admin_coordinator_emails, + template_name, + subject, + nsf_fee=nsf_fee, + logo_url=logo_url, + ) process_email(email_dict) def handle_team_actions(message_type, email_msg): """Handle the team actions messages.""" - if message_type in (QueueMessageTypes.TEAM_MODIFIED.value, QueueMessageTypes.TEAM_MEMBER_INVITED.value): - logger.debug('Team Modified message received') + if message_type in ( + QueueMessageTypes.TEAM_MODIFIED.value, + QueueMessageTypes.TEAM_MEMBER_INVITED.value, + ): + logger.debug("Team Modified message received") template_name = TemplateType.TEAM_MODIFIED_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.TEAM_MODIFIED_SUBJECT.value - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, - subject, logo_url=logo_url) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) process_email(email_dict) elif message_type == QueueMessageTypes.ADMIN_REMOVED.value: - logger.debug('ADMIN_REMOVED message received') + logger.debug("ADMIN_REMOVED message received") template_name = TemplateType.ADMIN_REMOVED_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') - recipient_email = email_msg.get('recipientEmail') + org_id = email_msg.get("accountId") + recipient_email = email_msg.get("recipientEmail") subject = SubjectType.ADMIN_REMOVED_SUBJECT.value - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, recipient_email, template_name, - subject, logo_url=logo_url) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process(org_id, recipient_email, template_name, subject, logo_url=logo_url) process_email(email_dict) @@ -207,34 +224,41 @@ def handle_pad_invoice_created(message_type, email_msg): if message_type != QueueMessageTypes.PAD_INVOICE_CREATED.value: return template_name = TemplateType.PAD_INVOICE_CREATED_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAD_INVOICE_CREATED.value - invoice_process_date = datetime.fromisoformat(email_msg.get('invoice_process_date')) - credit_total = email_msg.get('credit_total', '0') - invoice_total = email_msg.get('invoice_total', '0') + invoice_process_date = datetime.fromisoformat(email_msg.get("invoice_process_date")) + credit_total = email_msg.get("credit_total", "0") + invoice_total = email_msg.get("invoice_total", "0") withdraw_total = Decimal(str(invoice_total)) - Decimal(str(credit_total)) args = { - 'credit_total': format_currency(credit_total), - 'nsf_fee': format_currency(email_msg.get('nsfFee')), - 'invoice_total': format_currency(invoice_total), - 'invoice_process_date': get_local_formatted_date(invoice_process_date, '%m-%d-%Y'), - 'withdraw_total': format_currency(str(withdraw_total)), - 'invoice_number': email_msg.get('invoice_number', None), - 'transaction_url': get_transaction_url(org_id) + "credit_total": format_currency(credit_total), + "nsf_fee": format_currency(email_msg.get("nsfFee")), + "invoice_total": format_currency(invoice_total), + "invoice_process_date": get_local_formatted_date(invoice_process_date, "%B %d, %Y"), + "withdraw_total": format_currency(str(withdraw_total)), + "invoice_number": email_msg.get("invoice_number", None), + "transaction_url": get_transaction_url(org_id), } - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, - subject, logo_url=logo_url, - **args) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process( + org_id, + admin_coordinator_emails, + template_name, + subject, + logo_url=logo_url, + **args, + ) process_email(email_dict) def handle_online_banking(message_type, email_msg): """Handle the online banking payment message.""" - if message_type not in (QueueMessageTypes.ONLINE_BANKING_OVER_PAYMENT.value, - QueueMessageTypes.ONLINE_BANKING_UNDER_PAYMENT.value, - QueueMessageTypes.ONLINE_BANKING_PAYMENT.value): + if message_type not in ( + QueueMessageTypes.ONLINE_BANKING_OVER_PAYMENT.value, + QueueMessageTypes.ONLINE_BANKING_UNDER_PAYMENT.value, + QueueMessageTypes.ONLINE_BANKING_PAYMENT.value, + ): return if message_type == QueueMessageTypes.ONLINE_BANKING_OVER_PAYMENT.value: @@ -244,18 +268,16 @@ def handle_online_banking(message_type, email_msg): else: template_name = TemplateType.ONLINE_BANKING_PAYMENT_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value args = { - 'title': subject, - 'paid_amount': format_currency(email_msg.get('amount')), - 'credit_amount': format_currency(email_msg.get('creditAmount')), + "title": subject, + "paid_amount": format_currency(email_msg.get("amount")), + "credit_amount": format_currency(email_msg.get("creditAmount")), } - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_emails, template_name, - subject, logo_url=logo_url, - **args) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process(org_id, admin_emails, template_name, subject, logo_url=logo_url, **args) process_email(email_dict) @@ -264,16 +286,21 @@ def handle_pad_setup_failed(message_type, email_msg): if message_type != QueueMessageTypes.PAD_SETUP_FAILED.value: return template_name = TemplateType.PAD_SETUP_FAILED_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAD_SETUP_FAILED.value args = { - 'accountId': email_msg.get('accountId'), + "accountId": email_msg.get("accountId"), } - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, - subject, logo_url=logo_url, - **args) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process( + org_id, + admin_coordinator_emails, + template_name, + subject, + logo_url=logo_url, + **args, + ) process_email(email_dict) @@ -282,18 +309,23 @@ def handle_payment_pending(message_type, email_msg): if message_type != QueueMessageTypes.PAYMENT_PENDING.value: return template_name = TemplateType.PAYMENT_PENDING_TEMPLATE_NAME.value - org_id = email_msg.get('accountId') + org_id = email_msg.get("accountId") admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAYMENT_PENDING.value args = { - 'accountId': email_msg.get('accountId'), - 'cfsAccountId': email_msg.get('cfsAccountId'), - 'transactionAmount': format_currency(email_msg.get('transactionAmount')), + "accountId": email_msg.get("accountId"), + "cfsAccountId": email_msg.get("cfsAccountId"), + "transactionAmount": format_currency(email_msg.get("transactionAmount")), } - logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, - subject, logo_url=logo_url, - **args) + logo_url = email_msg.get("logo_url") + email_dict = common_mailer.process( + org_id, + admin_coordinator_emails, + template_name, + subject, + logo_url=logo_url, + **args, + ) process_email(email_dict) @@ -312,76 +344,82 @@ def handle_reset_passcode(message_type, email_msg): template_name = TemplateType.RESET_PASSCODE_TEMPLATE_NAME.value subject = SubjectType.RESET_PASSCODE.value - email_msg.update({ - 'header': Constants.RESET_PASSCODE_HEADER.value - }) + email_msg.update({"header": Constants.RESET_PASSCODE_HEADER.value}) email_dict = common_mailer.process( org_id=None, - recipients=email_msg.get('emailAddresses'), + recipients=email_msg.get("emailAddresses"), template_name=template_name, - subject=subject, **email_msg) + subject=subject, + **email_msg, + ) process_email(email_dict) def handle_affiliation_invitation(message_type, email_msg): """Handle the affiliation invitation messages.""" - if message_type not in {QueueMessageTypes.AFFILIATION_INVITATION_REQUEST.value, - QueueMessageTypes.AFFILIATION_INVITATION_REQUEST_AUTHORIZATION.value}: + if message_type not in { + QueueMessageTypes.AFFILIATION_INVITATION_REQUEST.value, + QueueMessageTypes.AFFILIATION_INVITATION_REQUEST_AUTHORIZATION.value, + }: return - business_name = email_msg.get('businessName') - logo_url = email_msg.get('logo_url') - requesting_account = email_msg.get('fromOrgName') - if from_branch_name := email_msg.get('fromOrgBranchName'): - requesting_account += ' - ' + from_branch_name + business_name = email_msg.get("businessName") + logo_url = email_msg.get("logo_url") + requesting_account = email_msg.get("fromOrgName") + if from_branch_name := email_msg.get("fromOrgBranchName"): + requesting_account += " - " + from_branch_name - account = email_msg.get('toOrgName') - if to_branch_name := email_msg.get('toOrgBranchName'): - account += ' - ' + to_branch_name + account = email_msg.get("toOrgName") + if to_branch_name := email_msg.get("toOrgBranchName"): + account += " - " + to_branch_name email_dict = common_mailer.process( **{ - 'org_id': None, - 'recipients': email_msg.get('emailAddresses'), - 'template_name': TemplateType[f'{QueueMessageTypes(message_type).name}_TEMPLATE_NAME'].value, - 'subject': SubjectType[QueueMessageTypes(message_type).name].value.format(business_name=business_name), - 'logo_url': logo_url, - 'business_name': business_name, - 'requesting_account': requesting_account, - 'account': account, - 'is_authorized': email_msg.get('isAuthorized', None), - 'additional_message': email_msg.get('additionalMessage', None) - }) + "org_id": None, + "recipients": email_msg.get("emailAddresses"), + "template_name": TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value, + "subject": SubjectType[QueueMessageTypes(message_type).name].value.format(business_name=business_name), + "logo_url": logo_url, + "business_name": business_name, + "requesting_account": requesting_account, + "account": account, + "is_authorized": email_msg.get("isAuthorized", None), + "additional_message": email_msg.get("additionalMessage", None), + } + ) process_email(email_dict) def handle_product_actions(message_type, email_msg): """Handle the product actions messages.""" - if message_type not in {QueueMessageTypes.PRODUCT_APPROVED_NOTIFICATION_DETAILED.value, - QueueMessageTypes.PRODUCT_REJECTED_NOTIFICATION_DETAILED.value, - QueueMessageTypes.PRODUCT_CONFIRMATION_NOTIFICATION.value}: + if message_type not in { + QueueMessageTypes.PRODUCT_APPROVED_NOTIFICATION_DETAILED.value, + QueueMessageTypes.PRODUCT_REJECTED_NOTIFICATION_DETAILED.value, + QueueMessageTypes.PRODUCT_CONFIRMATION_NOTIFICATION.value, + }: return - logo_url = email_msg.get('logo_url') - subject_descriptor = email_msg.get('subjectDescriptor') + logo_url = email_msg.get("logo_url") + subject_descriptor = email_msg.get("subjectDescriptor") subject_type = SubjectType[QueueMessageTypes(message_type).name].value - attachment_type = email_msg.get('attachmentType', None) + attachment_type = email_msg.get("attachmentType", None) email_dict = common_mailer.process( **{ - 'org_id': None, - 'recipients': email_msg.get('emailAddresses'), - 'template_name': TemplateType[f'{QueueMessageTypes(message_type).name}_TEMPLATE_NAME'].value, - 'subject': subject_type.format(subject_descriptor=subject_descriptor), - 'logo_url': logo_url, - 'product_access_descriptor': email_msg.get('productAccessDescriptor'), - 'category_descriptor': email_msg.get('categoryDescriptor'), - 'is_reapproved': email_msg.get('isReapproved', None), - 'product_name': email_msg.get('productName', None), - 'access_disclaimer': email_msg.get('accessDisclaimer', None), - 'remarks': email_msg.get('remarks', None), - 'contact_type': email_msg.get('contactType', None), - 'has_agreement_attachment': email_msg.get('hasAgreementAttachment', None), - 'attachment_type': attachment_type - }) + "org_id": None, + "recipients": email_msg.get("emailAddresses"), + "template_name": TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value, + "subject": subject_type.format(subject_descriptor=subject_descriptor), + "logo_url": logo_url, + "product_access_descriptor": email_msg.get("productAccessDescriptor"), + "category_descriptor": email_msg.get("categoryDescriptor"), + "is_reapproved": email_msg.get("isReapproved", None), + "product_name": email_msg.get("productName", None), + "access_disclaimer": email_msg.get("accessDisclaimer", None), + "remarks": email_msg.get("remarks", None), + "contact_type": email_msg.get("contactType", None), + "has_agreement_attachment": email_msg.get("hasAgreementAttachment", None), + "attachment_type": attachment_type, + } + ) email_dict = product_confirmation.process_attachment(email_dict, attachment_type) process_email(email_dict) @@ -391,45 +429,49 @@ def handle_statement_notification(message_type, email_msg): """Handle the statement notification message.""" if message_type not in {QueueMessageTypes.STATEMENT_NOTIFICATION.value}: return - from_date = datetime.fromisoformat(email_msg.get('fromDate')) - to_date = datetime.fromisoformat(email_msg.get('toDate')) - logo_url = email_msg.get('logo_url') + from_date = datetime.fromisoformat(email_msg.get("fromDate")) + to_date = datetime.fromisoformat(email_msg.get("toDate")) + logo_url = email_msg.get("logo_url") email_dict = common_mailer.process( **{ - 'org_id': email_msg.get('accountId'), - 'recipients': email_msg.get('emailAddresses'), - 'template_name': TemplateType[f'{QueueMessageTypes(message_type).name}_TEMPLATE_NAME'].value, - 'subject': SubjectType[QueueMessageTypes(message_type).name].value, - 'logo_url': logo_url, - 'from_date': from_date.strftime('%B ') + format_day_with_suffix(from_date.day), - 'to_date': to_date.strftime('%B ') + format_day_with_suffix(to_date.day), - 'total_amount_owing': format_currency(email_msg.get('totalAmountOwing')), - 'statement_frequency': email_msg.get('statementFrequency').lower() - }) + "org_id": email_msg.get("accountId"), + "recipients": email_msg.get("emailAddresses"), + "template_name": TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value, + "subject": SubjectType[QueueMessageTypes(message_type).name].value, + "logo_url": logo_url, + "from_date": from_date.strftime("%B ") + format_day_with_suffix(from_date.day), + "to_date": to_date.strftime("%B ") + format_day_with_suffix(to_date.day), + "total_amount_owing": format_currency(email_msg.get("totalAmountOwing")), + "statement_frequency": email_msg.get("statementFrequency").lower(), + } + ) process_email(email_dict) def handle_payment_reminder_or_due(message_type, email_msg): """Handle the payment reminder or due message.""" - if message_type not in {QueueMessageTypes.PAYMENT_REMINDER_NOTIFICATION.value, - QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value}: + if message_type not in { + QueueMessageTypes.PAYMENT_REMINDER_NOTIFICATION.value, + QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value, + }: return - due_date = datetime.fromisoformat(email_msg.get('dueDate')) - logo_url = email_msg.get('logo_url') + due_date = datetime.fromisoformat(email_msg.get("dueDate")) + logo_url = email_msg.get("logo_url") email_dict = common_mailer.process( **{ - 'org_id': email_msg.get('accountId'), - 'recipients': email_msg.get('emailAddresses'), - 'template_name': TemplateType[f'{QueueMessageTypes(message_type).name}_TEMPLATE_NAME'].value, - 'subject': SubjectType[QueueMessageTypes(message_type).name].value, - 'logo_url': logo_url, - 'due_date': due_date.strftime('%B ') + format_day_with_suffix(due_date.day) + f' {due_date.year}', - 'total_amount_owing': format_currency(email_msg.get('totalAmountOwing')), - 'statement_frequency': email_msg.get('statementFrequency').lower(), - 'statement_month': email_msg.get('statementMonth'), - 'statement_number': email_msg.get('statementNumber'), - 'short_name_links_count': email_msg.get('shortNameLinksCount'), - }) + "org_id": email_msg.get("accountId"), + "recipients": email_msg.get("emailAddresses"), + "template_name": TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value, + "subject": SubjectType[QueueMessageTypes(message_type).name].value, + "logo_url": logo_url, + "due_date": due_date.strftime("%B ") + format_day_with_suffix(due_date.day) + f" {due_date.year}", + "total_amount_owing": format_currency(email_msg.get("totalAmountOwing")), + "statement_frequency": email_msg.get("statementFrequency").lower(), + "statement_month": email_msg.get("statementMonth"), + "statement_number": email_msg.get("statementNumber"), + "short_name_links_count": email_msg.get("shortNameLinksCount"), + } + ) process_email(email_dict) @@ -460,55 +502,57 @@ def handle_other_messages(message_type, email_msg): QueueMessageTypes.PRODUCT_CONFIRMATION_NOTIFICATION.value, QueueMessageTypes.STATEMENT_NOTIFICATION.value, QueueMessageTypes.PAYMENT_REMINDER_NOTIFICATION.value, - QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value + QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value, ]: return if any(x for x in QueueMessageTypes if x.value == message_type): title = TitleType[QueueMessageTypes(message_type).name].value - subject = SubjectType[QueueMessageTypes(message_type).name].value\ - .format(user_first_name=email_msg.get('userFirstName'), - user_last_name=email_msg.get('userLastName'), - product_name=email_msg.get('productName'), - account_name=email_msg.get('orgName'), - business_name=email_msg.get('businessName') - ) - template_name = TemplateType[f'{QueueMessageTypes(message_type).name}_TEMPLATE_NAME'].value + subject = SubjectType[QueueMessageTypes(message_type).name].value.format( + user_first_name=email_msg.get("userFirstName"), + user_last_name=email_msg.get("userLastName"), + product_name=email_msg.get("productName"), + account_name=email_msg.get("orgName"), + business_name=email_msg.get("businessName"), + ) + template_name = TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value else: - logger.error('Unknown message type: %s', message_type) + logger.error("Unknown message type: %s", message_type) return kwargs = { - 'title': title, - 'user_first_name': email_msg.get('userFirstName'), - 'user_last_name': email_msg.get('userLastName'), - 'context_url': email_msg.get('contextUrl'), - 'role': email_msg.get('role'), - 'label': email_msg.get('label'), - 'product_name': email_msg.get('productName'), - 'remarks': email_msg.get('remarks'), - 'applicationDate': email_msg.get('applicationDate'), - 'business_name': email_msg.get('businessName') + "title": title, + "user_first_name": email_msg.get("userFirstName"), + "user_last_name": email_msg.get("userLastName"), + "context_url": email_msg.get("contextUrl"), + "role": email_msg.get("role"), + "label": email_msg.get("label"), + "product_name": email_msg.get("productName"), + "remarks": email_msg.get("remarks"), + "applicationDate": email_msg.get("applicationDate"), + "business_name": email_msg.get("businessName"), } - org_id = email_msg.get('accountId') - logo_url = email_msg.get('logo_url') + org_id = email_msg.get("accountId") + logo_url = email_msg.get("logo_url") email_dict = common_mailer.process( org_id=org_id, - recipients=email_msg.get('emailAddresses'), + recipients=email_msg.get("emailAddresses"), template_name=template_name, logo_url=logo_url, - subject=subject, **kwargs) + subject=subject, + **kwargs, + ) process_email(email_dict) def process_email(email_dict: dict, token: str = None): # pylint: disable=too-many-branches """Process the email contained in the message.""" - logger.debug('Attempting to process email: %s', email_dict.get('recipients', '')) + logger.debug("Attempting to process email: %s", email_dict.get("recipients", "")) if email_dict: if not token: token = RestService.get_service_account_token() notification_service.send_email(email_dict, token=token) else: - logger.error('No email content generated') + logger.error("No email content generated") diff --git a/queue_services/account-mailer/src/account_mailer/services/google_store.py b/queue_services/account-mailer/src/account_mailer/services/google_store.py new file mode 100644 index 0000000000..34fcb411fb --- /dev/null +++ b/queue_services/account-mailer/src/account_mailer/services/google_store.py @@ -0,0 +1,89 @@ +# Copyright © 2024 Province of British Columbia +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Module for interacting with Google Cloud Storage (GCS).""" + +from flask import current_app +from google.cloud import storage +from structured_logging import StructuredLogging + +logger = StructuredLogging.get_logger() + + +class GoogleStoreService: + """Document Storage class.""" + + @staticmethod + def download_file_from_bucket(bucket_name: str, source_blob_name: str) -> bytes: + """ + Download a file from a Google Cloud Storage bucket and return its content as bytes. + + Args: + bucket_name (str): The name of the bucket. + source_blob_name (str): The name of the blob (file) in the bucket. + + Returns: + bytes: The content of the file as bytes. + """ + client = storage.Client() + logger.debug(f"Get bucket file {bucket_name}/{source_blob_name}") + bucket = client.bucket(bucket_name) + blob = bucket.blob(source_blob_name) + file_content = blob.download_as_bytes() + return file_content + + @staticmethod + def upload_file_to_bucket(bucket_name, source_file_name, destination_blob_name): + """ + Upload a file to a specified Google Cloud Storage (GCS) bucket. + + Args: + bucket_name (str): The name of the GCS bucket where the file will be uploaded. + source_file_name (str): The local path to the file to be uploaded. + destination_blob_name (str): The name of the file as it will appear in the GCS bucket. + + Returns: + None + + Raises: + google.cloud.exceptions.GoogleCloudError: If an error occurs during the upload process. + + Example: + >>> GoogleStoreService.upload_file_to_bucket('my-bucket', 'local-file.txt', 'remote-file.txt') + Upload of remote-file.txt complete. + """ + client = storage.Client() + logger.debug(f"Put bucket file {bucket_name}/{destination_blob_name}") + bucket = client.bucket(bucket_name) + blob = bucket.blob(destination_blob_name) + blob.upload_from_filename(source_file_name) + current_app.logger.info("Upload of %s complete.", destination_blob_name) + + @staticmethod + def get_static_resource_url(key: str) -> str: + """ + Generate a publicly accessible URL for a file stored in a Google Cloud Storage (GCS) bucket. + + Args: + key (str): The name or path of the file in the GCS bucket. + + Returns: + str: A publicly accessible URL for the file. + + Example: + >>> GoogleStoreService.get_static_resource_url('my-file.txt') + 'https://my-bucket-url/my-file.txt' + """ + logger.debug(f"GET URL for {key}") + bucket_url = current_app.config["STATIC_RESOURCES_BUCKET_URL"] + return f"https://{bucket_url}/{key}" # noqa: E231 diff --git a/queue_services/account-mailer/src/account_mailer/services/minio_service.py b/queue_services/account-mailer/src/account_mailer/services/minio_service.py index e627ce0368..08aed32f7e 100644 --- a/queue_services/account-mailer/src/account_mailer/services/minio_service.py +++ b/queue_services/account-mailer/src/account_mailer/services/minio_service.py @@ -20,7 +20,6 @@ from minio import Minio from structured_logging import StructuredLogging - logger = StructuredLogging.get_logger() diff --git a/queue_services/account-mailer/src/account_mailer/services/notification_service.py b/queue_services/account-mailer/src/account_mailer/services/notification_service.py index bd7596b2c5..a0867f3675 100644 --- a/queue_services/account-mailer/src/account_mailer/services/notification_service.py +++ b/queue_services/account-mailer/src/account_mailer/services/notification_service.py @@ -16,13 +16,12 @@ from flask import current_app from structured_logging import StructuredLogging - logger = StructuredLogging.get_logger() def send_email(notify_body: dict, token: str): # pylint:disable=unused-argument """Send the email asynchronously, using the given details.""" logger.info(f'send_email to {notify_body.get("recipients")}') - notify_url = current_app.config.get('NOTIFY_API_URL') + '/notify/' + notify_url = current_app.config.get("NOTIFY_API_URL") + "/notify/" RestService.post(notify_url, token=token, data=notify_body) logger.info(f'Email sent to {notify_body.get("recipients")}') diff --git a/queue_services/account-mailer/src/account_mailer/utils.py b/queue_services/account-mailer/src/account_mailer/utils.py index a551db74f4..fbfa7a7f33 100644 --- a/queue_services/account-mailer/src/account_mailer/utils.py +++ b/queue_services/account-mailer/src/account_mailer/utils.py @@ -25,40 +25,40 @@ def _get_build_openshift_commit_hash(): - return os.getenv('OPENSHIFT_BUILD_COMMIT', None) + return os.getenv("OPENSHIFT_BUILD_COMMIT", None) def get_run_version(): """Return a formatted version string for this service.""" commit_hash = _get_build_openshift_commit_hash() if commit_hash: - return f'{__version__}-{commit_hash}' + return f"{__version__}-{commit_hash}" return __version__ def get_local_time(date_val: datetime): """Return local time value.""" - tz_name = current_app.config['LEGISLATIVE_TIMEZONE'] + tz_name = current_app.config["LEGISLATIVE_TIMEZONE"] tz_local = pytz.timezone(tz_name) date_val = date_val.astimezone(tz_local) return date_val -def get_local_formatted_date(date_val: datetime, dt_format: str = '%Y-%m-%d'): +def get_local_formatted_date(date_val: datetime, dt_format: str = "%Y-%m-%d"): """Return formatted local time.""" return get_local_time(date_val).strftime(dt_format) def format_currency(amount: str): """Format currency to two decimal places.""" - return f'{float(amount):0,.2f}' # noqa: E231 + return f"{float(amount):0,.2f}" # noqa: E231 def format_day_with_suffix(day: int) -> str: """Format a day with its suffix.""" # e.g 15 --> 15th if 11 <= day <= 13: - suffix = 'th' + suffix = "th" else: - suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day % 10, 'th') - return f'{day}{suffix}' + suffix = {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") + return f"{day}{suffix}" diff --git a/queue_services/account-mailer/src/account_mailer/version.py b/queue_services/account-mailer/src/account_mailer/version.py index ed2ae0453e..66135f5cc2 100644 --- a/queue_services/account-mailer/src/account_mailer/version.py +++ b/queue_services/account-mailer/src/account_mailer/version.py @@ -22,5 +22,4 @@ Development release segment: .devN """ -__version__ = '2.18.4' # pylint: disable=invalid-name -__version__ = '2.18.4' # pylint: disable=invalid-name +__version__ = "2.2.4" # pylint: disable=invalid-name diff --git a/queue_services/account-mailer/tests/__init__.py b/queue_services/account-mailer/tests/__init__.py index 3e44a42f53..213030638f 100644 --- a/queue_services/account-mailer/tests/__init__.py +++ b/queue_services/account-mailer/tests/__init__.py @@ -14,7 +14,6 @@ """The Test Suites to ensure that the service is built and operating correctly.""" import datetime - EPOCH_DATETIME = datetime.datetime.utcfromtimestamp(0) FROZEN_DATETIME = datetime.datetime(2001, 8, 5, 7, 7, 58, 272362) diff --git a/queue_services/account-mailer/tests/conftest.py b/queue_services/account-mailer/tests/conftest.py index 806de11619..6e773cc65b 100644 --- a/queue_services/account-mailer/tests/conftest.py +++ b/queue_services/account-mailer/tests/conftest.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Common setup and fixtures for the pytest suite used by this service.""" +import os import random import time from concurrent.futures import CancelledError @@ -26,6 +27,14 @@ from account_mailer import create_app +def find_subpath(root_dir, target_subpath): + """Auxiliary subpath search function.""" + for root, dirs, files in os.walk(root_dir): + if target_subpath in os.path.join(root, "").replace("\\", "/"): # Ensure cross-platform compatibility + return os.path.join(root, "") + return None + + @contextmanager def not_raises(exception): """Corallary to the pytest raises builtin. @@ -35,35 +44,38 @@ def not_raises(exception): try: yield except exception: - raise pytest.fail(f'DID RAISE {exception}') + raise pytest.fail(f"DID RAISE {exception}") -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def app(): """Return a session-wide application configured in TEST mode.""" - _app = create_app('testing') + _app = create_app("testing") # Bypass caching. def get_service_token(): pass + RestService.get_service_account_token = get_service_token return _app -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def db(app): # pylint: disable=redefined-outer-name, invalid-name """Return a session-wide initialised database. Drops all existing tables - Meta follows Postgres FKs """ with app.app_context(): - drop_schema_sql = text(""" + drop_schema_sql = text( + """ DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public; - """) + """ + ) sess = _db.session() sess.execute(drop_schema_sql) @@ -78,23 +90,17 @@ def db(app): # pylint: disable=redefined-outer-name, invalid-name # This is the path we'll use in legal_api!! # even though this isn't referenced directly, it sets up the internal configs that upgrade - import os - import sys - - venv_src_path = os.path.abspath( - os.path.join( - os.path.dirname(__file__), - os.pardir, - '.venv/src/sbc-auth/auth-api' - ) - ) - if venv_src_path not in sys.path: - sys.path.insert(0, venv_src_path) - auth_api_folder = [folder for folder in sys.path if 'auth-api' in folder][0] - migration_path = auth_api_folder.replace('/auth-api', '/auth-api/migrations') + root_directory = os.pardir + target_subpath = "auth-api/migrations" - Migrate(app, _db, directory=migration_path) + result = find_subpath(root_directory, target_subpath) + + if not result: + root_directory = '/home/runner' + result = find_subpath(root_directory, target_subpath) + + Migrate(app, _db, directory=result) upgrade() return _db @@ -106,29 +112,29 @@ def config(app): return app.config -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def client(app): # pylint: disable=redefined-outer-name """Return a session-wide Flask test client.""" return app.test_client() -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def client_ctx(app): # pylint: disable=redefined-outer-name """Return session-wide Flask test client.""" with app.test_client() as _client: yield _client -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def client_id(): """Return a unique client_id that can be used in tests.""" _id = random.SystemRandom().getrandbits(0x58) # _id = (base64.urlsafe_b64encode(uuid.uuid4().bytes)).replace('=', '') - return f'client-{_id}' + return f"client-{_id}" -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def session(app, db): # pylint: disable=redefined-outer-name, invalid-name """Return a function-scoped session.""" with app.app_context(): @@ -142,7 +148,7 @@ def session(app, db): # pylint: disable=redefined-outer-name, invalid-name # (http://docs.sqlalchemy.org/en/latest/orm/session_transaction.html#using-savepoint) sess.begin_nested() - @event.listens_for(sess(), 'after_transaction_end') + @event.listens_for(sess(), "after_transaction_end") def restart_savepoint(sess2, trans): # pylint: disable=unused-variable # Detecting whether this is indeed the nested transaction of the test if trans.nested and not trans._parent.nested: # pylint: disable=protected-access @@ -152,7 +158,7 @@ def restart_savepoint(sess2, trans): # pylint: disable=unused-variable db.session = sess - sql = text('select 1') + sql = text("select 1") sess.execute(sql) yield sess @@ -164,60 +170,65 @@ def restart_savepoint(sess2, trans): # pylint: disable=unused-variable conn.close() -@pytest.fixture(scope='session', autouse=True) +@pytest.fixture(scope="session", autouse=True) def auto(docker_services, app): """Spin up a keycloak instance and initialize jwt.""" - if app.config['USE_TEST_KEYCLOAK_DOCKER']: - docker_services.start('keycloak') - docker_services.wait_for_service('keycloak', 8081) - - if app.config['USE_DOCKER_MOCK']: - docker_services.start('notify') - docker_services.start('minio') + if app.config["USE_TEST_KEYCLOAK_DOCKER"]: + docker_services.start("keycloak") + docker_services.wait_for_service("keycloak", 8081) + + if app.config["USE_DOCKER_MOCK"]: + # docker_services.start("postgres") + docker_services.start("notify") + docker_services.start("gcs-emulator") time.sleep(10) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def docker_compose_files(pytestconfig): """Get the docker-compose.yml absolute path.""" import os - return [ - os.path.join(str(pytestconfig.rootdir), 'tests/docker', 'docker-compose.yml') - ] + + return [os.path.join(str(pytestconfig.rootdir), "tests/docker", "docker-compose.yml")] @pytest.fixture() def auth_mock(monkeypatch): """Mock check_auth.""" - monkeypatch.setattr('auth_api.services.entity.check_auth', lambda *args, **kwargs: None) - monkeypatch.setattr('auth_api.services.org.check_auth', lambda *args, **kwargs: None) - monkeypatch.setattr('auth_api.services.invitation.check_auth', lambda *args, **kwargs: None) + monkeypatch.setattr("auth_api.services.entity.check_auth", lambda *args, **kwargs: None) + monkeypatch.setattr("auth_api.services.org.check_auth", lambda *args, **kwargs: None) + monkeypatch.setattr("auth_api.services.invitation.check_auth", lambda *args, **kwargs: None) @pytest.fixture() def notify_mock(monkeypatch): """Mock send_email.""" - monkeypatch.setattr('auth_api.services.invitation.send_email', lambda *args, **kwargs: None) + monkeypatch.setattr("auth_api.services.invitation.send_email", lambda *args, **kwargs: None) @pytest.fixture() def notify_org_mock(monkeypatch): """Mock send_email.""" - monkeypatch.setattr('auth_api.services.org.send_email', lambda *args, **kwargs: None) + monkeypatch.setattr("auth_api.services.org.send_email", lambda *args, **kwargs: None) @pytest.fixture() def keycloak_mock(monkeypatch): """Mock keycloak services.""" - monkeypatch.setattr('auth_api.services.keycloak.KeycloakService.join_account_holders_group', - lambda *args, **kwargs: None) - monkeypatch.setattr('auth_api.services.keycloak.KeycloakService.remove_from_account_holders_group', - lambda *args, **kwargs: None) + monkeypatch.setattr( + "auth_api.services.keycloak.KeycloakService.join_account_holders_group", + lambda *args, **kwargs: None, + ) + monkeypatch.setattr( + "auth_api.services.keycloak.KeycloakService.remove_from_account_holders_group", + lambda *args, **kwargs: None, + ) @pytest.fixture(autouse=True) def mock_pub_sub_call(mocker): """Mock pub sub call.""" + class PublisherMock: """Publisher Mock.""" @@ -226,6 +237,6 @@ def __init__(self, *args, **kwargs): def publish(self, *args, **kwargs): """Publish mock.""" - raise CancelledError('This is a mock') + raise CancelledError("This is a mock") - mocker.patch('google.cloud.pubsub_v1.PublisherClient', PublisherMock) + mocker.patch("google.cloud.pubsub_v1.PublisherClient", PublisherMock) diff --git a/queue_services/account-mailer/tests/docker/docker-compose.yml b/queue_services/account-mailer/tests/docker/docker-compose.yml index caf7772f1e..34b7db3054 100644 --- a/queue_services/account-mailer/tests/docker/docker-compose.yml +++ b/queue_services/account-mailer/tests/docker/docker-compose.yml @@ -1,5 +1,18 @@ version: '3' services: + postgres: + image: postgres:15 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 keycloak: image: quay.io/keycloak/keycloak:12.0.2 ports: @@ -21,19 +34,29 @@ services: retries: 2 volumes: - ./setup:/tmp/keycloak/test/ - - nats: - image: nats-streaming - restart: always - expose: - - 4222 - - 8222 - labels: - - entity.services=nats - ports: - - 4222:4222 - - 8222:8222 - tty: true + + gcs-emulator: + image: fsouza/fake-gcs-server:latest + ports: + - "4443:4443" # HTTP port for GCS emulator + environment: + - FAKE_GCS_EXTERNAL_URL=http://localhost:4443 # Use HTTP + command: -scheme http # Force HTTP + volumes: + - gcs-data:/storage + + pubsub-emulator: + image: google/cloud-sdk:latest + ports: + - "8085:8085" # Pub/Sub emulator port + command: | + bash -c " + gcloud beta emulators pubsub start --host-port=0.0.0.0:8085 --project=test-project + " + environment: + - PUBSUB_PROJECT_ID=test-project + volumes: + - pubsub-data:/var/pubsub proxy: image: nginx:alpine @@ -49,12 +72,6 @@ services: command: > mock -p 4010 --host 0.0.0.0 https://raw.githubusercontent.com/bcgov/sbc-auth/main/docs/docs/api_contract/notify-api-1.0.0.yaml - - minio: - image: 'bitnami/minio:2022.2.5' - ports: - - '9000:9000' - environment: - - MINIO_ACCESS_KEY=minio - - MINIO_SECRET_KEY=minio123 - - MINIO_DEFAULT_BUCKETS=cgi-ejv +volumes: + gcs-data: + pubsub-data: \ No newline at end of file diff --git a/queue_services/account-mailer/tests/unit/__init__.py b/queue_services/account-mailer/tests/unit/__init__.py index 08692f0928..5e151b6ecf 100644 --- a/queue_services/account-mailer/tests/unit/__init__.py +++ b/queue_services/account-mailer/tests/unit/__init__.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Test suite for the integrations to NATS Queue.""" +"""Test suite for the integrations to PubSub.""" import uuid from enum import Enum @@ -25,8 +25,7 @@ from auth_api.utils.enums import AccessType -def factory_org_model(org_name: str = 'Test ORg', - user_id=None): +def factory_org_model(org_name: str = "Test ORg", user_id=None): """Produce a templated org model.""" org_type = OrgTypeModel.get_default_type() org_status = OrgStatusModel.get_default_status() @@ -43,18 +42,19 @@ def factory_org_model(org_name: str = 'Test ORg', def factory_user_model_with_contact(): """Produce a user model.""" user_info = { - 'username': 'foo', - 'firstname': 'bar', - 'lastname': 'User', - 'keycloak_guid': uuid.uuid4() + "username": "foo", + "firstname": "bar", + "lastname": "User", + "keycloak_guid": uuid.uuid4(), } - user = UserModel(username=user_info['username'], - firstname=user_info['firstname'], - lastname=user_info['lastname'], - keycloak_guid=user_info.get('keycloak_guid', None), - type=user_info.get('access_type', None), - ) + user = UserModel( + username=user_info["username"], + firstname=user_info["firstname"], + lastname=user_info["lastname"], + keycloak_guid=user_info.get("keycloak_guid", None), + type=user_info.get("access_type", None), + ) user.save() @@ -68,12 +68,14 @@ def factory_user_model_with_contact(): return user -def factory_membership_model(user_id, org_id, member_type='ADMIN', member_status=1): +def factory_membership_model(user_id, org_id, member_type="ADMIN", member_status=1): """Produce a Membership model.""" - membership = MembershipModel(user_id=user_id, - org_id=org_id, - membership_type_code=member_type, - membership_type_status=member_status) + membership = MembershipModel( + user_id=user_id, + org_id=org_id, + membership_type_code=member_type, + membership_type_status=member_status, + ) membership.created_by_id = user_id membership.save() @@ -83,11 +85,11 @@ def factory_membership_model(user_id, org_id, member_type='ADMIN', member_status def factory_contact_model(): """Return a valid contact object with the provided fields.""" contact_info = { - 'email': 'foo@bar.com', - 'phone': '(555) 555-5555', - 'phoneExtension': '123' + "email": "foo@bar.com", + "phone": "(555) 555-5555", + "phoneExtension": "123", } - contact = ContactModel(email=contact_info['email']) + contact = ContactModel(email=contact_info["email"]) contact.save() return contact @@ -96,8 +98,8 @@ class TestUserInfo(dict, Enum): """Test scenarios of user.""" user1 = { - 'username': 'foo', - 'firstname': 'bar', - 'lastname': 'User', - 'keycloak_guid': uuid.uuid4() + "username": "foo", + "firstname": "bar", + "lastname": "User", + "keycloak_guid": uuid.uuid4(), } diff --git a/queue_services/account-mailer/tests/unit/test_worker_queue.py b/queue_services/account-mailer/tests/unit/test_worker_queue.py index 03eba0ecde..7ef090cf71 100644 --- a/queue_services/account-mailer/tests/unit/test_worker_queue.py +++ b/queue_services/account-mailer/tests/unit/test_worker_queue.py @@ -12,35 +12,86 @@ # See the License for the specific language governing permissions and # limitations under the License. """Test Suite to ensure the worker routines are working as expected.""" +import os import types from datetime import datetime from unittest.mock import patch +import pytest from auth_api.services.rest_service import RestService +from google.cloud import storage from sbc_common_components.utils.enums import QueueMessageTypes from account_mailer.enums import SubjectType -from account_mailer.services import notification_service -from account_mailer.services.minio_service import MinioService +from account_mailer.services import google_store, notification_service from . import factory_membership_model, factory_org_model, factory_user_model_with_contact from .utils import helper_add_event_to_queue +def delete_all_objects(bucket_name): + """Delete all objects in a bucket.""" + # Set the environment variable for the GCS emulator + os.environ["CLOUD_STORAGE_EMULATOR_HOST"] = "http://localhost:4443" + + # Initialize the storage client + storage_client = storage.Client() + + # Get the bucket + bucket = storage_client.bucket(bucket_name) + + # Delete all objects in the bucket + for blob in bucket.list_blobs(): + blob.delete() + + +def create_bucket(bucket_name): + """Create a bucket in the Fake GCS Server.""" + # Set the environment variable for the GCS emulator + os.environ["CLOUD_STORAGE_EMULATOR_HOST"] = "http://localhost:4443" + + # Initialize the storage client + storage_client = storage.Client() + + # Create the bucket + bucket = storage_client.create_bucket(bucket_name) + + return bucket + + +def delete_bucket(bucket_name): + """Delete a bucket from the Fake GCS Server.""" + # Set the environment variable for the GCS emulator + os.environ["CLOUD_STORAGE_EMULATOR_HOST"] = "http://localhost:4443" + + # Initialize the storage client + storage_client = storage.Client() + delete_all_objects(bucket_name) + + # Get the bucket + bucket = storage_client.bucket(bucket_name) + + bucket.delete() + + def test_refund_request(app, session, client): """Assert that the refund request event works.""" mail_details = { - 'identifier': 'NR 123456789', - 'orderNumber': '1', - 'transactionDateTime': '2020-12-12 14:10:20', - 'transactionAmount': 50.00, - 'transactionId': 'REG1234', - 'refundDate': '20000101', - 'bcolAccount': '12345', - 'bcolUser': '009900' + "identifier": "NR 123456789", + "orderNumber": "1", + "transactionDateTime": "2020-12-12 14:10:20", + "transactionAmount": 50.00, + "transactionId": "REG1234", + "refundDate": "20000101", + "bcolAccount": "12345", + "bcolUser": "009900", } - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - helper_add_event_to_queue(client, QueueMessageTypes.REFUND_DRAWDOWN_REQUEST.value, mail_details=mail_details) + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + helper_add_event_to_queue( + client, + QueueMessageTypes.REFUND_DRAWDOWN_REQUEST.value, + mail_details=mail_details, + ) mock_send.assert_called @@ -50,23 +101,28 @@ def test_duplicate_messages(app, session, client): org = factory_org_model() factory_membership_model(user.id, org.id) id = org.id - mail_details = { - 'accountId': id, - 'accountName': org.name - } - - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - helper_add_event_to_queue(client, message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, - mail_details=mail_details, message_id='f76e5ca9-93f3-44ee-a0f8-f47ee83b1971') + mail_details = {"accountId": id, "accountName": org.name} + + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, + mail_details=mail_details, + message_id="f76e5ca9-93f3-44ee-a0f8-f47ee83b1971", + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value + assert mock_send.call_args.args[0].get("attachments") is None assert True - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - helper_add_event_to_queue(client, message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, - mail_details=mail_details, message_id='f76e5ca9-93f3-44ee-a0f8-f47ee83b1971') + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, + mail_details=mail_details, + message_id="f76e5ca9-93f3-44ee-a0f8-f47ee83b1971", + ) mock_send.assert_not_called @@ -76,17 +132,17 @@ def test_lock_account_mailer_queue(app, session, client): org = factory_org_model() factory_membership_model(user.id, org.id) id = org.id - mail_details = { - 'accountId': id, - 'accountName': org.name - } - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - helper_add_event_to_queue(client, message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, - mail_details=mail_details) + mail_details = {"accountId": id, "accountName": org.name} + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.NSF_LOCK_ACCOUNT.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value + assert mock_send.call_args.args[0].get("attachments") is None assert True @@ -99,92 +155,100 @@ def test_unlock_account_mailer_queue(app, session, client): response = types.SimpleNamespace() response.status_code = 200 - response.content = bytes('foo', 'utf-8') - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - with patch.object(RestService, 'post', return_value=response): + response.content = bytes("foo", "utf-8") + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + with patch.object(RestService, "post", return_value=response): # Note: This payload should work with report-api. mail_details = { - 'accountId': id, - 'accountName': org.name, - 'invoiceNumber': 'REG0123456', - 'receiptNumber': '99123', - 'paymentMethodDescription': 'Credit Card', - 'invoice': { - '_links': { - 'self': 'http://auth-web.dev.com/api/v1/payment-requests/2', - 'collection': 'http://auth-web.dev.com/api/v1/payment-requests?invoice_id=2' + "accountId": id, + "accountName": org.name, + "invoiceNumber": "REG0123456", + "receiptNumber": "99123", + "paymentMethodDescription": "Credit Card", + "invoice": { + "_links": { + "self": "http://auth-web.dev.com/api/v1/payment-requests/2", + "collection": "http://auth-web.dev.com/api/v1/payment-requests?invoice_id=2", }, - 'bcolAccount': 'TEST', - 'corpTypeCode': 'CP', - 'createdName': - 'test name', - 'id': 2, - 'createdBy': 'test', - 'paymentAccount': { - 'accountId': '1234', - 'billable': True - }, - 'paymentDate': '2024-02-27T09:52:03+00:00', - 'total': 130.0, - 'paymentMethod': 'CC', - 'overdueDate': '2024-03-01T09:52:02+00:00', - 'paid': 30.0, - 'details': [{'label': 'label', 'value': 'value'}], - 'serviceFees': 0.0, - 'updatedOn': '2024-02-27T09:52:03+00:00', - 'lineItems': [{ - 'waivedFees': None, - 'waivedBy': None, - 'gst': 0.0, - 'pst': 0.0, - 'filingFees': 10.0, - 'id': 2, - 'serviceFees': 0.0, - 'priorityFees': 0.0, - 'futureEffectiveFees': 0.0, - 'quantity': 1, - 'statusCode': 'ACTIVE', - 'total': 10.0, - 'description': 'NSF Fee' - }, { - 'waivedFees': None, - 'waivedBy': None, - 'gst': 0.0, - 'pst': 0.0, - 'filingFees': 10.0, - 'id': 1, - 'serviceFees': 0.0, - 'priorityFees': 0.0, - 'futureEffectiveFees': 0.0, - 'quantity': 1, - 'statusCode': 'ACTIVE', - 'total': 10.0, - 'description': 'Name Request' - }], - 'createdOn': '2024-02-27T09:51:55+00:00', - 'references': [{ - 'invoiceNumber': 'REG00001', - 'id': 2, - 'statusCode': 'COMPLETED' - }], - 'receipts': [{ - 'receiptAmount': 100.0, - 'id': 2, - 'receiptDate': '2024-02-27T09:52:03.018524', - 'receiptNumber': '1234567890' - }], - 'statusCode': 'COMPLETED', - 'folioNumber': '1234567890' - } + "bcolAccount": "TEST", + "corpTypeCode": "CP", + "createdName": "test name", + "id": 2, + "createdBy": "test", + "paymentAccount": {"accountId": "1234", "billable": True}, + "paymentDate": "2024-02-27T09:52:03+00:00", + "total": 130.0, + "paymentMethod": "CC", + "overdueDate": "2024-03-01T09:52:02+00:00", + "paid": 30.0, + "details": [{"label": "label", "value": "value"}], + "serviceFees": 0.0, + "updatedOn": "2024-02-27T09:52:03+00:00", + "lineItems": [ + { + "waivedFees": None, + "waivedBy": None, + "gst": 0.0, + "pst": 0.0, + "filingFees": 10.0, + "id": 2, + "serviceFees": 0.0, + "priorityFees": 0.0, + "futureEffectiveFees": 0.0, + "quantity": 1, + "statusCode": "ACTIVE", + "total": 10.0, + "description": "NSF Fee", + }, + { + "waivedFees": None, + "waivedBy": None, + "gst": 0.0, + "pst": 0.0, + "filingFees": 10.0, + "id": 1, + "serviceFees": 0.0, + "priorityFees": 0.0, + "futureEffectiveFees": 0.0, + "quantity": 1, + "statusCode": "ACTIVE", + "total": 10.0, + "description": "Name Request", + }, + ], + "createdOn": "2024-02-27T09:51:55+00:00", + "references": [ + { + "invoiceNumber": "REG00001", + "id": 2, + "statusCode": "COMPLETED", + } + ], + "receipts": [ + { + "receiptAmount": 100.0, + "id": 2, + "receiptDate": "2024-02-27T09:52:03.018524", + "receiptNumber": "1234567890", + } + ], + "statusCode": "COMPLETED", + "folioNumber": "1234567890", + }, } - helper_add_event_to_queue(client, message_type=QueueMessageTypes.NSF_UNLOCK_ACCOUNT.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.NSF_UNLOCK_ACCOUNT.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == \ - SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert ( + mock_send.call_args.args[0].get("content").get("subject") + == SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value + ) + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None assert True @@ -195,21 +259,20 @@ def test_account_conf_mailer_queue(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: # add an event to queue - mail_details = { - 'accountId': id, - 'nsfFee': '30' - } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.CONFIRMATION_PERIOD_OVER.value, - mail_details=mail_details) + mail_details = {"accountId": id, "nsfFee": "30"} + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.CONFIRMATION_PERIOD_OVER.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.ACCOUNT_CONF_OVER_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.ACCOUNT_CONF_OVER_SUBJECT.value + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None def test_account_pad_invoice_mailer_queue(app, session, client): @@ -219,33 +282,35 @@ def test_account_pad_invoice_mailer_queue(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: # add an event to queue, these are provided by cfs_create_invoice_task. mail_details = { - 'accountId': id, - 'credit_total': '20', - 'nsfFee': '30', - 'invoice_total': '100', - 'invoice_process_date': f'{datetime.now()}', - 'withdraw_total': '80', - 'invoice_number': '1234567890' + "accountId": id, + "credit_total": "20", + "nsfFee": "30", + "invoice_total": "100", + "invoice_process_date": f"{datetime.now()}", + "withdraw_total": "80", + "invoice_number": "1234567890", } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAD_INVOICE_CREATED.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAD_INVOICE_CREATED.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.PAD_INVOICE_CREATED.value - assert mock_send.call_args.args[0].get('attachments') is None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.PAD_INVOICE_CREATED.value + assert mock_send.call_args.args[0].get("attachments") is None - email_body = mock_send.call_args.args[0].get('content').get('body') + email_body = mock_send.call_args.args[0].get("content").get("body") assert email_body is not None - assert 'This email confirms recent transaction(s) on you account' in email_body - assert 'Invoice reference number: 1234567890' in email_body - assert 'Transaction date:' in email_body - assert 'Log in to view transaction details' in email_body - assert '/account/{org_id}/settings/transactions'.format(org_id=org.id) in email_body + assert "This email confirms recent transaction(s) on you account" in email_body + assert "Invoice reference number: 1234567890" in email_body + assert "Transaction date:" in email_body + assert "Log in to view transaction details" in email_body + assert "/account/{org_id}/settings/transactions".format(org_id=org.id) in email_body def test_account_admin_removed(app, session, client): @@ -255,19 +320,20 @@ def test_account_admin_removed(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - email = 'foo@testbar.com' - mail_details = { - 'accountId': id, - 'recipientEmail': email - } - helper_add_event_to_queue(client, message_type=QueueMessageTypes.ADMIN_REMOVED.value, mail_details=mail_details) + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + email = "foo@testbar.com" + mail_details = {"accountId": id, "recipientEmail": email} + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.ADMIN_REMOVED.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == email - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.ADMIN_REMOVED_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == email + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.ADMIN_REMOVED_SUBJECT.value + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None def test_account_team_modified(app, session, client): @@ -277,19 +343,21 @@ def test_account_team_modified(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: mail_details = { - 'accountId': id, + "accountId": id, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.TEAM_MEMBER_INVITED.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.TEAM_MEMBER_INVITED.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.TEAM_MODIFIED_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.TEAM_MODIFIED_SUBJECT.value + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None def test_online_banking_emails(app, session, client): @@ -299,44 +367,52 @@ def test_online_banking_emails(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - mail_details = { - 'amount': '100.00', - 'creditAmount': '10.00', - 'accountId': id - } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.ONLINE_BANKING_UNDER_PAYMENT.value, - mail_details=mail_details) + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + mail_details = {"amount": "100.00", "creditAmount": "10.00", "accountId": id} + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.ONLINE_BANKING_UNDER_PAYMENT.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get( - 'subject') == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None - - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.ONLINE_BANKING_OVER_PAYMENT.value, - mail_details=mail_details) + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert ( + mock_send.call_args.args[0].get("content").get("subject") + == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value + ) + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None + + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.ONLINE_BANKING_OVER_PAYMENT.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get( - 'subject') == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None - - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.ONLINE_BANKING_PAYMENT.value, - mail_details=mail_details) + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert ( + mock_send.call_args.args[0].get("content").get("subject") + == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value + ) + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None + + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.ONLINE_BANKING_PAYMENT.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get( - 'subject') == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert ( + mock_send.call_args.args[0].get("content").get("subject") + == SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value + ) + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None def test_pad_failed_emails(app, session, client): @@ -346,24 +422,25 @@ def test_pad_failed_emails(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - mail_details = { - 'accountId': id - } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAD_SETUP_FAILED.value, - mail_details=mail_details) + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + mail_details = {"accountId": id} + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAD_SETUP_FAILED.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get( - 'subject') == SubjectType.PAD_SETUP_FAILED.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.PAD_SETUP_FAILED.value + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAD_SETUP_FAILED.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAD_SETUP_FAILED.value, + mail_details=mail_details, + ) def test_payment_pending_emails(app, session, client): @@ -373,89 +450,112 @@ def test_payment_pending_emails(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: mail_details = { - 'accountId': id, - 'cfsAccountId': '12345678', - 'transactionAmount': 20.00 + "accountId": id, + "cfsAccountId": "12345678", + "transactionAmount": 20.00, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAYMENT_PENDING.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAYMENT_PENDING.value, + mail_details=mail_details, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get( - 'subject') == SubjectType.PAYMENT_PENDING.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None + assert mock_send.call_args.args[0].get("recipients") == "foo@bar.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.PAYMENT_PENDING.value + assert mock_send.call_args.args[0].get("attachments") is None + assert mock_send.call_args.args[0].get("content").get("body") is not None - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAYMENT_PENDING.value, - mail_details=mail_details) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAYMENT_PENDING.value, + mail_details=mail_details, + ) +@pytest.mark.skip(reason="Skipping until pay queue switches to google storage") def test_ejv_failure_emails(app, session, client): """Assert that events can be retrieved and decoded from the Queue.""" - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: - minio_file_name = 'FEEDBACK.1234567890' - minio_bucket = 'cgi-ejv' - - with open(minio_file_name, 'a+') as jv_file: - jv_file.write('TEST') - jv_file.close() + gcs_file_name = "FEEDBACK.1234567890" + gcs_bucket = "cgi-ejv" + try: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: + + # Set the environment variable for the GCS emulator + os.environ["CLOUD_STORAGE_EMULATOR_HOST"] = "http://localhost:4443" + os.environ["STORAGE_EMULATOR_HOST"] = "http://localhost:4443" # Add this if needed + + # Create the bucket in the GCS emulator + create_bucket(gcs_bucket) + # Create a temporary file for testing + with open(gcs_file_name, "w") as jv_file: + jv_file.write("TEST") + # Upload the file to the GCS emulator + google_store.GoogleStoreService.upload_file_to_bucket(gcs_bucket, gcs_file_name, gcs_file_name) + + file_content = google_store.GoogleStoreService.download_file_from_bucket(gcs_bucket, gcs_file_name) + assert file_content == b"TEST", f"File content mismatch: {file_content}" + + # Add an event to the queue + mail_details = { + "fileName": gcs_file_name, + "minioLocation": gcs_bucket, # TODO change this value later + } - # Now upload the ACK file to minio and publish message. - with open(minio_file_name, 'rb') as f: - MinioService.put_minio_file(minio_bucket, minio_file_name, f.read()) + # Ensure Pub/Sub emulator is correctly set up + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.EJV_FAILED.value, + mail_details=mail_details, + ) - # add an event to queue - mail_details = { - 'fileName': minio_file_name, - 'minioLocation': minio_bucket - } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.EJV_FAILED.value, - mail_details=mail_details) - - mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.EJV_FAILED.value + # Verify the email was sent + mock_send.assert_called() + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.EJV_FAILED.value + finally: + delete_bucket(gcs_bucket) def test_passcode_reset_email(app, session, client): """Assert that events can be retrieved and decoded from the Queue.""" - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: msg_payload = { - 'emailAddresses': 'test@test.com', - 'passCode': '1234', - 'businessIdentifier': 'CP1234', - 'businessName': 'TEST', - 'isStaffInitiated': True + "emailAddresses": "test@test.com", + "passCode": "1234", + "businessIdentifier": "CP1234", + "businessName": "TEST", + "isStaffInitiated": True, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.RESET_PASSCODE.value, - mail_details=msg_payload) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.RESET_PASSCODE.value, + mail_details=msg_payload, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.RESET_PASSCODE.value + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.RESET_PASSCODE.value # add an event to queue - staff initiated reset msg_payload = { - 'emailAddresses': 'test@test.com', - 'passCode': '1234', - 'businessIdentifier': 'CP1234', - 'businessName': 'TEST', - 'isStaffInitiated': False + "emailAddresses": "test@test.com", + "passCode": "1234", + "businessIdentifier": "CP1234", + "businessName": "TEST", + "isStaffInitiated": False, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.RESET_PASSCODE.value, - mail_details=msg_payload) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.RESET_PASSCODE.value, + mail_details=msg_payload, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.RESET_PASSCODE.value + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.RESET_PASSCODE.value def test_statement_notification_email(app, session, client): @@ -465,22 +565,24 @@ def test_statement_notification_email(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: msg_payload = { - 'accountId': id, - 'fromDate': '2023-09-15 00:00:00', - 'toDate': '2023-10-15 00:00:00', - 'emailAddresses': 'test@test.com', - 'statementFrequency': 'MONTHLY', - 'totalAmountOwing': 351.5 + "accountId": id, + "fromDate": "2023-09-15 00:00:00", + "toDate": "2023-10-15 00:00:00", + "emailAddresses": "test@test.com", + "statementFrequency": "MONTHLY", + "totalAmountOwing": 351.5, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.STATEMENT_NOTIFICATION.value, - mail_details=msg_payload) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.STATEMENT_NOTIFICATION.value, + mail_details=msg_payload, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.STATEMENT_NOTIFICATION.value + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.STATEMENT_NOTIFICATION.value def test_payment_reminder_notification_email(app, session, client): @@ -490,25 +592,28 @@ def test_payment_reminder_notification_email(app, session, client): factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: msg_payload = { - 'accountId': id, - 'dueDate': '2023-09-15 00:00:00', - 'emailAddresses': 'test@test.com', - 'statementFrequency': 'MONTHLY', - 'statementMonth': 'August', - 'statementNumber': 12345, - 'totalAmountOwing': 351.5, - 'shortNameLinksCount': 1 + "accountId": id, + "dueDate": "2023-09-15 00:00:00", + "emailAddresses": "test@test.com", + "statementFrequency": "MONTHLY", + "statementMonth": "August", + "statementNumber": 12345, + "totalAmountOwing": 351.5, + "shortNameLinksCount": 1, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAYMENT_REMINDER_NOTIFICATION.value, - mail_details=msg_payload) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAYMENT_REMINDER_NOTIFICATION.value, + mail_details=msg_payload, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].\ - get('content').get('subject') == SubjectType.PAYMENT_REMINDER_NOTIFICATION.value + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert ( + mock_send.call_args.args[0].get("content").get("subject") == SubjectType.PAYMENT_REMINDER_NOTIFICATION.value + ) def test_payment_due_notification_email(app, session, client): @@ -517,21 +622,23 @@ def test_payment_due_notification_email(app, session, client): org = factory_org_model() factory_membership_model(user.id, org.id) id = org.id - with patch.object(notification_service, 'send_email', return_value=None) as mock_send: + with patch.object(notification_service, "send_email", return_value=None) as mock_send: msg_payload = { - 'accountId': id, - 'dueDate': '2023-09-15 00:00:00', - 'emailAddresses': 'test@test.com', - 'statementFrequency': 'MONTHLY', - 'statementMonth': 'August', - 'statementNumber': 12345, - 'totalAmountOwing': 351.5, - 'shortNameLinksCount': 1 + "accountId": id, + "dueDate": "2023-09-15 00:00:00", + "emailAddresses": "test@test.com", + "statementFrequency": "MONTHLY", + "statementMonth": "August", + "statementNumber": 12345, + "totalAmountOwing": 351.5, + "shortNameLinksCount": 1, } - helper_add_event_to_queue(client, - message_type=QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value, - mail_details=msg_payload) + helper_add_event_to_queue( + client, + message_type=QueueMessageTypes.PAYMENT_DUE_NOTIFICATION.value, + mail_details=msg_payload, + ) mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'test@test.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.PAYMENT_DUE_NOTIFICATION.value + assert mock_send.call_args.args[0].get("recipients") == "test@test.com" + assert mock_send.call_args.args[0].get("content").get("subject") == SubjectType.PAYMENT_DUE_NOTIFICATION.value diff --git a/queue_services/account-mailer/tests/unit/utils.py b/queue_services/account-mailer/tests/unit/utils.py index e470ef24d4..f340478d41 100644 --- a/queue_services/account-mailer/tests/unit/utils.py +++ b/queue_services/account-mailer/tests/unit/utils.py @@ -22,34 +22,36 @@ def build_request_for_queue_push(message_type, payload, message_id=None): """Build request for queue message.""" - queue_message_bytes = to_queue_message(SimpleCloudEvent( - id=str(message_id if message_id else uuid.uuid4()), - source='account-mailer', - subject=None, - time=datetime.now(tz=timezone.utc).isoformat(), - type=message_type, - data=payload - )) + queue_message_bytes = to_queue_message( + SimpleCloudEvent( + id=str(message_id if message_id else uuid.uuid4()), + source="account-mailer", + subject=None, + time=datetime.now(tz=timezone.utc).isoformat(), + type=message_type, + data=payload, + ) + ) return { - 'message': { - 'data': base64.b64encode(queue_message_bytes).decode('utf-8') - }, - 'subscription': 'foobar' + "message": {"data": base64.b64encode(queue_message_bytes).decode("utf-8")}, + "subscription": "foobar", } def post_to_queue(client, request_payload): """Post request to worker using an http request on our wrapped flask instance.""" - response = client.post('/', data=json.dumps(request_payload), - headers={'Content-Type': 'application/json'}) + response = client.post( + "/", + data=json.dumps(request_payload), + headers={"Content-Type": "application/json"}, + ) assert response.status_code == 200 def helper_add_event_to_queue(client, message_type: str, mail_details: dict, message_id=None): """Add event to the Queue.""" if not mail_details: - mail_details = { - } + mail_details = {} payload = build_request_for_queue_push(message_type, mail_details, message_id) post_to_queue(client, payload) From 86914052b99d7f779e6b3063791556cc82220a17 Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Thu, 27 Mar 2025 08:41:37 -0700 Subject: [PATCH 07/10] 26272 - lint fix (#3336) --- .../auth/account-settings/account-info/AccountInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue index 31e1cca16c..ad828ce314 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue @@ -300,7 +300,7 @@ export default defineComponent({ AccountAccessType }, props: ['orgId'], - setup (props, { root }) { + setup () { const codesStore = useCodesStore() const orgStore = useOrgStore() const userStore = useUserStore() From 2e8fb6c8e0b66e1d5720dd5f7bff91383b27ce39 Mon Sep 17 00:00:00 2001 From: Travis Semple <travis8814@gmail.com> Date: Thu, 27 Mar 2025 10:07:43 -0700 Subject: [PATCH 08/10] minor changes --- auth-web/tests/unit/services/task.service.spec.ts | 4 ++-- auth-web/vite.config.ts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/auth-web/tests/unit/services/task.service.spec.ts b/auth-web/tests/unit/services/task.service.spec.ts index f08f67e1ab..a83af01836 100644 --- a/auth-web/tests/unit/services/task.service.spec.ts +++ b/auth-web/tests/unit/services/task.service.spec.ts @@ -30,8 +30,8 @@ const mocks = vi.hoisted(() => ({ describe('Task service', () => { beforeEach(() => { - TaskService.getTaskById = vi.fn().mockResolvedValue(mockTask) - TaskService.fetchTasks = vi.fn().mockResolvedValue(mockTask) + TaskService.getTaskById = vi.fn().mockResolvedValue(mockTask.data) + TaskService.fetchTasks = vi.fn().mockResolvedValue(mockTask.data) sessionStorage['AUTH_API_CONFIG'] = JSON.stringify(mockob) vi.doMock('axios', () => { return { diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index bbd39749ad..cb1e1b5e58 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -99,5 +99,9 @@ export default defineConfig({ deps: { inline: ['vuetify'] } + }, + // Needs to be in here so there aren't two instances of sbc-common-components created. + optimizeDeps: { + exclude: ['@vue/composition-api', 'sbc-common-components'] } }) From 79db6c1e143d9bfe96268dd0c9df50740584b36c Mon Sep 17 00:00:00 2001 From: Travis Semple <travis8814@gmail.com> Date: Thu, 27 Mar 2025 10:24:40 -0700 Subject: [PATCH 09/10] small tweaks for unit test --- auth-web/tests/unit/setup.ts | 10 ---------- auth-web/vite.config.ts | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/auth-web/tests/unit/setup.ts b/auth-web/tests/unit/setup.ts index 459c7c0bc0..53ebc87789 100644 --- a/auth-web/tests/unit/setup.ts +++ b/auth-web/tests/unit/setup.ts @@ -18,16 +18,6 @@ Vue.use(VueRouter) Vue.use(VueSanitize) Vue.directive('can', can) -// mock fix Error: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead. -// remove this once when vuex-module-decorators removed from bcrs-shared-components -vi.mock('@bcrs-shared-components/base-address/BaseAddress.vue', () => ({ - default: { - name: 'BaseAddress', - template: '<div class="base-address-mock" />', - props: ['editing', 'schema', 'address'] - } -})) - // Prevent the warning "[Vuetify] Unable to locate target [data-app]" document.body.setAttribute('data-app', 'true') diff --git a/auth-web/vite.config.ts b/auth-web/vite.config.ts index cb1e1b5e58..351a583311 100644 --- a/auth-web/vite.config.ts +++ b/auth-web/vite.config.ts @@ -97,7 +97,8 @@ export default defineConfig({ } }, deps: { - inline: ['vuetify'] + // Need sbc-common-components in there otherwise vue error + inline: ['vuetify', 'sbc-common-components'] } }, // Needs to be in here so there aren't two instances of sbc-common-components created. From 26bb905f65de0b4471a22f8010d3cf01e56fb22f Mon Sep 17 00:00:00 2001 From: Jia Xu <Jia.Xu@gov.bc.ca> Date: Thu, 27 Mar 2025 15:51:18 -0700 Subject: [PATCH 10/10] upgrade sbc-common-components version (#3337) --- auth-web/package-lock.json | 14 +++++++------- auth-web/package.json | 2 +- auth-web/tests/unit/setup.ts | 9 +++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/auth-web/package-lock.json b/auth-web/package-lock.json index 1a5a486d88..705339c39e 100644 --- a/auth-web/package-lock.json +++ b/auth-web/package-lock.json @@ -29,7 +29,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "^3.1.1", + "sbc-common-components": "^3.1.2", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", @@ -8935,9 +8935,9 @@ } }, "node_modules/sbc-common-components": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.1.tgz", - "integrity": "sha512-OXi3HOxSWmQJQPtsBaZO7kH7QNnvbCzbxi0sSD1wNCam0eN80lwx4L6XB9Uv7Xz3C8sB7+9+rCOx6iNuCQzt5g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.2.tgz", + "integrity": "sha512-e3jwrK4fK/8ilhNc0woNyRuC/Rt9/t0yRndfDIYQ3zwYgdArdIRbgXBk7wcIWDIXc05MsT26VfjeYtTBG4d+hw==", "dependencies": { "@mdi/font": "^4.5.95", "axios": "^1.8.1", @@ -19236,9 +19236,9 @@ } }, "sbc-common-components": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.1.tgz", - "integrity": "sha512-OXi3HOxSWmQJQPtsBaZO7kH7QNnvbCzbxi0sSD1wNCam0eN80lwx4L6XB9Uv7Xz3C8sB7+9+rCOx6iNuCQzt5g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/sbc-common-components/-/sbc-common-components-3.1.2.tgz", + "integrity": "sha512-e3jwrK4fK/8ilhNc0woNyRuC/Rt9/t0yRndfDIYQ3zwYgdArdIRbgXBk7wcIWDIXc05MsT26VfjeYtTBG4d+hw==", "requires": { "@mdi/font": "^4.5.95", "axios": "^1.8.1", diff --git a/auth-web/package.json b/auth-web/package.json index 1664eb39bf..10e91c6bbd 100644 --- a/auth-web/package.json +++ b/auth-web/package.json @@ -38,7 +38,7 @@ "pinia": "^2.1.6", "pinia-class": "^0.0.3", "sanitize-html": "^2.13.0", - "sbc-common-components": "^3.1.1", + "sbc-common-components": "^3.1.2", "vue": "2.6.14", "vue-auto-resize": "^1.0.1", "vue-debounce-decorator": "^1.0.1", diff --git a/auth-web/tests/unit/setup.ts b/auth-web/tests/unit/setup.ts index 53ebc87789..500f13940d 100644 --- a/auth-web/tests/unit/setup.ts +++ b/auth-web/tests/unit/setup.ts @@ -22,3 +22,12 @@ Vue.directive('can', can) document.body.setAttribute('data-app', 'true') setActivePinia(createPinia()) + +// Mock BaseAddress component to avoid decorator issues in tests +vi.mock('@bcrs-shared-components/base-address/BaseAddress.vue', () => ({ + default: { + name: 'BaseAddress', + template: '<div class="base-address-mock" />', + props: ['editing', 'schema', 'address'] + } +}))