From 23d551256cd5b56ac63303e5d85d9502f914de3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 22:11:14 +0800 Subject: [PATCH 01/16] chore(deps-dev): bump @typescript-eslint/eslint-plugin from 8.14.0 to 8.15.0 in /shared (#7912) chore(deps-dev): bump @typescript-eslint/eslint-plugin in /shared Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.14.0 to 8.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.15.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- shared/package-lock.json | 211 ++++++++++++--------------------------- 1 file changed, 63 insertions(+), 148 deletions(-) diff --git a/shared/package-lock.json b/shared/package-lock.json index c1224a1c9b..1665b09df4 100644 --- a/shared/package-lock.json +++ b/shared/package-lock.json @@ -109,16 +109,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz", - "integrity": "sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", + "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.14.0", - "@typescript-eslint/type-utils": "8.14.0", - "@typescript-eslint/utils": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/type-utils": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -141,53 +141,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", - "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", - "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", - "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz", @@ -291,14 +244,31 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", + "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz", - "integrity": "sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", + "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.14.0", - "@typescript-eslint/utils": "8.14.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/utils": "8.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -309,16 +279,19 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", - "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", + "node_modules/@typescript-eslint/types": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", + "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -328,14 +301,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", - "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", + "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -356,33 +329,16 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", - "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz", - "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", + "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.14.0", - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/typescript-estree": "8.14.0" + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -393,52 +349,21 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", - "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", - "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", - "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", + "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "8.15.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -446,28 +371,18 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", - "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "eslint-visitor-keys": "^3.4.3" - }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/eslint" } }, "node_modules/balanced-match": { From 2d10593de4dff410242be7b2446cb07a559990dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 22:11:43 +0800 Subject: [PATCH 02/16] fix(deps): bump @aws-sdk/client-lambda from 3.654.0 to 3.693.0 (#7910) Bumps [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-lambda) from 3.654.0 to 3.693.0. - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.693.0/clients/client-lambda) --- updated-dependencies: - dependency-name: "@aws-sdk/client-lambda" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 1092 +++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 552 insertions(+), 542 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdce0cebc1..03492b0b83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.536.0", - "@aws-sdk/client-lambda": "^3.654.0", + "@aws-sdk/client-lambda": "^3.693.0", "@babel/runtime": "^7.24.7", "@faker-js/faker": "^8.4.1", "@growthbook/growthbook": "^1.1.0", @@ -830,55 +830,55 @@ "optional": true }, "node_modules/@aws-sdk/client-lambda": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.654.0.tgz", - "integrity": "sha512-/ITRFpQeutTNsyZ5AjLCnNKM08rPq5WSEtNoJ2zLOAinOUnPpLFZ3p6w+5AVc2FYTeFY5gxby84Ejs4gzS8/Mg==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.693.0.tgz", + "integrity": "sha512-EEGaiBHoQrnIpFH5JMkPt3AQp47Jz2p1hYFdV6DYhyFki8QlDUryEo8Tl5zzIsPdPa9wI6nFxqwqU+q2b2CPOw==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.654.0", - "@aws-sdk/client-sts": "3.654.0", - "@aws-sdk/core": "3.654.0", - "@aws-sdk/credential-provider-node": "3.654.0", - "@aws-sdk/middleware-host-header": "3.654.0", - "@aws-sdk/middleware-logger": "3.654.0", - "@aws-sdk/middleware-recursion-detection": "3.654.0", - "@aws-sdk/middleware-user-agent": "3.654.0", - "@aws-sdk/region-config-resolver": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@aws-sdk/util-endpoints": "3.654.0", - "@aws-sdk/util-user-agent-browser": "3.654.0", - "@aws-sdk/util-user-agent-node": "3.654.0", - "@smithy/config-resolver": "^3.0.8", - "@smithy/core": "^2.4.3", - "@smithy/eventstream-serde-browser": "^3.0.9", - "@smithy/eventstream-serde-config-resolver": "^3.0.6", - "@smithy/eventstream-serde-node": "^3.0.8", - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/hash-node": "^3.0.6", - "@smithy/invalid-dependency": "^3.0.6", - "@smithy/middleware-content-length": "^3.0.8", - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@aws-sdk/client-sso-oidc": "3.693.0", + "@aws-sdk/client-sts": "3.693.0", + "@aws-sdk/core": "3.693.0", + "@aws-sdk/credential-provider-node": "3.693.0", + "@aws-sdk/middleware-host-header": "3.693.0", + "@aws-sdk/middleware-logger": "3.693.0", + "@aws-sdk/middleware-recursion-detection": "3.693.0", + "@aws-sdk/middleware-user-agent": "3.693.0", + "@aws-sdk/region-config-resolver": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@aws-sdk/util-endpoints": "3.693.0", + "@aws-sdk/util-user-agent-browser": "3.693.0", + "@aws-sdk/util-user-agent-node": "3.693.0", + "@smithy/config-resolver": "^3.0.11", + "@smithy/core": "^2.5.2", + "@smithy/eventstream-serde-browser": "^3.0.12", + "@smithy/eventstream-serde-config-resolver": "^3.0.9", + "@smithy/eventstream-serde-node": "^3.0.11", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/hash-node": "^3.0.9", + "@smithy/invalid-dependency": "^3.0.9", + "@smithy/middleware-content-length": "^3.0.11", + "@smithy/middleware-endpoint": "^3.2.2", + "@smithy/middleware-retry": "^3.0.26", + "@smithy/middleware-serde": "^3.0.9", + "@smithy/middleware-stack": "^3.0.9", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/node-http-handler": "^3.3.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/url-parser": "^3.0.9", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.18", - "@smithy/util-defaults-mode-node": "^3.0.18", - "@smithy/util-endpoints": "^2.1.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", - "@smithy/util-stream": "^3.1.6", + "@smithy/util-defaults-mode-browser": "^3.0.26", + "@smithy/util-defaults-mode-node": "^3.0.26", + "@smithy/util-endpoints": "^2.1.5", + "@smithy/util-middleware": "^3.0.9", + "@smithy/util-retry": "^3.0.9", + "@smithy/util-stream": "^3.3.0", "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.5", + "@smithy/util-waiter": "^3.1.8", "tslib": "^2.6.2" }, "engines": { @@ -968,46 +968,46 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sso": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.654.0.tgz", - "integrity": "sha512-4kBxs2IzCDtj6a6lRXa/lXK5wWpMGzwKtb+HMXf/rJYVM6x7wYRzc1hYrOd3DYkFQ/sR3dUFj+0mTP0os3aAbA==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz", + "integrity": "sha512-QEynrBC26x6TG9ZMzApR/kZ3lmt4lEIs2D+cHuDxt6fDGzahBUsQFBwJqhizzsM97JJI5YvmJhmihoYjdSSaXA==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.654.0", - "@aws-sdk/middleware-host-header": "3.654.0", - "@aws-sdk/middleware-logger": "3.654.0", - "@aws-sdk/middleware-recursion-detection": "3.654.0", - "@aws-sdk/middleware-user-agent": "3.654.0", - "@aws-sdk/region-config-resolver": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@aws-sdk/util-endpoints": "3.654.0", - "@aws-sdk/util-user-agent-browser": "3.654.0", - "@aws-sdk/util-user-agent-node": "3.654.0", - "@smithy/config-resolver": "^3.0.8", - "@smithy/core": "^2.4.3", - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/hash-node": "^3.0.6", - "@smithy/invalid-dependency": "^3.0.6", - "@smithy/middleware-content-length": "^3.0.8", - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@aws-sdk/core": "3.693.0", + "@aws-sdk/middleware-host-header": "3.693.0", + "@aws-sdk/middleware-logger": "3.693.0", + "@aws-sdk/middleware-recursion-detection": "3.693.0", + "@aws-sdk/middleware-user-agent": "3.693.0", + "@aws-sdk/region-config-resolver": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@aws-sdk/util-endpoints": "3.693.0", + "@aws-sdk/util-user-agent-browser": "3.693.0", + "@aws-sdk/util-user-agent-node": "3.693.0", + "@smithy/config-resolver": "^3.0.11", + "@smithy/core": "^2.5.2", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/hash-node": "^3.0.9", + "@smithy/invalid-dependency": "^3.0.9", + "@smithy/middleware-content-length": "^3.0.11", + "@smithy/middleware-endpoint": "^3.2.2", + "@smithy/middleware-retry": "^3.0.26", + "@smithy/middleware-serde": "^3.0.9", + "@smithy/middleware-stack": "^3.0.9", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/node-http-handler": "^3.3.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/url-parser": "^3.0.9", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.18", - "@smithy/util-defaults-mode-node": "^3.0.18", - "@smithy/util-endpoints": "^2.1.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", + "@smithy/util-defaults-mode-browser": "^3.0.26", + "@smithy/util-defaults-mode-node": "^3.0.26", + "@smithy/util-endpoints": "^2.1.5", + "@smithy/util-middleware": "^3.0.9", + "@smithy/util-retry": "^3.0.9", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1016,47 +1016,47 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.654.0.tgz", - "integrity": "sha512-gbHrKsEnaAtmkNCVQzLyiqMzpDaThV/bWl/ODEklI+t6stW3Pe3oDMstEHLfJ6JU5g8sYnx4VLuxlnJMtUkvPw==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.693.0.tgz", + "integrity": "sha512-UEDbYlYtK/e86OOMyFR4zEPyenIxDzO2DRdz3fwVW7RzZ94wfmSwBh/8skzPTuY1G7sI064cjHW0b0QG01Sdtg==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.654.0", - "@aws-sdk/credential-provider-node": "3.654.0", - "@aws-sdk/middleware-host-header": "3.654.0", - "@aws-sdk/middleware-logger": "3.654.0", - "@aws-sdk/middleware-recursion-detection": "3.654.0", - "@aws-sdk/middleware-user-agent": "3.654.0", - "@aws-sdk/region-config-resolver": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@aws-sdk/util-endpoints": "3.654.0", - "@aws-sdk/util-user-agent-browser": "3.654.0", - "@aws-sdk/util-user-agent-node": "3.654.0", - "@smithy/config-resolver": "^3.0.8", - "@smithy/core": "^2.4.3", - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/hash-node": "^3.0.6", - "@smithy/invalid-dependency": "^3.0.6", - "@smithy/middleware-content-length": "^3.0.8", - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@aws-sdk/core": "3.693.0", + "@aws-sdk/credential-provider-node": "3.693.0", + "@aws-sdk/middleware-host-header": "3.693.0", + "@aws-sdk/middleware-logger": "3.693.0", + "@aws-sdk/middleware-recursion-detection": "3.693.0", + "@aws-sdk/middleware-user-agent": "3.693.0", + "@aws-sdk/region-config-resolver": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@aws-sdk/util-endpoints": "3.693.0", + "@aws-sdk/util-user-agent-browser": "3.693.0", + "@aws-sdk/util-user-agent-node": "3.693.0", + "@smithy/config-resolver": "^3.0.11", + "@smithy/core": "^2.5.2", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/hash-node": "^3.0.9", + "@smithy/invalid-dependency": "^3.0.9", + "@smithy/middleware-content-length": "^3.0.11", + "@smithy/middleware-endpoint": "^3.2.2", + "@smithy/middleware-retry": "^3.0.26", + "@smithy/middleware-serde": "^3.0.9", + "@smithy/middleware-stack": "^3.0.9", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/node-http-handler": "^3.3.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/url-parser": "^3.0.9", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.18", - "@smithy/util-defaults-mode-node": "^3.0.18", - "@smithy/util-endpoints": "^2.1.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", + "@smithy/util-defaults-mode-browser": "^3.0.26", + "@smithy/util-defaults-mode-node": "^3.0.26", + "@smithy/util-endpoints": "^2.1.5", + "@smithy/util-middleware": "^3.0.9", + "@smithy/util-retry": "^3.0.9", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1064,52 +1064,52 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.654.0" + "@aws-sdk/client-sts": "^3.693.0" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/client-sts": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.654.0.tgz", - "integrity": "sha512-tyHa8jsBy+/NQZFHm6Q2Q09Vi9p3EH4yPy6PU8yPewpi2klreObtrUd0anJa6nzjS9SSuqnlZWsRic3cQ4QwCg==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz", + "integrity": "sha512-4S2y7VEtvdnjJX4JPl4kDQlslxXEZFnC50/UXVUYSt/AMc5A/GgspFNA5FVz4E3Gwpfobbf23hR2NBF8AGvYoQ==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.654.0", - "@aws-sdk/core": "3.654.0", - "@aws-sdk/credential-provider-node": "3.654.0", - "@aws-sdk/middleware-host-header": "3.654.0", - "@aws-sdk/middleware-logger": "3.654.0", - "@aws-sdk/middleware-recursion-detection": "3.654.0", - "@aws-sdk/middleware-user-agent": "3.654.0", - "@aws-sdk/region-config-resolver": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@aws-sdk/util-endpoints": "3.654.0", - "@aws-sdk/util-user-agent-browser": "3.654.0", - "@aws-sdk/util-user-agent-node": "3.654.0", - "@smithy/config-resolver": "^3.0.8", - "@smithy/core": "^2.4.3", - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/hash-node": "^3.0.6", - "@smithy/invalid-dependency": "^3.0.6", - "@smithy/middleware-content-length": "^3.0.8", - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@aws-sdk/client-sso-oidc": "3.693.0", + "@aws-sdk/core": "3.693.0", + "@aws-sdk/credential-provider-node": "3.693.0", + "@aws-sdk/middleware-host-header": "3.693.0", + "@aws-sdk/middleware-logger": "3.693.0", + "@aws-sdk/middleware-recursion-detection": "3.693.0", + "@aws-sdk/middleware-user-agent": "3.693.0", + "@aws-sdk/region-config-resolver": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@aws-sdk/util-endpoints": "3.693.0", + "@aws-sdk/util-user-agent-browser": "3.693.0", + "@aws-sdk/util-user-agent-node": "3.693.0", + "@smithy/config-resolver": "^3.0.11", + "@smithy/core": "^2.5.2", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/hash-node": "^3.0.9", + "@smithy/invalid-dependency": "^3.0.9", + "@smithy/middleware-content-length": "^3.0.11", + "@smithy/middleware-endpoint": "^3.2.2", + "@smithy/middleware-retry": "^3.0.26", + "@smithy/middleware-serde": "^3.0.9", + "@smithy/middleware-stack": "^3.0.9", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/node-http-handler": "^3.3.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/url-parser": "^3.0.9", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.18", - "@smithy/util-defaults-mode-node": "^3.0.18", - "@smithy/util-endpoints": "^2.1.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", + "@smithy/util-defaults-mode-browser": "^3.0.26", + "@smithy/util-defaults-mode-node": "^3.0.26", + "@smithy/util-endpoints": "^2.1.5", + "@smithy/util-middleware": "^3.0.9", + "@smithy/util-retry": "^3.0.9", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1118,18 +1118,19 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/core": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.654.0.tgz", - "integrity": "sha512-4Rwx7BVaNaFqmXBDmnOkMbyuIFFbpZ+ru4lr660p45zY1QoNNSalechfoRffcokLFOZO+VWEJkdcorPUUU993w==", - "dependencies": { - "@smithy/core": "^2.4.3", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/property-provider": "^3.1.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/signature-v4": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/util-middleware": "^3.0.6", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.693.0.tgz", + "integrity": "sha512-v6Z/kWmLFqRLDPEwl9hJGhtTgIFHjZugSfF1Yqffdxf4n1AWgtHS7qSegakuMyN5pP4K2tvUD8qHJ+gGe2Bw2A==", + "dependencies": { + "@aws-sdk/types": "3.692.0", + "@smithy/core": "^2.5.2", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.6", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/util-middleware": "^3.0.9", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -1138,13 +1139,14 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.654.0.tgz", - "integrity": "sha512-kogsx3Ql81JouHS7DkheCDU9MYAvK0AokxjcshDveGmf7BbgbWCA8Fnb9wjQyNDaOXNvkZu8Z8rgkX91z324/w==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/property-provider": "^3.1.6", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.693.0.tgz", + "integrity": "sha512-hMUZaRSF7+iBKZfBHNLihFs9zvpM1CB8MBOTnTp5NGCVkRYF3SB2LH+Kcippe0ats4qCyB1eEoyQX99rERp2iQ==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1152,18 +1154,19 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.654.0.tgz", - "integrity": "sha512-tgmAH4MBi/aDR882lfw48+tDV95ZH3GWc1Eoe6DpNLiM3GN2VfU/cZwuHmi6aq+vAbdIlswBHJ/+va0fOvlyjw==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/property-provider": "^3.1.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/util-stream": "^3.1.6", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz", + "integrity": "sha512-sL8MvwNJU7ZpD7/d2VVb3by1GknIJUxzTIgYtVkDVA/ojo+KRQSSHxcj0EWWXF5DTSh2Tm+LrEug3y1ZyKHsDA==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/node-http-handler": "^3.3.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.6", + "@smithy/smithy-client": "^3.4.3", + "@smithy/types": "^3.7.0", + "@smithy/util-stream": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1171,45 +1174,46 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.654.0.tgz", - "integrity": "sha512-DKSdaNu2hwdmuvnm9KnA0NLqMWxxmxSOLWjSUSoFIm++wGXUjPrRMFYKvMktaXnPuyf5my8gF/yGbwzPZ8wlTg==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.654.0", - "@aws-sdk/credential-provider-http": "3.654.0", - "@aws-sdk/credential-provider-process": "3.654.0", - "@aws-sdk/credential-provider-sso": "3.654.0", - "@aws-sdk/credential-provider-web-identity": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@smithy/credential-provider-imds": "^3.2.3", - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz", + "integrity": "sha512-kvaa4mXhCCOuW7UQnBhYqYfgWmwy7WSBSDClutwSLPZvgrhYj2l16SD2lN4IfYdxARYMJJ1lFYp3/jJG/9Yk4Q==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/credential-provider-env": "3.693.0", + "@aws-sdk/credential-provider-http": "3.693.0", + "@aws-sdk/credential-provider-process": "3.693.0", + "@aws-sdk/credential-provider-sso": "3.693.0", + "@aws-sdk/credential-provider-web-identity": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.654.0" + "@aws-sdk/client-sts": "^3.693.0" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.654.0.tgz", - "integrity": "sha512-wPV7CNYaXDEc+SS+3R0v8SZwkHRUE1z2k2j1d49tH5QBDT4tb/k2V/biXWkwSk3hbR+IMWXmuhJDv/5lybhIvg==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.654.0", - "@aws-sdk/credential-provider-http": "3.654.0", - "@aws-sdk/credential-provider-ini": "3.654.0", - "@aws-sdk/credential-provider-process": "3.654.0", - "@aws-sdk/credential-provider-sso": "3.654.0", - "@aws-sdk/credential-provider-web-identity": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@smithy/credential-provider-imds": "^3.2.3", - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz", + "integrity": "sha512-42WMsBjTNnjYxYuM3qD/Nq+8b7UdMopUq5OduMDxoM3mFTV6PXMMnfI4Z1TNnR4tYRvPXAnuNltF6xmjKbSJRA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.693.0", + "@aws-sdk/credential-provider-http": "3.693.0", + "@aws-sdk/credential-provider-ini": "3.693.0", + "@aws-sdk/credential-provider-process": "3.693.0", + "@aws-sdk/credential-provider-sso": "3.693.0", + "@aws-sdk/credential-provider-web-identity": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1217,14 +1221,15 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.654.0.tgz", - "integrity": "sha512-PmQoo8sZ9Q2Ow8OMzK++Z9lI7MsRUG7sNq3E72DVA215dhtTICTDQwGlXH2AAmIp7n+G9LLRds+4wo2ehG4mkg==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.693.0.tgz", + "integrity": "sha512-cvxQkrTWHHjeHrPlj7EWXPnFSq8x7vMx+Zn1oTsMpCY445N9KuzjfJTkmNGwU2GT6rSZI9/0MM02aQvl5bBBTQ==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1232,16 +1237,17 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.654.0.tgz", - "integrity": "sha512-7GFme6fWEdA/XYKzZPOAdj/jS6fMBy1NdSIZsDXikS0v9jU+ZzHrAaWt13YLzHyjgxB9Sg9id9ncdY1IiubQXQ==", - "dependencies": { - "@aws-sdk/client-sso": "3.654.0", - "@aws-sdk/token-providers": "3.654.0", - "@aws-sdk/types": "3.654.0", - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz", + "integrity": "sha512-479UlJxY+BFjj3pJFYUNC0DCMrykuG7wBAXfsvZqQxKUa83DnH5Q1ID/N2hZLkxjGd4ZW0AC3lTOMxFelGzzpQ==", + "dependencies": { + "@aws-sdk/client-sso": "3.693.0", + "@aws-sdk/core": "3.693.0", + "@aws-sdk/token-providers": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1249,30 +1255,31 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.654.0.tgz", - "integrity": "sha512-6a2g9gMtZToqSu+CusjNK5zvbLJahQ9di7buO3iXgbizXpLXU1rnawCpWxwslMpT5fLgMSKDnKDrr6wdEk7jSw==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/property-provider": "^3.1.6", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz", + "integrity": "sha512-8LB210Pr6VeCiSb2hIra+sAH4KUBLyGaN50axHtIgufVK8jbKIctTZcVY5TO9Se+1107TsruzeXS7VeqVdJfFA==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.654.0" + "@aws-sdk/client-sts": "^3.693.0" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.654.0.tgz", - "integrity": "sha512-rxGgVHWKp8U2ubMv+t+vlIk7QYUaRCHaVpmUlJv0Wv6Q0KeO9a42T9FxHphjOTlCGQOLcjCreL9CF8Qhtb4mdQ==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz", + "integrity": "sha512-BCki6sAZ5jYwIN/t3ElCiwerHad69ipHwPsDCxJQyeiOnJ8HG+lEpnVIfrnI8A0fLQNSF3Gtx6ahfBpKiv1Oug==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@aws-sdk/types": "3.692.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1280,12 +1287,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-logger": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.654.0.tgz", - "integrity": "sha512-OQYb+nWlmASyXfRb989pwkJ9EVUMP1CrKn2eyTk3usl20JZmKo2Vjis6I0tLUkMSxMhnBJJlQKyWkRpD/u1FVg==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz", + "integrity": "sha512-dXnXDPr+wIiJ1TLADACI1g9pkSB21KkMIko2u4CJ2JCBoxi5IqeTnVoa6YcC8GdFNVRl+PorZ3Zqfmf1EOTC6w==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/types": "^3.4.2", + "@aws-sdk/types": "3.692.0", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1293,13 +1300,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.654.0.tgz", - "integrity": "sha512-gKSomgltKVmsT8sC6W7CrADZ4GHwX9epk3GcH6QhebVO3LA9LRbkL3TwOPUXakxxOLLUTYdOZLIOtFf7iH00lg==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz", + "integrity": "sha512-0LDmM+VxXp0u3rG0xQRWD/q6Ubi7G8I44tBPahevD5CaiDZTkmNTrVUf0VEJgVe0iCKBppACMBDkLB0/ETqkFw==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@aws-sdk/types": "3.692.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1307,14 +1314,16 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.654.0.tgz", - "integrity": "sha512-liCcqPAyRsr53cy2tYu4qeH4MMN0eh9g6k56XzI5xd4SghXH5YWh4qOYAlQ8T66ZV4nPMtD8GLtLXGzsH8moFg==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@aws-sdk/util-endpoints": "3.654.0", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz", + "integrity": "sha512-/KUq/KEpFFbQmNmpp7SpAtFAdViquDfD2W0QcG07zYBfz9MwE2ig48ALynXm5sMpRmnG7sJXjdvPtTsSVPfkiw==", + "dependencies": { + "@aws-sdk/core": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@aws-sdk/util-endpoints": "3.693.0", + "@smithy/core": "^2.5.2", + "@smithy/protocol-http": "^4.1.6", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1322,29 +1331,29 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/token-providers": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.654.0.tgz", - "integrity": "sha512-D8GeJYmvbfWkQDtTB4owmIobSMexZel0fOoetwvgCQ/7L8VPph3Q2bn1TRRIXvH7wdt6DcDxA3tKMHPBkT3GlA==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz", + "integrity": "sha512-nDBTJMk1l/YmFULGfRbToOA2wjf+FkQT4dMgYCv+V9uSYsMzQj8A7Tha2dz9yv4vnQgYaEiErQ8d7HVyXcVEoA==", + "dependencies": { + "@aws-sdk/types": "3.692.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.654.0" + "@aws-sdk/client-sso-oidc": "^3.693.0" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/types": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.654.0.tgz", - "integrity": "sha512-VWvbED3SV+10QJIcmU/PKjsKilsTV16d1I7/on4bvD/jo1qGeMXqLDBSen3ks/tuvXZF/mFc7ZW/W2DiLVtO7A==", + "version": "3.692.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.692.0.tgz", + "integrity": "sha512-RpNvzD7zMEhiKgmlxGzyXaEcg2khvM7wd5sSHVapOcrde1awQSOMGI4zKBQ+wy5TnDfrm170ROz/ERLYtrjPZA==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1352,13 +1361,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-endpoints": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.654.0.tgz", - "integrity": "sha512-i902fcBknHs0Irgdpi62+QMvzxE+bczvILXigYrlHL4+PiEnlMVpni5L5W1qCkNZXf8AaMrSBuR1NZAGp6UOUw==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz", + "integrity": "sha512-eo4F6DRQ/kxS3gxJpLRv+aDNy76DxQJL5B3DPzpr9Vkq0ygVoi4GT5oIZLVaAVIJmi6k5qq9dLsYZfWLUxJJSg==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/types": "^3.4.2", - "@smithy/util-endpoints": "^2.1.2", + "@aws-sdk/types": "3.692.0", + "@smithy/types": "^3.7.0", + "@smithy/util-endpoints": "^2.1.5", "tslib": "^2.6.2" }, "engines": { @@ -1366,24 +1375,25 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.654.0.tgz", - "integrity": "sha512-ykYAJqvnxLt7wfrqya28wuH3/7NdrwzfiFd7NqEVQf7dXVxL5RPEpD7DxjcyQo3DsHvvdUvGZVaQhozycn1pzA==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.693.0.tgz", + "integrity": "sha512-6EUfuKOujtddy18OLJUaXfKBgs+UcbZ6N/3QV4iOkubCUdeM1maIqs++B9bhCbWeaeF5ORizJw5FTwnyNjE/mw==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/types": "^3.4.2", + "@aws-sdk/types": "3.692.0", + "@smithy/types": "^3.7.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.654.0.tgz", - "integrity": "sha512-a0ojjdBN6pqv6gB4H/QPPSfhs7mFtlVwnmKCM/QrTaFzN0U810PJ1BST3lBx5sa23I5jWHGaoFY+5q65C3clLQ==", - "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz", + "integrity": "sha512-td0OVX8m5ZKiXtecIDuzY3Y3UZIzvxEr57Hp21NOwieqKCG2UeyQWWeGPv0FQaU7dpTkvFmVNI+tx9iB8V/Nhg==", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.693.0", + "@aws-sdk/types": "3.692.0", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -1399,11 +1409,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/abort-controller": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.4.tgz", - "integrity": "sha512-VupaALAQlXViW3/enTf/f5l5JZYSAxoJL7f0nanhNNKnww6DGCg1oYIuNP78KDugnkwthBO6iEcym16HhWV8RQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1411,14 +1421,14 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/config-resolver": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.8.tgz", - "integrity": "sha512-Tv1obAC18XOd2OnDAjSWmmthzx6Pdeh63FbLin8MlPiuJ2ATpKkq0NcNOJFr0dO+JmZXnwu8FQxKJ3TKJ3Hulw==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", + "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -1426,18 +1436,16 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/core": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.3.tgz", - "integrity": "sha512-4LTusLqFMRVQUfC3RNuTg6IzYTeJNpydRdTKq7J5wdEyIRQSu3rGIa3s80mgG2hhe6WOZl9IqTSo1pgbn6EHhA==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.18", - "@smithy/middleware-serde": "^3.0.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz", + "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==", + "dependencies": { + "@smithy/middleware-serde": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-stream": "^3.3.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1446,14 +1454,14 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/credential-provider-imds": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.3.tgz", - "integrity": "sha512-VoxMzSzdvkkjMJNE38yQgx4CfnmT+Z+5EUXkg4x7yag93eQkVQgZvN3XBSHC/ylfBbLbAtdu7flTCChX9I+mVg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", + "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/property-provider": "^3.1.6", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -1461,23 +1469,23 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/eventstream-codec": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.5.tgz", - "integrity": "sha512-6pu+PT2r+5ZnWEV3vLV1DzyrpJ0TmehQlniIDCSpZg6+Ji2SfOI38EqUyQ+O8lotVElCrfVc9chKtSMe9cmCZQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz", + "integrity": "sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ==", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.9.tgz", - "integrity": "sha512-PiQLo6OQmZAotJweIcObL1H44gkvuJACKMNqpBBe5Rf2Ax1DOcGi/28+feZI7yTe1ERHlQQaGnm8sSkyDUgsMg==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.13.tgz", + "integrity": "sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.8", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1485,11 +1493,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.6.tgz", - "integrity": "sha512-iew15It+c7WfnVowWkt2a7cdPp533LFJnpjDQgfZQcxv2QiOcyEcea31mnrk5PVbgo0nNH3VbYGq7myw2q/F6A==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz", + "integrity": "sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1497,12 +1505,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.8.tgz", - "integrity": "sha512-6m+wI+fT0na+6oao6UqALVA38fsScCpoG5UO/A8ZSyGLnPM2i4MS1cFUhpuALgvLMxfYoTCh7qSeJa0aG4IWpQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.12.tgz", + "integrity": "sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.8", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1510,12 +1518,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.8.tgz", - "integrity": "sha512-09tqzIQ6e+7jLqGvRji1yJoDbL/zob0OFhq75edgStWErGLf16+yI5hRc/o9/YAybOhUZs/swpW2SPn892G5Gg==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz", + "integrity": "sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A==", "dependencies": { - "@smithy/eventstream-codec": "^3.1.5", - "@smithy/types": "^3.4.2", + "@smithy/eventstream-codec": "^3.1.9", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1523,23 +1531,23 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/fetch-http-handler": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.7.tgz", - "integrity": "sha512-Ra6IPI1spYLO+t62/3jQbodjOwAbto9wlpJdHZwkycm0Kit+GVpzHW/NMmSgY4rK1bjJ4qLAmCnaBzePO5Nkkg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", "dependencies": { - "@smithy/protocol-http": "^4.1.3", - "@smithy/querystring-builder": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/hash-node": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.6.tgz", - "integrity": "sha512-c/FHEdKK/7DU2z6ZE91L36ahyXWayR3B+FzELjnYq7wH5YqIseM24V+pWCS9kFn1Ln8OFGTf+pyYPiHZuX0s/Q==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", + "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -1561,11 +1569,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/invalid-dependency": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.6.tgz", - "integrity": "sha512-czM7Ioq3s8pIXht7oD+vmgy4Wfb4XavU/k/irO8NdXFFOx7YAlsCCcKOh/lJD1mJSYQqiR7NmpZ9JviryD/7AQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", + "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -1581,12 +1589,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/middleware-content-length": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.8.tgz", - "integrity": "sha512-VuyszlSO49WKh3H9/kIO2kf07VUwGV80QRiaDxUfP8P8UKlokz381ETJvwLhwuypBYhLymCYyNhB3fLAGBX2og==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", + "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", "dependencies": { - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1594,16 +1602,17 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/middleware-endpoint": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.3.tgz", - "integrity": "sha512-KeM/OrK8MVFUsoJsmCN0MZMVPjKKLudn13xpgwIMpGTYpA8QZB2Xq5tJ+RE6iu3A6NhOI4VajDTwBsm8pwwrhg==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.6", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", - "@smithy/url-parser": "^3.0.6", - "@smithy/util-middleware": "^3.0.6", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz", + "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==", + "dependencies": { + "@smithy/core": "^2.5.3", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -1611,17 +1620,17 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/middleware-retry": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.18.tgz", - "integrity": "sha512-YU1o/vYob6vlqZdd97MN8cSXRToknLXhFBL3r+c9CZcnxkO/rgNZ++CfgX2vsmnEKvlqdi26+SRtSzlVp5z6Mg==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/protocol-http": "^4.1.3", - "@smithy/service-error-classification": "^3.0.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", - "@smithy/util-middleware": "^3.0.6", - "@smithy/util-retry": "^3.0.6", + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz", + "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.7", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -1630,11 +1639,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/middleware-serde": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.6.tgz", - "integrity": "sha512-KKTUSl1MzOM0MAjGbudeaVNtIDo+PpekTBkCNwvfZlKndodrnvRo+00USatiyLOc0ujjO9UydMRu3O9dYML7ag==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", + "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1642,11 +1651,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/middleware-stack": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.6.tgz", - "integrity": "sha512-2c0eSYhTQ8xQqHMcRxLMpadFbTXg6Zla5l0mwNftFCZMQmuhI7EbAJMx6R5eqfuV3YbJ3QGyS3d5uSmrHV8Khg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", + "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1654,13 +1663,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/node-config-provider": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.7.tgz", - "integrity": "sha512-g3mfnC3Oo8pOI0dYuPXLtdW1WGVb3bR2tkV21GNkm0ZvQjLTtamXAwCWt/FCb0HGvKt3gHHmF1XerG0ICfalOg==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", "dependencies": { - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1668,14 +1677,14 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/node-http-handler": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.2.tgz", - "integrity": "sha512-42Cy4/oT2O+00aiG1iQ7Kd7rE6q8j7vI0gFfnMlUiATvyo8vefJkhb7O10qZY0jAqo5WZdUzfl9IV6wQ3iMBCg==", - "dependencies": { - "@smithy/abort-controller": "^3.1.4", - "@smithy/protocol-http": "^4.1.3", - "@smithy/querystring-builder": "^3.0.6", - "@smithy/types": "^3.4.2", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", + "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", + "dependencies": { + "@smithy/abort-controller": "^3.1.8", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1683,11 +1692,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/property-provider": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.6.tgz", - "integrity": "sha512-NK3y/T7Q/Bw+Z8vsVs9MYIQ5v7gOX7clyrXcwhhIBQhbPgRl6JDrZbusO9qWDhcEus75Tg+VCxtIRfo3H76fpw==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1695,11 +1704,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/protocol-http": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.3.tgz", - "integrity": "sha512-GcbMmOYpH9iRqtC05RbRnc/0FssxSTHlmaNhYBTgSgNCYpdR3Kt88u5GAZTBmouzv+Zlj/VRv92J9ruuDeJuEw==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", + "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1707,11 +1716,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/querystring-builder": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.6.tgz", - "integrity": "sha512-sQe08RunoObe+Usujn9+R2zrLuQERi3CWvRO3BvnoWSYUaIrLKuAIeY7cMeDax6xGyfIP3x/yFWbEKSXvOnvVg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", + "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -1720,11 +1729,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/querystring-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.6.tgz", - "integrity": "sha512-UJKw4LlEkytzz2Wq+uIdHf6qOtFfee/o7ruH0jF5I6UAuU+19r9QV7nU3P/uI0l6+oElRHmG/5cBBcGJrD7Ozg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", + "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1732,22 +1741,22 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/service-error-classification": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.6.tgz", - "integrity": "sha512-53SpchU3+DUZrN7J6sBx9tBiCVGzsib2e4sc512Q7K9fpC5zkJKs6Z9s+qbMxSYrkEkle6hnMtrts7XNkMJJMg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", + "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", "dependencies": { - "@smithy/types": "^3.4.2" + "@smithy/types": "^3.7.1" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.7.tgz", - "integrity": "sha512-IA4K2qTJYXkF5OfVN4vsY1hfnUZjaslEE8Fsr/gGFza4TAC2A9NfnZuSY2srQIbt9bwtjHiAayrRVgKse4Q7fA==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1755,15 +1764,15 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/signature-v4": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.3.tgz", - "integrity": "sha512-YD2KYSCEEeFHcWZ1E3mLdAaHl8T/TANh6XwmocQ6nPcTdBfh4N5fusgnblnWDlnlU1/cUqEq3PiGi22GmT2Lkg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", + "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.10", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -1773,15 +1782,16 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/smithy-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.2.tgz", - "integrity": "sha512-RKDfhF2MTwXl7jan5d7QfS9eCC6XJbO3H+EZAvLQN8A5in4ib2Ml4zoeLo57w9QrqFekBPcsoC2hW3Ekw4vQ9Q==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-stack": "^3.0.6", - "@smithy/protocol-http": "^4.1.3", - "@smithy/types": "^3.4.2", - "@smithy/util-stream": "^3.1.6", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz", + "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==", + "dependencies": { + "@smithy/core": "^2.5.3", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1789,9 +1799,9 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/types": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", - "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dependencies": { "tslib": "^2.6.2" }, @@ -1800,12 +1810,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/url-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.6.tgz", - "integrity": "sha512-47Op/NU8Opt49KyGpHtVdnmmJMsp2hEwBdyjuFB9M2V5QVOwA7pBhhxKN5z6ztKGrMw76gd8MlbPuzzvaAncuQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", + "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", "dependencies": { - "@smithy/querystring-parser": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/querystring-parser": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -1865,13 +1875,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.18.tgz", - "integrity": "sha512-/eveCzU6Z6Yw8dlYQLA4rcK30XY0E4L3lD3QFHm59mzDaWYelrXE1rlynuT3J6qxv+5yNy3a1JuzhG5hk5hcmw==", + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz", + "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==", "dependencies": { - "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -1880,16 +1890,16 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.18.tgz", - "integrity": "sha512-9cfzRjArtOFPlTYRREJk00suUxVXTgbrzVncOyMRTUeMKnecG/YentLF3cORa+R6mUOMSrMSnT18jos1PKqK6Q==", - "dependencies": { - "@smithy/config-resolver": "^3.0.8", - "@smithy/credential-provider-imds": "^3.2.3", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.2", - "@smithy/types": "^3.4.2", + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz", + "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==", + "dependencies": { + "@smithy/config-resolver": "^3.0.12", + "@smithy/credential-provider-imds": "^3.2.7", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1897,12 +1907,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-endpoints": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.2.tgz", - "integrity": "sha512-FEISzffb4H8DLzGq1g4MuDpcv6CIG15fXoQzDH9SjpRJv6h7J++1STFWWinilG0tQh9H1v2UKWG19Jjr2B16zQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", + "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", "dependencies": { - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1921,11 +1931,11 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-middleware": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.6.tgz", - "integrity": "sha512-BxbX4aBhI1O9p87/xM+zWy0GzT3CEVcXFPBRDoHAM+pV0eSW156pR+PSYEz0DQHDMYDsYAflC2bQNz2uaDBUZQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1933,12 +1943,12 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-retry": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.6.tgz", - "integrity": "sha512-BRZiuF7IwDntAbevqMco67an0Sr9oLQJqqRCsSPZZHYRnehS0LHDAkJk/pSmI7Z8c/1Vet294H7fY2fWUgB+Rg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", + "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", "dependencies": { - "@smithy/service-error-classification": "^3.0.6", - "@smithy/types": "^3.4.2", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -1946,13 +1956,13 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.6.tgz", - "integrity": "sha512-lQEUfTx1ht5CRdvIjdAN/gUL6vQt2wSARGGLaBHNe+iJSkRHlWzY+DOn0mFTmTgyU3jcI5n9DkT5gTzYuSOo6A==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", + "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", "dependencies": { - "@smithy/fetch-http-handler": "^3.2.7", - "@smithy/node-http-handler": "^3.2.2", - "@smithy/types": "^3.4.2", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/types": "^3.7.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -2032,9 +2042,9 @@ } }, "node_modules/@aws-sdk/client-lambda/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/@aws-sdk/client-lambda/node_modules/uuid": { "version": "9.0.1", @@ -3037,15 +3047,15 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.654.0.tgz", - "integrity": "sha512-ydGOrXJxj3x0sJhsXyTmvJVLAE0xxuTWFJihTl67RtaO7VRNtd82I3P3bwoMMaDn5WpmV5mPo8fEUDRlBm3fPg==", + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.693.0.tgz", + "integrity": "sha512-YLUkMsUY0GLW/nfwlZ69cy1u07EZRmsv8Z9m0qW317/EZaVx59hcvmcvb+W4bFqj5E8YImTjoGfE4cZ0F9mkyw==", "dependencies": { - "@aws-sdk/types": "3.654.0", - "@smithy/node-config-provider": "^3.1.7", - "@smithy/types": "^3.4.2", + "@aws-sdk/types": "3.692.0", + "@smithy/node-config-provider": "^3.1.10", + "@smithy/types": "^3.7.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.6", + "@smithy/util-middleware": "^3.0.9", "tslib": "^2.6.2" }, "engines": { @@ -3053,11 +3063,11 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@aws-sdk/types": { - "version": "3.654.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.654.0.tgz", - "integrity": "sha512-VWvbED3SV+10QJIcmU/PKjsKilsTV16d1I7/on4bvD/jo1qGeMXqLDBSen3ks/tuvXZF/mFc7ZW/W2DiLVtO7A==", + "version": "3.692.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.692.0.tgz", + "integrity": "sha512-RpNvzD7zMEhiKgmlxGzyXaEcg2khvM7wd5sSHVapOcrde1awQSOMGI4zKBQ+wy5TnDfrm170ROz/ERLYtrjPZA==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.0", "tslib": "^2.6.2" }, "engines": { @@ -3065,13 +3075,13 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/node-config-provider": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.7.tgz", - "integrity": "sha512-g3mfnC3Oo8pOI0dYuPXLtdW1WGVb3bR2tkV21GNkm0ZvQjLTtamXAwCWt/FCb0HGvKt3gHHmF1XerG0ICfalOg==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", "dependencies": { - "@smithy/property-provider": "^3.1.6", - "@smithy/shared-ini-file-loader": "^3.1.7", - "@smithy/types": "^3.4.2", + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3079,11 +3089,11 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/property-provider": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.6.tgz", - "integrity": "sha512-NK3y/T7Q/Bw+Z8vsVs9MYIQ5v7gOX7clyrXcwhhIBQhbPgRl6JDrZbusO9qWDhcEus75Tg+VCxtIRfo3H76fpw==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3091,11 +3101,11 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.7.tgz", - "integrity": "sha512-IA4K2qTJYXkF5OfVN4vsY1hfnUZjaslEE8Fsr/gGFza4TAC2A9NfnZuSY2srQIbt9bwtjHiAayrRVgKse4Q7fA==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3103,9 +3113,9 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/types": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", - "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dependencies": { "tslib": "^2.6.2" }, @@ -3125,11 +3135,11 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/util-middleware": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.6.tgz", - "integrity": "sha512-BxbX4aBhI1O9p87/xM+zWy0GzT3CEVcXFPBRDoHAM+pV0eSW156pR+PSYEz0DQHDMYDsYAflC2bQNz2uaDBUZQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3137,9 +3147,9 @@ } }, "node_modules/@aws-sdk/region-config-resolver/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/@aws-sdk/token-providers": { "version": "3.535.0", @@ -8293,12 +8303,12 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@smithy/util-waiter": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.5.tgz", - "integrity": "sha512-jYOSvM3H6sZe3CHjzD2VQNCjWBJs+4DbtwBMvUp9y5EnnwNa7NQxTeYeQw0CKCAdGGZ3QvVkyJmvbvs5M/B10A==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.9.tgz", + "integrity": "sha512-/aMXPANhMOlMPjfPtSrDfPeVP8l56SJlz93xeiLmhLe5xvlXA5T3abZ2ilEsDEPeY9T/wnN/vNGn9wa1SbufWA==", "dependencies": { - "@smithy/abort-controller": "^3.1.4", - "@smithy/types": "^3.4.2", + "@smithy/abort-controller": "^3.1.8", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -8306,11 +8316,11 @@ } }, "node_modules/@smithy/util-waiter/node_modules/@smithy/abort-controller": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.4.tgz", - "integrity": "sha512-VupaALAQlXViW3/enTf/f5l5JZYSAxoJL7f0nanhNNKnww6DGCg1oYIuNP78KDugnkwthBO6iEcym16HhWV8RQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", "dependencies": { - "@smithy/types": "^3.4.2", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -8318,9 +8328,9 @@ } }, "node_modules/@smithy/util-waiter/node_modules/@smithy/types": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", - "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dependencies": { "tslib": "^2.6.2" }, @@ -8329,9 +8339,9 @@ } }, "node_modules/@smithy/util-waiter/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", diff --git a/package.json b/package.json index 9543cd9af4..5a595b8baf 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ }, "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.536.0", - "@aws-sdk/client-lambda": "^3.654.0", + "@aws-sdk/client-lambda": "^3.693.0", "@babel/runtime": "^7.24.7", "@faker-js/faker": "^8.4.1", "@growthbook/growthbook": "^1.1.0", From 5bbbe14b49468514991fe521a8e7753ba4a7c7fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 22:21:53 +0800 Subject: [PATCH 03/16] chore(deps-dev): bump @typescript-eslint/parser from 8.14.0 to 8.15.0 in /shared (#7911) chore(deps-dev): bump @typescript-eslint/parser in /shared Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.14.0 to 8.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.15.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- shared/package-lock.json | 89 ++++------------------------------------ 1 file changed, 7 insertions(+), 82 deletions(-) diff --git a/shared/package-lock.json b/shared/package-lock.json index 1665b09df4..3a217a2944 100644 --- a/shared/package-lock.json +++ b/shared/package-lock.json @@ -142,15 +142,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz", - "integrity": "sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", + "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.14.0", - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/typescript-estree": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "debug": "^4.3.4" }, "engines": { @@ -169,81 +169,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", - "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", - "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", - "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", - "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.14.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", From 06aaef72c6089ba277c09dff1c0ef9438bab1c50 Mon Sep 17 00:00:00 2001 From: Kevin Foong <55353265+kevin9foong@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:08:46 +0800 Subject: [PATCH 04/16] chore(approvals-ga): remove beta flag for MRF email notifications and approvals (#7920) * chore: remove beta flag for mrfEmailNotifications and approvals * chore: retain flag --- .../FieldListDrawer/FieldListOption.tsx | 15 +- .../EditStepBlock/EditStepBlock.tsx | 16 +- .../InactiveStepBlock/InactiveStepBlock.tsx | 14 +- .../WorkflowContent/WorkflowContent.tsx | 10 +- .../admin-form/settings/SettingsPage.tsx | 44 +---- shared/types/user.ts | 3 +- src/app/models/user.server.model.ts | 3 +- .../multirespondent-submission.service.ts | 157 +++++++----------- 8 files changed, 84 insertions(+), 178 deletions(-) diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/FieldListOption.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/FieldListOption.tsx index 80a24a91a2..0394a6e944 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/FieldListOption.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/FieldListOption.tsx @@ -16,7 +16,6 @@ import { BASICFIELD_TO_DRAWER_META, MYINFO_FIELD_TO_DRAWER_META, } from '~features/admin-form/create/constants' -import { useUser } from '~features/user/queries' import { useCreateTabForm } from '../../useCreateTabForm' import { @@ -150,9 +149,6 @@ export const DraggableMyInfoFieldListOption = ({ export const BasicFieldOption = forwardRef( ({ fieldType, isDisabled, ...props }, ref) => { - // TODO: (MRF-email-notif) Remove isTest and useUser when approvals is out of beta - const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test' - const { user } = useUser() const meta = useMemo( () => BASICFIELD_TO_DRAWER_META[fieldType], [fieldType], @@ -183,13 +179,10 @@ export const BasicFieldOption = forwardRef( > {meta.label} - {/* TODO: (MRF-email-notif) Remove isTest and betaFlag check when approvals is out of beta */} - {isTest || user?.betaFlags?.mrfEmailNotifications ? ( - isMrf && fieldType === BasicField.YesNo ? ( - - Use for approvals - - ) : null + {isMrf && fieldType === BasicField.YesNo ? ( + + Use for approvals + ) : null} ) diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx index 060475415f..55a4927911 100644 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx @@ -113,9 +113,6 @@ export const EditStepBlock = ({ const isFirstStep = isFirstStepByStepNumber(stepNumber) - // TODO: (MRF-email-notif) Remove isTest check when approvals is out of beta - const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test' - return ( - {/*TODO: (MRF-email-notif) Remove isTest and betaFlag check when approvals is out of beta */} - {isTest || user?.betaFlags?.mrfEmailNotifications ? ( - !isFirstStep ? ( - <> - - - - ) : null + {!isFirstStep ? ( + <> + + + ) : null} !!stateData, [stateData]) @@ -141,8 +136,6 @@ export const InactiveStepBlock = ({ Respondent in this step - {/* TODO: (MRF-email-notif) Remove isTest and betaFlag check when MRF email - notifications is out of beta */} {isFirstStep ? ( Anyone who has access to your form ) : ( @@ -166,11 +159,8 @@ export const InactiveStepBlock = ({ {questionBadges} - {/* TODO: (MRF-email-notif) Remove isTest and betaFlag check when approvals is out of beta */} - {isTest || user?.betaFlags?.mrfEmailNotifications ? ( - !isFirstStep ? ( - - ) : null + {!isFirstStep ? ( + ) : null} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/WorkflowContent.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/WorkflowContent.tsx index 284cc66ed6..d4a0ee9441 100644 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/WorkflowContent.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/WorkflowContent.tsx @@ -2,8 +2,6 @@ import { Box, Divider, Stack } from '@chakra-ui/react' import { BxsChevronDown } from '~assets/icons/BxsChevronDown' -import { useUser } from '~features/user/queries' - import { useAdminFormWorkflow } from '../../hooks/useAdminFormWorkflow' import { NewStepBlock } from './NewStepBlock' @@ -12,9 +10,6 @@ import { WorkflowCompletionMessageBlock } from './WorkflowCompletionMessageBlock export const WorkflowContent = (): JSX.Element | null => { const { formWorkflow, isLoading } = useAdminFormWorkflow() - // TODO: (MRF-email-notif) Remove isTest and useUser when email notifications is out of beta - const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test' - const { user } = useUser() if (isLoading) return null @@ -26,10 +21,7 @@ export const WorkflowContent = (): JSX.Element | null => { ))} - {/*TODO: (MRF-email-notif) Remove flag check when email notifications is out of beta */} - {isTest || user?.betaFlags?.mrfEmailNotifications ? ( - - ) : null} + ) } diff --git a/frontend/src/features/admin-form/settings/SettingsPage.tsx b/frontend/src/features/admin-form/settings/SettingsPage.tsx index 53020f1e85..6a59d66716 100644 --- a/frontend/src/features/admin-form/settings/SettingsPage.tsx +++ b/frontend/src/features/admin-form/settings/SettingsPage.tsx @@ -1,12 +1,5 @@ import { useEffect } from 'react' -import { - BiCodeBlock, - BiCog, - BiDollar, - BiKey, - BiMailSend, - BiMessage, -} from 'react-icons/bi' +import { BiCodeBlock, BiCog, BiDollar, BiKey, BiMailSend } from 'react-icons/bi' import { IconType } from 'react-icons/lib' import { useNavigate, useParams } from 'react-router-dom' import { @@ -19,17 +12,12 @@ import { Tabs, } from '@chakra-ui/react' -import { FormResponseMode } from '~shared/types' - import { ADMINFORM_RESULTS_SUBROUTE, ADMINFORM_ROUTE } from '~constants/routes' import { useDraggable } from '~hooks/useDraggable' -import { useUser } from '~features/user/queries' - import { useAdminFormCollaborators } from '../common/queries' import { SettingsTab } from './components/SettingsTab' -import { useAdminFormSettings } from './queries' import { SettingsAuthPage } from './SettingsAuthPage' import { SettingsEmailsPage } from './SettingsEmailsPage' import { SettingsGeneralPage } from './SettingsGeneralPage' @@ -46,9 +34,6 @@ interface TabEntry { export const SettingsPage = (): JSX.Element => { const { formId, settingsTab } = useParams() - const { data: formSettings, isLoading: isFormSettingLoading } = - useAdminFormSettings() - const { user, isLoading: isUserLoading } = useUser() if (!formId) throw new Error('No formId provided') @@ -62,25 +47,6 @@ export const SettingsPage = (): JSX.Element => { navigate(`${ADMINFORM_ROUTE}/${formId}/${ADMINFORM_RESULTS_SUBROUTE}`) }, [formId, hasEditAccess, isCollabLoading, navigate]) - // TODO: (MRF-email-notif) Remove isTest when email notifications is out of beta - const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test' - // For beta flagging email notifications tab. - const emailNotificationsTab = - isUserLoading || - isFormSettingLoading || - // TODO: (MRF-email-notif) Remove isTest and betaFlag check when MRF email notifications is out of beta - (!isTest && - formSettings?.responseMode === FormResponseMode.Multirespondent && - !user?.betaFlags?.mrfEmailNotifications) - ? null - : { - label: 'Email notifications', - icon: BiMailSend, - component: SettingsEmailsPage, - path: 'email-notifications', - showRedDot: true, - } - const tabConfig: TabEntry[] = [ { label: 'General', @@ -94,7 +60,13 @@ export const SettingsPage = (): JSX.Element => { component: SettingsAuthPage, path: 'singpass', }, - emailNotificationsTab, + { + label: 'Email notifications', + icon: BiMailSend, + component: SettingsEmailsPage, + path: 'email-notifications', + showRedDot: true, + }, { label: 'Webhooks', icon: BiCodeBlock, diff --git a/shared/types/user.ts b/shared/types/user.ts index 415b0ca78b..6def658b50 100644 --- a/shared/types/user.ts +++ b/shared/types/user.ts @@ -21,8 +21,7 @@ export const UserBase = z.object({ payment: z.boolean().optional(), children: z.boolean().optional(), postmanSms: z.boolean().optional(), - // TODO: (MRF-email-notif) Remove betaFlag when MRF email notifications is out of beta - mrfEmailNotifications: z.boolean().optional(), + mrfEmailNotifications: z.boolean().optional(), // Previously used for MRF email notifications, not currently used mrfAdminSubmissionKey: z.boolean().optional(), mfb: z.boolean().optional(), }) diff --git a/src/app/models/user.server.model.ts b/src/app/models/user.server.model.ts index 740b5a2810..e3fed82425 100644 --- a/src/app/models/user.server.model.ts +++ b/src/app/models/user.server.model.ts @@ -75,8 +75,7 @@ const compileUserModel = (db: Mongoose) => { payment: Boolean, children: Boolean, postmanSms: Boolean, - // TODO: (MRF-email-notif) Remove betaFlag when MRF email notifications is out of beta - mrfEmailNotifications: Boolean, + mrfEmailNotifications: Boolean, // Previously used for MRF email notifications, not currently used mrfAdminSubmissionKey: Boolean, mfb: Boolean, }, diff --git a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts index 536c53bc01..48a3fa068e 100644 --- a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts +++ b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts @@ -16,8 +16,7 @@ import { IPopulatedMultirespondentForm, } from '../../../../types' import { MultirespondentSubmissionDto } from '../../../../types/api' -// TODO: (MRF-email-notif) Remove isTest import when MRF email notifications is out of beta -import config, { isTest } from '../../../config/config' +import config from '../../../config/config' import { createLoggerWithLabel, CustomLoggerParams, @@ -436,16 +435,12 @@ export const performMultiRespondentPostSubmissionCreateActions = ({ return error }) .andThen(() => { - // TODO: (MRF-email-notif) Remove isTest and betaFlag check when MRF email notifications is out of beta - if (isTest || form.admin.betaFlags.mrfEmailNotifications) { - return sendMrfOutcomeEmails({ - currentStepNumber, - form, - responses, - submissionId, - }) - } - return okAsync(true) + return sendMrfOutcomeEmails({ + currentStepNumber, + form, + responses, + submissionId, + }) }) .mapErr((error) => { logger.error({ @@ -566,22 +561,18 @@ export const performMultiRespondentPostSubmissionUpdateActions = ({ submissionId, } - const isStepRejectedResult = - // TODO: (MRF-email-notif): Remove flag once approvals is out of beta - isTest || form.admin.betaFlags.mrfEmailNotifications - ? checkIsStepRejected({ - zeroIndexedStepNumber: currentStepNumber, - form, - responses, - }).mapErr((error) => { - logger.error({ - message: 'Error checking if step is rejected', - meta: logMeta, - error, - }) - return error - }) - : ok(false) + const isStepRejectedResult = checkIsStepRejected({ + zeroIndexedStepNumber: currentStepNumber, + form, + responses, + }).mapErr((error) => { + logger.error({ + message: 'Error checking if step is rejected', + meta: logMeta, + error, + }) + return error + }) if (isStepRejectedResult.isErr()) { logger.error({ @@ -594,84 +585,60 @@ export const performMultiRespondentPostSubmissionUpdateActions = ({ const isStepRejected = isStepRejectedResult.value - // TODO: (MRF-email-notif): Remove flag once approvals is out of beta - if (isTest || form.admin.betaFlags.mrfEmailNotifications) { - if (isStepRejected) { - return sendMrfOutcomeEmails({ - currentStepNumber, - form, - responses, - submissionId, - isApproval: true, - isRejected: true, - }).mapErr((error) => { - logger.error({ - message: 'Send mrf outcome email error', - meta: logMeta, - error, - }) - return error - }) - } + if (isStepRejected) { return sendMrfOutcomeEmails({ currentStepNumber, form, responses, submissionId, - isApproval: checkIsFormApproval(form), + isApproval: true, + isRejected: true, + }).mapErr((error) => { + logger.error({ + message: 'Send mrf outcome email error', + meta: logMeta, + error, + }) + return error }) - .mapErr((error) => { + } + return sendMrfOutcomeEmails({ + currentStepNumber, + form, + responses, + submissionId, + isApproval: checkIsFormApproval(form), + }) + .mapErr((error) => { + logger.error({ + message: 'Send mrf outcome email error', + meta: logMeta, + error, + }) + return error + }) + .andThen(() => + sendNextStepEmail({ + nextStepNumber: currentStepNumber + 1, + form, + formTitle: form.title, + responseUrl: `${appUrl}/${getMultirespondentSubmissionEditPath( + form._id, + submissionId, + { key: submissionSecretKey }, + )}`, + formId: form._id, + submissionId, + responses, + }).mapErr((error) => { logger.error({ - message: 'Send mrf outcome email error', + message: 'Send multirespondent workflow email error', meta: logMeta, error, }) return error - }) - .andThen(() => - sendNextStepEmail({ - nextStepNumber: currentStepNumber + 1, - form, - formTitle: form.title, - responseUrl: `${appUrl}/${getMultirespondentSubmissionEditPath( - form._id, - submissionId, - { key: submissionSecretKey }, - )}`, - formId: form._id, - submissionId, - responses, - }).mapErr((error) => { - logger.error({ - message: 'Send multirespondent workflow email error', - meta: logMeta, - error, - }) - return error - }), - ) - } - // TODO: (MRF-email-notif): Remove this case once approvals is out of beta - return sendNextStepEmail({ - nextStepNumber: currentStepNumber + 1, - form, - formTitle: form.title, - responseUrl: `${appUrl}/${getMultirespondentSubmissionEditPath( - form._id, - submissionId, - { key: submissionSecretKey }, - )}`, - formId: form._id, - submissionId, - responses, - }).mapErr((error) => { - logger.error({ - message: 'Send multirespondent workflow email error', - meta: logMeta, - error, - }) - return error - }) + }), + ) } export const getMultirespondentSubmission = ( From dda0dde762fcfe06f93da96ca4105a25f7b7988b Mon Sep 17 00:00:00 2001 From: LoneRifle Date: Wed, 20 Nov 2024 11:08:41 +0800 Subject: [PATCH 05/16] feat(i18n): extract text for form metadata (#7926) Extract labels for form metadata, namely last modified data and form type [i18n] - Add Meta section to `adminForm` [features] - Replace constants file with i18n equivalent mapping of type labels --- .../src/features/admin-form/common/constants.ts | 7 ------- .../settings/components/GeneralTabHeader.tsx | 6 +++--- .../WorkspaceFormRow/WorkspaceFormRow.tsx | 15 +++++++++++---- .../src/i18n/locales/features/admin-form/en-sg.ts | 2 ++ .../src/i18n/locales/features/admin-form/index.ts | 1 + .../locales/features/admin-form/meta/en-sg.ts | 10 ++++++++++ .../locales/features/admin-form/meta/index.ts | 10 ++++++++++ frontend/src/i18n/locales/features/index.ts | 13 ++++++++----- frontend/src/i18n/locales/types.ts | 2 ++ 9 files changed, 47 insertions(+), 19 deletions(-) delete mode 100644 frontend/src/features/admin-form/common/constants.ts create mode 100644 frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts create mode 100644 frontend/src/i18n/locales/features/admin-form/meta/index.ts diff --git a/frontend/src/features/admin-form/common/constants.ts b/frontend/src/features/admin-form/common/constants.ts deleted file mode 100644 index 50b574a1fe..0000000000 --- a/frontend/src/features/admin-form/common/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { FormResponseMode } from '~shared/types' - -export const RESPONSE_MODE_TO_TEXT: { [key in FormResponseMode]: string } = { - [FormResponseMode.Multirespondent]: 'Multi-respondent form', - [FormResponseMode.Email]: 'Email mode', - [FormResponseMode.Encrypt]: 'Storage mode', -} diff --git a/frontend/src/features/admin-form/settings/components/GeneralTabHeader.tsx b/frontend/src/features/admin-form/settings/components/GeneralTabHeader.tsx index 08bba58986..f07ee84f97 100644 --- a/frontend/src/features/admin-form/settings/components/GeneralTabHeader.tsx +++ b/frontend/src/features/admin-form/settings/components/GeneralTabHeader.tsx @@ -1,20 +1,20 @@ +import { useTranslation } from 'react-i18next' import { Skeleton, Wrap } from '@chakra-ui/react' import Badge from '~components/Badge' -import { RESPONSE_MODE_TO_TEXT } from '~features/admin-form/common/constants' - import { useAdminFormSettings } from '../queries' import { CategoryHeader } from './CategoryHeader' export const GeneralTabHeader = (): JSX.Element => { + const { t } = useTranslation() const { data: settings, isLoading: isLoadingSettings } = useAdminFormSettings() const readableFormResponseMode = !settings ? 'Loading...' - : RESPONSE_MODE_TO_TEXT[settings.responseMode] + : t(`features.adminForm.meta.responseModeText.${settings.responseMode}`) return ( { + const { t } = useTranslation() const prettyLastModified = useMemo(() => { return dayjs(formMeta.lastModified).calendar(null, RELATIVE_DATE_FORMAT) }, [formMeta.lastModified]) @@ -83,12 +83,19 @@ export const WorkspaceFormRow = ({ {formMeta.title} - Edited {prettyLastModified} + {t('features.adminForm.meta.prettyLastModified', { + prettyLastModified, + })} - {RESPONSE_MODE_TO_TEXT[formMeta.responseMode]} + {t( + `features.adminForm.meta.responseModeText.${formMeta.responseMode}`, + { + prettyLastModified, + }, + )} diff --git a/frontend/src/i18n/locales/features/admin-form/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/en-sg.ts index 0a4c022da9..88818573df 100644 --- a/frontend/src/i18n/locales/features/admin-form/en-sg.ts +++ b/frontend/src/i18n/locales/features/admin-form/en-sg.ts @@ -1,7 +1,9 @@ +import { enSG as meta } from './meta' import { enSG as navbar } from './navbar' import { enSG as sidebar } from './sidebar' export const enSG = { navbar, sidebar, + meta, } diff --git a/frontend/src/i18n/locales/features/admin-form/index.ts b/frontend/src/i18n/locales/features/admin-form/index.ts index 11ebfdc6ac..e53c29786f 100644 --- a/frontend/src/i18n/locales/features/admin-form/index.ts +++ b/frontend/src/i18n/locales/features/admin-form/index.ts @@ -1,4 +1,5 @@ export * from './en-sg' +export { type Meta } from './meta' export { type Navbar } from './navbar' export { type Fields } from './sidebar' export { type HeaderAndInstructions } from './sidebar' diff --git a/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts new file mode 100644 index 0000000000..33760a82b2 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts @@ -0,0 +1,10 @@ +import { FormResponseMode } from '~shared/types' + +export const enSG = { + prettyLastModified: 'Edited {prettyLastModified}', + responseModeText: { + [FormResponseMode.Multirespondent]: 'Multi-respondent form', + [FormResponseMode.Email]: 'Email mode', + [FormResponseMode.Encrypt]: 'Storage mode', + }, +} diff --git a/frontend/src/i18n/locales/features/admin-form/meta/index.ts b/frontend/src/i18n/locales/features/admin-form/meta/index.ts new file mode 100644 index 0000000000..42e6830698 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/meta/index.ts @@ -0,0 +1,10 @@ +import { FormResponseMode } from '~shared/types' + +export * from './en-sg' + +export interface Meta { + prettyLastModified: string + responseModeText: { + [k in FormResponseMode]: string + } +} diff --git a/frontend/src/i18n/locales/features/index.ts b/frontend/src/i18n/locales/features/index.ts index 72f4eb1983..08617516d5 100644 --- a/frontend/src/i18n/locales/features/index.ts +++ b/frontend/src/i18n/locales/features/index.ts @@ -1,8 +1,11 @@ -export { type Navbar } from './admin-form' -export { type Fields } from './admin-form' -export { type HeaderAndInstructions } from './admin-form' -export { type Logic } from './admin-form' -export { type ThankYou } from './admin-form' +export { + type Fields, + type HeaderAndInstructions, + type Logic, + type Meta, + type Navbar, + type ThankYou, +} from './admin-form' export { type Common } from './common' export { type Login } from './login' export { type PublicForm } from './public-form' diff --git a/frontend/src/i18n/locales/types.ts b/frontend/src/i18n/locales/types.ts index 201e5f9cb7..66205d3cac 100644 --- a/frontend/src/i18n/locales/types.ts +++ b/frontend/src/i18n/locales/types.ts @@ -6,6 +6,7 @@ import { HeaderAndInstructions, Logic, Login, + Meta, Navbar, PublicForm, ThankYou, @@ -22,6 +23,7 @@ interface Translation { thankYou?: ThankYou } navbar?: Navbar + meta?: Meta } common?: Common publicForm?: PublicForm From 663a74a7c7d853fce0e9c0a9ea66dede074c4207 Mon Sep 17 00:00:00 2001 From: LoneRifle Date: Wed, 20 Nov 2024 13:52:36 +0800 Subject: [PATCH 06/16] feat(i18n): move workspace relative date format (#7929) --- .../WorkspaceFormRow/WorkspaceFormRow.tsx | 16 +++++----------- .../locales/features/admin-form/meta/en-sg.ts | 8 ++++++++ .../locales/features/admin-form/meta/index.ts | 8 ++++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/frontend/src/features/workspace/components/WorkspaceFormRow/WorkspaceFormRow.tsx b/frontend/src/features/workspace/components/WorkspaceFormRow/WorkspaceFormRow.tsx index 706938cb47..69c830ecb0 100644 --- a/frontend/src/features/workspace/components/WorkspaceFormRow/WorkspaceFormRow.tsx +++ b/frontend/src/features/workspace/components/WorkspaceFormRow/WorkspaceFormRow.tsx @@ -16,23 +16,17 @@ export interface WorkspaceFormRowProps extends ButtonProps { formMeta: AdminDashboardFormMetaDto } -const RELATIVE_DATE_FORMAT = { - sameDay: '[today,] D MMM h:mma', // today, 16 Jun 9:30am - nextDay: '[tomorrow,] D MMM h:mma', // tomorrow, 16 Jun 9:30am - lastDay: '[yesterday,] D MMM h:mma', // yesterday, 16 Jun 9:30am - nextWeek: 'ddd, D MMM YYYY h:mma', // Tue, 17 Oct 2021 9:30pm - lastWeek: 'ddd, D MMM YYYY h:mma', // Tue, 17 Oct 2021 9:30pm - sameElse: 'D MMM YYYY h:mma', // 6 Oct 2021 9:30pm -} - export const WorkspaceFormRow = ({ formMeta, ...buttonProps }: WorkspaceFormRowProps): JSX.Element => { const { t } = useTranslation() + const relativeDateFormat = t('features.adminForm.meta.relativeDateFormat', { + returnObjects: true, + }) const prettyLastModified = useMemo(() => { - return dayjs(formMeta.lastModified).calendar(null, RELATIVE_DATE_FORMAT) - }, [formMeta.lastModified]) + return dayjs(formMeta.lastModified).calendar(null, relativeDateFormat) + }, [formMeta.lastModified, relativeDateFormat]) return ( diff --git a/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts index 33760a82b2..ccba7a006e 100644 --- a/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts +++ b/frontend/src/i18n/locales/features/admin-form/meta/en-sg.ts @@ -2,6 +2,14 @@ import { FormResponseMode } from '~shared/types' export const enSG = { prettyLastModified: 'Edited {prettyLastModified}', + relativeDateFormat: { + sameDay: '[today,] D MMM h:mma', // today, 16 Jun 9:30am + nextDay: '[tomorrow,] D MMM h:mma', // tomorrow, 16 Jun 9:30am + lastDay: '[yesterday,] D MMM h:mma', // yesterday, 16 Jun 9:30am + nextWeek: 'ddd, D MMM YYYY h:mma', // Tue, 17 Oct 2021 9:30pm + lastWeek: 'ddd, D MMM YYYY h:mma', // Tue, 17 Oct 2021 9:30pm + sameElse: 'D MMM YYYY h:mma', // 6 Oct 2021 9:30pm + }, responseModeText: { [FormResponseMode.Multirespondent]: 'Multi-respondent form', [FormResponseMode.Email]: 'Email mode', diff --git a/frontend/src/i18n/locales/features/admin-form/meta/index.ts b/frontend/src/i18n/locales/features/admin-form/meta/index.ts index 42e6830698..2888a1f1c5 100644 --- a/frontend/src/i18n/locales/features/admin-form/meta/index.ts +++ b/frontend/src/i18n/locales/features/admin-form/meta/index.ts @@ -4,6 +4,14 @@ export * from './en-sg' export interface Meta { prettyLastModified: string + relativeDateFormat: { + sameDay: string + nextDay: string + lastDay: string + nextWeek: string + lastWeek: string + sameElse: string + } responseModeText: { [k in FormResponseMode]: string } From a86c7294b798f6327d24667b302e9ee0b3ae4714 Mon Sep 17 00:00:00 2001 From: Michel Fang <43075287+littlemight@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:26:06 +0800 Subject: [PATCH 07/16] chore(FE): use consistent vite port for dev with README (#7930) * chore(FE): use consistent vite port for dev with README * docs: reflect vite's default on README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cb8ac3556..9d5866e476 100755 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ npm run dev After the Docker image has finished building, the following local applications can be accessed: -- React application can be accessed at [localhost:3000](localhost:3000) +- React application can be accessed at [localhost:5173](localhost:5173) - The backend API server can be accessed at [localhost:5001](localhost:5001) - The development mail server can be accessed at [localhost:1080](localhost:1080) From a8ff4920385713b4357acab458eb49f0acc0350c Mon Sep 17 00:00:00 2001 From: Ken Lee Shu Ming Date: Wed, 20 Nov 2024 19:26:22 +0800 Subject: [PATCH 08/16] chore(FE): cleanup date check on sex field (#7922) remove date checking code --- .../edit-fieldtype/EditMyInfo/EditMyInfo.tsx | 25 ------------- .../EditMyInfoChildren/EditMyInfoChildren.tsx | 25 ------------- .../features/admin-form/create/constants.ts | 25 ++----------- shared/constants/field/myinfo/index.ts | 35 +++---------------- 4 files changed, 6 insertions(+), 104 deletions(-) diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfo/EditMyInfo.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfo/EditMyInfo.tsx index c495eb3c23..4502b62f4f 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfo/EditMyInfo.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfo/EditMyInfo.tsx @@ -45,34 +45,9 @@ export const EditMyInfo = ({ field }: EditMyInfoProps): JSX.Element => { }, }) - function conditionallyDisplayInfoBox() { - const currentDate = new Date().toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - const targetDate = new Date('2024-06-28T00:00:00').toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - - if (new Date(currentDate) <= new Date(targetDate)) { - return ( - <> - - - To align with MyInfo terminology, the “Gender” field will be - renamed to “Sex” from 28 Jun 2024. - - {' '} - - ) - } else { - return null - } - } - return ( - {conditionallyDisplayInfoBox()} Data source {extendedField.dataSource.map((dataSource, idx) => ( diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx index 367dfbc862..a93ba49f0c 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditMyInfoChildren/EditMyInfoChildren.tsx @@ -61,34 +61,9 @@ export const EditMyInfoChildren = ({ }, }) - function conditionallyDisplayInfoBox() { - const currentDate = new Date().toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - const targetDate = new Date('2024-06-28T00:00:00').toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - - if (new Date(currentDate) <= new Date(targetDate)) { - return ( - <> - - - To align with MyInfo terminology, the “Gender” field will be - renamed to “Sex” from 28 Jun 2024. - - {' '} - - ) - } else { - return null - } - } - return ( - {conditionallyDisplayInfoBox()} Data source {extendedField.dataSource.map((dataSource, idx) => ( diff --git a/frontend/src/features/admin-form/create/constants.ts b/frontend/src/features/admin-form/create/constants.ts index a5690a73d8..8ceca71882 100644 --- a/frontend/src/features/admin-form/create/constants.ts +++ b/frontend/src/features/admin-form/create/constants.ts @@ -203,7 +203,7 @@ export const MYINFO_FIELD_TO_DRAWER_META: { isSubmitted: true, }, [MyInfoAttribute.Sex]: { - label: 'Gender', + label: 'Sex', icon: BiInfinite, isSubmitted: true, }, @@ -346,7 +346,7 @@ export const MYINFO_FIELD_TO_DRAWER_META: { isSubmitted: true, }, [MyInfoAttribute.ChildGender]: { - label: 'Gender', + label: 'Sex', icon: BiDummyIcon, isSubmitted: true, }, @@ -361,24 +361,3 @@ export const MYINFO_FIELD_TO_DRAWER_META: { isSubmitted: true, }, } -// TODO: remove after 28 Jun 2024 as this would have fully taken effect -function updateLabelsBasedOnDate() { - const currentDate = new Date().toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - const targetDate = new Date('2024-06-28T00:00:00').toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - if (new Date(currentDate) >= new Date(targetDate)) { - const sexAttribute = MYINFO_FIELD_TO_DRAWER_META[MyInfoAttribute.Sex] - if (sexAttribute) { - sexAttribute.label = 'Sex' - } - const childGenderAttribute = - MYINFO_FIELD_TO_DRAWER_META[MyInfoAttribute.ChildGender] - if (childGenderAttribute) { - childGenderAttribute.label = 'Sex' - } - } -} -updateLabelsBasedOnDate() diff --git a/shared/constants/field/myinfo/index.ts b/shared/constants/field/myinfo/index.ts index 333bbe5b1e..68139b2cc8 100644 --- a/shared/constants/field/myinfo/index.ts +++ b/shared/constants/field/myinfo/index.ts @@ -53,12 +53,12 @@ export const types: MyInfoFieldBlock[] = [ }, { name: MyInfoAttribute.Sex, - value: 'Gender', + value: 'Sex', category: 'personal', verified: ['SG', 'PR', 'F'], source: 'Immigration & Checkpoints Authority / Ministry of Manpower', description: - 'The gender of the form-filler. This field is verified by ICA for Singaporeans/PRs & foreigners on Long-Term Visit Pass, and by MOM for Employment Pass holders.', + 'The sex of the form-filler. This field is verified by ICA for Singaporeans/PRs & foreigners on Long-Term Visit Pass, and by MOM for Employment Pass holders.', fieldType: BasicField.Dropdown, fieldOptions: ['FEMALE', 'MALE', 'UNKNOWN'], previewValue: 'MALE', @@ -349,11 +349,11 @@ export const types: MyInfoFieldBlock[] = [ }, { name: MyInfoAttribute.ChildGender, - value: "Child's gender", + value: "Child's sex", category: 'children', verified: [], source: 'Immigration & Checkpoints Authority', - description: 'Gender', + description: 'Sex', fieldType: BasicField.ShortText, fieldOptions: ['FEMALE', 'MALE', 'UNKNOWN'], previewValue: 'MALE', @@ -394,30 +394,3 @@ export const types: MyInfoFieldBlock[] = [ ] export const MYINFO_ATTRIBUTE_MAP = keyBy(types, 'name') - -// TODO: remove after 28 Jun 2024 as this would have fully taken effect -function updateLabelBasedOnDate() { - const currentDate = new Date().toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - const targetDate = new Date('2024-06-28T00:00:00').toLocaleString('en-US', { - timeZone: 'Asia/Singapore', - }) - if (new Date(currentDate) >= new Date(targetDate)) { - const sexAttribute = MYINFO_ATTRIBUTE_MAP[MyInfoAttribute.Sex] - if (sexAttribute) { - sexAttribute.description = 'Sex' - sexAttribute.value = 'Sex' - sexAttribute.description = - 'The sex of the form-filler. This field is verified by ICA for Singaporeans/PRs & foreigners on Long-Term Visit Pass, and by MOM for Employment Pass holders.' - } - const childGenderAttribute = - MYINFO_ATTRIBUTE_MAP[MyInfoAttribute.ChildGender] - if (childGenderAttribute) { - childGenderAttribute.value = "Child's Sex" - childGenderAttribute.description = 'Sex' - } - } -} - -updateLabelBasedOnDate() From d8c8558bc4d7823f5f29d087e08b6a5e7557f292 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:26:56 +0800 Subject: [PATCH 09/16] chore(deps-dev): bump @playwright/test from 1.45.1 to 1.49.0 (#7923) Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.45.1 to 1.49.0. - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.45.1...v1.49.0) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dc6a82a6b..1255d41123 100644 --- a/package-lock.json +++ b/package-lock.json @@ -114,7 +114,7 @@ "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-env": "^7.25.4", "@opengovsg/mockpass": "^4.3.4", - "@playwright/test": "^1.45.1", + "@playwright/test": "^1.49.0", "@stoplight/prism-cli": "^5.10.0", "@types/bcrypt": "^5.0.0", "@types/bluebird": "^3.5.42", @@ -7091,12 +7091,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz", + "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==", "dev": true, "dependencies": { - "playwright": "1.45.1" + "playwright": "1.49.0" }, "bin": { "playwright": "cli.js" @@ -23748,12 +23748,12 @@ } }, "node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", + "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==", "dev": true, "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.49.0" }, "bin": { "playwright": "cli.js" @@ -23766,9 +23766,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz", + "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==", "dev": true, "bin": { "playwright-core": "cli.js" diff --git a/package.json b/package.json index f219792174..922598656b 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-env": "^7.25.4", "@opengovsg/mockpass": "^4.3.4", - "@playwright/test": "^1.45.1", + "@playwright/test": "^1.49.0", "@stoplight/prism-cli": "^5.10.0", "@types/bcrypt": "^5.0.0", "@types/bluebird": "^3.5.42", From d76e77cb5d6acbb494915ce4a0e024617598a6c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:19:01 +0800 Subject: [PATCH 10/16] fix(deps): bump libphonenumber-js from 1.11.14 to 1.11.15 in /shared (#7936) Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.11.14 to 1.11.15. - [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md) - [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.11.14...v1.11.15) --- updated-dependencies: - dependency-name: libphonenumber-js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- shared/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/package-lock.json b/shared/package-lock.json index 3a217a2944..7b0b65aaa4 100644 --- a/shared/package-lock.json +++ b/shared/package-lock.json @@ -554,9 +554,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.11.14", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.14.tgz", - "integrity": "sha512-sexvAfwcW1Lqws4zFp8heAtAEXbEDnvkYCEGzvOoMgZR7JhXo/IkE9MkkGACgBed5fWqh3ShBGnJBdDnU9N8EQ==" + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.15.tgz", + "integrity": "sha512-M7+rtYi9l5RvMmHyjyoF3BHHUpXTYdJ0PezZGHNs0GyW1lO+K7jxlXpbdIb7a56h0nqLYdjIw+E+z0ciGaJP7g==" }, "node_modules/lie": { "version": "3.3.0", From 07aabd341b051904eb4b40c5f01c61c05f41e658 Mon Sep 17 00:00:00 2001 From: LoneRifle Date: Fri, 22 Nov 2024 13:22:28 +0800 Subject: [PATCH 11/16] feat(i18n): extract text from admin-form prompts (#7931) * feat(i18n): extract text from modals * feat(i18n): extract text from admin-form toasts --- .../components/DirtyModal/DirtyModal.tsx | 5 +++- .../FieldRow/FieldRowContainer.tsx | 2 +- .../BuilderAndDesignContent/PaymentView.tsx | 12 ++++++--- .../BuilderAndDesignContent/StartPageView.tsx | 4 ++- .../DeleteFieldModal/DeleteFieldModal.tsx | 19 +++++++------- .../DeletePaymentModal/DeletePaymentModal.tsx | 19 +++++++++----- .../mutations/useCreateFormField.ts | 13 +++++----- .../mutations/useDeleteFormField.ts | 23 ++++++++-------- .../mutations/useDuplicateFormField.ts | 19 ++++++++------ .../mutations/useEditFormField.ts | 13 +++++----- .../i18n/locales/features/admin-form/en-sg.ts | 4 +++ .../i18n/locales/features/admin-form/index.ts | 2 ++ .../features/admin-form/modals/en-sg.ts | 23 ++++++++++++++++ .../features/admin-form/modals/index.ts | 22 ++++++++++++++++ .../features/admin-form/toasts/en-sg.ts | 26 +++++++++++++++++++ .../features/admin-form/toasts/index.ts | 15 +++++++++++ .../src/i18n/locales/features/common/en-sg.ts | 1 + .../src/i18n/locales/features/common/index.ts | 1 + frontend/src/i18n/locales/features/index.ts | 2 ++ frontend/src/i18n/locales/types.ts | 4 +++ .../NavigationPrompt/NavigationPrompt.tsx | 6 +++++ 21 files changed, 181 insertions(+), 54 deletions(-) create mode 100644 frontend/src/i18n/locales/features/admin-form/modals/en-sg.ts create mode 100644 frontend/src/i18n/locales/features/admin-form/modals/index.ts create mode 100644 frontend/src/i18n/locales/features/admin-form/toasts/en-sg.ts create mode 100644 frontend/src/i18n/locales/features/admin-form/toasts/index.ts diff --git a/frontend/src/features/admin-form/common/components/DirtyModal/DirtyModal.tsx b/frontend/src/features/admin-form/common/components/DirtyModal/DirtyModal.tsx index fced365825..5305476ea5 100644 --- a/frontend/src/features/admin-form/common/components/DirtyModal/DirtyModal.tsx +++ b/frontend/src/features/admin-form/common/components/DirtyModal/DirtyModal.tsx @@ -1,3 +1,5 @@ +import { useTranslation } from 'react-i18next' + import { UnsavedChangesModal } from '~templates/NavigationPrompt' import { usePaymentStore } from '~features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/FieldListDrawer/field-panels/usePaymentStore' @@ -93,12 +95,13 @@ export const useDirtyModal = () => { export const DirtyModal = (): JSX.Element => { const { isOpen, handleCancelNavigate, handleConfirmNavigate } = useDirtyModal() + const { t } = useTranslation() return ( diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx index 1d3f96b566..55636375cc 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx @@ -408,7 +408,7 @@ const FieldButtonGroup = ({ } onClick={handleEditFieldClick} /> diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/PaymentView.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/PaymentView.tsx index fab0fa421a..7d7a4f6f7a 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/PaymentView.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/PaymentView.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useRef } from 'react' import { FormProvider, useForm } from 'react-hook-form' +import { useTranslation } from 'react-i18next' import { BiCog, BiTrash } from 'react-icons/bi' import { Box, ButtonGroup, Collapse, Flex } from '@chakra-ui/react' @@ -147,11 +148,16 @@ const PaymentButtonGroup = ({ handleBuilderClick(false) } }, [handleBuilderClick, isMobile]) + const { t } = useTranslation() const { deletePaymentModalDisclosure: { onOpen: onDeleteModalOpen }, } = useBuilderAndDesignContext() + const { deleteField, editField } = t('features.common.tooltip', { + returnObjects: true, + }) + return ( } onClick={handleEditFieldClick} /> )} - + } onClick={onDeleteModalOpen} /> diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/StartPageView.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/StartPageView.tsx index 87c7dc52e3..acb96de6a8 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/StartPageView.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/StartPageView.tsx @@ -1,4 +1,5 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' import { BiCog } from 'react-icons/bi' import { Box, ButtonGroup, Collapse, Flex, IconButton } from '@chakra-ui/react' @@ -37,6 +38,7 @@ import { } from '../useFieldBuilderStore' export const StartPageView = () => { + const { t } = useTranslation() const isMobile = useIsMobile() const { data: form, isLoading } = useCreateTabForm() const setFieldBuilderToInactive = useFieldBuilderStore( @@ -259,7 +261,7 @@ export const StartPageView = () => { } onClick={handleEditInstructionsClick} /> diff --git a/frontend/src/features/admin-form/create/builder-and-design/DeleteFieldModal/DeleteFieldModal.tsx b/frontend/src/features/admin-form/create/builder-and-design/DeleteFieldModal/DeleteFieldModal.tsx index 996c22edf9..127a86d5c8 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/DeleteFieldModal/DeleteFieldModal.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/DeleteFieldModal/DeleteFieldModal.tsx @@ -58,21 +58,20 @@ export const DeleteFieldModal = (): JSX.Element => { } }, [deleteFieldMutation, onClose, stateData]) + const { + title, + description: { field, logic }, + confirmButtonText, + } = t('features.adminForm.modals.deleteField', { returnObjects: true }) + return ( - Delete field + {title} - - {fieldIsInLogic - ? `This field is used in your form logic, so deleting it may cause - your logic to stop working correctly. Are you sure you want to - delete this field?` - : `Are you sure you want to delete this field? This action - cannot be undone.`} - + {fieldIsInLogic ? logic : field} { onClick={handleDeleteConfirmation} isLoading={deleteFieldMutation.isLoading} > - Yes, delete field + {confirmButtonText} diff --git a/frontend/src/features/admin-form/create/builder-and-design/DeletePaymentModal/DeletePaymentModal.tsx b/frontend/src/features/admin-form/create/builder-and-design/DeletePaymentModal/DeletePaymentModal.tsx index 733369b8be..2027fa4a3c 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/DeletePaymentModal/DeletePaymentModal.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/DeletePaymentModal/DeletePaymentModal.tsx @@ -1,4 +1,5 @@ import { useCallback } from 'react' +import { useTranslation } from 'react-i18next' import { ButtonGroup, Modal, @@ -28,6 +29,7 @@ export const DeletePaymentModal = (): JSX.Element => { const { deletePaymentModalDisclosure: { onClose }, } = useBuilderAndDesignContext() + const { t } = useTranslation() const { deletePaymentFieldMutation } = useDeleteFormField() @@ -44,29 +46,32 @@ export const DeletePaymentModal = (): JSX.Element => { } }, [deletePaymentFieldMutation, onClose, stateData, setFieldListTabIndex]) + const { + title, + description: { payment: description }, + confirmButtonText, + } = t('features.adminForm.modals.deleteField', { returnObjects: true }) + return ( - Delete field + {title} - - Are you sure you want to delete payment field? This action can't be - undone. - + {description} diff --git a/frontend/src/features/admin-form/create/builder-and-design/mutations/useCreateFormField.ts b/frontend/src/features/admin-form/create/builder-and-design/mutations/useCreateFormField.ts index 8bd5c43595..ab27216ed4 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/mutations/useCreateFormField.ts +++ b/frontend/src/features/admin-form/create/builder-and-design/mutations/useCreateFormField.ts @@ -1,4 +1,5 @@ import { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { useMutation, useQueryClient } from 'react-query' import { useParams } from 'react-router-dom' @@ -22,6 +23,7 @@ import { } from '../utils/getMutationMessage' export const useCreateFormField = () => { + const { t } = useTranslation() const { formId } = useParams() if (!formId) throw new Error('No formId provided') @@ -45,15 +47,14 @@ export const useCreateFormField = () => { if (stateData.state !== FieldBuilderState.CreatingField) { toast({ status: 'warning', - description: - 'Something went wrong when creating your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.create.error'), }) return } toast({ - description: `The ${getMutationToastDescriptionFieldName( - newField, - )} was created.`, + description: t('features.adminForm.toasts.field.create.success', { + field: getMutationToastDescriptionFieldName(newField), + }), }) queryClient.setQueryData(adminFormKey, (oldForm) => { // Should not happen, should not be able to update field if there is no @@ -65,7 +66,7 @@ export const useCreateFormField = () => { // Switch from creation to editing updateEditState(newField) }, - [adminFormKey, stateData, queryClient, updateEditState, toast], + [adminFormKey, stateData, queryClient, updateEditState, toast, t], ) const handleError = useCallback( diff --git a/frontend/src/features/admin-form/create/builder-and-design/mutations/useDeleteFormField.ts b/frontend/src/features/admin-form/create/builder-and-design/mutations/useDeleteFormField.ts index 151cf696f9..0267708698 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/mutations/useDeleteFormField.ts +++ b/frontend/src/features/admin-form/create/builder-and-design/mutations/useDeleteFormField.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react' +import { useTranslation } from 'react-i18next' import { useMutation, useQueryClient } from 'react-query' import { useParams } from 'react-router-dom' @@ -34,6 +35,7 @@ import { } from '../utils/getMutationMessage' export const useDeleteFormField = () => { + const { t } = useTranslation() const { formId } = useParams() if (!formId) throw new Error('No formId provided') @@ -66,15 +68,14 @@ export const useDeleteFormField = () => { if (stateData.state !== FieldBuilderState.EditingField) { toast({ status: 'warning', - description: - 'Something went wrong when deleting your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.delete.error'), }) return } toast({ - description: `The ${getMutationToastDescriptionFieldName( - stateData.field, - )} was deleted.`, + description: t('features.adminForm.toasts.field.delete.success', { + field: getMutationToastDescriptionFieldName(stateData.field), + }), }) queryClient.setQueryData(adminFormKey, (oldForm) => { // Should not happen, should not be able to update field if there is no @@ -86,8 +87,7 @@ export const useDeleteFormField = () => { if (deletedFieldIndex < 0) { toast({ status: 'warning', - description: - 'Something went wrong when deleting your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.delete.error'), }) } else { oldForm.form_fields.splice(deletedFieldIndex, 1) @@ -95,7 +95,7 @@ export const useDeleteFormField = () => { return oldForm }) setToInactive() - }, [adminFormKey, stateData, queryClient, setToInactive, toast]) + }, [adminFormKey, stateData, queryClient, setToInactive, toast, t]) const handleError = useCallback( (error: Error) => { @@ -116,8 +116,7 @@ export const useDeleteFormField = () => { if (paymentState !== PaymentState.EditingPayment) { toast({ status: 'warning', - description: - 'Something went wrong when deleting your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.delete.error'), }) return } @@ -128,7 +127,9 @@ export const useDeleteFormField = () => { }, ) toast({ - description: 'The payment was deleted.', + description: t('features.adminForm.toasts.field.delete.success', { + field: 'payment', + }), }) setPaymentToInactive() }, diff --git a/frontend/src/features/admin-form/create/builder-and-design/mutations/useDuplicateFormField.ts b/frontend/src/features/admin-form/create/builder-and-design/mutations/useDuplicateFormField.ts index f7381b9859..8c559a6df6 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/mutations/useDuplicateFormField.ts +++ b/frontend/src/features/admin-form/create/builder-and-design/mutations/useDuplicateFormField.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react' +import { useTranslation } from 'react-i18next' import { useMutation, useQueryClient } from 'react-query' import { useParams } from 'react-router-dom' @@ -23,6 +24,7 @@ import { } from '../utils/getMutationMessage' export const useDuplicateFormField = () => { + const { t } = useTranslation() const { formId } = useParams() if (!formId) throw new Error('No formId provided') const fieldBuilderState = useFieldBuilderStore(fieldBuilderStateSelector) @@ -40,20 +42,20 @@ export const useDuplicateFormField = () => { if (fieldBuilderState !== FieldBuilderState.EditingField) { toast({ status: 'warning', - description: - 'Something went wrong when creating your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.duplicate.error'), }) return } toast({ - description: `The ${getMutationToastDescriptionFieldName( - newField, - )} was duplicated.${ + description: t( logicedFieldIdsSet?.has(fieldId) - ? ' Associated logic was not duplicated.' - : '' - }`, + ? 'features.adminForm.toasts.field.duplicate.successButNoLogic' + : 'features.adminForm.toasts.field.duplicate.success', + { + field: getMutationToastDescriptionFieldName(newField), + }, + ), }) queryClient.setQueryData(adminFormKey, (oldForm) => { @@ -80,6 +82,7 @@ export const useDuplicateFormField = () => { queryClient, adminFormKey, updateEditState, + t, ], ) diff --git a/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts b/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts index 694fd7bab5..f5104cd672 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts +++ b/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react' +import { useTranslation } from 'react-i18next' import { useMutation, useQueryClient } from 'react-query' import { useParams } from 'react-router-dom' @@ -21,6 +22,7 @@ import { } from '../utils/getMutationMessage' export const useEditFormField = () => { + const { t } = useTranslation() const { formId } = useParams() if (!formId) throw new Error('No formId provided') @@ -36,15 +38,14 @@ export const useEditFormField = () => { if (fieldBuilderState !== FieldBuilderState.EditingField) { toast({ status: 'warning', - description: - 'Something went wrong when editing your field. Please refresh and try again.', + description: t('features.adminForm.toasts.field.update.error'), }) return } toast({ - description: `The ${getMutationToastDescriptionFieldName( - newField, - )} was updated.`, + description: t('features.adminForm.toasts.field.update.success', { + field: getMutationToastDescriptionFieldName(newField), + }), }) queryClient.setQueryData(adminFormKey, (oldForm) => { // Should not happen, should not be able to update field if there is no @@ -57,7 +58,7 @@ export const useEditFormField = () => { return oldForm }) }, - [adminFormKey, fieldBuilderState, queryClient, toast], + [adminFormKey, fieldBuilderState, queryClient, toast, t], ) const handleError = useCallback( diff --git a/frontend/src/i18n/locales/features/admin-form/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/en-sg.ts index 88818573df..b194d9d51e 100644 --- a/frontend/src/i18n/locales/features/admin-form/en-sg.ts +++ b/frontend/src/i18n/locales/features/admin-form/en-sg.ts @@ -1,9 +1,13 @@ import { enSG as meta } from './meta' +import { enSG as modals } from './modals' import { enSG as navbar } from './navbar' import { enSG as sidebar } from './sidebar' +import { enSG as toasts } from './toasts' export const enSG = { navbar, sidebar, meta, + modals, + toasts, } diff --git a/frontend/src/i18n/locales/features/admin-form/index.ts b/frontend/src/i18n/locales/features/admin-form/index.ts index e53c29786f..34644c6f72 100644 --- a/frontend/src/i18n/locales/features/admin-form/index.ts +++ b/frontend/src/i18n/locales/features/admin-form/index.ts @@ -1,7 +1,9 @@ export * from './en-sg' export { type Meta } from './meta' +export { type Modals } from './modals' export { type Navbar } from './navbar' export { type Fields } from './sidebar' export { type HeaderAndInstructions } from './sidebar' export { type Logic } from './sidebar' export { type ThankYou } from './sidebar' +export { type Toasts } from './toasts' diff --git a/frontend/src/i18n/locales/features/admin-form/modals/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/modals/en-sg.ts new file mode 100644 index 0000000000..0a86a083d4 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/modals/en-sg.ts @@ -0,0 +1,23 @@ +export const enSG = { + deleteField: { + title: 'Delete field', + description: { + field: + 'Are you sure you want to delete this field? This action cannot be undone.', + logic: + 'This field is used in your form logic, so deleting it may cause your logic to stop working correctly. Are you sure you want to delete this field?', + payment: + "Are you sure you want to delete payment field? This action can't be undone.", + }, + confirmButtonText: 'Yes, delete field', + }, + unsavedChanges: { + title: 'You have unsaved changes', + description: 'Are you sure you want to leave? Your changes will be lost.', + confirmButtonText: 'Yes, discard changes', + cancelButtonText: 'No, stay on page', + }, + dirty: { + cancelButtonText: 'No, return to editing', + }, +} diff --git a/frontend/src/i18n/locales/features/admin-form/modals/index.ts b/frontend/src/i18n/locales/features/admin-form/modals/index.ts new file mode 100644 index 0000000000..27a681fbb8 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/modals/index.ts @@ -0,0 +1,22 @@ +export * from './en-sg' + +export interface Modals { + deleteField: { + title: string + description: { + field: string + logic: string + payment: string + } + confirmButtonText: string + } + unsavedChanges: { + title: string + description: string + confirmButtonText: string + cancelButtonText: string + } + dirty: { + cancelButtonText: string + } +} diff --git a/frontend/src/i18n/locales/features/admin-form/toasts/en-sg.ts b/frontend/src/i18n/locales/features/admin-form/toasts/en-sg.ts new file mode 100644 index 0000000000..7bd6036ff7 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/toasts/en-sg.ts @@ -0,0 +1,26 @@ +export const enSG = { + field: { + delete: { + success: 'The {field} was deleted.', + error: + 'Something went wrong when deleting your field. Please refresh and try again.', + }, + create: { + success: 'The {field} was created.', + error: + 'Something went wrong when creating your field. Please refresh and try again.', + }, + update: { + success: 'The {field} was updated.', + error: + 'Something went wrong when editing your field. Please refresh and try again.', + }, + duplicate: { + success: 'The {field} was duplicated.', + successButNoLogic: + 'The {field} was duplicated. Associated logic was not duplicated.', + error: + 'Something went wrong when creating your field. Please refresh and try again.', + }, + }, +} diff --git a/frontend/src/i18n/locales/features/admin-form/toasts/index.ts b/frontend/src/i18n/locales/features/admin-form/toasts/index.ts new file mode 100644 index 0000000000..d82358aa13 --- /dev/null +++ b/frontend/src/i18n/locales/features/admin-form/toasts/index.ts @@ -0,0 +1,15 @@ +export * from './en-sg' + +interface Toast { + success: string + error: string +} + +export interface Toasts { + field: { + delete: Toast + create: Toast + update: Toast + duplicate: Toast & { successButNoLogic: string } + } +} diff --git a/frontend/src/i18n/locales/features/common/en-sg.ts b/frontend/src/i18n/locales/features/common/en-sg.ts index 3942bae1a6..910803c2dd 100644 --- a/frontend/src/i18n/locales/features/common/en-sg.ts +++ b/frontend/src/i18n/locales/features/common/en-sg.ts @@ -55,6 +55,7 @@ export const enSG: Common = { tooltip: { deleteField: 'Delete field', duplicateField: 'Duplicate field', + editField: 'Edit field', }, dropdown: { placeholder: 'Select an option', diff --git a/frontend/src/i18n/locales/features/common/index.ts b/frontend/src/i18n/locales/features/common/index.ts index bc84abddfa..304c1d78c2 100644 --- a/frontend/src/i18n/locales/features/common/index.ts +++ b/frontend/src/i18n/locales/features/common/index.ts @@ -55,6 +55,7 @@ export interface Common { tooltip: { deleteField: string duplicateField: string + editField: string } dropdown: { placeholder: string diff --git a/frontend/src/i18n/locales/features/index.ts b/frontend/src/i18n/locales/features/index.ts index 08617516d5..b612fc14f5 100644 --- a/frontend/src/i18n/locales/features/index.ts +++ b/frontend/src/i18n/locales/features/index.ts @@ -3,8 +3,10 @@ export { type HeaderAndInstructions, type Logic, type Meta, + type Modals, type Navbar, type ThankYou, + type Toasts, } from './admin-form' export { type Common } from './common' export { type Login } from './login' diff --git a/frontend/src/i18n/locales/types.ts b/frontend/src/i18n/locales/types.ts index 66205d3cac..9bcc910574 100644 --- a/frontend/src/i18n/locales/types.ts +++ b/frontend/src/i18n/locales/types.ts @@ -7,9 +7,11 @@ import { Logic, Login, Meta, + Modals, Navbar, PublicForm, ThankYou, + Toasts, } from './features' interface Translation { @@ -24,6 +26,8 @@ interface Translation { } navbar?: Navbar meta?: Meta + modals?: Modals + toasts?: Toasts } common?: Common publicForm?: PublicForm diff --git a/frontend/src/templates/NavigationPrompt/NavigationPrompt.tsx b/frontend/src/templates/NavigationPrompt/NavigationPrompt.tsx index 9bd84ab36f..8860b847a6 100644 --- a/frontend/src/templates/NavigationPrompt/NavigationPrompt.tsx +++ b/frontend/src/templates/NavigationPrompt/NavigationPrompt.tsx @@ -1,4 +1,5 @@ import { memo } from 'react' +import { useTranslation } from 'react-i18next' import { UnsavedChangesModal } from './UnsavedChangesModal' import { useNavigationPrompt } from './useNavigationPrompt' @@ -26,8 +27,13 @@ export const NavigationPrompt = memo( confirmButtonText = 'Yes, discard changes', cancelButtonText = 'No, stay on page', }: NavigationPromptProps) => { + const { t } = useTranslation() const { isPromptShown, onCancel, onConfirm } = useNavigationPrompt(when) + const defaultText = t('features.adminForm.modals.unsavedChanges', { + returnObjects: true, + }) + return ( Date: Fri, 22 Nov 2024 13:23:12 +0800 Subject: [PATCH 12/16] chore: remove unused deps (#7906) * chore: remove unused debounce * chore: remove unused webpack chore: remove unused worker-loader chore: update readme to exclude webpack issues chore: remove unused regenerator chore: remove unused puppeteer chore: remove nocache chore: remove @types/jsonfile --- .../integration/helpers/express-setup.ts | 2 - docs/TROUBLESHOOTING.md | 13 - frontend/package-lock.json | 942 +---- frontend/package.json | 5 +- frontend/src/typings/worker-loader.d.ts | 8 - package-lock.json | 3476 +---------------- package.json | 5 - 7 files changed, 293 insertions(+), 4158 deletions(-) delete mode 100644 frontend/src/typings/worker-loader.d.ts diff --git a/__tests__/integration/helpers/express-setup.ts b/__tests__/integration/helpers/express-setup.ts index 6b2afebe97..35c598857a 100644 --- a/__tests__/integration/helpers/express-setup.ts +++ b/__tests__/integration/helpers/express-setup.ts @@ -2,7 +2,6 @@ import compression from 'compression' import cookieParser from 'cookie-parser' import express, { Express, Router } from 'express' import session from 'express-session' -import nocache from 'nocache' import { errorHandlerMiddlewares } from 'src/app/loaders/express/error-handler' import helmetMiddlewares from 'src/app/loaders/express/helmet' @@ -37,7 +36,6 @@ export const setupApp = ( app.use(compression()) app.use(parserMiddlewares()) app.use(helmetMiddlewares()) - app.use(nocache()) app.use(testSessionMiddlewares()) diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 4821449c6a..fb0edafb18 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -41,19 +41,6 @@ conf.members[0].host = 'database:27017' rs.reconfig(conf, {force:true}) ``` -## `TypeError: Cannot read property 'tap' of undefined` - -If you are using a machine with an M1 chip, you may be facing this issue due to your `node` installation, as an inappropriate version of `node` would cause more updated versions of `webpack` to be installed and thus introduces breaking changes in the code. - -To overcome this, use Rosetta to install `node` in -x86_64 architecture as described in the "Macs with M1 chip" section [here](https://github.com/nvm-sh/nvm#macos-troubleshooting). - -Be sure to check that the correct `node` is installed with: - -```bash -$ node -p process.arch -x64 -``` - ## `npm` not found Make sure `nvm` is loaded to the environment in `~/.bash_profile`. To do so, the `~/.bash_profile` should include the following lines: diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4a7ef43251..d316d0dcb9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -90,7 +90,6 @@ "tweetnacl": "^1.0.3", "type-fest": "^4.17.0", "typescript": "^5.4.5", - "use-debounce": "^7.0.1", "use-draggable-scroll": "^0.1.0", "validator": "^13.7.0", "vite-plugin-node-stdlib-browser": "^0.2.1", @@ -149,7 +148,6 @@ "msw": "^1.3.3", "msw-storybook-addon": "^1.10.0", "prettier": "^3.2.5", - "puppeteer": "^13.0.0", "react-refresh": "^0.14.0", "resize-observer-polyfill": "^1.5.1", "rimraf": "^3.0.2", @@ -158,8 +156,7 @@ "vite": "^5.4.6", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.5.2", - "worker-loader": "^3.0.8" + "vitest": "^1.5.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -347,6 +344,7 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -427,20 +425,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", @@ -2174,27 +2158,28 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz", - "integrity": "sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA==", - "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "^4.0.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "stylis": "4.2.0" } }, + "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/cache": { "version": "11.6.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.6.0.tgz", @@ -2208,18 +2193,23 @@ } }, "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz", - "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "dependencies": { - "@emotion/memoize": "^0.7.4" + "@emotion/memoize": "^0.9.0" } }, + "node_modules/@emotion/is-prop-valid/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/memoize": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", @@ -2252,56 +2242,66 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", "dependencies": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", "csstype": "^3.0.2" } }, + "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/sheet": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" }, "node_modules/@emotion/styled": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz", - "integrity": "sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.3.0", - "@emotion/is-prop-valid": "^1.1.1", - "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.0.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } }, "node_modules/@emotion/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==" }, "node_modules/@emotion/weak-memoize": { "version": "0.2.5", @@ -5525,16 +5525,6 @@ "integrity": "sha512-+jBxVvXVuggZOrm04NR8z+5+bgoW4VZyLzUO+hmPPW1mVFL/HaitLAkizfv4yg9TbG8lkfHWVMQ11yDqrVVCzA==", "dev": true }, - "node_modules/@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz", @@ -6546,18 +6536,6 @@ "node": ">= 10.0.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -6946,13 +6924,32 @@ } }, "node_modules/babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dependencies": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/bail": { @@ -7331,15 +7328,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -8117,12 +8105,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { "version": "0.6.0", @@ -8805,12 +8790,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/devtools-protocol": { - "version": "0.0.937139", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.937139.tgz", - "integrity": "sha512-daj+rzR3QSxsPRy5vjjthn58axO8c11j58uY0lG5vvlJk/EiOdCWOptGdkXDjtuRHr78emKq0udHCXM4trhoDQ==", - "dev": true - }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -8967,15 +8946,6 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/endent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", @@ -10299,41 +10269,6 @@ "node": ">=4" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -10395,15 +10330,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -10766,12 +10692,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -11403,19 +11323,6 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -13915,12 +13822,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/mlly": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", @@ -14996,12 +14897,6 @@ "node": ">=0.12" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -15243,15 +15138,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -15307,16 +15193,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -15325,102 +15201,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.0.0.tgz", - "integrity": "sha512-kZfGAieIVSo4bFqYuvY2KvhgP9txzmPbbnpZIzLlfdt8nEu9evXEwsbBt1BHocVQM4fJmCiS+FRyw7c8aWadNg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "debug": "4.3.2", - "devtools-protocol": "0.0.937139", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "node-fetch": "2.6.5", - "pkg-dir": "4.2.0", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.2.3" - }, - "engines": { - "node": ">=10.18.1" - } - }, - "node_modules/puppeteer/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/puppeteer/node_modules/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/puppeteer/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "node_modules/puppeteer/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "node_modules/puppeteer/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/puppeteer/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -17260,7 +17040,7 @@ "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } @@ -17628,9 +17408,9 @@ } }, "node_modules/stylis": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.11.tgz", - "integrity": "sha512-Q7gWFqMXrpDAnqhkFZdgBjXzybYc4WaJNtFdnQQSfww/cIiBUx/3sPGYMKFh3muXA47dhaWfYqc/HQkg8j7+ig==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -17689,40 +17469,6 @@ "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/telejson": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", @@ -18166,16 +17912,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -18416,17 +18152,6 @@ "react": "^16.8.0 || ^17.0.0" } }, - "node_modules/use-debounce": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-7.0.1.tgz", - "integrity": "sha512-fOrzIw2wstbAJuv8PC9Vg4XgwyTLEOdq4y/Z3IhVl8DAE4svRcgyEUvrEXu+BMNgMoc3YND6qLT61kkgEKXh7Q==", - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, "node_modules/use-draggable-scroll": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/use-draggable-scroll/-/use-draggable-scroll-0.1.0.tgz", @@ -19391,44 +19116,6 @@ "node": ">=8" } }, - "node_modules/worker-loader": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", - "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/worker-loader/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -19554,16 +19241,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -19756,7 +19433,8 @@ "@babel/helper-plugin-utils": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==" + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true }, "@babel/helper-simple-access": { "version": "7.24.7", @@ -19810,14 +19488,6 @@ "@babel/types": "^7.25.6" } }, - "@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", - "requires": { - "@babel/helper-plugin-utils": "^7.24.0" - } - }, "@babel/plugin-transform-react-jsx-self": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", @@ -21007,22 +20677,28 @@ } }, "@emotion/babel-plugin": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz", - "integrity": "sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA==", - "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "^4.0.3" + "stylis": "4.2.0" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + } } }, "@emotion/cache": { @@ -21038,16 +20714,23 @@ } }, "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "@emotion/is-prop-valid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz", - "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "requires": { - "@emotion/memoize": "^0.7.4" + "@emotion/memoize": "^0.9.0" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + } } }, "@emotion/memoize": { @@ -21070,15 +20753,22 @@ } }, "@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", "requires": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", "csstype": "^3.0.2" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + } } }, "@emotion/sheet": { @@ -21087,26 +20777,32 @@ "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" }, "@emotion/styled": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz", - "integrity": "sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "requires": { - "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.3.0", - "@emotion/is-prop-valid": "^1.1.1", - "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.0.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" } }, "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==" }, "@emotion/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==" }, "@emotion/weak-memoize": { "version": "0.2.5", @@ -23259,16 +22955,6 @@ "integrity": "sha512-+jBxVvXVuggZOrm04NR8z+5+bgoW4VZyLzUO+hmPPW1mVFL/HaitLAkizfv4yg9TbG8lkfHWVMQ11yDqrVVCzA==", "dev": true }, - "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, "@typescript-eslint/eslint-plugin": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz", @@ -23953,15 +23639,6 @@ "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==" }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -24244,13 +23921,27 @@ } }, "babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "requires": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + } } }, "bail": { @@ -24545,12 +24236,6 @@ "ieee754": "^1.1.13" } }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -25115,12 +24800,9 @@ "dev": true }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { "version": "0.6.0", @@ -25678,12 +25360,6 @@ "dequal": "^2.0.0" } }, - "devtools-protocol": { - "version": "0.0.937139", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.937139.tgz", - "integrity": "sha512-daj+rzR3QSxsPRy5vjjthn58axO8c11j58uY0lG5vvlJk/EiOdCWOptGdkXDjtuRHr78emKq0udHCXM4trhoDQ==", - "dev": true - }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -25822,15 +25498,6 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "endent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", @@ -26794,29 +26461,6 @@ "tmp": "^0.0.33" } }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -26875,15 +26519,6 @@ "reusify": "^1.0.4" } }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -27136,12 +26771,6 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -27596,16 +27225,6 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -29321,12 +28940,6 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "mlly": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", @@ -30104,12 +29717,6 @@ "sha.js": "^2.4.8" } }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -30276,12 +29883,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -30332,89 +29933,11 @@ } } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "puppeteer": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.0.0.tgz", - "integrity": "sha512-kZfGAieIVSo4bFqYuvY2KvhgP9txzmPbbnpZIzLlfdt8nEu9evXEwsbBt1BHocVQM4fJmCiS+FRyw7c8aWadNg==", - "dev": true, - "requires": { - "debug": "4.3.2", - "devtools-protocol": "0.0.937139", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "node-fetch": "2.6.5", - "pkg-dir": "4.2.0", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.2.3" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true - } - } - }, "qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -31756,7 +31279,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" }, "source-map-js": { "version": "1.2.1", @@ -32036,9 +31559,9 @@ } }, "stylis": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.11.tgz", - "integrity": "sha512-Q7gWFqMXrpDAnqhkFZdgBjXzybYc4WaJNtFdnQQSfww/cIiBUx/3sPGYMKFh3muXA47dhaWfYqc/HQkg8j7+ig==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "supports-color": { "version": "5.5.0", @@ -32079,39 +31602,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - }, - "dependencies": { - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - } - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, "telejson": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", @@ -32438,16 +31928,6 @@ "which-boxed-primitive": "^1.0.2" } }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -32606,11 +32086,6 @@ "ts-essentials": "^2.0.3" } }, - "use-debounce": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-7.0.1.tgz", - "integrity": "sha512-fOrzIw2wstbAJuv8PC9Vg4XgwyTLEOdq4y/Z3IhVl8DAE4svRcgyEUvrEXu+BMNgMoc3YND6qLT61kkgEKXh7Q==" - }, "use-draggable-scroll": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/use-draggable-scroll/-/use-draggable-scroll-0.1.0.tgz", @@ -33149,29 +32624,6 @@ "stackback": "0.0.2" } }, - "worker-loader": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", - "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -33257,16 +32709,6 @@ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0581bc899b..adbf2695fa 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -86,7 +86,6 @@ "tweetnacl": "^1.0.3", "type-fest": "^4.17.0", "typescript": "^5.4.5", - "use-debounce": "^7.0.1", "use-draggable-scroll": "^0.1.0", "validator": "^13.7.0", "vite-plugin-node-stdlib-browser": "^0.2.1", @@ -172,7 +171,6 @@ "msw": "^1.3.3", "msw-storybook-addon": "^1.10.0", "prettier": "^3.2.5", - "puppeteer": "^13.0.0", "react-refresh": "^0.14.0", "resize-observer-polyfill": "^1.5.1", "rimraf": "^3.0.2", @@ -181,8 +179,7 @@ "vite": "^5.4.6", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.5.2", - "worker-loader": "^3.0.8" + "vitest": "^1.5.2" }, "proxy": "http://localhost:5001", "msw": { diff --git a/frontend/src/typings/worker-loader.d.ts b/frontend/src/typings/worker-loader.d.ts deleted file mode 100644 index 7224a3ccb0..0000000000 --- a/frontend/src/typings/worker-loader.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -declare module 'worker-loader!*' { - // You need to change `Worker`, if you specified a different value for the `workerType` option - class WebpackWorker extends Worker { - constructor() - } - - export default WebpackWorker -} diff --git a/package-lock.json b/package-lock.json index 1255d41123..f627f8630a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,6 @@ "multiparty": ">=4.2.3", "nan": "^2.19.0", "neverthrow": "^8.0.0", - "nocache": "^3.0.4", "node-cache": "^5.1.2", "nodemailer": "^6.9.16", "openai": "^4.70.3", @@ -134,7 +133,6 @@ "@types/ip": "^1.1.0", "@types/jest": "^29.5.1", "@types/json-stringify-safe": "^5.0.3", - "@types/jsonfile": "^6.1.1", "@types/jsonwebtoken": "^9.0.7", "@types/jwk-to-pem": "^2.0.3", "@types/lodash": "^4.17.6", @@ -179,7 +177,6 @@ "maildev": "^2.1.0", "mockdate": "^3.0.5", "prettier": "^3.3.3", - "regenerator": "^0.14.10", "rimraf": "^5.0.5", "stripe-event-types": "^3.1.0", "supertest": "^6.3.3", @@ -190,8 +187,6 @@ "ts-node-dev": "^2.0.0", "type-fest": "^4.17.0", "typescript": "^5.4.5", - "webpack": "^4.46.0", - "webpack-cli": "^4.10.0", "worker-loader": "^2.0.0" }, "engines": { @@ -3793,23 +3788,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-function-sent": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.18.6.tgz", - "integrity": "sha512-UdaOKPOLPt0O+Xu26tnw6oAZMLXhk+yMrXOzn6kAzTHBnWHJsoN1hlrgxFAQ+FRLS0ql1oYIQ2phvoFzmN3GMw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-wrap-function": "^7.18.6", - "@babel/plugin-syntax-function-sent": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", @@ -3896,21 +3874,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-function-sent": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.18.6.tgz", - "integrity": "sha512-f3OJHIlFIkg+cP1Hfo2SInLhsg0pz2Ikmgo7jMdIIKC+3jVXQlHB0bgSapOWxeWI0SU28qIWmfn5ZKu1yPJHkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", @@ -5309,15 +5272,6 @@ "version": "2.1.0", "license": "Apache-2.0" }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.11", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", @@ -9270,15 +9224,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/jsonfile": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.1.tgz", - "integrity": "sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/jsonwebtoken": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", @@ -10207,209 +10152,6 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "dev": true, - "license": "ISC" - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", - "dev": true, - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -10535,14 +10277,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": ">=5.0.0" - } - }, "node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", @@ -10702,30 +10436,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/arr-diff": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -10775,14 +10485,6 @@ "node": ">=8" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.findlastindex": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", @@ -10883,52 +10585,6 @@ "safer-buffer": "^2.1.0" } }, - "node_modules/assert": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "2.0.1" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ast-types": { - "version": "0.15.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ast-types/node_modules/tslib": { - "version": "2.4.0", - "dev": true, - "license": "0BSD" - }, "node_modules/astral-regex": { "version": "2.0.0", "dev": true, @@ -10941,12 +10597,6 @@ "version": "3.2.3", "license": "MIT" }, - "node_modules/async-each": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/async-mutex": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.1.tgz", @@ -10964,17 +10614,6 @@ "version": "0.4.0", "license": "MIT" }, - "node_modules/atob": { - "version": "2.1.2", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/atomic-sleep": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", @@ -11394,92 +11033,29 @@ "bare-os": "^2.1.0" } }, - "node_modules/base": { - "version": "0.11.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/base-64": { "version": "1.0.0", "dev": true, "license": "MIT" }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", + "node_modules/base32.js": { + "version": "0.1.0", "dev": true, "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12.0" } }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, + "node_modules/base64-js": { + "version": "1.3.1", + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base32.js": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/base64-js": { - "version": "1.3.1", - "license": "MIT" - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" + "node": "^4.5.0 || >= 5.9" } }, "node_modules/base64url": { @@ -11662,102 +11238,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~1.0.5" - } - }, "node_modules/browserslist": { "version": "4.23.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", @@ -11843,16 +11323,6 @@ "version": "1.1.1", "license": "MIT" }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/busboy": { "version": "1.6.0", "dependencies": { @@ -11870,25 +11340,6 @@ "node": ">= 0.8" } }, - "node_modules/cache-base": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -12020,22 +11471,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, - "node_modules/chrome-trace-event": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "node": ">=6.0" - } - }, "node_modules/chromium-bidi": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.16.tgz", @@ -12066,45 +11501,11 @@ "node": ">=8" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, - "node_modules/class-utils": { - "version": "0.3.6", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -12258,20 +11659,6 @@ "node": ">=0.8" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -12288,18 +11675,6 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "node_modules/collection-visit": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "license": "MIT", @@ -12359,61 +11734,10 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "2.20.3", - "dev": true, - "license": "MIT" - }, "node_modules/commondir": { "version": "1.0.1", "license": "MIT" }, - "node_modules/commoner": { - "version": "0.10.8", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^2.5.0", - "detective": "^4.3.1", - "glob": "^5.0.15", - "graceful-fs": "^4.1.2", - "iconv-lite": "^0.4.5", - "mkdirp": "^0.5.0", - "private": "^0.1.6", - "q": "^1.1.2", - "recast": "^0.11.17" - }, - "bin": { - "commonize": "bin/commonize" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commoner/node_modules/glob": { - "version": "5.0.15", - "dev": true, - "license": "ISC", - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/commoner/node_modules/q": { - "version": "1.5.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/component-emitter": { "version": "1.3.0", "dev": true, @@ -12672,20 +11996,11 @@ "mongodb": "^4.1.0" } }, - "node_modules/console-browserify": { - "version": "1.2.0", - "dev": true - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/content-disposition": { "version": "0.5.4", "license": "MIT", @@ -12774,38 +12089,6 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/copyfiles": { "version": "2.4.1", "dev": true, @@ -12907,40 +12190,6 @@ "node": ">= 0.10" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/create-require": { "version": "1.1.1", "dev": true, @@ -12982,27 +12231,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, "node_modules/crypto-randomuuid": { "version": "1.0.0", "license": "MIT" @@ -13040,11 +12268,6 @@ "version": "2.1.8", "license": "MIT" }, - "node_modules/cyclist": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -13286,15 +12509,6 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "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, - "engines": { - "node": ">=0.10" - } - }, "node_modules/dedent": { "version": "0.7.0", "dev": true, @@ -13369,61 +12583,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-property": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defined": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/degenerator": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", @@ -13495,15 +12654,6 @@ "node": ">= 0.8" } }, - "node_modules/des.js": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/destroy": { "version": "1.2.0", "license": "MIT", @@ -13528,26 +12678,6 @@ "node": ">=8" } }, - "node_modules/detective": { - "version": "4.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^5.2.1", - "defined": "^1.0.0" - } - }, - "node_modules/detective/node_modules/acorn": { - "version": "5.7.4", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/devtools-protocol": { "version": "0.0.1262051", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1262051.tgz", @@ -13580,16 +12710,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -13634,15 +12754,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/domain-browser": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -13698,17 +12809,6 @@ "url": "https://dotenvx.com" } }, - "node_modules/duplexify": { - "version": "3.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, "node_modules/dynamic-dedupe": { "version": "0.3.0", "dev": true, @@ -13940,18 +13040,6 @@ "node": ">= 6" } }, - "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -15212,15 +14300,6 @@ "node": ">=0.4.x" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -15274,58 +14353,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/expect": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", @@ -15538,104 +14565,6 @@ "dev": true, "license": "MIT" }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -15736,15 +14665,6 @@ "fxparser": "src/cli/cli.js" } }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, "node_modules/fastestsmallesttextencoderdecoder": { "version": "1.0.22", "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", @@ -15780,11 +14700,6 @@ "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "dev": true, - "license": "ISC" - }, "node_modules/figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -15911,19 +14826,6 @@ "node": ">= 0.8" } }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/find-up": { "version": "4.1.0", "license": "MIT", @@ -15942,15 +14844,6 @@ "node": ">=8" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, "node_modules/flat-cache": { "version": "3.0.4", "dev": true, @@ -15989,15 +14882,6 @@ "dev": true, "license": "ISC" }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, "node_modules/fn.name": { "version": "1.1.0", "license": "MIT" @@ -16034,14 +14918,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/for-in": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/foreach": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", @@ -16136,17 +15012,6 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.8.tgz", "integrity": "sha512-nmDtNqmMZkOxu0M5hkrS9YA15/KPkYkILb6Axg9XBAoUoYEtzg+LFmVWqZrl9FNttsW0qIUpx9RCA9INbv+Bxw==" }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -16155,15 +15020,6 @@ "node": ">= 0.6" } }, - "node_modules/from2": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -16212,17 +15068,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "license": "ISC" @@ -16396,14 +15241,6 @@ "node": ">= 14" } }, - "node_modules/get-value": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob": { "version": "7.1.6", "license": "ISC", @@ -16604,95 +15441,6 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, - "node_modules/has-value": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/hash.js": { "version": "1.1.7", "license": "MIT", @@ -16977,11 +15725,6 @@ "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==" }, - "node_modules/https-browserify": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "license": "MIT", @@ -17039,11 +15782,6 @@ "version": "1.1.13", "license": "BSD-3-Clause" }, - "node_modules/iferr": { - "version": "0.1.5", - "dev": true, - "license": "MIT" - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -17132,11 +15870,6 @@ "node": ">=0.8.19" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "dev": true, - "license": "ISC" - }, "node_modules/inflight": { "version": "1.0.6", "license": "ISC", @@ -17173,15 +15906,6 @@ "node": ">= 0.4" } }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/intl-tel-input": { "version": "12.4.0", "license": "MIT", @@ -17215,33 +15939,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-arguments": { "version": "1.1.1", "license": "MIT", @@ -17338,33 +16035,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-data-view": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", @@ -17395,35 +16065,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "dev": true, @@ -17518,17 +16159,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "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", @@ -17643,14 +16273,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "1.0.0", "license": "MIT" @@ -17659,14 +16281,6 @@ "version": "2.0.0", "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isomorphic-fetch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", @@ -20439,14 +19053,6 @@ "node": ">=12.0.0" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -20870,14 +19476,6 @@ "node": ">=4" } }, - "node_modules/loader-runner": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, "node_modules/loader-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", @@ -21583,18 +20181,6 @@ "node": ">=12" } }, - "node_modules/make-dir": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/make-error": { "version": "1.3.6", "dev": true, @@ -21620,25 +20206,6 @@ "node": ">=7.6" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/marked": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/marked/-/marked-7.0.4.tgz", @@ -21661,18 +20228,8 @@ "react": "18.x" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", + "node_modules/media-typer": { + "version": "0.3.0", "license": "MIT", "engines": { "node": ">= 0.6" @@ -21749,18 +20306,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -21878,54 +20423,11 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/mississippi": { - "version": "3.0.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mkdirp": { "version": "0.5.5", "license": "MIT", @@ -22219,30 +20721,6 @@ "dev": true, "license": "MIT" }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/mpath": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", @@ -22367,27 +20845,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -22482,13 +20939,6 @@ } } }, - "node_modules/nocache": { - "version": "3.0.4", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -22661,86 +21111,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/buffer": { - "version": "4.9.2", - "dev": true, - "license": "MIT", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/node-libs-browser/node_modules/events": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/node-libs-browser/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC" - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/node-libs-browser/node_modules/url": { - "version": "0.11.0", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/node-libs-browser/node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "dev": true, - "license": "MIT" - }, - "node_modules/node-libs-browser/node_modules/util": { - "version": "0.11.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -22847,46 +21217,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-hash": { "version": "2.2.0", "license": "MIT", @@ -22911,17 +21241,6 @@ "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", @@ -22972,17 +21291,6 @@ "node": ">= 0.4" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -23244,11 +21552,6 @@ "node": ">=8" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "dev": true, - "license": "MIT" - }, "node_modules/p-defer": { "version": "1.0.0", "dev": true, @@ -23349,16 +21652,6 @@ "version": "1.0.11", "license": "(MIT AND Zlib)" }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, "node_modules/parent-module": { "version": "1.0.1", "dev": true, @@ -23370,18 +21663,6 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "node_modules/parse-github-url": { "version": "1.0.2", "dev": true, @@ -23450,25 +21731,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/path-exists": { "version": "3.0.0", "dev": true, @@ -23535,21 +21797,6 @@ "node": ">=8" } }, - "node_modules/pbkdf2": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/peberminta": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", @@ -23590,14 +21837,6 @@ "node": ">=0.10" } }, - "node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pino": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz", @@ -23702,51 +21941,6 @@ "node": ">=4" } }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/playwright": { "version": "1.49.0", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", @@ -23777,14 +21971,6 @@ "node": ">=18" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -23976,14 +22162,6 @@ "node": ">=6" } }, - "node_modules/private": { - "version": "0.1.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/process": { "version": "0.11.10", "license": "MIT", @@ -24008,11 +22186,6 @@ "node": ">=0.4.0" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, "node_modules/promise-retry": { "version": "2.0.1", "license": "MIT", @@ -24143,19 +22316,6 @@ "dev": true, "license": "MIT" }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/pump": { "version": "3.0.0", "license": "MIT", @@ -24164,25 +22324,6 @@ "once": "^1.3.1" } }, - "node_modules/pumpify": { - "version": "1.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -24262,13 +22403,6 @@ "node": ">=0.4.x" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/querystringify": { "version": "2.2.0", "license": "MIT" @@ -24291,23 +22425,6 @@ "node": ">= 0.8" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -24641,52 +22758,6 @@ "node": ">=8.10.0" } }, - "node_modules/recast": { - "version": "0.11.23", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "0.9.6", - "esprima": "~3.1.0", - "private": "~0.1.5", - "source-map": "~0.5.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/recast/node_modules/ast-types": { - "version": "0.9.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/recast/node_modules/esprima": { - "version": "3.1.3", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -24705,51 +22776,6 @@ "node": ">=4" } }, - "node_modules/regenerator": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/regenerator/-/regenerator-0.14.10.tgz", - "integrity": "sha512-gkjFZExU9FbaGlQ89aK49ZJ1bLl0C+8yKGrDrAwxArwiKlDeWJi/VH4Ao1Q//yCGk2axXMJcYrPp0WXmjTX+vw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.4", - "@babel/runtime": "^7.8.4", - "@babel/types": "^7.8.3", - "commoner": "^0.10.8", - "private": "^0.1.8", - "recast": "^0.21.5", - "regenerator-preset": "^0.14.1", - "regenerator-runtime": "^0.13.11", - "regenerator-transform": "^0.15.1", - "through": "^2.3.8" - }, - "bin": { - "regenerator": "bin/regenerator" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/regenerator-preset": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-preset/-/regenerator-preset-0.14.1.tgz", - "integrity": "sha512-7zEo8AK6N87TvOtFXEGec+LAGvCjgZyP/pbxm5NYAoWsmQCCd/IUKBwBqoOffiIhr1UOlgCGsRtwlR71Hl3Ewg==", - "dev": true, - "dependencies": { - "@babel/plugin-proposal-function-sent": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.8.4", - "regenerator-transform": "^0.15.0" - } - }, - "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==", - "dev": true - }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", @@ -24759,57 +22785,6 @@ "@babel/runtime": "^7.8.4" } }, - "node_modules/regenerator/node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator/node_modules/recast": { - "version": "0.21.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "0.15.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/regenerator/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regenerator/node_modules/tslib": { - "version": "2.4.0", - "dev": true, - "license": "0BSD" - }, - "node_modules/regex-not": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -24878,28 +22853,6 @@ "jsesc": "bin/jsesc" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "license": "MIT", @@ -24964,11 +22917,6 @@ "node": ">=8" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, "node_modules/resolve.exports": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", @@ -24990,14 +22938,6 @@ "node": ">=8" } }, - "node_modules/ret": { - "version": "0.1.15", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, "node_modules/retry": { "version": "0.12.0", "license": "MIT", @@ -25084,15 +23024,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", @@ -25103,14 +23034,6 @@ "dev": true, "license": "MIT" }, - "node_modules/run-queue": { - "version": "1.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1" - } - }, "node_modules/rxjs": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", @@ -25167,14 +23090,6 @@ ], "license": "MIT" }, - "node_modules/safe-regex": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -25303,14 +23218,6 @@ "node": ">= 0.8" } }, - "node_modules/serialize-javascript": { - "version": "3.1.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -25368,31 +23275,6 @@ "node": ">= 0.4" } }, - "node_modules/set-value": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "license": "MIT" @@ -25401,30 +23283,6 @@ "version": "1.2.0", "license": "ISC" }, - "node_modules/sha.js": { - "version": "2.4.11", - "dev": true, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -25597,172 +23455,33 @@ "node": ">=6.0.0" } }, - "node_modules/snapdragon": { - "version": "0.8.2", + "node_modules/sns-validator": { + "version": "0.3.5", + "license": "Apache-2.0" + }, + "node_modules/socket.io": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", + "integrity": "sha512-b65bp6INPk/BMMrIgVvX12x3Q+NqlGqSlTuvKQWt0BUJ3Hyy3JangBl7fEoWZTXbOKlCqNPbQ6MbWgok/km28w==", "dev": true, - "license": "MIT", "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "dev": true, - "license": "MIT", + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/sns-validator": { - "version": "0.3.5", - "license": "Apache-2.0" - }, - "node_modules/socket.io": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", - "integrity": "sha512-b65bp6INPk/BMMrIgVvX12x3Q+NqlGqSlTuvKQWt0BUJ3Hyy3JangBl7fEoWZTXbOKlCqNPbQ6MbWgok/km28w==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.4.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", - "dependencies": { - "ws": "~8.11.0" + "ws": "~8.11.0" } }, "node_modules/socket.io-parser": { @@ -25829,19 +23548,6 @@ "flatstr": "^1.0.12" } }, - "node_modules/source-list-map": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.5.7", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -25850,18 +23556,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -25880,11 +23574,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-url": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/spark-md5": { "version": "3.0.2", "license": "(WTFPL OR MIT)" @@ -25902,17 +23591,6 @@ "dev": true, "license": "MIT" }, - "node_modules/split-string": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -25987,29 +23665,6 @@ "node": ">=8" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.1", "license": "MIT", @@ -26017,41 +23672,6 @@ "node": ">= 0.8" } }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/streamsearch": { "version": "1.1.0", "engines": { @@ -26502,190 +24122,55 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/terser": { - "version": "4.8.0", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/terser-webpack-plugin": { - "version": "1.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } + "node_modules/text-encoding": { + "version": "0.7.0", + "license": "(Unlicense OR Apache-2.0)" }, - "node_modules/terser-webpack-plugin/node_modules/cacache": { - "version": "12.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } + "node_modules/text-hex": { + "version": "1.0.0", + "license": "MIT" }, - "node_modules/terser-webpack-plugin/node_modules/is-wsl": { - "version": "1.1.0", + "node_modules/text-table": { + "version": "0.2.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/terser-webpack-plugin/node_modules/lru-cache": { - "version": "5.1.1", + "node_modules/through": { + "version": "2.3.8", + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "yallist": "^3.0.2" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "node_modules/terser-webpack-plugin/node_modules/rimraf": { - "version": "2.7.1", - "dev": true, - "license": "ISC", + "node_modules/tldts": { + "version": "6.1.47", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.47.tgz", + "integrity": "sha512-R/K2tZ5MiY+mVrnSkNJkwqYT2vUv1lcT6wJvd2emGaMJ7PHUGRY4e3tUsdFCXgqxi2QgbHjL3yJgXCo40v9Hxw==", "dependencies": { - "glob": "^7.1.3" + "tldts-core": "^6.1.47" }, "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ssri": { - "version": "6.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-encoding": { - "version": "0.7.0", - "license": "(Unlicense OR Apache-2.0)" - }, - "node_modules/text-hex": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "license": "MIT" - }, - "node_modules/through2": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "dev": true, - "license": "MIT", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tldts": { - "version": "6.1.47", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.47.tgz", - "integrity": "sha512-R/K2tZ5MiY+mVrnSkNJkwqYT2vUv1lcT6wJvd2emGaMJ7PHUGRY4e3tUsdFCXgqxi2QgbHjL3yJgXCo40v9Hxw==", - "dependencies": { - "tldts-core": "^6.1.47" - }, - "bin": { - "tldts": "bin/cli.js" + "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { @@ -26704,11 +24189,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/to-fast-properties": { "version": "2.0.0", "license": "MIT", @@ -26716,47 +24196,6 @@ "node": ">=4" } }, - "node_modules/to-object-path": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -27182,11 +24621,6 @@ "version": "1.13.0", "license": "0BSD" }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/tweetnacl": { "version": "1.0.3", "license": "Unlicense" @@ -27478,36 +24912,6 @@ "node": ">=4" } }, - "node_modules/union-value": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, "node_modules/universalify": { "version": "0.1.2", "dev": true, @@ -27536,50 +24940,6 @@ "node": ">= 0.8" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/untildify": { "version": "4.0.0", "dev": true, @@ -27588,16 +24948,6 @@ "node": ">=8" } }, - "node_modules/upath": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -27647,11 +24997,6 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", "dev": true }, - "node_modules/urix": { - "version": "0.1.0", - "dev": true, - "license": "MIT" - }, "node_modules/url": { "version": "0.10.3", "license": "MIT", @@ -27677,14 +25022,6 @@ "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" }, - "node_modules/use": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/util": { "version": "0.12.5", "license": "MIT", @@ -27822,11 +25159,6 @@ "node": ">= 0.8" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, "node_modules/w3c-hr-time": { "version": "1.0.2", "dev": true, @@ -27855,643 +25187,54 @@ "makeerror": "1.0.12" } }, - "node_modules/watchpack": { - "version": "1.7.5", - "dev": true, - "license": "MIT", + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" + "defaults": "^1.0.3" } }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" } }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "optional": true, + "node_modules/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==", + "engines": { + "node": ">=12" + } + }, + "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": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" } }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/whatwg-encoding/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": { - "remove-trailing-separator": "^1.0.1" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/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==", - "engines": { - "node": ">=12" - } - }, - "node_modules/webpack": { - "version": "4.46.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - }, - "webpack-command": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "4.5.0", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/memory-fs": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/whatwg-encoding/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/whatwg-fetch": { - "version": "3.6.2", + "node_modules/whatwg-fetch": { + "version": "3.6.2", "dev": true, "license": "MIT" }, @@ -28558,12 +25301,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, "node_modules/winston": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", @@ -28708,14 +25445,6 @@ "node": ">=0.10.0" } }, - "node_modules/worker-farm": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.7" - } - }, "node_modules/worker-loader": { "version": "2.0.0", "dev": true, @@ -28917,11 +25646,6 @@ "node": ">=0.4" } }, - "node_modules/y18n": { - "version": "4.0.1", - "dev": true, - "license": "ISC" - }, "node_modules/yallist": { "version": "3.1.1", "license": "ISC" diff --git a/package.json b/package.json index 922598656b..a6d151a9f6 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,6 @@ "multiparty": ">=4.2.3", "nan": "^2.19.0", "neverthrow": "^8.0.0", - "nocache": "^3.0.4", "node-cache": "^5.1.2", "nodemailer": "^6.9.16", "openai": "^4.70.3", @@ -180,7 +179,6 @@ "@types/ip": "^1.1.0", "@types/jest": "^29.5.1", "@types/json-stringify-safe": "^5.0.3", - "@types/jsonfile": "^6.1.1", "@types/jsonwebtoken": "^9.0.7", "@types/jwk-to-pem": "^2.0.3", "@types/lodash": "^4.17.6", @@ -225,7 +223,6 @@ "maildev": "^2.1.0", "mockdate": "^3.0.5", "prettier": "^3.3.3", - "regenerator": "^0.14.10", "rimraf": "^5.0.5", "stripe-event-types": "^3.1.0", "supertest": "^6.3.3", @@ -236,8 +233,6 @@ "ts-node-dev": "^2.0.0", "type-fest": "^4.17.0", "typescript": "^5.4.5", - "webpack": "^4.46.0", - "webpack-cli": "^4.10.0", "worker-loader": "^2.0.0" }, "config": { From b8371afc9b7c79efe2a35528a11506fd009a8fe3 Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Fri, 22 Nov 2024 13:36:32 +0800 Subject: [PATCH 13/16] test(story): add chromatic story to ensure thankyou page renders (#7264) --- .../public-form/PublicFormPage.stories.tsx | 42 +++++++++++++++++++ .../src/mocks/msw/handlers/public-form.ts | 18 ++++++++ 2 files changed, 60 insertions(+) diff --git a/frontend/src/features/public-form/PublicFormPage.stories.tsx b/frontend/src/features/public-form/PublicFormPage.stories.tsx index 296d4504ee..987a598f85 100644 --- a/frontend/src/features/public-form/PublicFormPage.stories.tsx +++ b/frontend/src/features/public-form/PublicFormPage.stories.tsx @@ -15,6 +15,8 @@ import { envHandlers } from '~/mocks/msw/handlers/env' import { getPublicFormErrorResponse, getPublicFormResponse, + getPublicFormSubmissionSuccessResponse, + getPublicFormWithoutSectionsResponse, postGenerateVfnOtpResponse, postVerifyVfnOtpResponse, postVfnTransactionResponse, @@ -790,6 +792,7 @@ FormNotFoundMobile.parameters = { } export const WithMyInfo = Template.bind({}) +WithMyInfo.storyName = 'With MyInfo' WithMyInfo.parameters = { msw: [ getPublicFormResponse({ @@ -821,3 +824,42 @@ WithPayment.parameters = { ...DEFAULT_MSW_HANDLERS, ], } + +export const ThankYouPage = Template.bind({}) +ThankYouPage.parameters = { + msw: [ + getPublicFormWithoutSectionsResponse(), + getPublicFormSubmissionSuccessResponse(), + ...DEFAULT_MSW_HANDLERS, + ], +} +ThankYouPage.play = async ({ canvasElement }) => { + const canvas = within(canvasElement) + await waitFor(async () => { + await expect(canvas.getByText(/yes\/no/i)).toBeInTheDocument + }) + await waitFor(async () => { + const noQuestionChoice = canvas.getByRole('button', { + name: /1\. yes\/no no option, unselected/i, + }) + await userEvent.click(noQuestionChoice) + }) + await waitFor( + async () => { + await userEvent.click(canvas.getByRole('button', { name: /submit/i })) + }, + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await expect( + canvas.getByRole('link', { name: /submit another form/i }), + ).toBeInTheDocument() + }, + { + timeout: 5000, + }, + ) +} diff --git a/frontend/src/mocks/msw/handlers/public-form.ts b/frontend/src/mocks/msw/handlers/public-form.ts index ccecba1e9f..f400a5d524 100644 --- a/frontend/src/mocks/msw/handlers/public-form.ts +++ b/frontend/src/mocks/msw/handlers/public-form.ts @@ -486,6 +486,24 @@ export const getPublicFormWithoutSectionsResponse = ({ ) } +export const getPublicFormSubmissionSuccessResponse = ( + type: 'email' | 'storage' = 'email', +) => { + return rest.post( + `/api/v3/forms/:formId/submissions/${type}`, + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + message: 'Form submission successful.', + submissionId: '6625dfd68f4364af26332097', + timestamp: 1713758166140, + }), + ) + }, + ) +} + export const getPublicFormErrorResponse = ({ delay = 0, status = 404, From f15acda7339909f8b83eb2208dd88a164568186c Mon Sep 17 00:00:00 2001 From: Kevin Foong <55353265+kevin9foong@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:17:37 +0800 Subject: [PATCH 14/16] fix: trim text input before sending to backend (#7937) * fix: trim text input before sending to backend * fix: make comment more terse and fix typo * chore: use flow to prevent nested function calls --- .../public-form/PublicFormProvider.tsx | 89 ++++++++++++++----- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/frontend/src/features/public-form/PublicFormProvider.tsx b/frontend/src/features/public-form/PublicFormProvider.tsx index 53714f67af..79bd1f6b77 100644 --- a/frontend/src/features/public-form/PublicFormProvider.tsx +++ b/frontend/src/features/public-form/PublicFormProvider.tsx @@ -14,6 +14,7 @@ import { useDisclosure } from '@chakra-ui/react' import { datadogLogs } from '@datadog/browser-logs' import { useGrowthBook } from '@growthbook/growthbook-react' import { differenceInMilliseconds, isPast } from 'date-fns' +import { flow } from 'lodash' import get from 'lodash/get' import { @@ -123,6 +124,63 @@ export function useCommonFormProvider(formId: string) { } } +// Country/region data must be upper-case in backend for myinfo-countries compatibility, +// while displaying in title-case to users in the frontend. +// Hence, we need to map the frontend title-case to upper-case when submitting to backend. +const transformFormInputCountryRegionToUpperCase = + (form_fields: Array<{ fieldType: BasicField; _id: string }>) => + (formInputs: Record) => { + const countryRegionFieldIds = new Set( + form_fields + .filter((field) => field.fieldType === BasicField.CountryRegion) + .map((field) => field._id), + ) + + return Object.keys(formInputs).reduce( + (newFormInputs: typeof formInputs, fieldId) => { + const currentInput = formInputs[fieldId] + if ( + countryRegionFieldIds.has(fieldId) && + typeof currentInput === 'string' + ) { + newFormInputs[fieldId] = currentInput.toUpperCase() + } else { + newFormInputs[fieldId] = currentInput + } + return newFormInputs + }, + {}, + ) + } + +// Trim text inputs before sending to backend to match frontend validation +const transformFormInputTrimTextInputs = + (form_fields: Array<{ fieldType: BasicField; _id: string }>) => + (formInputs: Record) => { + const textFieldIds = new Set( + form_fields + .filter( + (field) => + field.fieldType === BasicField.ShortText || + field.fieldType === BasicField.LongText, + ) + .map((field) => field._id), + ) + + return Object.keys(formInputs).reduce( + (newFormInputs: typeof formInputs, fieldId) => { + const currentInput = formInputs[fieldId] + if (textFieldIds.has(fieldId) && typeof currentInput === 'string') { + newFormInputs[fieldId] = currentInput.trim() + } else { + newFormInputs[fieldId] = currentInput + } + return newFormInputs + }, + {}, + ) + } + export const PublicFormProvider = ({ formId, submissionId: previousSubmissionId, @@ -515,32 +573,15 @@ export const PublicFormProvider = ({ } } - const countryRegionFieldIds = new Set( - form.form_fields - .filter((field) => field.fieldType === BasicField.CountryRegion) - .map((field) => field._id), - ) - // We want users to see the country/region options in title-case but we also need the data in the backend to remain in upper-case. - // Country/region data in the backend needs to remain in upper-case so that they remain consistent with myinfo-countries. - const formInputsWithCountryRegionInUpperCase = Object.keys( - formInputs, - ).reduce((newFormInputs: typeof formInputs, fieldId) => { - const currentInput = formInputs[fieldId] - if ( - countryRegionFieldIds.has(fieldId) && - typeof currentInput === 'string' - ) { - newFormInputs[fieldId] = currentInput.toUpperCase() - } else { - newFormInputs[fieldId] = currentInput - } - return newFormInputs - }, {}) + const transformedFormInputs = flow([ + transformFormInputCountryRegionToUpperCase(form.form_fields), + transformFormInputTrimTextInputs(form.form_fields), + ])(formInputs) as typeof formInputs const formData = { formFields: form.form_fields, formLogics: form.form_logics, - formInputs: formInputsWithCountryRegionInUpperCase, + formInputs: transformedFormInputs, captchaResponse, captchaType, responseMetadata: { @@ -602,7 +643,7 @@ export const PublicFormProvider = ({ .mutateAsync( { ...formData, - formInputs: formInputsWithCountryRegionInUpperCase, + formInputs: transformedFormInputs, }, { onSuccess }, ) @@ -640,7 +681,7 @@ export const PublicFormProvider = ({ .mutateAsync( { ...formData, - formInputs: formInputsWithCountryRegionInUpperCase, + formInputs: transformedFormInputs, }, { onSuccess }, ) From 07a51972d15678ce7325407915ee2e0b6944f22b Mon Sep 17 00:00:00 2001 From: Kevin Foong <55353265+kevin9foong@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:21:58 +0800 Subject: [PATCH 15/16] feat(mrf): conditional routing (#7804) * feat: add cond routing type and modal to workflow builder * feat: add step 2 modal content * feat: add step 3 modal content * feat: add attachment box under radio button and fix modal interaction * feat: allow save conditional workflow step * feat: allow download of csv edit file * feat: set up fe component * feat: store optionsToFieldsMap in dropdown * feat: add be email routing for conditional routing * feat: move conditional field to main form and update modal to 2 step * feat: add be routing for conditional routing * feat: add spacing for cond routing, fix inactive state undefined error * feat: create endpoint for updating dropdown mapping * feat: update attachment state when singleselect changes * feat: add FE validation for CSV * feat: add validation at the workflow block * feat: update positioning of error message, modal copy and update fe cache * feat: use state instead of using the same form state * feat: implement download csv * feat: add error message to inactive step block * feat: add warning text to dropdown * fix: build errors * feat: clear error on button press and update error copy * feat: conditionally show dropdown edit warning if cond routing * fix: validation of options * feat: add warning in inactive step block for mismatched options * feat: add be validation for mapping * chore: remove stray console log * chore: remove step number from modal * chore: update error message copy * feat: add tc for validation * feat: add tc for conditional fetch email * feat: add tc for updating options mapping * chore: remove unused import * chore: add beta flag for cond routing * fix: move isDisabled to radiogroup to bypass undefined re-render issue * feat: add tc for edit step block * feat: active and inactive step block chromatic stories * feat: edit dropdown stories * feat: add stories for conditional routing option modal * chore: expose subroutine errors * chore: add field validation test * chore: remove unused prop * fix: reduce usage of watch to getValues, refactor variables * chore: move conditional-routing-example.png to the same folder as usage for colocation * fix: remove renderHook from stories which is not supported * fix: import image directly instead of using path * chore: refactor respondent block into smaller components * feat: move csv template parsing for header to common function * feat: add rationale for attaching mapping to field instead of step * chore: remove multiple string duplicates by shifting into getFileName function * feat: add trimming of email * feat: add trimming of email during validation * fix: display update error if no mapping for selected cond field * fix: cannot change respondent type bug * chore: add info logs if no target emails found * fix: remove word template from modal * fix: copy changes and bugs * feat: disable modal step 2 before csv template downloaded * fix: chromatic stories to reflect new changes * fix: prettier formatting * fix: add . to error message --------- Co-authored-by: Ken --- .../Button/NextAndBackButtonGroup.tsx | 55 +++ frontend/src/components/Button/index.ts | 1 + .../EditDropdown/EditDropdown.stories.tsx | 43 +- .../EditDropdown/EditDropdown.tsx | 19 + .../UpdateFormFieldService.ts | 23 +- .../mutations/useEditFormField.ts | 41 +- .../DeleteLogicModal/DeleteLogicModal.tsx | 4 +- .../InactiveLogicBlock/FieldLogicBadge.tsx | 2 +- .../CreatePageWorkflowTab.stories.tsx | 70 +++ .../DeleteStepModal/DeleteStepModal.tsx | 4 +- .../EditStepBlock/EditStepBlock.stories.tsx | 314 +++++++++++- .../EditStepBlock/EditStepBlock.tsx | 31 +- .../EditStepBlock/RespondentBlock.tsx | 258 ---------- .../ConditionalRoutingMappingDeleteModal.tsx | 46 ++ .../Components/ConditionalRoutingOption.tsx | 464 ++++++++++++++++++ .../ConditionalRoutingOptionModal.stories.tsx | 162 ++++++ .../ConditionalRoutingOptionModal.tsx | 278 +++++++++++ .../Components/DynamicRespondentOption.tsx | 86 ++++ .../Components/StaticRespondentOption.tsx | 87 ++++ .../RespondentBlock/Components/common.ts | 10 + .../conditional-routing-example.png | Bin 0 -> 47964 bytes .../RespondentBlock/Components/types.ts | 18 + .../RespondentBlock/RespondentBlock.tsx | 105 ++++ .../EditStepBlock/RespondentBlock/index.tsx | 1 + .../InactiveStepBlock/InactiveStepBlock.tsx | 43 +- .../workflow/hooks/useAdminFormWorkflow.ts | 13 + .../admin-form/create/workflow/mutations.ts | 6 +- .../admin-form/create/workflow/types.ts | 4 +- .../FormWhitelistAttachmentField.tsx | 2 +- .../SecretKeyDownloadWhitelistFileModal.tsx | 2 +- shared/constants/errors.ts | 17 +- shared/types/field/dropdownField.ts | 5 + shared/types/form/workflow.ts | 11 +- shared/types/user.ts | 1 + .../options-recipients-map-validation.spec.ts | 16 + .../options-recipients-map-validation.ts | 19 + src/app/models/field/dropdownField.ts | 1 + src/app/models/form.server.model.ts | 5 + .../form_workflow_step.server.schema.ts | 9 + src/app/models/user.server.model.ts | 1 + src/app/modules/core/core.errors.ts | 1 + .../__tests__/admin-form.service.spec.ts | 290 +++++++++++ .../form/admin-form/admin-form.controller.ts | 63 +++ .../form/admin-form/admin-form.middlewares.ts | 10 + .../form/admin-form/admin-form.service.ts | 162 +++++- src/app/modules/form/form.errors.ts | 6 + .../multirespondent-submission.utils.spec.ts | 211 ++++++++ .../multirespondent-submission.service.ts | 23 +- .../multirespondent-submission.utils.ts | 42 ++ .../v3/admin/forms/admin-forms.form.routes.ts | 5 + src/types/form_workflow_step.ts | 12 +- 51 files changed, 2804 insertions(+), 298 deletions(-) create mode 100644 frontend/src/components/Button/NextAndBackButtonGroup.tsx delete mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingMappingDeleteModal.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOption.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.stories.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/DynamicRespondentOption.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/StaticRespondentOption.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/common.ts create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/conditional-routing-example.png create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/types.ts create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/RespondentBlock.tsx create mode 100644 frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/index.tsx create mode 100644 shared/utils/__tests__/options-recipients-map-validation.spec.ts create mode 100644 shared/utils/options-recipients-map-validation.ts diff --git a/frontend/src/components/Button/NextAndBackButtonGroup.tsx b/frontend/src/components/Button/NextAndBackButtonGroup.tsx new file mode 100644 index 0000000000..b97cfb796a --- /dev/null +++ b/frontend/src/components/Button/NextAndBackButtonGroup.tsx @@ -0,0 +1,55 @@ +import { Stack } from '@chakra-ui/react' + +import { useIsMobile } from '~hooks/useIsMobile' + +import { Button } from './Button' + +interface NextAndBackButtonProps { + handleBack: () => void + handleNext: () => void + nextButtonLabel?: string + backButtonLabel?: string + isNextDisabled?: boolean + isBackDisabled?: boolean + nextButtonColorScheme?: 'danger' +} + +export const NextAndBackButtonGroup = ({ + handleBack, + handleNext, + nextButtonLabel = 'Next', + backButtonLabel = 'Back', + isNextDisabled = false, + isBackDisabled = false, + nextButtonColorScheme, +}: NextAndBackButtonProps): JSX.Element => { + const isMobile = useIsMobile() + + return ( + + + + + ) +} diff --git a/frontend/src/components/Button/index.ts b/frontend/src/components/Button/index.ts index 488da99022..1391d60646 100644 --- a/frontend/src/components/Button/index.ts +++ b/frontend/src/components/Button/index.ts @@ -1,2 +1,3 @@ export type { ButtonProps } from './Button' export { Button as default } from './Button' +export * from './NextAndBackButtonGroup' diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.stories.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.stories.tsx index f8c23f7795..a3c0c6195d 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.stories.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.stories.tsx @@ -1,6 +1,13 @@ import { Meta, StoryFn } from '@storybook/react' -import { BasicField, DropdownFieldBase } from '~shared/types' +import { + BasicField, + DropdownFieldBase, + FormFieldDto, + FormResponseMode, + FormWorkflowStepDto, + WorkflowType, +} from '~shared/types' import { createFormBuilderMocks } from '~/mocks/msw/handlers/admin-form' @@ -8,7 +15,9 @@ import { EditFieldDrawerDecorator, StoryRouter } from '~utils/storybook' import { EditDropdown } from './EditDropdown' -const DEFAULT_DROPDOWN_FIELD: DropdownFieldBase = { +const DEFAULT_DROPDOWN_FIELD: DropdownFieldBase & { + _id: FormFieldDto['_id'] +} = { title: 'Storybook Dropdown', description: 'Some description about Dropdown', required: true, @@ -16,6 +25,7 @@ const DEFAULT_DROPDOWN_FIELD: DropdownFieldBase = { fieldType: BasicField.Dropdown, fieldOptions: ['Option 1', 'Option 2', 'Option 3'], globalId: 'unused', + _id: 'dropdown_field_id', } export default { @@ -39,7 +49,9 @@ export default { } as Meta interface StoryArgs { - field: DropdownFieldBase + field: DropdownFieldBase & { + _id: FormFieldDto['_id'] + } } const Template: StoryFn = ({ field }) => { @@ -48,3 +60,28 @@ const Template: StoryFn = ({ field }) => { export const Default = Template.bind({}) Default.storyName = 'EditDropdown' + +const workflow_step_1: FormWorkflowStepDto = { + _id: '61e6857c9c794b0012f1c6f8', + workflow_type: WorkflowType.Static, + emails: [], + edit: [], +} + +const workflow_step_2: FormWorkflowStepDto = { + _id: '61e6857c9c794b0012f1c6f8', + workflow_type: WorkflowType.Conditional, + conditional_field: DEFAULT_DROPDOWN_FIELD._id, + edit: [], +} + +export const FieldUsedForConditionalRouting = Template.bind({}) +FieldUsedForConditionalRouting.parameters = { + msw: createFormBuilderMocks( + { + responseMode: FormResponseMode.Multirespondent, + workflow: [workflow_step_1, workflow_step_2], + }, + 0, + ), +} diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.tsx index 91e7a78999..6767c16486 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditDropdown/EditDropdown.tsx @@ -3,15 +3,18 @@ import { useTranslation } from 'react-i18next' import { FormControl } from '@chakra-ui/react' import { extend, pick } from 'lodash' +import { WorkflowType } from '~shared/types' import { DropdownFieldBase } from '~shared/types/field' import { createBaseValidationRules } from '~utils/fieldValidation' import FormErrorMessage from '~components/FormControl/FormErrorMessage' import FormLabel from '~components/FormControl/FormLabel' +import InlineMessage from '~components/InlineMessage' import Input from '~components/Input' import Textarea from '~components/Textarea' import Toggle from '~components/Toggle' +import { useAdminFormWorkflow } from '../../../../../../create/workflow/hooks/useAdminFormWorkflow' import { CreatePageDrawerContentContainer } from '../../../../../common' import { SPLIT_TEXTAREA_TRANSFORM, @@ -51,6 +54,7 @@ const transformDropdownEditFormToField = ( export const EditDropdown = ({ field }: EditDropdownProps): JSX.Element => { const { t } = useTranslation() + const { formWorkflow } = useAdminFormWorkflow() const { register, formState: { errors }, @@ -72,6 +76,14 @@ export const EditDropdown = ({ field }: EditDropdownProps): JSX.Element => { [], ) + const isFieldUsedForConditionalRouting = useMemo(() => { + return formWorkflow?.some( + (workflow) => + workflow.workflow_type === WorkflowType.Conditional && + workflow.conditional_field === field._id, + ) + }, [formWorkflow, field._id]) + return ( @@ -106,6 +118,13 @@ export const EditDropdown = ({ field }: EditDropdownProps): JSX.Element => { {errors?.fieldOptionsString?.message} + {isFieldUsedForConditionalRouting ? ( + + This field is linked to a step in your workflow. If you make any + changes, ensure that the options and emails are updated in your CSV + file. + + ) : null} => { + return ApiService.put( + `${ADMIN_FORM_ENDPOINT}/${formId}/fields/${fieldId}/options-to-recipients-map`, + { optionsToRecipientsMap }, + ) + .then(({ data }) => data) + .then(transformAllIsoStringsToDate) +} + /** * Reorders the field to the given new position. * @param formId the id of the form to perform the field reorder diff --git a/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts b/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts index f5104cd672..036b07c67c 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts +++ b/frontend/src/features/admin-form/create/builder-and-design/mutations/useEditFormField.ts @@ -3,14 +3,17 @@ import { useTranslation } from 'react-i18next' import { useMutation, useQueryClient } from 'react-query' import { useParams } from 'react-router-dom' -import { FormFieldDto } from '~shared/types/field' +import { DropdownFieldBase, FormFieldDto } from '~shared/types/field' import { AdminFormDto } from '~shared/types/form' import { useToast } from '~hooks/useToast' import { adminFormKeys } from '~features/admin-form/common/queries' -import { updateSingleFormField } from '../UpdateFormFieldService' +import { + updateOptionsToRecipientsMap, + updateSingleFormField, +} from '../UpdateFormFieldService' import { FieldBuilderState, fieldBuilderStateSelector, @@ -81,5 +84,39 @@ export const useEditFormField = () => { onError: handleError, }, ), + editOptionToRecipientsMutation: useMutation( + ({ + fieldId, + optionsToRecipientsMap, + }: { + fieldId: string + optionsToRecipientsMap: DropdownFieldBase['optionsToRecipientsMap'] + }) => { + return updateOptionsToRecipientsMap({ + formId, + fieldId, + optionsToRecipientsMap, + }) + }, + { + onSuccess: (newField: FormFieldDto) => { + toast.closeAll() + toast({ + description: 'Your options and emails have been saved.', + }) + queryClient.setQueryData(adminFormKey, (oldForm) => { + // Should not happen, should not be able to update field if there is no + // existing data. + if (!oldForm) throw new Error('Query should have been set') + const currentFieldIndex = oldForm.form_fields.findIndex( + (ff) => ff._id === newField._id, + ) + oldForm.form_fields[currentFieldIndex] = newField + return oldForm + }) + }, + onError: handleError, + }, + ), } } diff --git a/frontend/src/features/admin-form/create/logic/components/DeleteLogicModal/DeleteLogicModal.tsx b/frontend/src/features/admin-form/create/logic/components/DeleteLogicModal/DeleteLogicModal.tsx index 2b7e392486..b1657f4ee2 100644 --- a/frontend/src/features/admin-form/create/logic/components/DeleteLogicModal/DeleteLogicModal.tsx +++ b/frontend/src/features/admin-form/create/logic/components/DeleteLogicModal/DeleteLogicModal.tsx @@ -61,8 +61,8 @@ export const DeleteLogicModal = ({ Delete logic - Are you sure you want to delete this logic? This action is not - reversible. + Are you sure you want to delete this logic? This action cannot be + undone. diff --git a/frontend/src/features/admin-form/create/logic/components/LogicContent/InactiveLogicBlock/FieldLogicBadge.tsx b/frontend/src/features/admin-form/create/logic/components/LogicContent/InactiveLogicBlock/FieldLogicBadge.tsx index 9ce584bba6..bd5cdd564c 100644 --- a/frontend/src/features/admin-form/create/logic/components/LogicContent/InactiveLogicBlock/FieldLogicBadge.tsx +++ b/frontend/src/features/admin-form/create/logic/components/LogicContent/InactiveLogicBlock/FieldLogicBadge.tsx @@ -26,7 +26,7 @@ export const FieldLogicBadge = ({ field, defaults = { variant: 'error', - message: 'This field was deleted and has been removed from your workflow', + message: 'This field was deleted, please select another field', }, }: FieldLogicBadgeProps) => { const fieldMeta = useMemo( diff --git a/frontend/src/features/admin-form/create/workflow/CreatePageWorkflowTab.stories.tsx b/frontend/src/features/admin-form/create/workflow/CreatePageWorkflowTab.stories.tsx index d1842724c6..678d86e81a 100644 --- a/frontend/src/features/admin-form/create/workflow/CreatePageWorkflowTab.stories.tsx +++ b/frontend/src/features/admin-form/create/workflow/CreatePageWorkflowTab.stories.tsx @@ -124,6 +124,37 @@ const form_field_7: FormFieldDto = { _id: '61e6857c9c794b0012f1c6u9', } +const dropdown_field_valid_mapping: FormFieldDto = { + title: 'Department', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Dropdown, + fieldOptions: ['Engineering', 'Design', 'Operations', 'Product'], + optionsToRecipientsMap: { + Engineering: ['kevin@example.com'], + Design: ['alicia@example.com'], + Operations: ['ruchel@example.com'], + Product: ['kenneth@example.com'], + }, + _id: '6200e1534ad4f00012848d91', +} + +const dropdown_field_missing_options_mapping: FormFieldDto = { + title: 'Department', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Dropdown, + fieldOptions: ['Engineering', 'Design', 'Operations', 'Product'], + optionsToRecipientsMap: { + Engineering: ['kevin@example.com'], + Design: ['alicia@example.com'], + Operations: ['ruchel@example.com'], + }, + _id: '6200e1534ad4f00012848d92', +} + const workflow_step_1: FormWorkflowStepDto = { _id: '61e6857c9c794b0012f1c6f8', workflow_type: WorkflowType.Static, @@ -152,6 +183,21 @@ const workflow_step_2_with_all_fields_deleted: FormWorkflowStepDto = { edit: ['deleted_object_id_1', 'deleted_object_id_2'], } +const workflow_step_2_with_valid_conditional_recipient: FormWorkflowStepDto = { + _id: '61e6857c9c794b001ak3cnkl', + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_valid_mapping._id, + edit: [form_field_3._id, form_field_4._id], +} + +const workflow_step_2_with_invalid_conditional_recipient: FormWorkflowStepDto = + { + _id: '61e6857c9c794b001ak3cnkl', + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_missing_options_mapping._id, + edit: [form_field_3._id, form_field_4._id], + } + const workflow_step_3_with_approval: FormWorkflowStepDto = { _id: '61e6857c9c794b0012f1c6g2', workflow_type: WorkflowType.Dynamic, @@ -178,6 +224,8 @@ const FORM_WITH_WORKFLOW: Partial = { form_field_5, form_field_6, form_field_7, + dropdown_field_valid_mapping, + dropdown_field_missing_options_mapping, ], workflow: [workflow_step_1, workflow_step_2], } @@ -255,6 +303,28 @@ Step2AllFieldsDeleted.parameters = { }), } +export const Step2ValidConditionalRecipientSelected = Template.bind({}) +Step2ValidConditionalRecipientSelected.parameters = { + msw: buildMswRoutes({ + ...FORM_WITH_WORKFLOW, + workflow: [ + workflow_step_1, + workflow_step_2_with_valid_conditional_recipient, + ], + }), +} + +export const Step2InvalidConditionalRecipientSelected = Template.bind({}) +Step2InvalidConditionalRecipientSelected.parameters = { + msw: buildMswRoutes({ + ...FORM_WITH_WORKFLOW, + workflow: [ + workflow_step_1, + workflow_step_2_with_invalid_conditional_recipient, + ], + }), +} + export const Loading = Template.bind({}) Loading.parameters = { msw: buildMswRoutes({}, 'infinite'), diff --git a/frontend/src/features/admin-form/create/workflow/components/DeleteStepModal/DeleteStepModal.tsx b/frontend/src/features/admin-form/create/workflow/components/DeleteStepModal/DeleteStepModal.tsx index e85fffe4f9..75ec888fbf 100644 --- a/frontend/src/features/admin-form/create/workflow/components/DeleteStepModal/DeleteStepModal.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/DeleteStepModal/DeleteStepModal.tsx @@ -61,8 +61,8 @@ export const DeleteStepModal = ({ Delete step - Are you sure you want to delete this step? This action is not - reversible. + Are you sure you want to delete this step? This action cannot be + undone. diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.stories.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.stories.tsx index 1f586db932..0f0a646fa7 100644 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.stories.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.stories.tsx @@ -1,4 +1,4 @@ -import { expect, userEvent, waitFor, within } from '@storybook/test' +import { expect, screen, userEvent, waitFor, within } from '@storybook/test' import { BasicField, @@ -83,6 +83,47 @@ const form_field_5: FormFieldDto = { allowPrefill: false, } +const dropdown_field_no_mapping: FormFieldDto = { + title: 'Department', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Dropdown, + fieldOptions: ['Engineering', 'Design', 'Operations', 'Product'], + _id: '6200e1534ad4f00012848d90', +} + +const dropdown_field_valid_mapping: FormFieldDto = { + title: 'Department', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Dropdown, + fieldOptions: ['Engineering', 'Design', 'Operations', 'Product'], + optionsToRecipientsMap: { + Engineering: ['kevin@example.com'], + Design: ['alicia@example.com'], + Operations: ['ruchel@example.com'], + Product: ['kenneth@example.com'], + }, + _id: '6200e1534ad4f00012848d91', +} + +const dropdown_field_missing_options_mapping: FormFieldDto = { + title: 'Department', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Dropdown, + fieldOptions: ['Engineering', 'Design', 'Operations', 'Product'], + optionsToRecipientsMap: { + Engineering: ['kevin@example.com'], + Design: ['alicia@example.com'], + Operations: ['ruchel@example.com'], + }, + _id: '6200e1534ad4f00012848d92', +} + const mrfFormViewWithFields = [ getAdminFormView({ mode: FormResponseMode.Multirespondent, @@ -93,6 +134,9 @@ const mrfFormViewWithFields = [ form_field_3, form_field_4, form_field_5, + dropdown_field_no_mapping, + dropdown_field_valid_mapping, + dropdown_field_missing_options_mapping, ], }, }), @@ -178,9 +222,275 @@ export const Step2FixedEmailEmpty = { }, ) }, + args: { + stepNumber: 1, + }, +} + +export const Step2ConditionalRoutingEmpty = { + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + }, + args: { + stepNumber: 1, + }, +} + +export const Step2ConditionalRouting = { + // due to the double registration of 'workflow_type' there would be a weird interaction + // where the default value will be reset + // thus we have to manually select the field again + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + }, + args: { + stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_no_mapping._id, + }, + }, +} + +export const Step2ConditionalRoutingValidOptionsUploaded = { + // due to the double registration of 'workflow_type' there would be a weird interaction + // where the default value will be reset + // thus we have to manually select the field again + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + }, + args: { + stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_valid_mapping._id, + }, + }, +} + +export const Step2ConditionalRoutingDeleteWarningModal = { + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + const deleteButton = await canvas.getByLabelText('Click to remove file') + await userEvent.click(deleteButton) + }, + { timeout: 5000 }, + ) + // Assert the modal appears + await waitFor( + async () => { + expect(await screen.getByText('Delete CSV file')).toBeInTheDocument() + }, + { timeout: 5000 }, + ) + }, + args: { + stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_valid_mapping._id, + }, + }, +} + +export const Step2ConditionalRoutingInvalidOptionsUploadedErrorMessage = { + // due to the double registration of 'workflow_type' there would be a weird interaction + // where the default value will be reset + // thus we have to manually select the field again + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + }, + args: { + stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_missing_options_mapping._id, + }, + }, +} + +export const Step2ConditionalRoutingNoFieldSelectedErrorMessage = { + // due to the double registration of 'workflow_type' there would be a weird interaction + // where the default value will be reset + // thus we have to manually select the field again + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => + expect(await canvas.getByText('Save step')).not.toBeDisabled(), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + const saveStep = canvas.getByText('Save step') + expect(saveStep).not.toBeDisabled() + await userEvent.click(saveStep) + }, + { + timeout: 5000, + }, + ) + }, + args: { + stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + }, + }, +} +export const Step2ConditionalRoutingNoOptionsToReicipientsMapErrorMessage = { + // due to the double registration of 'workflow_type' there would be a weird interaction + // where the default value will be reset + // thus we have to manually select the field again + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { + const canvas = within(canvasElement) + await waitFor( + async () => await userEvent.click(canvas.getByText('Save step')), + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + await userEvent.click( + await canvas.getByText( + 'Emails assigned to options in a dropdown field', + ), + ) + }, + { + timeout: 5000, + }, + ) + await waitFor( + async () => { + const saveStep = canvas.getByText('Save step') + expect(saveStep).not.toBeDisabled() + await userEvent.click(saveStep) + }, + { + timeout: 5000, + }, + ) + }, args: { stepNumber: 1, + defaultValues: { + workflow_type: WorkflowType.Conditional, + conditional_field: dropdown_field_no_mapping._id, + }, }, } @@ -207,7 +517,7 @@ export const Step3AllSelectedValid = { args: { stepNumber: 2, defaultValues: { - workflow_type: WorkflowType.Dynamic, + workflow_type: WorkflowType.Static, field: form_field_4._id, edit: [form_field_1._id, form_field_5._id], approval_field: form_field_1._id, diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx index 55a4927911..17b519a200 100644 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/EditStepBlock.tsx @@ -2,7 +2,11 @@ import { useLayoutEffect, useRef } from 'react' import { useForm } from 'react-hook-form' import { Box, Divider, Stack } from '@chakra-ui/react' -import { FormWorkflowStep, WorkflowType } from '~shared/types' +import { + FormWorkflowStep, + FormWorkflowStepBase, + WorkflowType, +} from '~shared/types' import { SaveActionGroup } from '~features/admin-form/create/logic/components/LogicContent/EditLogicBlock/EditCondition' import { useUser } from '~features/user/queries' @@ -82,11 +86,19 @@ export const EditStepBlock = ({ }) } - let step: FormWorkflowStep + let step: FormWorkflowStep & { _id: string } + + const workflowStepBase: FormWorkflowStepBase & { _id: string } = { + _id: inputs._id, + workflow_type: inputs.workflow_type, + edit: inputs.edit, + approval_field: inputs.approval_field, + } + switch (inputs.workflow_type) { case WorkflowType.Static: { step = { - ...inputs, + ...workflowStepBase, // Need to explicitly set workflow_type in this object to help with typechecking. workflow_type: WorkflowType.Static, emails: inputs.emails ?? [], @@ -96,15 +108,22 @@ export const EditStepBlock = ({ case WorkflowType.Dynamic: { if (!inputs.field) return step = { - ...inputs, + ...workflowStepBase, workflow_type: WorkflowType.Dynamic, field: inputs.field, } break } + case WorkflowType.Conditional: { + if (!inputs.conditional_field) return + step = { + ...workflowStepBase, + workflow_type: WorkflowType.Conditional, + conditional_field: inputs.conditional_field, + } + break + } default: { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _: never = inputs.workflow_type throw new Error('Invalid workflow type') } } diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock.tsx deleted file mode 100644 index a376d090d1..0000000000 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock.tsx +++ /dev/null @@ -1,258 +0,0 @@ -import { Controller, UseFormReturn } from 'react-hook-form' -import { As, FormControl, Stack, Text } from '@chakra-ui/react' -import { get } from 'lodash' -import isEmail from 'validator/lib/isEmail' - -import { UserDto, WorkflowType } from '~shared/types' - -import { textStyles } from '~theme/textStyles' -import { SingleSelect } from '~components/Dropdown' -import FormErrorMessage from '~components/FormControl/FormErrorMessage' -import FormLabel from '~components/FormControl/FormLabel' -import Radio from '~components/Radio' -import { TagInput } from '~components/TagInput' - -import { BASICFIELD_TO_DRAWER_META } from '~features/admin-form/create/constants' -import { EditStepInputs } from '~features/admin-form/create/workflow/types' - -import { useAdminFormWorkflow } from '../../../hooks/useAdminFormWorkflow' -import { isFirstStepByStepNumber } from '../utils/isFirstStepByStepNumber' - -import { EditStepBlockContainer } from './EditStepBlockContainer' - -const WORKFLOW_TYPE_VALIDATION = { - required: 'Please select a respondent type', - validate: (value: WorkflowType) => { - if (![WorkflowType.Static, WorkflowType.Dynamic].includes(value)) { - return 'The selected respondent type is invalid' - } - }, -} - -interface RespondentOptionProps { - isLoading: boolean - formMethods: UseFormReturn - selectedWorkflowType: WorkflowType -} - -const StaticRespondentOption = ({ - isLoading, - formMethods, - selectedWorkflowType, -}: RespondentOptionProps) => { - const { - register, - control, - formState: { errors }, - } = formMethods - const staticTagInputErrorMessage = get(errors, 'emails.message') - - return ( - <> - - Specific email(s) - {selectedWorkflowType === WorkflowType.Static ? ( - - - !emails || emails.length === 0 - ? 'You must enter at least one email to receive responses' - : true, - isEmails: (emails) => - !emails || - emails.every((email) => isEmail(email)) || - 'Please enter valid email(s) (e.g. me@example.com) separated by commas, as invalid emails will not be saved', - }, - }} - render={({ field }) => ( - - )} - /> - {staticTagInputErrorMessage} - {!staticTagInputErrorMessage ? ( - - Separate multiple emails with a comma - - ) : null} - - ) : null} - - - ) -} - -interface DynamicRespondentOptionProps extends RespondentOptionProps { - emailFieldItems: { - label: string - value: string - icon?: As - }[] -} - -const DynamicRespondentOption = ({ - isLoading, - selectedWorkflowType, - formMethods, - emailFieldItems, -}: DynamicRespondentOptionProps) => { - const { - register, - formState: { errors }, - control, - } = formMethods - - return ( - <> - - An email field from the form - {selectedWorkflowType === WorkflowType.Dynamic ? ( - - { - return ( - isLoading || - !emailFieldItems || - emailFieldItems.some( - ({ value: fieldValue }) => fieldValue === selectedValue, - ) || - 'Field is not an email field' - ) - }, - }} - render={({ field: { value = '', ...rest } }) => ( - <> - - - )} - /> - {errors.field?.message} - - ) : null} - - - ) -} - -interface RespondentBlockProps { - stepNumber: number - isLoading: boolean - formMethods: UseFormReturn - user: UserDto | undefined -} - -export const RespondentBlock = ({ - stepNumber, - isLoading, - formMethods, -}: RespondentBlockProps): JSX.Element => { - const { - formState: { errors }, - watch, - } = formMethods - - const { emailFormFields = [] } = useAdminFormWorkflow() - - const emailFieldItems = emailFormFields.map( - ({ _id, questionNumber, title, fieldType }) => ({ - label: `${questionNumber}. ${title}`, - value: _id, - icon: BASICFIELD_TO_DRAWER_META[fieldType].icon, - }), - ) - - const selectedWorkflowType = watch('workflow_type') - - const isFirstStep = isFirstStepByStepNumber(stepNumber) - - return ( - - {isFirstStep ? ( - - Respondent in this step - Anyone who has access to your form - - ) : ( - - Select a respondent - - - - - - - {errors.workflow_type?.message} - - )} - - ) -} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingMappingDeleteModal.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingMappingDeleteModal.tsx new file mode 100644 index 0000000000..8b5b1c60fc --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingMappingDeleteModal.tsx @@ -0,0 +1,46 @@ +import { + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, +} from '@chakra-ui/react' + +import { NextAndBackButtonGroup } from '~components/Button/NextAndBackButtonGroup' + +interface ConditionalRoutingMappingDeleteModalProps { + isOpen: boolean + onClose: () => void + handleDelete: () => void +} + +export const ConditionalRoutingMappingDeleteModal = ({ + isOpen, + onClose, + handleDelete, +}: ConditionalRoutingMappingDeleteModalProps) => { + return ( + + + + + Delete CSV file + + Are you sure you want to delete this CSV file? This action cannot be + undone. + + + + + + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOption.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOption.tsx new file mode 100644 index 0000000000..53e32ff692 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOption.tsx @@ -0,0 +1,464 @@ +import { useEffect, useMemo, useState } from 'react' +import { Controller, useForm } from 'react-hook-form' +import { BiPlus } from 'react-icons/bi' +import { useParams } from 'react-router' +import { + Button, + FormControl, + Stack, + Text, + useDisclosure, +} from '@chakra-ui/react' +import Papa from 'papaparse' +import isEmail from 'validator/lib/isEmail' + +import { + CONDITIONAL_ROUTING_CSV_PARSE_ERROR_MESSAGE, + CONDITIONAL_ROUTING_DUPLICATE_OPTIONS_ERROR_MESSAGE, + CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE, + CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE, + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, +} from '~shared/constants/errors' +import { DropdownFieldBase, FormFieldDto, WorkflowType } from '~shared/types' +import { checkIsOptionsMismatched } from '~shared/utils/options-recipients-map-validation' + +import { parseCsvFileToCsvString } from '~utils/parseCsvFileToCsvString' +import { SingleSelect } from '~components/Dropdown' +import Attachment from '~components/Field/Attachment' +import { downloadFile } from '~components/Field/Attachment/utils/downloadFile' +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import Radio from '~components/Radio' + +import { useEditFormField } from '~features/admin-form/create/builder-and-design/mutations/useEditFormField' +import { BASICFIELD_TO_DRAWER_META } from '~features/admin-form/create/constants' +import { FormFieldWithQuestionNo } from '~features/form/types' + +import { WORKFLOW_TYPE_VALIDATION } from './common' +import { ConditionalRoutingMappingDeleteModal } from './ConditionalRoutingMappingDeleteModal' +import { ConditionalRoutingOptionModal } from './ConditionalRoutingOptionModal' +import { RespondentOptionProps } from './types' + +interface ConditionalRoutingOptionProps extends RespondentOptionProps { + conditionalFormFields: FormFieldWithQuestionNo< + FormFieldDto + >[] +} + +export interface ConditionalRoutingConfig { + csvFile: File | null +} + +/** + * Converts a CSV file into a string, validating that it has the required csv template file headers. + * @param csvFile - The CSV file to parse + * @returns A promise that resolves to the CSV content as a string + * @throws Error if CSV headers are invalid (must have 'Options' and 'Add emails in this column' columns) + */ +const parseCsvTemplateToString = async (csvFile: File) => + parseCsvFileToCsvString(csvFile, (headerRow) => { + return { + isValid: + headerRow && + headerRow.length === 2 && + headerRow[0] === 'Options' && + headerRow[1] === 'Add emails in this column', + invalidReason: + 'Your CSV file should only contain 2 columns with the headers "Options" and "Add emails in this column".', + } + }) + +const getFileName = ( + formId: string | undefined, + fieldTitle: string | undefined, +) => + `conditional_routing_form_${formId ?? ''}_field_${fieldTitle ?? ''}_mapping.csv` + +export const ConditionalRoutingOption = ({ + isLoading, + formMethods, + selectedWorkflowType, + conditionalFormFields, +}: ConditionalRoutingOptionProps) => { + const [isDeleteConfirmModalOpen, setIsDeleteConfirmModalOpen] = + useState(false) + const { + register, + control, + watch, + getValues, + formState: { errors }, + clearErrors, + } = formMethods + + const { formId } = useParams() + + const conditionalFieldItems = conditionalFormFields.map( + ({ _id, questionNumber, title, fieldType }) => ({ + label: `${questionNumber}. ${title}`, + value: _id, + icon: BASICFIELD_TO_DRAWER_META[fieldType].icon, + }), + ) + + const [csvFile, setCsvFile] = useState(null) + + const { + control: conditionalRoutingConfigControl, + formState: { errors: conditionalRoutingConfigErrors }, + watch: watchConditionalRoutingConfig, + handleSubmit, + } = useForm() + + const selectedConditionalFieldId = watch('conditional_field') + const selectedConditionalField = conditionalFormFields.find( + (field) => field._id === selectedConditionalFieldId, + ) + const isSelectedConditionalFieldFound = !!selectedConditionalField + const selectedConditionalFieldTitle = selectedConditionalField?.title + const selectedConditionalFieldOptionsToRecipientsMap = + selectedConditionalField?.optionsToRecipientsMap + + const isOptionsToRecipientsMapAttached = !!csvFile + + const standardCsvDownloadFileName = getFileName( + formId, + selectedConditionalFieldTitle, + ) + + const placeholderOptionToEmailMappingCsvFile = useMemo( + () => + ({ + name: standardCsvDownloadFileName, + type: 'text/csv', + }) as File, + [standardCsvDownloadFileName], + ) + + useEffect(() => { + if (selectedConditionalFieldOptionsToRecipientsMap) { + setCsvFile(placeholderOptionToEmailMappingCsvFile) + } else { + setCsvFile(null) + } + }, [ + setCsvFile, + placeholderOptionToEmailMappingCsvFile, + selectedConditionalFieldOptionsToRecipientsMap, + ]) + + const { isOpen, onOpen, onClose } = useDisclosure() + + const handleCsvDownload = () => { + if (!selectedConditionalFieldOptionsToRecipientsMap) return + const csvData = { + fields: ['Options', 'Add emails in this column'], + data: Object.entries(selectedConditionalFieldOptionsToRecipientsMap).map( + ([option, recipients]) => [option, recipients.join(',')], + ), + } + + const csvString = Papa.unparse(csvData, { + header: true, + delimiter: ',', + skipEmptyLines: 'greedy', + }) + const csvBlob = new Blob([csvString], { + type: 'text/csv', + }) + const csvFile = new File([csvBlob], standardCsvDownloadFileName, { + type: 'text/csv', + }) + downloadFile(csvFile) + } + + const handleSkeletonCsvDownload = + (formId: string = '') => + () => { + const getFieldOptions = (conditionalFieldId: string) => { + const conditionalField = conditionalFormFields.find( + (field) => field._id === conditionalFieldId, + ) + return conditionalField?.fieldOptions + } + const generateCsvContent = (fieldOptions: string[] | undefined) => { + const headerRow = ['Options', 'Add emails in this column'] + const optionsRows = fieldOptions?.map((field) => [field, '']) ?? [] + const jsonContent = [headerRow, ...optionsRows] + return Papa.unparse(jsonContent, { + header: true, + delimiter: ',', + }) + } + + const csvStringToFile = (csvString: string, downloadFileName: string) => { + const csvBlob = new Blob([csvString], { + type: 'text/csv', + }) + const csvFile = new File([csvBlob], downloadFileName, { + type: 'text/csv', + }) + return csvFile + } + + if (!selectedConditionalFieldId) return + + const fieldOptions = getFieldOptions(selectedConditionalFieldId) + const csvContent = generateCsvContent(fieldOptions) + const csvFile = csvStringToFile( + csvContent, + getFileName(formId, selectedConditionalFieldTitle), + ) + downloadFile(csvFile) + } + + const { editOptionToRecipientsMutation } = useEditFormField() + + const handleConditionalRoutingConfigSubmit = + (conditionalFieldId: string | undefined) => + async (data: ConditionalRoutingConfig) => { + if (!(data.csvFile && conditionalFieldId)) { + return + } + + const conditionalRoutingCsvString = await parseCsvTemplateToString( + data.csvFile, + ).catch(() => { + return null + }) + + if (!conditionalRoutingCsvString) return + const csvToOptionsToRecipientsMap = (csvString: string) => { + const csvRows = csvString.split('\r\n') + return csvRows.reduce((acc, row) => { + const [option, ...recipients] = row.split(',') + return { + ...acc, + [option]: recipients.map((email) => email.trim()), + } + }, {}) + } + + editOptionToRecipientsMutation.mutate( + { + fieldId: conditionalFieldId, + optionsToRecipientsMap: csvToOptionsToRecipientsMap( + conditionalRoutingCsvString, + ), + }, + { + onSuccess: () => { + setCsvFile(placeholderOptionToEmailMappingCsvFile) + clearErrors('conditional_field') + onClose() + }, + }, + ) + } + + const removeOptionsToRecipientsMapping = () => { + if (!selectedConditionalField) return + editOptionToRecipientsMutation.mutate( + { + fieldId: selectedConditionalField._id, + optionsToRecipientsMap: {}, + }, + { + onSuccess: () => { + setCsvFile(null) + setIsDeleteConfirmModalOpen(false) + }, + }, + ) + } + + const validateCsvOptionsWithFieldOptions = ( + optionsToRecipientsMapOptions: string[], + selectedConditionalFieldOptions: string[], + ) => { + if (optionsToRecipientsMapOptions.length <= 0) { + return + } + if ( + checkIsOptionsMismatched( + optionsToRecipientsMapOptions, + selectedConditionalFieldOptions, + ) + ) { + return CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE + } + } + + const validateOptionsToRecipientsMapErrorMessage = + validateCsvOptionsWithFieldOptions( + [...Object.keys(selectedConditionalFieldOptionsToRecipientsMap || {})], + selectedConditionalField?.fieldOptions || [], + ) + + const noEmailToOptionsMappingErrorMessage = + !selectedConditionalFieldOptionsToRecipientsMap + ? 'You must add emails to options before saving this step.' + : null + + const validateCsvFile = async ( + file: File | null, + ): Promise => { + if (!file) return 'Please upload a CSV file' + + let conditionalRoutingCsvString + try { + conditionalRoutingCsvString = await parseCsvTemplateToString(file) + } catch (error) { + if (error instanceof Error) { + return error.message + } + return CONDITIONAL_ROUTING_CSV_PARSE_ERROR_MESSAGE + } + + const options = conditionalRoutingCsvString.split('\r\n') + const optionsSet = new Set() + + for (const row of options) { + const [option, ...recipients] = row.split(',') + if (recipients.length <= 0 || !recipients[0] || !option) { + return CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE + } + if (recipients.some((recipient) => !isEmail(recipient.trim()))) { + return CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE + } + optionsSet.add(option) + } + + const selectedConditionalFieldOptions = + selectedConditionalField?.fieldOptions + + if (optionsSet.size < options.length) { + return CONDITIONAL_ROUTING_DUPLICATE_OPTIONS_ERROR_MESSAGE + } + + return validateCsvOptionsWithFieldOptions( + [...optionsSet], + selectedConditionalFieldOptions || [], + ) + } + + return ( + <> + setIsDeleteConfirmModalOpen(false)} + handleDelete={removeOptionsToRecipientsMapping} + /> + + + + Emails assigned to options in a dropdown field + {selectedWorkflowType === WorkflowType.Conditional ? ( + + + { + if (noEmailToOptionsMappingErrorMessage) { + return noEmailToOptionsMappingErrorMessage + } + if (validateOptionsToRecipientsMapErrorMessage) { + return validateOptionsToRecipientsMapErrorMessage + } + return ( + isLoading || + !conditionalFieldItems || + conditionalFieldItems.some( + ({ value: fieldValue }) => fieldValue === selectedValue, + ) || + 'Field is not an dropdown field' + ) + }, + }} + render={({ field: { value = '', ...rest } }) => ( + + )} + /> + {isSelectedConditionalFieldFound ? ( + isOptionsToRecipientsMapAttached ? ( + {}} + value={csvFile} + showDownload + showRemove + handleDownloadFileOverride={handleCsvDownload} + handleRemoveFileOverride={() => + setIsDeleteConfirmModalOpen(true) + } + accept={['.csv']} + /> + ) : ( + + ) + ) : null} + + + {validateOptionsToRecipientsMapErrorMessage || + errors.conditional_field?.message} + + + ) : null} + + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.stories.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.stories.tsx new file mode 100644 index 0000000000..f6da2ba005 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.stories.tsx @@ -0,0 +1,162 @@ +import { useForm } from 'react-hook-form' +import { expect, screen, userEvent, waitFor } from '@storybook/test' + +import { StoryRouter } from '~utils/storybook' + +import { ConditionalRoutingConfig } from './ConditionalRoutingOption' +import { + ConditionalRoutingOptionModal, + ConditionalRoutingOptionModalProps, +} from './ConditionalRoutingOptionModal' + +const ModalContainer = ({ + isOpen, + onClose, + errors, + onDownloadCsvClick, + onSubmit, + isSubmitDisabled, + validateCsvFile, + csvFile, +}: Omit & { + csvFile?: File | null +}) => { + const { control } = useForm({ + defaultValues: { + csvFile, + }, + }) + + return ( + + ) +} + +export default { + component: ModalContainer, + title: + 'Features/AdminForm/create/workflow/components/WorkflowContent/EditStepBlock/ConditionalRoutingOptionModal', + args: { + isOpen: true, + onClose: () => {}, + errors: {}, + onDownloadCsvClick: () => {}, + onSubmit: () => {}, + isSubmitDisabled: false, + validateCsvFile: async () => undefined, + }, + decorators: [StoryRouter({ initialEntries: ['/12345'], path: '/:formId' })], +} + +export const DownloadCsvTemplateStep = {} + +export const UploadCsvFileStep = { + play: async () => { + const downloadButton = screen.getByText('Download and edit CSV template') + const nextButton = screen.getByText('Next: Upload CSV file') + await waitFor( + async () => { + expect(downloadButton).not.toBeDisabled() + await userEvent.click(downloadButton) + }, + { timeout: 5000 }, + ) + await waitFor( + async () => { + expect(nextButton).not.toBeDisabled() + await userEvent.click(nextButton) + }, + { timeout: 5000 }, + ) + await waitFor( + async () => { + expect( + screen.getByText('Upload your completed CSV file'), + ).toBeInTheDocument() + }, + { timeout: 5000 }, + ) + }, +} + +export const UploadCsvFileStepWithAttachmentSelected = { + play: async () => { + const downloadButton = screen.getByText('Download and edit CSV template') + const nextButton = screen.getByText('Next: Upload CSV file') + await waitFor( + async () => { + expect(downloadButton).not.toBeDisabled() + await userEvent.click(downloadButton) + }, + { timeout: 5000 }, + ) + await waitFor( + async () => { + expect(nextButton).not.toBeDisabled() + await userEvent.click(nextButton) + }, + { timeout: 5000 }, + ) + + await waitFor( + async () => { + expect( + screen.getByText('Upload your completed CSV file'), + ).toBeInTheDocument() + }, + { timeout: 5000 }, + ) + }, + args: { + csvFile: new File([''], 'test.csv', { type: 'text/csv' }), + }, +} + +export const UploadCsvFileStepWithAttachmentSelectedDummyErrorMessage = { + play: async () => { + const downloadButton = screen.getByText('Download and edit CSV template') + const nextButton = screen.getByText('Next: Upload CSV file') + await waitFor( + async () => { + expect(downloadButton).not.toBeDisabled() + await userEvent.click(downloadButton) + }, + { timeout: 5000 }, + ) + await waitFor( + async () => { + expect(nextButton).not.toBeDisabled() + await userEvent.click(nextButton) + }, + { timeout: 5000 }, + ) + + await waitFor( + async () => { + expect( + screen.getByText('Upload your completed CSV file'), + ).toBeInTheDocument() + }, + { timeout: 5000 }, + ) + }, + args: { + csvFile: new File([''], 'test.csv', { type: 'text/csv' }), + errors: { + csvFile: { + message: 'Dummy error message', + }, + }, + }, +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.tsx new file mode 100644 index 0000000000..cf730ab720 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/ConditionalRoutingOptionModal.tsx @@ -0,0 +1,278 @@ +import { useState } from 'react' +import { Controller, FieldErrors, UseFormReturn } from 'react-hook-form' +import { BiDownload } from 'react-icons/bi' +import { + Box, + Button, + FormControl, + Image, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Stack, + Text, +} from '@chakra-ui/react' + +import { MAX_UPLOAD_FILE_SIZE } from '~shared/constants' + +import { useIsMobile } from '~hooks/useIsMobile' +import { NextAndBackButtonGroup } from '~components/Button' +import Attachment from '~components/Field/Attachment' +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import { ModalCloseButton } from '~components/Modal' +import { ProgressIndicator } from '~components/ProgressIndicator/ProgressIndicator' + +import CSV_TEMPLATE_EXAMPLE_IMAGE from './conditional-routing-example.png' +import { ConditionalRoutingConfig } from './ConditionalRoutingOption' +import { FieldItem } from './types' + +const NUM_STEPS = 2 + +interface StepOneModalContentProps { + stepNumber: number + setStepNumber: (step: number) => void + isMobile: boolean + onDownloadCsvClick: ConditionalRoutingOptionModalProps['onDownloadCsvClick'] + isCsvTemplateDownloaded: boolean + onClose: ConditionalRoutingOptionModalProps['onClose'] +} + +const StepOneModalContent = ({ + stepNumber, + setStepNumber, + isMobile, + onDownloadCsvClick, + isCsvTemplateDownloaded, + onClose, +}: StepOneModalContentProps) => { + return ( + + + + Add emails to options + { + if (selectedStepNumber > stepNumber && !isCsvTemplateDownloaded) { + return + } + setStepNumber(selectedStepNumber) + }} + /> + + + + + + + We have created a CSV template with the options from the field + you selected.{' '} + + Please download the CSV template and add the emails for each + option. + + + + + + + How to use the CSV template: + + + + Column A + + + This contains all the options from your field.{' '} + + Do not edit, reorder or delete anything in this column. + + + + + + Column B + + + Add the emails to send the form to for each option.{' '} + + Separate multiple email(s) with a comma. + + + + + + + + + Your CSV template should look like this + + + + + + setStepNumber(1)} + isNextDisabled={!isCsvTemplateDownloaded} + /> + + + ) +} + +interface StepTwoModalContentProps { + stepNumber: number + setStepNumber: (step: number) => void + control: ConditionalRoutingOptionModalProps['control'] + errors: ConditionalRoutingOptionModalProps['errors'] + onSubmit: ConditionalRoutingOptionModalProps['onSubmit'] + isSubmitDisabled: ConditionalRoutingOptionModalProps['isSubmitDisabled'] + validateCsvFile: ConditionalRoutingOptionModalProps['validateCsvFile'] +} + +const StepTwoModalContent = ({ + stepNumber, + setStepNumber, + control, + errors, + onSubmit, + isSubmitDisabled, + validateCsvFile, +}: StepTwoModalContentProps) => ( + + + + Upload your completed CSV file + + + + + Please ensure that your file is saved in{' '} + + comma-separated values (.csv) + {' '} + format. + + + ( + + )} + /> + {errors.csvFile?.message} + + + + setStepNumber(0)} + handleNext={onSubmit} + isNextDisabled={isSubmitDisabled} + /> + + +) + +export interface ConditionalRoutingOptionModalProps { + isOpen: boolean + onClose: () => void + conditionalFieldItems: FieldItem[] + isLoading: boolean + control: UseFormReturn['control'] + errors: FieldErrors + onDownloadCsvClick: () => void + onSubmit: () => void + isSubmitDisabled: boolean + validateCsvFile: (value: File | null) => Promise +} + +export const ConditionalRoutingOptionModal = ({ + isOpen, + onClose, + control, + errors, + onDownloadCsvClick, + onSubmit, + isSubmitDisabled, + validateCsvFile, +}: ConditionalRoutingOptionModalProps): JSX.Element => { + const isMobile = useIsMobile() + + const [stepNumber, setStepNumber] = useState(0) + const [isCsvTemplateDownloaded, setIsCsvTemplateDownloaded] = useState(false) + + const onModalClose = () => { + setStepNumber(0) + onClose() + } + + return ( + + + {stepNumber === 0 && ( + { + onDownloadCsvClick() + setIsCsvTemplateDownloaded(true) + }} + isCsvTemplateDownloaded={isCsvTemplateDownloaded} + onClose={onModalClose} + /> + )} + {stepNumber === 1 && ( + + )} + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/DynamicRespondentOption.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/DynamicRespondentOption.tsx new file mode 100644 index 0000000000..c562f3e620 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/DynamicRespondentOption.tsx @@ -0,0 +1,86 @@ +import { Controller } from 'react-hook-form' +import { FormControl, Text } from '@chakra-ui/react' + +import { WorkflowType } from '~shared/types' + +import { SingleSelect } from '~components/Dropdown' +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import Radio from '~components/Radio' + +import { WORKFLOW_TYPE_VALIDATION } from './common' +import { FieldItem, RespondentOptionProps } from './types' + +interface DynamicRespondentOptionProps extends RespondentOptionProps { + emailFieldItems: FieldItem[] +} + +export const DynamicRespondentOption = ({ + isLoading, + selectedWorkflowType, + formMethods, + emailFieldItems, +}: DynamicRespondentOptionProps) => { + const { + register, + formState: { errors }, + control, + } = formMethods + + return ( + <> + + An email field from the form + {selectedWorkflowType === WorkflowType.Dynamic ? ( + + { + return ( + isLoading || + !emailFieldItems || + emailFieldItems.some( + ({ value: fieldValue }) => fieldValue === selectedValue, + ) || + 'Field is not an email field' + ) + }, + }} + render={({ field: { value = '', ...rest } }) => ( + + )} + /> + {errors.field?.message} + + ) : null} + + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/StaticRespondentOption.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/StaticRespondentOption.tsx new file mode 100644 index 0000000000..6afdfde9a2 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/StaticRespondentOption.tsx @@ -0,0 +1,87 @@ +import { Controller } from 'react-hook-form' +import { FormControl, Text } from '@chakra-ui/react' +import { get } from 'lodash' +import isEmail from 'validator/lib/isEmail' + +import { WorkflowType } from '~shared/types' + +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import Radio from '~components/Radio' +import { TagInput } from '~components/TagInput' + +import { WORKFLOW_TYPE_VALIDATION } from './common' +import { RespondentOptionProps } from './types' + +export const StaticRespondentOption = ({ + isLoading, + formMethods, + selectedWorkflowType, +}: RespondentOptionProps) => { + const { + register, + control, + formState: { errors }, + } = formMethods + const staticTagInputErrorMessage = get(errors, 'emails.message') + + return ( + <> + + Specific email(s) + {selectedWorkflowType === WorkflowType.Static ? ( + + + !emails || emails.length === 0 + ? 'You must enter at least one email to receive responses' + : true, + isEmails: (emails) => + !emails || + emails.every((email) => isEmail(email)) || + 'Please enter valid email(s) (e.g. me@example.com) separated by commas, as invalid emails will not be saved', + }, + }} + render={({ field }) => ( + + )} + /> + {staticTagInputErrorMessage} + {!staticTagInputErrorMessage ? ( + + Separate multiple emails with a comma + + ) : null} + + ) : null} + + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/common.ts b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/common.ts new file mode 100644 index 0000000000..6b7fc79225 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/common.ts @@ -0,0 +1,10 @@ +import { WorkflowType } from '~shared/types/form/workflow' + +export const WORKFLOW_TYPE_VALIDATION = { + required: 'Please select a respondent type', + validate: (value: WorkflowType) => { + if (!Object.values(WorkflowType).includes(value)) { + return 'The selected respondent type is invalid' + } + }, +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/conditional-routing-example.png b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/conditional-routing-example.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe884cc8bcd9848e2416432663bc52007ebe872 GIT binary patch literal 47964 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 literal 0 HcmV?d00001 diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/types.ts b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/types.ts new file mode 100644 index 0000000000..8a2fb480de --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/Components/types.ts @@ -0,0 +1,18 @@ +import { UseFormReturn } from 'react-hook-form' +import { As } from '@chakra-ui/react' + +import { WorkflowType } from '~shared/types/form/workflow' + +import { EditStepInputs } from '~features/admin-form/create/workflow/types' + +export interface RespondentOptionProps { + isLoading: boolean + formMethods: UseFormReturn + selectedWorkflowType: WorkflowType +} + +export interface FieldItem { + label: string + value: string + icon?: As +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/RespondentBlock.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/RespondentBlock.tsx new file mode 100644 index 0000000000..ee1b32cb4c --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/RespondentBlock.tsx @@ -0,0 +1,105 @@ +import { UseFormReturn } from 'react-hook-form' +import { FormControl, Stack, Text } from '@chakra-ui/react' + +import { UserDto } from '~shared/types' + +import { textStyles } from '~theme/textStyles' +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import FormLabel from '~components/FormControl/FormLabel' +import Radio from '~components/Radio' + +import { BASICFIELD_TO_DRAWER_META } from '~features/admin-form/create/constants' +import { EditStepInputs } from '~features/admin-form/create/workflow/types' +import { useUser } from '~features/user/queries' + +import { useAdminFormWorkflow } from '../../../../hooks/useAdminFormWorkflow' +import { isFirstStepByStepNumber } from '../../utils/isFirstStepByStepNumber' +import { EditStepBlockContainer } from '../EditStepBlockContainer' + +import { ConditionalRoutingOption } from './Components/ConditionalRoutingOption' +import { DynamicRespondentOption } from './Components/DynamicRespondentOption' +import { StaticRespondentOption } from './Components/StaticRespondentOption' + +interface RespondentBlockProps { + stepNumber: number + isLoading: boolean + formMethods: UseFormReturn + user: UserDto | undefined +} + +export const RespondentBlock = ({ + stepNumber, + isLoading, + formMethods, +}: RespondentBlockProps): JSX.Element => { + const { + formState: { errors }, + watch, + } = formMethods + + // TODO (MRF-Conditional-Routing): Remove isTest and user/useUser when conditional routing is out of beta + const { user } = useUser() + const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test' + + const { emailFormFields = [], dropdownFormFields = [] } = + useAdminFormWorkflow() + + const emailFieldItems = emailFormFields.map( + ({ _id, questionNumber, title, fieldType }) => ({ + label: `${questionNumber}. ${title}`, + value: _id, + icon: BASICFIELD_TO_DRAWER_META[fieldType].icon, + }), + ) + + const selectedWorkflowType = watch('workflow_type') + + const isFirstStep = isFirstStepByStepNumber(stepNumber) + + return ( + + {isFirstStep ? ( + + Respondent in this step + Anyone who has access to your form + + ) : ( + + Select a respondent + + + + + {/* TODO (MRF-Conditional-Routing): Remove isTest and user check when + conditional routing is out of beta */} + {isTest || user?.betaFlags?.mrfConditionalRouting ? ( + <> + + + ) : null} + + + {errors.workflow_type?.message} + + )} + + ) +} diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/index.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/index.tsx new file mode 100644 index 0000000000..5edd75c0f1 --- /dev/null +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/EditStepBlock/RespondentBlock/index.tsx @@ -0,0 +1 @@ +export { RespondentBlock } from './RespondentBlock' diff --git a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/InactiveStepBlock/InactiveStepBlock.tsx b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/InactiveStepBlock/InactiveStepBlock.tsx index 15b7419093..850b24f257 100644 --- a/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/InactiveStepBlock/InactiveStepBlock.tsx +++ b/frontend/src/features/admin-form/create/workflow/components/WorkflowContent/InactiveStepBlock/InactiveStepBlock.tsx @@ -3,8 +3,9 @@ import { BiPencil } from 'react-icons/bi' import { Box, chakra, Flex, Stack, Text } from '@chakra-ui/react' import { Dictionary } from 'lodash' -import { FormField } from '~shared/types' +import { BasicField, FormField } from '~shared/types' import { FormWorkflowStepDto, WorkflowType } from '~shared/types/form' +import { checkIsOptionsMismatched } from '~shared/utils/options-recipients-map-validation' import IconButton from '~components/IconButton' @@ -48,6 +49,43 @@ const SubsequentStepRespondentBadges = ({ ) case WorkflowType.Dynamic: return + case WorkflowType.Conditional: { + const selectedConditionalField = idToFieldMap[step.conditional_field] + if ( + !selectedConditionalField || + selectedConditionalField.fieldType !== BasicField.Dropdown + ) { + return + } + const selectedConditionalFieldOptions = + selectedConditionalField.fieldOptions + const optionsToRecipientsMapOptions = Object.keys( + selectedConditionalField.optionsToRecipientsMap || {}, + ) + const isOptionsMismatched = checkIsOptionsMismatched( + optionsToRecipientsMapOptions, + selectedConditionalFieldOptions, + ) + return ( + + + {isOptionsMismatched ? ( + + ) : null} + + ) + } default: { // eslint-disable-next-line @typescript-eslint/no-unused-vars const _: never = step @@ -108,8 +146,7 @@ export const InactiveStepBlock = ({ field={idToFieldMap[fieldId]} defaults={{ variant: 'info', - message: - 'This field was deleted and has been removed from your workflow', + message: 'This field was deleted, please select another field', }} /> )) diff --git a/frontend/src/features/admin-form/create/workflow/hooks/useAdminFormWorkflow.ts b/frontend/src/features/admin-form/create/workflow/hooks/useAdminFormWorkflow.ts index 3434f1e13f..b8bbc7ded2 100644 --- a/frontend/src/features/admin-form/create/workflow/hooks/useAdminFormWorkflow.ts +++ b/frontend/src/features/admin-form/create/workflow/hooks/useAdminFormWorkflow.ts @@ -3,6 +3,7 @@ import { keyBy } from 'lodash' import { BasicField, + DropdownFieldBase, EmailFieldBase, FormFieldDto, FormResponseMode, @@ -48,6 +49,17 @@ export const useAdminFormWorkflow = () => { [augmentedFormFields], ) + const dropdownFormFields = useMemo( + () => + augmentedFormFields.filter( + ( + field, + ): field is FormFieldWithQuestionNo> => + field.fieldType === BasicField.Dropdown, + ), + [augmentedFormFields], + ) + const formWorkflow = form?.responseMode === FormResponseMode.Multirespondent ? form.workflow @@ -60,5 +72,6 @@ export const useAdminFormWorkflow = () => { idToFieldMap, emailFormFields, yesNoFormFields, + dropdownFormFields, } } diff --git a/frontend/src/features/admin-form/create/workflow/mutations.ts b/frontend/src/features/admin-form/create/workflow/mutations.ts index 06e20ae440..86153f605b 100644 --- a/frontend/src/features/admin-form/create/workflow/mutations.ts +++ b/frontend/src/features/admin-form/create/workflow/mutations.ts @@ -114,5 +114,9 @@ export const useWorkflowMutations = () => { }, ) - return { createStepMutation, deleteStepMutation, updateStepMutation } + return { + createStepMutation, + deleteStepMutation, + updateStepMutation, + } } diff --git a/frontend/src/features/admin-form/create/workflow/types.ts b/frontend/src/features/admin-form/create/workflow/types.ts index 68e2eba413..4998bb1e19 100644 --- a/frontend/src/features/admin-form/create/workflow/types.ts +++ b/frontend/src/features/admin-form/create/workflow/types.ts @@ -11,9 +11,11 @@ export enum AdminEditWorkflowState { EditingStep, } -export type EditStepInputs = Omit & { +export type EditStepInputs = FormWorkflowStep & { + _id: string workflow_type: WorkflowType emails?: FormWorkflowStepStatic['emails'] field?: FormWorkflowStepDynamic['field'] approval_field?: FormFieldDto['_id'] + conditional_field?: FormFieldDto['_id'] } diff --git a/frontend/src/features/admin-form/settings/components/AuthSettingsSection/FormWhitelistAttachmentField.tsx b/frontend/src/features/admin-form/settings/components/AuthSettingsSection/FormWhitelistAttachmentField.tsx index 7a9ec94bc2..edaf41c44a 100644 --- a/frontend/src/features/admin-form/settings/components/AuthSettingsSection/FormWhitelistAttachmentField.tsx +++ b/frontend/src/features/admin-form/settings/components/AuthSettingsSection/FormWhitelistAttachmentField.tsx @@ -109,7 +109,7 @@ export const FormWhitelistAttachmentField = ({ headerRow[0].replace(/(\r\n|\n|\r)/gm, '').toLowerCase() === 'respondent', invalidReason: - 'Your CSV file should only contain a single column with the "Respondent" header.', + 'Your CSV file should only contain a single column with the header "Respondent".', } }) diff --git a/frontend/src/features/admin-form/settings/components/AuthSettingsSection/SecretKeyDownloadWhitelistFileModal.tsx b/frontend/src/features/admin-form/settings/components/AuthSettingsSection/SecretKeyDownloadWhitelistFileModal.tsx index 344f0c9e0c..d5d54bd75a 100644 --- a/frontend/src/features/admin-form/settings/components/AuthSettingsSection/SecretKeyDownloadWhitelistFileModal.tsx +++ b/frontend/src/features/admin-form/settings/components/AuthSettingsSection/SecretKeyDownloadWhitelistFileModal.tsx @@ -130,7 +130,7 @@ export const SecretKeyDownloadWhitelistFileModal = ({ onClose={onClose} isOpen={isOpen} publicKey={publicKey} - modalActionText=" Download CSV file of whitelisted NRIC/FIN/UEN(s)" + modalActionText="Download CSV file of whitelisted NRIC/FIN/UEN(s)" submitButtonText="Download file" hasAck={false} /> diff --git a/shared/constants/errors.ts b/shared/constants/errors.ts index dae6390895..cbaf35133d 100644 --- a/shared/constants/errors.ts +++ b/shared/constants/errors.ts @@ -20,6 +20,21 @@ export const FORM_WHITELIST_SETTING_CONTAINS_DUPLICATES_ERROR_MESSAGE = export const FORM_WHITELIST_SETTING_CONTAINS_INVALID_FORMAT_SUBMITTERID_ERROR_MESSAGE = (exampleInvalidSubmitterId: string) => - `Your CSV contains NRIC/FIN/UEN(s) that are not in the correct format. (e.g, ${exampleInvalidSubmitterId})` + `Your CSV contains NRIC/FIN/UEN(s) that are not in the correct format (e.g, ${exampleInvalidSubmitterId}).` export const FORM_WHITELIST_CONTAINS_EMPTY_ROWS_ERROR_MESSAGE = `Your CSV contains empty row(s).` + +export const CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE = + 'The options in your CSV file and selected field do not match.' + +export const CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE = + 'There are missing options and/or emails in your CSV file.' + +export const CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE = + 'Your CSV file contains entries that are not in the correct format.' + +export const CONDITIONAL_ROUTING_DUPLICATE_OPTIONS_ERROR_MESSAGE = + 'There are contains duplicate options in your CSV file.' + +export const CONDITIONAL_ROUTING_CSV_PARSE_ERROR_MESSAGE = + 'An error occurred when parsing your CSV file.' diff --git a/shared/types/field/dropdownField.ts b/shared/types/field/dropdownField.ts index c13675dd31..380af1d58a 100644 --- a/shared/types/field/dropdownField.ts +++ b/shared/types/field/dropdownField.ts @@ -3,4 +3,9 @@ import { BasicField, MyInfoableFieldBase } from './base' export interface DropdownFieldBase extends MyInfoableFieldBase { fieldType: BasicField.Dropdown fieldOptions: string[] + // Note: `optionsToRecipientsMap` is attached to the field instead of MRF workflow step to: + // 1. Allow immediate assignment without requiring step creation + // (since step might not be created yet at the point of map assignment, leading to UX issues) + // 2. Prevent orphaned mappings if field is deleted + optionsToRecipientsMap?: Record } diff --git a/shared/types/form/workflow.ts b/shared/types/form/workflow.ts index a317eb24f4..bc3846dee5 100644 --- a/shared/types/form/workflow.ts +++ b/shared/types/form/workflow.ts @@ -3,6 +3,7 @@ import { FormFieldDto } from '../field' export enum WorkflowType { Static = 'static', Dynamic = 'dynamic', + Conditional = 'conditional', } export interface FormWorkflowStepBase { @@ -21,7 +22,15 @@ export interface FormWorkflowStepDynamic extends FormWorkflowStepBase { field: FormFieldDto['_id'] } -export type FormWorkflowStep = FormWorkflowStepStatic | FormWorkflowStepDynamic +export interface FormWorkflowStepConditional extends FormWorkflowStepBase { + workflow_type: WorkflowType.Conditional + conditional_field: FormFieldDto['_id'] +} + +export type FormWorkflowStep = + | FormWorkflowStepStatic + | FormWorkflowStepDynamic + | FormWorkflowStepConditional export type FormWorkflow = Array diff --git a/shared/types/user.ts b/shared/types/user.ts index 6def658b50..e1622d89a2 100644 --- a/shared/types/user.ts +++ b/shared/types/user.ts @@ -23,6 +23,7 @@ export const UserBase = z.object({ postmanSms: z.boolean().optional(), mrfEmailNotifications: z.boolean().optional(), // Previously used for MRF email notifications, not currently used mrfAdminSubmissionKey: z.boolean().optional(), + mrfConditionalRouting: z.boolean().optional(), mfb: z.boolean().optional(), }) .optional(), diff --git a/shared/utils/__tests__/options-recipients-map-validation.spec.ts b/shared/utils/__tests__/options-recipients-map-validation.spec.ts new file mode 100644 index 0000000000..9c994b51dc --- /dev/null +++ b/shared/utils/__tests__/options-recipients-map-validation.spec.ts @@ -0,0 +1,16 @@ +import { checkIsOptionsMismatched } from '../options-recipients-map-validation' + +describe('checkIsOptionsMismatched', () => { + it('should return true if options have intersection but mismatched', () => { + expect(checkIsOptionsMismatched(['a', 'b'], ['b', 'c'])).toBe(true) + }) + it('should return true if options in csv are missing from selected field', () => { + expect(checkIsOptionsMismatched(['a', 'b'], ['b'])).toBe(true) + }) + it('should return true if options in selected field are missing from csv', () => { + expect(checkIsOptionsMismatched(['a', 'b'], ['a', 'b', 'c'])).toBe(true) + }) + it('should return false if options are exactly the same', () => { + expect(checkIsOptionsMismatched(['a', 'b'], ['a', 'b'])).toBe(false) + }) +}) diff --git a/shared/utils/options-recipients-map-validation.ts b/shared/utils/options-recipients-map-validation.ts new file mode 100644 index 0000000000..88aad5ecf2 --- /dev/null +++ b/shared/utils/options-recipients-map-validation.ts @@ -0,0 +1,19 @@ +const checkMissingElement = (actual: string[], expected: Set) => { + return actual.some((option) => !expected.has(option)) +} + +export const checkIsOptionsMismatched = ( + optionsToRecipientsMapOptions: string[], + selectedConditionalFieldOptions: string[], +) => { + return ( + checkMissingElement( + optionsToRecipientsMapOptions, + new Set(selectedConditionalFieldOptions), + ) || + checkMissingElement( + selectedConditionalFieldOptions, + new Set(optionsToRecipientsMapOptions), + ) + ) +} diff --git a/src/app/models/field/dropdownField.ts b/src/app/models/field/dropdownField.ts index 2732902c96..76c68384d7 100644 --- a/src/app/models/field/dropdownField.ts +++ b/src/app/models/field/dropdownField.ts @@ -7,6 +7,7 @@ import { MyInfoSchema } from './baseField' const createDropdownFieldSchema = () => { return new Schema({ fieldOptions: [String], + optionsToRecipientsMap: { type: Object, of: [String] }, myInfo: MyInfoSchema, }) } diff --git a/src/app/models/form.server.model.ts b/src/app/models/form.server.model.ts index 2678165ba0..af03450619 100644 --- a/src/app/models/form.server.model.ts +++ b/src/app/models/form.server.model.ts @@ -111,6 +111,7 @@ import LogicSchema, { import { CustomFormLogoSchema, FormLogoSchema } from './form_logo.server.schema' import { FORM_WHITELISTED_SUBMITTER_IDS_ID } from './form_whitelist.server.model' import WorkflowStepSchema, { + WorkflowStepConditionalSchema, WorkflowStepDynamicSchema, WorkflowStepStaticSchema, } from './form_workflow_step.server.schema' @@ -398,6 +399,10 @@ MultirespondentFormWorkflowPath.discriminator( WorkflowType.Dynamic, WorkflowStepDynamicSchema, ) +MultirespondentFormWorkflowPath.discriminator( + WorkflowType.Conditional, + WorkflowStepConditionalSchema, +) const compileFormModel = (db: Mongoose): IFormModel => { const User = getUserModel(db) diff --git a/src/app/models/form_workflow_step.server.schema.ts b/src/app/models/form_workflow_step.server.schema.ts index bf84c557d8..a4b91b72d6 100644 --- a/src/app/models/form_workflow_step.server.schema.ts +++ b/src/app/models/form_workflow_step.server.schema.ts @@ -3,6 +3,7 @@ import validator from 'validator' import { WorkflowType } from '../../../shared/types' import { + IWorkflowStepConditionalSchema, IWorkflowStepDynamicSchema, IWorkflowStepSchema, IWorkflowStepStaticSchema, @@ -60,4 +61,12 @@ export const WorkflowStepDynamicSchema = new Schema( }, ) +export const WorkflowStepConditionalSchema = + new Schema({ + conditional_field: { + type: Schema.Types.ObjectId, + required: true, + }, + }) + export default WorkflowStepSchema diff --git a/src/app/models/user.server.model.ts b/src/app/models/user.server.model.ts index e3fed82425..d4c1447c4d 100644 --- a/src/app/models/user.server.model.ts +++ b/src/app/models/user.server.model.ts @@ -77,6 +77,7 @@ const compileUserModel = (db: Mongoose) => { postmanSms: Boolean, mrfEmailNotifications: Boolean, // Previously used for MRF email notifications, not currently used mrfAdminSubmissionKey: Boolean, + mrfConditionalRouting: Boolean, mfb: Boolean, }, flags: { diff --git a/src/app/modules/core/core.errors.ts b/src/app/modules/core/core.errors.ts index 3f114767e9..f412756124 100644 --- a/src/app/modules/core/core.errors.ts +++ b/src/app/modules/core/core.errors.ts @@ -27,6 +27,7 @@ export enum ErrorCodes { FORM_RESPONDENT_NOT_WHITELISTED = 100008, FORM_RESPONDENT_SINGLE_SUBMISSION_VALIDATION_FAILED = 100009, FORM_UNEXPECTED_WHITELIST_SETTING_NOT_FOUND = 100010, + FORM_INVALID_RESPONSE_MODE = 100011, // [100100 - 100199] Admin Form Errors (/modules/form/admin-form) ADMIN_FORM_INVALID_FILE_TYPE = 100100, ADMIN_FORM_EDIT_FIELD = 100101, diff --git a/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts b/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts index 27954370f6..77a3c609b8 100644 --- a/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts +++ b/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts @@ -46,6 +46,9 @@ import { import { EditFormFieldParams } from 'src/types/api' import { + CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE, + CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE, + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, FORM_WHITELIST_CONTAINS_EMPTY_ROWS_ERROR_MESSAGE, FORM_WHITELIST_SETTING_CONTAINS_DUPLICATES_ERROR_MESSAGE, FORM_WHITELIST_SETTING_CONTAINS_INVALID_FORMAT_SUBMITTERID_ERROR_MESSAGE, @@ -3072,4 +3075,291 @@ describe('admin-form.service', () => { ) }) }) + + describe('updateOptionsToRecipientsMap', () => { + describe('validation of field', () => { + it('should return error if field is not a dropdown field', async () => { + // Arrange + const mockFormFields = [ + { + _id: 'fieldId', + fieldType: BasicField.ShortText, + }, + ] + const mockForm = { + _id: 'formId', + form_fields: mockFormFields, + updateFormFieldById: jest.fn().mockResolvedValue({ + form_fields: [mockFormFields], + }), + } as unknown as IPopulatedForm + + const optionsMap = {} + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + optionsMap, + ) + + // Assert + expect(result.isErr()).toBe(true) + expect(result._unsafeUnwrapErr()).toBeInstanceOf(EditFieldError) + }) + + it('should allow operation if field is a dropdown field', async () => { + // Arrange + const mockFormFields = [ + { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + toObject: jest.fn().mockReturnValue({ + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + }), + }, + ] + + const mockForm = { + _id: 'formId', + form_fields: mockFormFields, + updateFormFieldById: jest.fn().mockResolvedValue({ + form_fields: mockFormFields, + }), + } as unknown as IPopulatedForm + + const optionsMap = { + option1: ['test1@example.com'], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + optionsMap, + ) + + // Assert + expect(result.isOk()).toBe(true) + }) + }) + + describe('validation of options to recipients map', () => { + it('should return error if options to recipients map has options that are not in the field options', async () => { + // Arrange + const mockForm = { + _id: 'formId', + form_fields: [ + { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', 'option2'], + }, + ], + } as unknown as IPopulatedForm + + const invalidOptionsMap = { + option1: ['test1@example.com'], + option2: ['test2@example.com'], + option3: ['test3@example.com'], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + invalidOptionsMap, + ) + + // Assert + expect(result.isErr()).toBe(true) + expect(result._unsafeUnwrapErr().message).toBe( + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, + ) + }) + + it('should return error if options to recipients map does not have options that are in the field options', async () => { + // Arrange + const mockForm = { + _id: 'formId', + form_fields: [ + { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', 'option2'], + }, + ], + } as unknown as IPopulatedForm + + const incompleteOptionsMap = { + option2: ['test2@example.com'], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + incompleteOptionsMap, + ) + + // Assert + expect(result.isErr()).toBe(true) + expect(result._unsafeUnwrapErr().message).toBe( + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, + ) + }) + + it('should return error if some options is empty string', async () => { + // Arrange + const mockForm = { + _id: 'formId', + form_fields: [ + { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', ''], + }, + ], + } as unknown as IPopulatedForm + + const emptyOptionsMap = { + '': ['test@example.com'], + option2: ['test2@example.com'], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + emptyOptionsMap, + ) + + // Assert + expect(result.isErr()).toBe(true) + expect(result._unsafeUnwrapErr().message).toBe( + CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE, + ) + }) + + it('should return error if some recipients are invalid emails', async () => { + // Arrange + const mockForm = { + _id: 'formId', + form_fields: [ + { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + }, + ], + } as unknown as IPopulatedForm + + const invalidEmailsMap = { + option1: ['invalid-email', 'valid-email@example.com'], + option2: ['valid-email2@example.com'], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm, + 'fieldId', + invalidEmailsMap, + ) + + // Assert + expect(result.isErr()).toBe(true) + expect(result._unsafeUnwrapErr().message).toBe( + CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE, + ) + }) + + it('should save if the options to recipients map is valid', async () => { + // Arrange + const mockFormField = { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', 'option2'], + toObject: jest.fn().mockReturnValue({ + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', 'option2'], + }), + } + + const mockForm = { + _id: 'formId', + form_fields: [mockFormField], + updateFormFieldById: jest.fn().mockResolvedValue({ + form_fields: [mockFormField], + }), + } + + const validOptionsMap = { + option1: ['test@example.com'], + option2: [ + 'test2@example.com', + 'test3@example.com', + 'test4@example.com', + ], + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm as unknown as IPopulatedForm, + 'fieldId', + validOptionsMap, + ) + + // Assert + expect(result.isOk()).toBe(true) + expect(mockForm.updateFormFieldById).toHaveBeenCalledWith('fieldId', { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1', 'option2'], + optionsToRecipientsMap: validOptionsMap, + }) + }) + + it('should save if the options to recipients map is empty aka deleted', async () => { + // Arrange + const mockFormField = { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + toObject: jest.fn().mockReturnValue({ + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + }), + } + + const mockForm = { + _id: 'formId', + form_fields: [mockFormField], + updateFormFieldById: jest.fn().mockResolvedValue({ + form_fields: [mockFormField], + }), + } + + // Act + const result = await AdminFormService.updateOptionsToRecipientsMap( + mockForm as unknown as IPopulatedForm, + 'fieldId', + {}, + ) + + // Assert + expect(result.isOk()).toBe(true) + expect(mockForm.updateFormFieldById).toHaveBeenCalledWith('fieldId', { + _id: 'fieldId', + fieldType: BasicField.Dropdown, + fieldOptions: ['option1'], + optionsToRecipientsMap: {}, + }) + }) + }) + }) }) diff --git a/src/app/modules/form/admin-form/admin-form.controller.ts b/src/app/modules/form/admin-form/admin-form.controller.ts index 5ce6a1940f..53268049e3 100644 --- a/src/app/modules/form/admin-form/admin-form.controller.ts +++ b/src/app/modules/form/admin-form/admin-form.controller.ts @@ -2277,6 +2277,69 @@ export const handleUpdateFormField = [ _handleUpdateFormField, ] +const _handleUpdateOptionsToRecipientsMap: ControllerHandler< + { + formId: string + fieldId: string + }, + FormFieldDto | ErrorDto, + { optionsToRecipientsMap: Record } +> = (req, res) => { + const { formId, fieldId } = req.params + const { optionsToRecipientsMap } = req.body + const sessionUserId = (req.session as AuthedSessionData).user._id + + // Step 1: Retrieve currently logged in user. + return UserService.getPopulatedUserById(sessionUserId) + .andThen((user) => + // Step 2: Retrieve form with write permission check. + AuthService.getFormAfterPermissionChecks({ + user, + formId, + level: PermissionLevel.Write, + }), + ) + .andThen((form) => { + return AdminFormService.updateOptionsToRecipientsMap( + form, + fieldId, + optionsToRecipientsMap, + ) + }) + .map((updatedFormField) => + res.status(StatusCodes.OK).json(updatedFormField as FormFieldDto), + ) + .mapErr((error) => { + logger.error({ + message: 'Error occurred when updating options to recipients map', + meta: { + action: '_handleUpdateOptionsToRecipientsMap', + ...createReqMeta(req), + userId: sessionUserId, + formId, + fieldId, + optionsToRecipientsMap, + }, + error, + }) + const { errorMessage, statusCode } = mapRouteError(error) + return res.status(statusCode).json({ message: errorMessage }) + }) +} + +export const handleUpdateOptionsToRecipientsMap = [ + celebrate({ + [Segments.BODY]: Joi.object({ + optionsToRecipientsMap: Joi.object(), + }), + [Segments.PARAMS]: Joi.object({ + formId: Joi.string().required(), + fieldId: Joi.string().required(), + }), + }), + _handleUpdateOptionsToRecipientsMap, +] as ControllerHandler[] + /** * NOTE: Exported for testing. * Private handler for POST /forms/:formId/fields diff --git a/src/app/modules/form/admin-form/admin-form.middlewares.ts b/src/app/modules/form/admin-form/admin-form.middlewares.ts index 7621bdd6b3..c4c26708eb 100644 --- a/src/app/modules/form/admin-form/admin-form.middlewares.ts +++ b/src/app/modules/form/admin-form/admin-form.middlewares.ts @@ -82,6 +82,11 @@ export const createWorkflowStepValidator = celebrate({ }), edit: Joi.array().items(Joi.string()).required(), approval_field: Joi.string().optional(), + conditional_field: Joi.when('workflow_type', { + is: WorkflowType.Conditional, + then: Joi.string().required(), + otherwise: Joi.forbidden(), + }), }), [Segments.PARAMS]: Joi.object({ formId: Joi.string().required(), @@ -105,6 +110,11 @@ export const updateWorkflowStepValidator = celebrate({ }), edit: Joi.array().items(Joi.string().hex().length(24)).required(), approval_field: Joi.string().optional(), + conditional_field: Joi.when('workflow_type', { + is: WorkflowType.Conditional, + then: Joi.string().required(), + otherwise: Joi.forbidden(), + }), }), [Segments.PARAMS]: Joi.object({ formId: Joi.string().required(), diff --git a/src/app/modules/form/admin-form/admin-form.service.ts b/src/app/modules/form/admin-form/admin-form.service.ts index 69ff7b5535..49cb88e44e 100644 --- a/src/app/modules/form/admin-form/admin-form.service.ts +++ b/src/app/modules/form/admin-form/admin-form.service.ts @@ -13,8 +13,13 @@ import { EncryptedStringsMessageContentWithMyPrivateKey, } from 'shared/utils/crypto' import type { Except, Merge } from 'type-fest' +import validator from 'validator' import { + CONDITIONAL_ROUTING_DUPLICATE_OPTIONS_ERROR_MESSAGE, + CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE, + CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE, + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, FORM_WHITELIST_CONTAINS_EMPTY_ROWS_ERROR_MESSAGE, FORM_WHITELIST_SETTING_CONTAINS_DUPLICATES_ERROR_MESSAGE, FORM_WHITELIST_SETTING_CONTAINS_INVALID_FORMAT_SUBMITTERID_ERROR_MESSAGE, @@ -26,11 +31,13 @@ import { MYINFO_ATTRIBUTE_MAP } from '../../../../../shared/constants/field/myin import { AdminDashboardFormMetaDto, BasicField, + DropdownFieldBase, DuplicateFormOverwriteDto, EndPageUpdateDto, FieldCreateDto, FieldUpdateDto, FormAuthType, + FormFieldDto, FormLogoState, FormMetadata, FormPermission, @@ -49,6 +56,7 @@ import { isMFinSeriesValid, isNricValid, } from '../../../../../shared/utils/nric-validation' +import { checkIsOptionsMismatched } from '../../../../../shared/utils/options-recipients-map-validation' import { isUenValid } from '../../../../../shared/utils/uen-validation' import { EditFieldActions } from '../../../../shared/constants' import { @@ -96,6 +104,7 @@ import { MissingUserError } from '../../user/user.errors' import * as UserService from '../../user/user.service' import { removeFormsFromAllWorkspaces } from '../../workspace/workspace.service' import { + FormInvalidResponseModeError, FormNotFoundError, FormWhitelistSettingNotFoundError, LogicNotFoundError, @@ -737,6 +746,153 @@ export const duplicateForm = ( ) } +/** + * Validates the mapping between dropdown/radio field options and recipient emails + * @param optionsToRecipientsMap Object mapping field options to arrays of recipient emails + * @param selectedConditionalFieldOptions Array of valid options for the selected field + * @returns Ok if validation passes, Error with appropriate message if validation fails + * + * Performs the following validations: + * - No duplicate options in the mapping + * - All options have at least one recipient email + * - Options cannot be empty strings + * - All recipient emails are valid email addresses + * - All options in mapping exist in the field's options and vice versa + */ + +const validateOptionsToRecipientsMap = ( + optionsToRecipientsMap: Record, + selectedConditionalFieldOptions: string[], +): Result => { + // Mapping is being removed + if ( + !optionsToRecipientsMap || + Object.entries(optionsToRecipientsMap).length === 0 + ) { + return ok(undefined) + } + + // Check for duplicate options + const options = Object.keys(optionsToRecipientsMap) + if (new Set(options).size !== options.length) { + return err( + new MalformedParametersError( + CONDITIONAL_ROUTING_DUPLICATE_OPTIONS_ERROR_MESSAGE, + ), + ) + } + // Check if there are missing options or emails + for (const [option, recipients] of Object.entries(optionsToRecipientsMap)) { + // Check if all recipients are valid emails + if ( + recipients.some((recipientEmail) => !validator.isEmail(recipientEmail)) + ) { + return err( + new MalformedParametersError( + CONDITIONAL_ROUTING_INVALID_CSV_FORMAT_ERROR_MESSAGE, + ), + ) + } + + if (!option || !recipients || recipients.length <= 0) { + return err( + new MalformedParametersError( + CONDITIONAL_ROUTING_EMAILS_OPTIONS_MISSING_ERROR_MESSAGE, + ), + ) + } + } + + if ( + checkIsOptionsMismatched( + Object.keys(optionsToRecipientsMap), + selectedConditionalFieldOptions, + ) + ) { + return err( + new MalformedParametersError( + CONDITIONAL_ROUTING_MISMATCHED_OPTIONS_ERROR_MESSAGE, + ), + ) + } + + return ok(undefined) +} + +export const updateOptionsToRecipientsMap = ( + form: IPopulatedForm, + fieldId: string, + optionsToRecipientsMap: Record, +): ResultAsync< + FormFieldSchema, + PossibleDatabaseError | FieldNotFoundError | MalformedParametersError +> => { + const formFieldToUpdate = getFormFieldById(form.form_fields, fieldId) + + if (!formFieldToUpdate) { + return errAsync(new FieldNotFoundError()) + } + + if (formFieldToUpdate.fieldType !== BasicField.Dropdown) { + return errAsync( + new EditFieldError( + 'Field is not a dropdown field, only dropdown fields contain options to recipients map', + ), + ) + } + + const validationResult = validateOptionsToRecipientsMap( + optionsToRecipientsMap, + formFieldToUpdate.fieldOptions, + ) + + if (validationResult.isErr()) { + logger.error({ + message: 'Options to recipients map is invalid', + meta: { + action: 'updateOptionsToRecipientsMap', + formId: form._id, + fieldId, + }, + error: validationResult.error, + }) + return errAsync(validationResult.error) + } + + const updatedFormField = { + ...formFieldToUpdate.toObject(), + optionsToRecipientsMap, + } + + return ResultAsync.fromPromise( + form.updateFormFieldById( + fieldId, + updatedFormField as FormFieldDto, + ), + (error) => { + logger.error({ + message: 'Error encountered while updating options to recipients map', + meta: { + action: 'updateOptionsToRecipientsMap', + formId: form._id, + fieldId, + }, + error, + }) + return transformMongoError(error) + }, + ).andThen((updatedForm) => { + if (!updatedForm) { + return errAsync(new FieldNotFoundError()) + } + + const updatedFormField = getFormFieldById(updatedForm.form_fields, fieldId) + return updatedFormField + ? okAsync(updatedFormField) + : errAsync(new FieldNotFoundError()) + }) +} + /** * Updates the targeted form field with the new field provided * @param form the form the field to update belongs to @@ -1402,7 +1558,7 @@ export const createWorkflowStep = ( ): ResultAsync => { if (originalForm.responseMode !== FormResponseMode.Multirespondent) { return errAsync( - new MalformedParametersError( + new FormInvalidResponseModeError( 'Cannot update workflow step for non-multirespondent mode forms', ), ) @@ -1524,7 +1680,7 @@ export const updateFormWorkflowStep = ( ): ResultAsync => { if (originalForm.responseMode !== FormResponseMode.Multirespondent) { return errAsync( - new MalformedParametersError( + new FormInvalidResponseModeError( 'Cannot update workflow step for non-multirespondent mode forms', ), ) @@ -1653,7 +1809,7 @@ export const deleteFormWorkflowStep = ( ): ResultAsync => { if (originalForm.responseMode !== FormResponseMode.Multirespondent) { return errAsync( - new MalformedParametersError( + new FormInvalidResponseModeError( 'Cannot update workflow step for non-multirespondent mode forms', ), ) diff --git a/src/app/modules/form/form.errors.ts b/src/app/modules/form/form.errors.ts index a0e20cdf16..7c08bd12b3 100644 --- a/src/app/modules/form/form.errors.ts +++ b/src/app/modules/form/form.errors.ts @@ -11,6 +11,12 @@ export class FormNotFoundError extends ApplicationError { } } +export class FormInvalidResponseModeError extends ApplicationError { + constructor(message = 'Invalid response mode') { + super(message, undefined, ErrorCodes.FORM_INVALID_RESPONSE_MODE) + } +} + export class FormDeletedError extends ApplicationError { constructor(message = 'This form is no longer active') { super(message, undefined, ErrorCodes.FORM_DELETED) diff --git a/src/app/modules/submission/multirespondent-submission/__tests__/multirespondent-submission.utils.spec.ts b/src/app/modules/submission/multirespondent-submission/__tests__/multirespondent-submission.utils.spec.ts index 8401e4bb38..5b22c65008 100644 --- a/src/app/modules/submission/multirespondent-submission/__tests__/multirespondent-submission.utils.spec.ts +++ b/src/app/modules/submission/multirespondent-submission/__tests__/multirespondent-submission.utils.spec.ts @@ -10,11 +10,13 @@ import { ChildBirthRecordsResponseV3, EmailResponseV3, FieldResponsesV3, + FormWorkflowStepDto, LongTextResponseV3, NumberResponseV3, ShortTextResponseV3, SubmissionType, TableResponseV3, + WorkflowType, } from 'shared/types' import { @@ -23,6 +25,7 @@ import { ICheckboxFieldSchema, IEmailFieldSchema, INumberFieldSchema, + IPopulatedForm, IShortTextFieldSchema, ITableFieldSchema, MultirespondentSubmissionData, @@ -33,6 +36,7 @@ import { ValidateFieldErrorV3 } from '../../submission.errors' import { createMultirespondentSubmissionDto, getQuestionTitleAnswerString, + retrieveWorkflowStepEmailAddresses, validateMrfFieldResponses, } from '../multirespondent-submission.utils' @@ -352,6 +356,213 @@ describe('multirespondent-submission.utils', () => { }) }) + describe('retrieveWorkflowStepEmailAddresses', () => { + describe('conditional workflow type', () => { + it('should return correct emails for response for conditional routing workflow step', () => { + // Arrange + const mockConditionalFieldId = 'conditionalField' + const mockShortTextFieldId = 'shortTextField' + const mockForm = { + form_fields: [ + generateDefaultField(BasicField.Dropdown, { + _id: mockConditionalFieldId, + fieldOptions: ['Option A', 'Option B'], + optionsToRecipientsMap: { + 'Option A': ['test1@example.com'], + 'Option B': ['test2@example.com', 'test3@example.com'], + }, + }), + generateDefaultField(BasicField.ShortText, { + _id: mockShortTextFieldId, + }), + ], + } as IPopulatedForm + + // Test Option A + const mockResponsesA = { + [mockConditionalFieldId]: { + fieldType: BasicField.Dropdown, + answer: 'Option A', + }, + [mockShortTextFieldId]: { + fieldType: BasicField.ShortText, + answer: 'Some text response', + }, + } as FieldResponsesV3 + + const mockWorkflowStep = { + workflow_type: WorkflowType.Conditional, + conditional_field: mockConditionalFieldId, + } as FormWorkflowStepDto + + // Act & Assert for Option A + const resultA = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponsesA, + ) + expect(resultA._unsafeUnwrap()).toEqual(['test1@example.com']) + + // Test Option B + const mockResponsesB = { + [mockConditionalFieldId]: { + fieldType: BasicField.Dropdown, + answer: 'Option B', + }, + [mockShortTextFieldId]: { + fieldType: BasicField.ShortText, + answer: 'Some text response', + }, + } as FieldResponsesV3 + + // Act & Assert for Option B + const resultB = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponsesB, + ) + expect(resultB._unsafeUnwrap()).toEqual([ + 'test2@example.com', + 'test3@example.com', + ]) + }) + + it('should return empty array if response for field id not found', () => { + // Arrange + const mockConditionalFieldId = 'conditionalField' + const mockForm = { + form_fields: [ + generateDefaultField(BasicField.Dropdown, { + _id: mockConditionalFieldId, + fieldOptions: ['Option A', 'Option B'], + optionsToRecipientsMap: { + 'Option A': ['test1@example.com'], + 'Option B': ['test2@example.com'], + }, + }), + ], + } as IPopulatedForm + const mockResponses = {} as FieldResponsesV3 + const mockWorkflowStep = { + workflow_type: WorkflowType.Conditional, + conditional_field: mockConditionalFieldId, + } as FormWorkflowStepDto + + // Act + const result = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponses, + ) + + // Assert + expect(result._unsafeUnwrap()).toEqual([]) + }) + + it('should return empty array if response is not a dropdown field', () => { + // Arrange + const mockConditionalFieldId = 'conditionalField' + const mockForm = { + form_fields: [ + generateDefaultField(BasicField.ShortText, { + _id: mockConditionalFieldId, + }), + ], + } as IPopulatedForm + const mockResponses = { + [mockConditionalFieldId]: { + fieldType: BasicField.ShortText, + answer: 'Some text', + }, + } as FieldResponsesV3 + const mockWorkflowStep = { + workflow_type: WorkflowType.Conditional, + conditional_field: mockConditionalFieldId, + } as FormWorkflowStepDto + + // Act + const result = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponses, + ) + + // Assert + expect(result._unsafeUnwrap()).toEqual([]) + }) + + it('should return empty array if no optionsToRecipientsMap is found for the conditional field', () => { + // Arrange + const mockConditionalFieldId = 'conditionalField' + const mockForm = { + form_fields: [ + generateDefaultField(BasicField.Dropdown, { + _id: mockConditionalFieldId, + fieldOptions: ['Option A', 'Option B'], + }), + ], + } as IPopulatedForm + const mockResponses = { + [mockConditionalFieldId]: { + fieldType: BasicField.Dropdown, + answer: 'Option A', + }, + } as FieldResponsesV3 + const mockWorkflowStep = { + workflow_type: WorkflowType.Conditional, + conditional_field: mockConditionalFieldId, + } as FormWorkflowStepDto + + // Act + const result = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponses, + ) + + // Assert + expect(result._unsafeUnwrap()).toEqual([]) + }) + }) + + it('should return an empty array if the optionsToRecipientsMap does not contain an email mapping for the option selected', () => { + // Arrange + const mockConditionalFieldId = 'conditionalField' + const mockForm = { + form_fields: [ + generateDefaultField(BasicField.Dropdown, { + _id: mockConditionalFieldId, + fieldOptions: ['Option A', 'Option B'], + optionsToRecipientsMap: { + 'Option A': ['test1@example.com'], + 'Option B': ['test2@example.com'], + }, + }), + ], + } as IPopulatedForm + const mockResponses = { + [mockConditionalFieldId]: { + fieldType: BasicField.Dropdown, + answer: 'Option C', // Option not in mapping + }, + } as FieldResponsesV3 + const mockWorkflowStep = { + workflow_type: WorkflowType.Conditional, + conditional_field: mockConditionalFieldId, + } as FormWorkflowStepDto + + // Act + const result = retrieveWorkflowStepEmailAddresses( + mockForm, + mockWorkflowStep, + mockResponses, + ) + + // Assert + expect(result._unsafeUnwrap()).toEqual([]) + }) + }) + it('should return an empty array when formFields is not iterable', () => { const formFields = null as unknown as FormFieldSchema[] const responses: FieldResponsesV3 = { diff --git a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts index 48a3fa068e..81e3977fca 100644 --- a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts +++ b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts @@ -127,7 +127,7 @@ const sendNextStepEmail = ({ }): ResultAsync => { const logMeta = { action: 'sendNextStepEmail', - formId, + formId: formId.toString(), submissionId, nextWorkflowStep: nextStepNumber, } @@ -139,7 +139,7 @@ const sendNextStepEmail = ({ return ( // Step 1: Retrieve email addresses for current workflow step - retrieveWorkflowStepEmailAddresses(nextStep, responses) + retrieveWorkflowStepEmailAddresses(form, nextStep, responses) .mapErr((error) => { logger.error({ message: 'Failed to retrieve workflow step email addresses', @@ -150,7 +150,13 @@ const sendNextStepEmail = ({ }) // Step 2: send out next workflow step email .asyncAndThen((emails) => { - if (!emails) return okAsync(true) + if (emails.length <= 0) { + logger.info({ + message: 'No destination email found for MRF next step email', + meta: logMeta, + }) + return okAsync(true) + } return MailService.sendMRFWorkflowStepEmail({ emails, formTitle, @@ -185,7 +191,7 @@ const sendMrfOutcomeEmails = ({ }): ResultAsync => { const logMeta = { action: 'sendMrfOutcomeEmails', - formId: form._id, + formId: form._id?.toString(), submissionId, } const emailsToNotify = @@ -216,7 +222,7 @@ const sendMrfOutcomeEmails = ({ // Step 1: Fetch email address from all workflow steps that are selected to notify Result.combine( validWorkflowStepsToNotify.map((workflowStep) => - retrieveWorkflowStepEmailAddresses(workflowStep, responses), + retrieveWorkflowStepEmailAddresses(form, workflowStep, responses), ), ) .mapErr((error) => { @@ -236,8 +242,13 @@ const sendMrfOutcomeEmails = ({ }) // Step 3: Send outcome emails based on type .asyncAndThen((destinationEmails) => { - if (!destinationEmails || destinationEmails.length <= 0) + if (!destinationEmails || destinationEmails.length <= 0) { + logger.info({ + message: 'No destination email found for MRF outcome email', + meta: logMeta, + }) return okAsync(true) + } const lastStepNumber = form.workflow.length - 1 const isLastStep = currentStepNumber === lastStepNumber diff --git a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.utils.ts b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.utils.ts index e6c799d565..b405842203 100644 --- a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.utils.ts +++ b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.utils.ts @@ -13,6 +13,7 @@ import { } from '../../../../../shared/types' import { FormFieldSchema, + IPopulatedForm, MultirespondentSubmissionData, } from '../../../../types' import { ParsedClearFormFieldResponsesV3 } from '../../../../types/api' @@ -63,7 +64,39 @@ export const getEmailFromResponses = ( return field.answer.value } +const getConditionalFieldEmailRecipient = ( + form: IPopulatedForm, + fieldId: string, + responses: FieldResponsesV3, +): string[] => { + const conditionalField = form.form_fields.find( + (field) => field._id.toString() === fieldId.toString(), + ) + const conditionalFieldResponse = responses[fieldId] + + const isFieldValid = + !!conditionalField && + conditionalField.fieldType === BasicField.Dropdown && + !!conditionalField.optionsToRecipientsMap + + const isResponseValid = + !!conditionalFieldResponse && + conditionalFieldResponse.fieldType === BasicField.Dropdown + + if (!isFieldValid || !isResponseValid) { + return [] // Not an error, misconfigured or respondent has not filled. + } + + const emailRecipients = + conditionalField?.optionsToRecipientsMap?.[ + conditionalFieldResponse.answer + ] ?? [] + + return emailRecipients +} + export const retrieveWorkflowStepEmailAddresses = ( + form: IPopulatedForm, step: FormWorkflowStepDto, responses: FieldResponsesV3, ): Result => { @@ -77,6 +110,15 @@ export const retrieveWorkflowStepEmailAddresses = ( if (!email) return ok([]) return ok([email]) } + case WorkflowType.Conditional: { + return ok( + getConditionalFieldEmailRecipient( + form, + step.conditional_field, + responses, + ), + ) + } default: { return err(new InvalidWorkflowTypeError()) } diff --git a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts index ec44aaae91..a300e0591a 100644 --- a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts +++ b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts @@ -183,6 +183,11 @@ AdminFormsFormRouter.route( */ .get(AdminFormController.handleGetFormField) +AdminFormsFormRouter.put( + '/:formId([a-fA-F0-9]{24})/fields/:fieldId([a-fA-F0-9]{24})/options-to-recipients-map', + AdminFormController.handleUpdateOptionsToRecipientsMap, +) + /** * Duplicates the form field with the fieldId from the specified form * @security session diff --git a/src/types/form_workflow_step.ts b/src/types/form_workflow_step.ts index 29c9947bff..1b5ba401ea 100644 --- a/src/types/form_workflow_step.ts +++ b/src/types/form_workflow_step.ts @@ -2,6 +2,7 @@ import { Document } from 'mongoose' import { FormWorkflowStepBase, + FormWorkflowStepConditional, FormWorkflowStepDynamic, FormWorkflowStepStatic, WorkflowType, @@ -33,6 +34,11 @@ export interface IWorkflowStepDynamicSchema edit: IFieldSchema['_id'][] } -export type FormWorkflowStepSchema = - | IWorkflowStepStaticSchema - | IWorkflowStepDynamicSchema +export interface IWorkflowStepConditionalSchema + extends IWorkflowStepSchema, + FormWorkflowStepConditional, + Document { + workflow_type: WorkflowType.Conditional + edit: IFieldSchema['_id'][] + conditional_field: IFieldSchema['_id'] +} From c51e8074cce5ca0d5ac3ae4904e1c48ee94f5ec0 Mon Sep 17 00:00:00 2001 From: Kevin Foong <55353265+kevin9foong@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:22:43 +0800 Subject: [PATCH 16/16] chore: bump version to v6.166.0 --- CHANGELOG.md | 19 +++++++++++++++++++ frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4574a6d186..1a60a0d1c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,33 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v6.166.0](https://github.com/opengovsg/FormSG/compare/v6.165.0...v6.166.0) + +- feat(mrf): conditional routing [`#7804`](https://github.com/opengovsg/FormSG/pull/7804) +- fix: trim text input before sending to backend [`#7937`](https://github.com/opengovsg/FormSG/pull/7937) +- test(story): add chromatic story to ensure thankyou page renders [`#7264`](https://github.com/opengovsg/FormSG/pull/7264) +- chore: remove unused deps [`#7906`](https://github.com/opengovsg/FormSG/pull/7906) +- feat(i18n): extract text from admin-form prompts [`#7931`](https://github.com/opengovsg/FormSG/pull/7931) +- fix(deps): bump libphonenumber-js from 1.11.14 to 1.11.15 in /shared [`#7936`](https://github.com/opengovsg/FormSG/pull/7936) +- chore(deps-dev): bump @playwright/test from 1.45.1 to 1.49.0 [`#7923`](https://github.com/opengovsg/FormSG/pull/7923) +- chore(FE): cleanup date check on sex field [`#7922`](https://github.com/opengovsg/FormSG/pull/7922) +- chore(FE): use consistent vite port for dev with README [`#7930`](https://github.com/opengovsg/FormSG/pull/7930) +- feat(i18n): move workspace relative date format [`#7929`](https://github.com/opengovsg/FormSG/pull/7929) +- build: release v6.165.0 [`#7928`](https://github.com/opengovsg/FormSG/pull/7928) +- build: release v6.165.0 [`#7927`](https://github.com/opengovsg/FormSG/pull/7927) +- feat(i18n): extract text for form metadata [`#7926`](https://github.com/opengovsg/FormSG/pull/7926) + #### [v6.165.0](https://github.com/opengovsg/FormSG/compare/v6.164.0...v6.165.0) +> 20 November 2024 + - chore(approvals-ga): remove beta flag for MRF email notifications and approvals [`#7920`](https://github.com/opengovsg/FormSG/pull/7920) - chore(deps-dev): bump @typescript-eslint/parser from 8.14.0 to 8.15.0 in /shared [`#7911`](https://github.com/opengovsg/FormSG/pull/7911) - fix(deps): bump @aws-sdk/client-lambda from 3.654.0 to 3.693.0 [`#7910`](https://github.com/opengovsg/FormSG/pull/7910) - chore(deps-dev): bump @typescript-eslint/eslint-plugin from 8.14.0 to 8.15.0 in /shared [`#7912`](https://github.com/opengovsg/FormSG/pull/7912) - build: merge release v6.164.0 to develop [`#7921`](https://github.com/opengovsg/FormSG/pull/7921) - build: release v6.164.0 [`#7919`](https://github.com/opengovsg/FormSG/pull/7919) +- chore: bump version to v6.165.0 [`7984ee9`](https://github.com/opengovsg/FormSG/commit/7984ee906d7c6eef156a15569694f9c6784f9e8a) #### [v6.164.0](https://github.com/opengovsg/FormSG/compare/v6.163.0...v6.164.0) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d316d0dcb9..9133872b85 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "form-frontend", - "version": "6.165.0", + "version": "6.166.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "form-frontend", - "version": "6.165.0", + "version": "6.166.0", "hasInstallScript": true, "dependencies": { "@chakra-ui/react": "^2.8.2", diff --git a/frontend/package.json b/frontend/package.json index adbf2695fa..5c4a8720a1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "form-frontend", - "version": "6.165.0", + "version": "6.166.0", "homepage": ".", "type": "module", "private": true, diff --git a/package-lock.json b/package-lock.json index f627f8630a..48d3db4adb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "FormSG", - "version": "6.165.0", + "version": "6.166.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "FormSG", - "version": "6.165.0", + "version": "6.166.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.536.0", diff --git a/package.json b/package.json index a6d151a9f6..5f22099957 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "FormSG", "description": "Form Manager for Government", - "version": "6.165.0", + "version": "6.166.0", "homepage": "https://form.gov.sg", "authors": [ "FormSG "