From 5a9381ebdba8ffd9486e2605d9677e4f59c5b943 Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 14 Oct 2025 13:23:32 -0400 Subject: [PATCH] feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Checkpoint --- client/src/pages/dms/dms.container.jsx | 18 +- package-lock.json | 823 ++++++++++++------------ package.json | 24 +- server/rr/rr-calculate-allocations.js | 381 ----------- server/rr/rr-config.js | 81 +++ server/rr/rr-constants.js | 29 +- server/rr/rr-helpers.js | 75 ++- server/rr/rr-mappers.js | 56 +- server/rr/rr-test.js | 92 ++- server/rr/rrRoutes.js | 51 +- server/web-sockets/redisSocketEvents.js | 35 +- 11 files changed, 754 insertions(+), 911 deletions(-) delete mode 100644 server/rr/rr-calculate-allocations.js create mode 100644 server/rr/rr-config.js diff --git a/client/src/pages/dms/dms.container.jsx b/client/src/pages/dms/dms.container.jsx index 496ea81f2..60f710dab 100644 --- a/client/src/pages/dms/dms.container.jsx +++ b/client/src/pages/dms/dms.container.jsx @@ -23,6 +23,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; import { useSocket } from "../../contexts/SocketIO/useSocket.js"; +import { determineDmsType } from "../../utils/determineDmsType"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -168,16 +169,21 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse if (loading) return ; if (error) return ; - if (!jobId || !(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) || bodyshop.rr_dealerid || !data?.jobs_by_pk) + if (!jobId || !(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || bodyshop.rr_dealerid) || !data?.jobs_by_pk) return ; - if (data.jobs_by_pk && data.jobs_by_pk.date_exported) - return ; + if (data.jobs_by_pk?.date_exported) return ; return (
{Fortellis.treatment === "on" && ( - + )} @@ -185,7 +191,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse title={ {`${ - data && data.jobs_by_pk && data.jobs_by_pk.ro_number + data?.jobs_by_pk && data.jobs_by_pk.ro_number }`} {` | ${OwnerNameDisplayFunction(data.jobs_by_pk)} | ${ data.jobs_by_pk.v_model_yr || "" @@ -197,7 +203,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse /> - + diff --git a/package-lock.json b/package-lock.json index 463116ee9..c619b65a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.901.0", - "@aws-sdk/client-elasticache": "^3.901.0", - "@aws-sdk/client-s3": "^3.901.0", - "@aws-sdk/client-secrets-manager": "^3.901.0", - "@aws-sdk/client-ses": "^3.901.0", - "@aws-sdk/credential-provider-node": "^3.901.0", - "@aws-sdk/lib-storage": "^3.903.0", - "@aws-sdk/s3-request-presigner": "^3.901.0", + "@aws-sdk/client-cloudwatch-logs": "^3.908.0", + "@aws-sdk/client-elasticache": "^3.908.0", + "@aws-sdk/client-s3": "^3.908.0", + "@aws-sdk/client-secrets-manager": "^3.908.0", + "@aws-sdk/client-ses": "^3.908.0", + "@aws-sdk/credential-provider-node": "^3.908.0", + "@aws-sdk/lib-storage": "^3.908.0", + "@aws-sdk/s3-request-presigner": "^3.908.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -26,13 +26,13 @@ "axios-curlirize": "^2.0.0", "better-queue": "^3.8.12", "bullmq": "^5.61.0", - "chart.js": "^4.5.0", + "chart.js": "^4.5.1", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.70.0", + "dd-trace": "^5.71.0", "dinero.js": "^1.9.1", "dotenv": "^17.2.3", "express": "^4.21.1", @@ -40,7 +40,7 @@ "firebase-admin": "^13.5.0", "graphql": "^16.11.0", "graphql-request": "^6.1.0", - "intuit-oauth": "^4.2.0", + "intuit-oauth": "^4.2.1", "ioredis": "^5.8.1", "json-2-csv": "^5.5.9", "jsonwebtoken": "^9.0.2", @@ -61,7 +61,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.10.2", + "twilio": "^5.10.3", "uuid": "^11.1.0", "winston": "^3.18.3", "winston-cloudwatch": "^6.3.0", @@ -289,48 +289,48 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.901.0.tgz", - "integrity": "sha512-36T3Vev/StVPPkZG8zhs+Pzch4T1LtwGZgPluF5nyaRO+s/1KbzwUEaKV/6Ts3DvdA6bq8aNBQ0psss6+r0LDw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.908.0.tgz", + "integrity": "sha512-UHozlv3xajFaWV0qltEeT3ApN4rHC6hBxywDkCxCUK+avkzaQFpExnCCkc6EU+sZm4SFFI4zImVYThvggYj3Lw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-node": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", + "@smithy/core": "^3.15.0", "@smithy/eventstream-serde-browser": "^4.2.0", "@smithy/eventstream-serde-config-resolver": "^4.3.0", "@smithy/eventstream-serde-node": "^4.2.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -343,45 +343,45 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.901.0.tgz", - "integrity": "sha512-l6nZ6sF9IYttojAiCiCUrCnScSpXfaxWX12of/PkJIF5uiwu0fGESkHDU4ZVfBxbUeYNp/FnQPdHfMJH2RD9qA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.908.0.tgz", + "integrity": "sha512-GlN5Z4NEpmQQvlyte/oHhvDIqIev8Y9nmgmdQynjF6dDHNxYtBYzlQ/B5dimm6OOvSdr0uZH0MFvx4jCRcllng==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-node": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/core": "^3.15.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -394,64 +394,64 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.901.0.tgz", - "integrity": "sha512-wyKhZ51ur1tFuguZ6PgrUsot9KopqD0Tmxw8O8P/N3suQDxFPr0Yo7Y77ezDRDZQ95Ml3C0jlvx79HCo8VxdWA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.908.0.tgz", + "integrity": "sha512-c/89iG3of8UEiWbRK014DoHLy8PLLTJtM9IvYLPsvrf83kpV2P/K9WrdbjW4h6e5qt9XPgfNTZ8U607mt7pdmA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-node": "3.908.0", "@aws-sdk/middleware-bucket-endpoint": "3.901.0", "@aws-sdk/middleware-expect-continue": "3.901.0", - "@aws-sdk/middleware-flexible-checksums": "3.901.0", + "@aws-sdk/middleware-flexible-checksums": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-location-constraint": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-sdk-s3": "3.901.0", + "@aws-sdk/middleware-sdk-s3": "3.908.0", "@aws-sdk/middleware-ssec": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", - "@aws-sdk/signature-v4-multi-region": "3.901.0", + "@aws-sdk/signature-v4-multi-region": "3.908.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@aws-sdk/xml-builder": "3.901.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", + "@smithy/core": "^3.15.0", "@smithy/eventstream-serde-browser": "^4.2.0", "@smithy/eventstream-serde-config-resolver": "^4.3.0", "@smithy/eventstream-serde-node": "^4.2.0", - "@smithy/fetch-http-handler": "^5.3.0", - "@smithy/hash-blob-browser": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.1", + "@smithy/hash-blob-browser": "^4.2.1", "@smithy/hash-node": "^4.2.0", "@smithy/hash-stream-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/md5-js": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/util-stream": "^4.5.0", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.0", "@smithy/uuid": "^1.1.0", @@ -462,45 +462,45 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.901.0.tgz", - "integrity": "sha512-k5HEJfPiwgGVAjDGRPbysD3K2W0iMKQUv3zKTqHLFxog6X7JBrKGNgQwwtdz3vE5z9SFjGov7cFS1T1QuLVKQg==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.908.0.tgz", + "integrity": "sha512-OJVKq6vzG2w0B+Al4Hx+iLRVt2GuRopu5Obs8YzD2gzl4WIFqk6gK7SFr+vNFZAfd5VjsKhXpbgYD7JWnDIacg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-node": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/core": "^3.15.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -513,45 +513,45 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.901.0.tgz", - "integrity": "sha512-CJfIsqloxgFvTb3arx/ZGVfxWo6zA8VzNQoMowd1G8ab6PjsqFSWufRGbQcvfwuKoUhHvtPAZw1zrqp7LJwAww==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.908.0.tgz", + "integrity": "sha512-e4bglczZvoDLmMeAgr0lou5QKCIOGfdCnfXp9jkEhkL6JLKNYvkmrRZpCrQiBwm/4j4H88oRPgLYk+sGQKFPlw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-node": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/core": "^3.15.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -564,44 +564,44 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.901.0.tgz", - "integrity": "sha512-sGyDjjkJ7ppaE+bAKL/Q5IvVCxtoyBIzN+7+hWTS/mUxWJ9EOq9238IqmVIIK6sYNIzEf9yhobfMARasPYVTNg==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.908.0.tgz", + "integrity": "sha512-PseFMWvtac+Q+zaY9DMISE+2+glNh0ROJ1yR4gMzeafNHSwkdYu4qcgxLWIOnIodGydBv/tQ6nzHPzExXnUUgw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/core": "^3.15.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -613,21 +613,21 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.901.0.tgz", - "integrity": "sha512-brKAc3y64tdhyuEf+OPIUln86bRTqkLgb9xkd6kUdIeA5+qmp/N6amItQz+RN4k4O3kqkCPYnAd3LonTKluobw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.908.0.tgz", + "integrity": "sha512-okl6FC2cQT1Oidvmnmvyp/IEvqENBagKO0ww4YV5UtBkf0VlhAymCWkZqhovtklsqgq0otag2VRPAgnrMt6nVQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.901.0", "@aws-sdk/xml-builder": "3.901.0", - "@smithy/core": "^3.14.0", + "@smithy/core": "^3.15.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/property-provider": "^4.2.0", "@smithy/protocol-http": "^5.3.0", "@smithy/signature-v4": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -637,12 +637,12 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.901.0.tgz", - "integrity": "sha512-5hAdVl3tBuARh3zX5MLJ1P/d+Kr5kXtDU3xm1pxUEF4xt2XkEEpwiX5fbkNkz2rbh3BCt2gOHsAbh6b3M7n+DA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.908.0.tgz", + "integrity": "sha512-FK2YuxoI5CxUflPOIMbVAwDbi6Xvu+2sXopXLmrHc2PfI39M3vmjEoQwYCP8WuQSRb+TbAP3xAkxHjFSBFR35w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/property-provider": "^4.2.0", "@smithy/types": "^4.6.0", @@ -653,20 +653,20 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.901.0.tgz", - "integrity": "sha512-Ggr7+0M6QZEsrqRkK7iyJLf4LkIAacAxHz9c4dm9hnDdU7vqrlJm6g73IxMJXWN1bIV7IxfpzB11DsRrB/oNjQ==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.908.0.tgz", + "integrity": "sha512-eLbz0geVW9EykujQNnYfR35Of8MreI6pau5K6XDFDUSWO9GF8wqH7CQwbXpXHBlCTHtq4QSLxzorD8U5CROhUw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/node-http-handler": "^4.3.0", "@smithy/property-provider": "^4.2.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/util-stream": "^4.5.0", "tslib": "^2.6.2" }, "engines": { @@ -674,18 +674,18 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.901.0.tgz", - "integrity": "sha512-zxadcDS0hNJgv8n4hFYJNOXyfjaNE1vvqIiF/JzZSQpSSYXzCd+WxXef5bQh+W3giDtRUmkvP5JLbamEFjZKyw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.908.0.tgz", + "integrity": "sha512-7Cgnv5wabgFtsgr+Uc/76EfPNGyxmbG8aICn3g3D3iJlcO4uuOZI8a77i0afoDdchZrTC6TG6UusS/NAW6zEoQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", - "@aws-sdk/credential-provider-env": "3.901.0", - "@aws-sdk/credential-provider-http": "3.901.0", - "@aws-sdk/credential-provider-process": "3.901.0", - "@aws-sdk/credential-provider-sso": "3.901.0", - "@aws-sdk/credential-provider-web-identity": "3.901.0", - "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/credential-provider-env": "3.908.0", + "@aws-sdk/credential-provider-http": "3.908.0", + "@aws-sdk/credential-provider-process": "3.908.0", + "@aws-sdk/credential-provider-sso": "3.908.0", + "@aws-sdk/credential-provider-web-identity": "3.908.0", + "@aws-sdk/nested-clients": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/credential-provider-imds": "^4.2.0", "@smithy/property-provider": "^4.2.0", @@ -698,17 +698,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.901.0.tgz", - "integrity": "sha512-dPuFzMF7L1s/lQyT3wDxqLe82PyTH+5o1jdfseTEln64LJMl0ZMWaKX/C1UFNDxaTd35Cgt1bDbjjAWHMiKSFQ==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.908.0.tgz", + "integrity": "sha512-8OKbykpGw5bdfF/pLTf8YfUi1Kl8o1CTjBqWQTsLOkE3Ho3hsp1eQx8Cz4ttrpv0919kb+lox62DgmAOEmTr1w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.901.0", - "@aws-sdk/credential-provider-http": "3.901.0", - "@aws-sdk/credential-provider-ini": "3.901.0", - "@aws-sdk/credential-provider-process": "3.901.0", - "@aws-sdk/credential-provider-sso": "3.901.0", - "@aws-sdk/credential-provider-web-identity": "3.901.0", + "@aws-sdk/credential-provider-env": "3.908.0", + "@aws-sdk/credential-provider-http": "3.908.0", + "@aws-sdk/credential-provider-ini": "3.908.0", + "@aws-sdk/credential-provider-process": "3.908.0", + "@aws-sdk/credential-provider-sso": "3.908.0", + "@aws-sdk/credential-provider-web-identity": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/credential-provider-imds": "^4.2.0", "@smithy/property-provider": "^4.2.0", @@ -721,12 +721,12 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.901.0.tgz", - "integrity": "sha512-/IWgmgM3Cl1wTdJA5HqKMAojxLkYchh5kDuphApxKhupLu6Pu0JBOHU8A5GGeFvOycyaVwosod6zDduINZxe+A==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.908.0.tgz", + "integrity": "sha512-sWnbkGjDPBi6sODUzrAh5BCDpnPw0wpK8UC/hWI13Q8KGfyatAmCBfr+9OeO3+xBHa8N5AskMncr7C4qS846yQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/property-provider": "^4.2.0", "@smithy/shared-ini-file-loader": "^4.3.0", @@ -738,14 +738,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.901.0.tgz", - "integrity": "sha512-SjmqZQHmqFSET7+6xcZgtH7yEyh5q53LN87GqwYlJZ6KJ5oNw11acUNEhUOL1xTSJEvaWqwTIkS2zqrzLcM9bw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.908.0.tgz", + "integrity": "sha512-WV/aOzuS6ZZhrkPty6TJ3ZG24iS8NXP0m3GuTVuZ5tKi9Guss31/PJ1CrKPRCYGm15CsIjf+mrUxVnNYv9ap5g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.901.0", - "@aws-sdk/core": "3.901.0", - "@aws-sdk/token-providers": "3.901.0", + "@aws-sdk/client-sso": "3.908.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/token-providers": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/property-provider": "^4.2.0", "@smithy/shared-ini-file-loader": "^4.3.0", @@ -757,13 +757,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.901.0.tgz", - "integrity": "sha512-NYjy/6NLxH9m01+pfpB4ql8QgAorJcu8tw69kzHwUd/ql6wUDTbC7HcXqtKlIwWjzjgj2BKL7j6SyFapgCuafA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.908.0.tgz", + "integrity": "sha512-9xWrFn6nWlF5KlV4XYW+7E6F33S3wUUEGRZ/+pgDhkIZd527ycT2nPG2dZ3fWUZMlRmzijP20QIJDqEbbGWe1Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", - "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/nested-clients": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/property-provider": "^4.2.0", "@smithy/shared-ini-file-loader": "^4.3.0", @@ -775,14 +775,14 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.903.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.903.0.tgz", - "integrity": "sha512-/CFhz/QtPSI9CVAdlW6JrfMyPjnE38a8pzTi8CMCWXu51c1NqzcGXo80LZUwzWkcWk5ZqPWRYzrw43TQ8ia78w==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.908.0.tgz", + "integrity": "sha512-tWYvGPAImOHSGYyau5rrVQA3OS0MV8ZCgf5ywtRIAmMEV4CSctDBP8WR2FrO7shAPKMRkjgdul5f0pZAjOYd2Q==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/smithy-client": "^4.7.1", "buffer": "5.6.0", "events": "3.3.0", "stream-browserify": "3.0.0", @@ -792,7 +792,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.901.0" + "@aws-sdk/client-s3": "^3.908.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -829,22 +829,22 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.901.0.tgz", - "integrity": "sha512-63lcKfggVUFyXhE4SsFXShCTCyh7ZHEqXLyYEL4DwX+VWtxutf9t9m3fF0TNUYDE8eEGWiRXhegj8l4FjuW+wA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.908.0.tgz", + "integrity": "sha512-hYGhNBvdfnxhhywYRkesdxIZD8rvhsp2CBci5kCqrR2o5VvEkn5+waUQtkREtkciEpC4ent4fadg7N9XfTKvgQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/is-array-buffer": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "@smithy/util-middleware": "^4.2.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/util-stream": "^4.5.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, @@ -912,23 +912,23 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.901.0.tgz", - "integrity": "sha512-prgjVC3fDT2VIlmQPiw/cLee8r4frTam9GILRUVQyDdNtshNwV3MiaSCLzzQJjKJlLgnBLNUHJCSmvUVtg+3iA==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.908.0.tgz", + "integrity": "sha512-23MbAOHsGaD0kTVMVLumaIM1f9vtDImIn2lSvPullbjFHKS4XxfrKuPumtKDzl8gzcux+98XnmfDRKH0fzkOUA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-arn-parser": "3.893.0", - "@smithy/core": "^3.14.0", + "@smithy/core": "^3.15.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/protocol-http": "^5.3.0", "@smithy/signature-v4": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/util-stream": "^4.5.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, @@ -951,15 +951,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.901.0.tgz", - "integrity": "sha512-Zby4F03fvD9xAgXGPywyk4bC1jCbnyubMEYChLYohD+x20ULQCf+AimF/Btn7YL+hBpzh1+RmqmvZcx+RgwgNQ==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.908.0.tgz", + "integrity": "sha512-R0ePEOku72EvyJWy/D0Z5f/Ifpfxa0U9gySO3stpNhOox87XhsILpcIsCHPy0OHz1a7cMoZsF6rMKSzDeCnogQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@smithy/core": "^3.14.0", + "@smithy/core": "^3.15.0", "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" @@ -969,44 +969,44 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.901.0.tgz", - "integrity": "sha512-feAAAMsVwctk2Tms40ONybvpfJPLCmSdI+G+OTrNpizkGLNl6ik2Ng2RzxY6UqOfN8abqKP/DOUj1qYDRDG8ag==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.908.0.tgz", + "integrity": "sha512-ZxDYrfxOKXNFHLyvJtT96TJ0p4brZOhwRE4csRXrezEVUN+pNgxuem95YvMALPVhlVqON2CTzr8BX+CcBKvX9Q==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.901.0", + "@aws-sdk/core": "3.908.0", "@aws-sdk/middleware-host-header": "3.901.0", "@aws-sdk/middleware-logger": "3.901.0", "@aws-sdk/middleware-recursion-detection": "3.901.0", - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/region-config-resolver": "3.901.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-endpoints": "3.901.0", - "@aws-sdk/util-user-agent-browser": "3.901.0", - "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.907.0", + "@aws-sdk/util-user-agent-node": "3.908.0", "@smithy/config-resolver": "^4.3.0", - "@smithy/core": "^3.14.0", - "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/core": "^3.15.0", + "@smithy/fetch-http-handler": "^5.3.1", "@smithy/hash-node": "^4.2.0", "@smithy/invalid-dependency": "^4.2.0", "@smithy/middleware-content-length": "^4.2.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-endpoint": "^4.3.1", + "@smithy/middleware-retry": "^4.4.1", "@smithy/middleware-serde": "^4.2.0", "@smithy/middleware-stack": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/node-http-handler": "^4.3.0", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.0", - "@smithy/util-defaults-mode-browser": "^4.2.0", - "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.0", + "@smithy/util-defaults-mode-node": "^4.2.1", "@smithy/util-endpoints": "^3.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", @@ -1035,17 +1035,17 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.901.0.tgz", - "integrity": "sha512-G/0G5tL3beETs2zkI0YQuM2SkrAsYJSe2vN2XtouVSN5c9v6EiSvdSsHAqMhLebnSs2suUkq0JO9ZotbXkUfMQ==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.908.0.tgz", + "integrity": "sha512-MN/0kk2ZDazemXm5FHtB4sfefamIjxrtvPZtCkGYrxopAqoHEkHKS7WqflWz4dtvPtc1A1uMDDZMXTNQbjRkYw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.901.0", + "@aws-sdk/signature-v4-multi-region": "3.908.0", "@aws-sdk/types": "3.901.0", "@aws-sdk/util-format-url": "3.901.0", - "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-endpoint": "^4.3.1", "@smithy/protocol-http": "^5.3.0", - "@smithy/smithy-client": "^4.7.0", + "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, @@ -1054,12 +1054,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.901.0.tgz", - "integrity": "sha512-2IWxbll/pRucp1WQkHi2W5E2SVPGBvk4Is923H7gpNksbVFws18ItjMM8ZpGm44cJEoy1zR5gjhLFklatpuoOw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.908.0.tgz", + "integrity": "sha512-8OodflIzZM2GVuCGiGK6hqwsbfHRDl4kQcEYzHRg9p91H4h5Y876DPvLRkwM7pSC7LKUL0XkKWWVVjwJbp6/Ig==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.901.0", + "@aws-sdk/middleware-sdk-s3": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/protocol-http": "^5.3.0", "@smithy/signature-v4": "^5.3.0", @@ -1071,13 +1071,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.901.0.tgz", - "integrity": "sha512-pJEr1Ggbc/uVTDqp9IbNu9hdr0eQf3yZix3s4Nnyvmg4xmJSGAlbPC9LrNr5u3CDZoc8Z9CuLrvbP4MwYquNpQ==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.908.0.tgz", + "integrity": "sha512-4SosHWRQ8hj1X2yDenCYHParcCjHcd7S+Mdb/lelwF0JBFCNC+dNCI9ws3cP/dFdZO/AIhJQGUBzEQtieloixw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.901.0", - "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/core": "3.908.0", + "@aws-sdk/nested-clients": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/property-provider": "^4.2.0", "@smithy/shared-ini-file-loader": "^4.3.0", @@ -1157,9 +1157,9 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.901.0.tgz", - "integrity": "sha512-Ntb6V/WFI21Ed4PDgL/8NSfoZQQf9xzrwNgiwvnxgAl/KvAvRBgQtqj5gHsDX8Nj2YmJuVoHfH9BGjL9VQ4WNg==", + "version": "3.907.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.907.0.tgz", + "integrity": "sha512-Hus/2YCQmtCEfr4Ls88d07Q99Ex59uvtktiPTV963Q7w7LHuIT/JBjrbwNxtSm2KlJR9PHNdqxwN+fSuNsMGMQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.901.0", @@ -1169,12 +1169,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.901.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.901.0.tgz", - "integrity": "sha512-l59KQP5TY7vPVUfEURc7P5BJKuNg1RSsAKBQW7LHLECXjLqDUbo2SMLrexLBEoArSt6E8QOrIN0C8z/0Xk0jYw==", + "version": "3.908.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.908.0.tgz", + "integrity": "sha512-l6AEaKUAYarcEy8T8NZ+dNZ00VGLs3fW2Cqu1AuPENaSad0/ahEU+VU7MpXS8FhMRGPgplxKVgCTLyTY0Lbssw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.908.0", "@aws-sdk/types": "3.901.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/types": "^4.6.0", @@ -2156,12 +2156,12 @@ ] }, "node_modules/@smithy/abort-controller": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.0.tgz", - "integrity": "sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.2.tgz", + "integrity": "sha512-fPbcmEI+A6QiGOuumTpKSo7z+9VYr5DLN8d5/8jDJOwmt4HAKy/UGuRstCMpKbtr+FMaHH4pvFinSAbIAYCHZQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2181,12 +2181,12 @@ } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.0.tgz", - "integrity": "sha512-HNbGWdyTfSM1nfrZKQjYTvD8k086+M8s1EYkBUdGC++lhxegUp2HgNf5RIt6oOGVvsC26hBCW/11tv8KbwLn/Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", + "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^4.2.0", + "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" }, "engines": { @@ -2194,15 +2194,15 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.3.0.tgz", - "integrity": "sha512-9oH+n8AVNiLPK/iK/agOsoWfrKZ3FGP3502tkksd6SRsKMYiu7AFX0YXo6YBADdsAj7C+G/aLKdsafIJHxuCkQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.3.2.tgz", + "integrity": "sha512-F/G+VaulIebINyfvcoXmODgIc7JU/lxWK9/iI0Divxyvd2QWB7/ZcF7JKwMssWI6/zZzlMkq/Pt6ow2AOEebPw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.0", - "@smithy/types": "^4.6.0", + "@smithy/node-config-provider": "^4.3.2", + "@smithy/types": "^4.7.1", "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-middleware": "^4.2.0", + "@smithy/util-middleware": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -2210,18 +2210,18 @@ } }, "node_modules/@smithy/core": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.14.0.tgz", - "integrity": "sha512-XJ4z5FxvY/t0Dibms/+gLJrI5niRoY0BCmE02fwmPcRYFPI4KI876xaE79YGWIKnEslMbuQPsIEsoU/DXa0DoA==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.16.1.tgz", + "integrity": "sha512-yRx5ag3xEQ/yGvyo80FVukS7ZkeUP49Vbzg0MjfHLkuCIgg5lFtaEJfZR178KJmjWPqLU4d0P4k7SKgF9UkOaQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.0", - "@smithy/protocol-http": "^5.3.0", - "@smithy/types": "^4.6.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/middleware-serde": "^4.2.2", + "@smithy/protocol-http": "^5.3.2", + "@smithy/types": "^4.7.1", + "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/util-middleware": "^4.2.2", + "@smithy/util-stream": "^4.5.2", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" @@ -2231,15 +2231,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.0.tgz", - "integrity": "sha512-SOhFVvFH4D5HJZytb0bLKxCrSnwcqPiNlrw+S4ZXjMnsC+o9JcUQzbZOEQcA8yv9wJFNhfsUiIUKiEnYL68Big==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.2.tgz", + "integrity": "sha512-hOjFTK+4mfehDnfjNkPqHUKBKR2qmlix5gy7YzruNbTdeoBE3QkfNCPvuCK2r05VUJ02QQ9bz2G41CxhSexsMw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.0", - "@smithy/property-provider": "^4.2.0", - "@smithy/types": "^4.6.0", - "@smithy/url-parser": "^4.2.0", + "@smithy/node-config-provider": "^4.3.2", + "@smithy/property-provider": "^4.2.2", + "@smithy/types": "^4.7.1", + "@smithy/url-parser": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -2317,15 +2317,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.0.tgz", - "integrity": "sha512-BG3KSmsx9A//KyIfw+sqNmWFr1YBUr+TwpxFT7yPqAk0yyDh7oSNgzfNH7pS6OC099EGx2ltOULvumCFe8bcgw==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.3.tgz", + "integrity": "sha512-cipIcM3xQ5NdIVwcRb37LaQwIxZNMEZb/ZOPmLFS9uGo9TGx2dGCyMBj9oT7ypH4TUD/kOTc/qHmwQzthrSk+g==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.0", - "@smithy/querystring-builder": "^4.2.0", - "@smithy/types": "^4.6.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/protocol-http": "^5.3.2", + "@smithy/querystring-builder": "^4.2.2", + "@smithy/types": "^4.7.1", + "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" }, "engines": { @@ -2333,14 +2333,14 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.0.tgz", - "integrity": "sha512-MWmrRTPqVKpN8NmxmJPTeQuhewTt8Chf+waB38LXHZoA02+BeWYVQ9ViAwHjug8m7lQb1UWuGqp3JoGDOWvvuA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.3.tgz", + "integrity": "sha512-ZYd5FYhyvD4PCnqa1vO1tzqQ1s9fWs+el8DJZUfHumvq9wl7UXoLAqof+lAqSe/mVsf2I4tclf9BbTr6NL/pjQ==", "license": "Apache-2.0", "dependencies": { "@smithy/chunked-blob-reader": "^5.2.0", - "@smithy/chunked-blob-reader-native": "^4.2.0", - "@smithy/types": "^4.6.0", + "@smithy/chunked-blob-reader-native": "^4.2.1", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2430,18 +2430,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.0.tgz", - "integrity": "sha512-jFVjuQeV8TkxaRlcCNg0GFVgg98tscsmIrIwRFeC74TIUyLE3jmY9xgc1WXrPQYRjQNK3aRoaIk6fhFRGOIoGw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.3.tgz", + "integrity": "sha512-CfxQ6X9L87/3C67Po6AGWXsx8iS4w2BO8vQEZJD6hwqg2vNRC/lMa2O5wXYCG9tKotdZ0R8KG33TS7kpUnYKiw==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.14.0", - "@smithy/middleware-serde": "^4.2.0", - "@smithy/node-config-provider": "^4.3.0", - "@smithy/shared-ini-file-loader": "^4.3.0", - "@smithy/types": "^4.6.0", - "@smithy/url-parser": "^4.2.0", - "@smithy/util-middleware": "^4.2.0", + "@smithy/core": "^3.16.1", + "@smithy/middleware-serde": "^4.2.2", + "@smithy/node-config-provider": "^4.3.2", + "@smithy/shared-ini-file-loader": "^4.3.2", + "@smithy/types": "^4.7.1", + "@smithy/url-parser": "^4.2.2", + "@smithy/util-middleware": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -2449,18 +2449,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.0.tgz", - "integrity": "sha512-yaVBR0vQnOnzex45zZ8ZrPzUnX73eUC8kVFaAAbn04+6V7lPtxn56vZEBBAhgS/eqD6Zm86o6sJs6FuQVoX5qg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.3.tgz", + "integrity": "sha512-EHnKGeFuzbmER4oSl/VJDxPLi+aiZUb3nk5KK8eNwHjMhI04jHlui2ZkaBzMfNmXOgymaS6zV//fyt6PSnI1ow==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.0", - "@smithy/protocol-http": "^5.3.0", - "@smithy/service-error-classification": "^4.2.0", - "@smithy/smithy-client": "^4.7.0", - "@smithy/types": "^4.6.0", - "@smithy/util-middleware": "^4.2.0", - "@smithy/util-retry": "^4.2.0", + "@smithy/node-config-provider": "^4.3.2", + "@smithy/protocol-http": "^5.3.2", + "@smithy/service-error-classification": "^4.2.2", + "@smithy/smithy-client": "^4.8.1", + "@smithy/types": "^4.7.1", + "@smithy/util-middleware": "^4.2.2", + "@smithy/util-retry": "^4.2.2", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" }, @@ -2469,13 +2469,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.0.tgz", - "integrity": "sha512-rpTQ7D65/EAbC6VydXlxjvbifTf4IH+sADKg6JmAvhkflJO2NvDeyU9qsWUNBelJiQFcXKejUHWRSdmpJmEmiw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.2.tgz", + "integrity": "sha512-tDMPMBCsA1GBxanShhPvQYwdiau3NmctUp+eELMhUTDua+EUrugXlaKCnTMMoEB5mbHFebdv81uJPkVP02oihA==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.0", - "@smithy/types": "^4.6.0", + "@smithy/protocol-http": "^5.3.2", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2483,12 +2483,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.0.tgz", - "integrity": "sha512-G5CJ//eqRd9OARrQu9MK1H8fNm2sMtqFh6j8/rPozhEL+Dokpvi1Og+aCixTuwDAGZUkJPk6hJT5jchbk/WCyg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.2.tgz", + "integrity": "sha512-7rgzDyLOQouh1bC6gOXnCGSX2dqvbOclgClsFkj735xQM2CHV63Ams8odNZGJgcqnBsEz44V/pDGHU6ALEUD+w==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2496,14 +2496,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.0.tgz", - "integrity": "sha512-5QgHNuWdT9j9GwMPPJCKxy2KDxZ3E5l4M3/5TatSZrqYVoEiqQrDfAq8I6KWZw7RZOHtVtCzEPdYz7rHZixwcA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.2.tgz", + "integrity": "sha512-u38G0Audi2ORsL0QnzhopZ3yweMblQf8CZNbzUJ3wfTtZ7OiOwOzee0Nge/3dKeG/8lx0kt8K0kqDi6sYu0oKQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.0", - "@smithy/shared-ini-file-loader": "^4.3.0", - "@smithy/types": "^4.6.0", + "@smithy/property-provider": "^4.2.2", + "@smithy/shared-ini-file-loader": "^4.3.2", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2511,15 +2511,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.3.0.tgz", - "integrity": "sha512-RHZ/uWCmSNZ8cneoWEVsVwMZBKy/8123hEpm57vgGXA3Irf/Ja4v9TVshHK2ML5/IqzAZn0WhINHOP9xl+Qy6Q==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.1.tgz", + "integrity": "sha512-9gKJoL45MNyOCGTG082nmx0A6KrbLVQ+5QSSKyzRi0AzL0R81u3wC1+nPvKXgTaBdAKM73fFPdCBHpmtipQwdQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.0", - "@smithy/protocol-http": "^5.3.0", - "@smithy/querystring-builder": "^4.2.0", - "@smithy/types": "^4.6.0", + "@smithy/abort-controller": "^4.2.2", + "@smithy/protocol-http": "^5.3.2", + "@smithy/querystring-builder": "^4.2.2", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2527,12 +2527,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.0.tgz", - "integrity": "sha512-rV6wFre0BU6n/tx2Ztn5LdvEdNZ2FasQbPQmDOPfV9QQyDmsCkOAB0osQjotRCQg+nSKFmINhyda0D3AnjSBJw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.2.tgz", + "integrity": "sha512-MW7MfI+qYe/Ue5RH0uEztEKB+vBlOMM+1Dz68qzTsY8fC9kanXMFPEVdiq35JTGKWt5wZAjU1R0uXYEjK2MM1g==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2540,12 +2540,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.0.tgz", - "integrity": "sha512-6POSYlmDnsLKb7r1D3SVm7RaYW6H1vcNcTWGWrF7s9+2noNYvUsm7E4tz5ZQ9HXPmKn6Hb67pBDRIjrT4w/d7Q==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.2.tgz", + "integrity": "sha512-nkKOI8xEkBXUmdxsFExomOb+wkU+Xgn0Fq2LMC7YIX5r4YPUg7PLayV/s/u3AtbyjWYlrvN7nAiDTLlqSdUjHw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2553,12 +2553,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.0.tgz", - "integrity": "sha512-Q4oFD0ZmI8yJkiPPeGUITZj++4HHYCW3pYBYfIobUCkYpI6mbkzmG1MAQQ3lJYYWj3iNqfzOenUZu+jqdPQ16A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.2.tgz", + "integrity": "sha512-YgXvq89o+R/8zIoeuXYv8Ysrbwgjx+iVYu9QbseqZjMDAhIg/FRt7jis0KASYFtd/Cnsnz4/nYTJXkJDWe8wHg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" }, @@ -2567,12 +2567,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.0.tgz", - "integrity": "sha512-BjATSNNyvVbQxOOlKse0b0pSezTWGMvA87SvoFoFlkRsKXVsN3bEtjCxvsNXJXfnAzlWFPaT9DmhWy1vn0sNEA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.2.tgz", + "integrity": "sha512-DczOD2yJy3NXcv1JvhjFC7bIb/tay6nnIRD/qrzBaju5lrkVBOwCT3Ps37tra20wy8PicZpworStK7ZcI9pCRQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2580,24 +2580,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.0.tgz", - "integrity": "sha512-Ylv1ttUeKatpR0wEOMnHf1hXMktPUMObDClSWl2TpCVT4DwtJhCeighLzSLbgH3jr5pBNM0LDXT5yYxUvZ9WpA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.2.tgz", + "integrity": "sha512-1X17cMLwe/vb4RpZbQVpJ1xQQ7fhQKggMdt3qjdV3+6QNllzvUXyS3WFnyaFWLyaGqfYHKkNONbO1fBCMQyZtQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0" + "@smithy/types": "^4.7.1" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.3.0.tgz", - "integrity": "sha512-VCUPPtNs+rKWlqqntX0CbVvWyjhmX30JCtzO+s5dlzzxrvSfRh5SY0yxnkirvc1c80vdKQttahL71a9EsdolSQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.3.2.tgz", + "integrity": "sha512-AWnLgSmOTdDXM8aZCN4Im0X07M3GGffeL9vGfea4mdKZD0cPT9yLF9SsRbEa00tHLI+KfubDrmjpaKT2pM4GdQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2605,16 +2605,16 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.0.tgz", - "integrity": "sha512-MKNyhXEs99xAZaFhm88h+3/V+tCRDQ+PrDzRqL0xdDpq4gjxcMmf5rBA3YXgqZqMZ/XwemZEurCBQMfxZOWq/g==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.2.tgz", + "integrity": "sha512-BRnQGGyaRSSL0KtjjFF9YoSSg8qzSqHMub4H2iKkd+LZNzZ1b7H5amslZBzi+AnvuwPMyeiNv0oqay/VmIuoRA==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.0", - "@smithy/types": "^4.6.0", + "@smithy/protocol-http": "^5.3.2", + "@smithy/types": "^4.7.1", "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.0", + "@smithy/util-middleware": "^4.2.2", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -2624,17 +2624,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.7.0.tgz", - "integrity": "sha512-3BDx/aCCPf+kkinYf5QQhdQ9UAGihgOVqI3QO5xQfSaIWvUE4KYLtiGRWsNe1SR7ijXC0QEPqofVp5Sb0zC8xQ==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.8.1.tgz", + "integrity": "sha512-N5wK57pVThzLVK5NgmHxocTy5auqGDGQ+JsL5RjCTriPt8JLYgXT0Awa915zCpzc9hXHDOKqDX5g9BFdwkSfUA==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.14.0", - "@smithy/middleware-endpoint": "^4.3.0", - "@smithy/middleware-stack": "^4.2.0", - "@smithy/protocol-http": "^5.3.0", - "@smithy/types": "^4.6.0", - "@smithy/util-stream": "^4.4.0", + "@smithy/core": "^3.16.1", + "@smithy/middleware-endpoint": "^4.3.3", + "@smithy/middleware-stack": "^4.2.2", + "@smithy/protocol-http": "^5.3.2", + "@smithy/types": "^4.7.1", + "@smithy/util-stream": "^4.5.2", "tslib": "^2.6.2" }, "engines": { @@ -2642,9 +2642,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.6.0.tgz", - "integrity": "sha512-4lI9C8NzRPOv66FaY1LL1O/0v0aLVrq/mXP/keUa9mJOApEeae43LsLd2kZRUJw91gxOQfLIrV3OvqPgWz1YsA==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.7.1.tgz", + "integrity": "sha512-WwP7vzoDyzvIFLzF5UhLQ6AsEx/PvSObzlNtJNW3lLy+BaSvTqCU628QKVvcJI/dydlAS1mSHQP7anKcxDcOxA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2654,13 +2654,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.0.tgz", - "integrity": "sha512-AlBmD6Idav2ugmoAL6UtR6ItS7jU5h5RNqLMZC7QrLCoITA9NzIN3nx9GWi8g4z1pfWh2r9r96SX/jHiNwPJ9A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.2.tgz", + "integrity": "sha512-s2EYKukaswzjiHJCss6asB1F4zjRc0E/MFyceAKzb3+wqKA2Z/+Gfhb5FP8xVVRHBAvBkregaQAydifgbnUlCw==", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.0", - "@smithy/types": "^4.6.0", + "@smithy/querystring-parser": "^4.2.2", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2668,9 +2668,9 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.2.0.tgz", - "integrity": "sha512-+erInz8WDv5KPe7xCsJCp+1WCjSbah9gWcmUXc9NqmhyPx59tf7jqFz+za1tRG1Y5KM1Cy1rWCcGypylFp4mvA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.2.0", @@ -2694,9 +2694,9 @@ } }, "node_modules/@smithy/util-body-length-node": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.0.tgz", - "integrity": "sha512-U8q1WsSZFjXijlD7a4wsDQOvOwV+72iHSfq1q7VD+V75xP/pdtm0WIGuaFJ3gcADDOKj2MIBn4+zisi140HEnQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2731,15 +2731,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.2.0.tgz", - "integrity": "sha512-qzHp7ZDk1Ba4LDwQVCNp90xPGqSu7kmL7y5toBpccuhi3AH7dcVBIT/pUxYcInK4jOy6FikrcTGq5wxcka8UaQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.2.tgz", + "integrity": "sha512-6JvKHZ5GORYkEZ2+yJKEHp6dQQKng+P/Mu3g3CDy0fRLQgXEO8be+FLrBGGb4kB9lCW6wcQDkN7kRiGkkVAXgg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.0", - "@smithy/smithy-client": "^4.7.0", - "@smithy/types": "^4.6.0", - "bowser": "^2.11.0", + "@smithy/property-provider": "^4.2.2", + "@smithy/smithy-client": "^4.8.1", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2747,17 +2746,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.0.tgz", - "integrity": "sha512-FxUHS3WXgx3bTWR6yQHNHHkQHZm/XKIi/CchTnKvBulN6obWpcbzJ6lDToXn+Wp0QlVKd7uYAz2/CTw1j7m+Kg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.3.tgz", + "integrity": "sha512-bkTGuMmKvghfCh9NayADrQcjngoF8P+XTgID5r3rm+8LphFiuM6ERqpBS95YyVaLjDetnKus9zK/bGlkQOOtNQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.3.0", - "@smithy/credential-provider-imds": "^4.2.0", - "@smithy/node-config-provider": "^4.3.0", - "@smithy/property-provider": "^4.2.0", - "@smithy/smithy-client": "^4.7.0", - "@smithy/types": "^4.6.0", + "@smithy/config-resolver": "^4.3.2", + "@smithy/credential-provider-imds": "^4.2.2", + "@smithy/node-config-provider": "^4.3.2", + "@smithy/property-provider": "^4.2.2", + "@smithy/smithy-client": "^4.8.1", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2791,12 +2790,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.0.tgz", - "integrity": "sha512-u9OOfDa43MjagtJZ8AapJcmimP+K2Z7szXn8xbty4aza+7P1wjFmy2ewjSbhEiYQoW1unTlOAIV165weYAaowA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.2.tgz", + "integrity": "sha512-wL9tZwWKy0x0qf6ffN7tX5CT03hb1e7XpjdepaKfKcPcyn5+jHAWPqivhF1Sw/T5DYi9wGcxsX8Lu07MOp2Puw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.6.0", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2804,13 +2803,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.0.tgz", - "integrity": "sha512-BWSiuGbwRnEE2SFfaAZEX0TqaxtvtSYPM/J73PFVm+A29Fg1HTPiYFb8TmX1DXp4hgcdyJcNQmprfd5foeORsg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.2.tgz", + "integrity": "sha512-TlbnWAOoCuG2PgY0Hi3BGU1w2IXs3xDsD4E8WDfKRZUn2qx3wRA9mbYnmpWHPswTJCz2L+ebh+9OvD42sV4mNw==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.0", - "@smithy/types": "^4.6.0", + "@smithy/service-error-classification": "^4.2.2", + "@smithy/types": "^4.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2818,15 +2817,15 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.4.0.tgz", - "integrity": "sha512-vtO7ktbixEcrVzMRmpQDnw/Ehr9UWjBvSJ9fyAbadKkC4w5Cm/4lMO8cHz8Ysb8uflvQUNRcuux/oNHKPXkffg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.2.tgz", + "integrity": "sha512-RWYVuQVKtNbr7E0IxV8XHDId714yHPTxU6dHScd6wSMWAXboErzTG7+xqcL+K3r0Xg0cZSlfuNhl1J0rzMLSSw==", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.0", - "@smithy/node-http-handler": "^4.3.0", - "@smithy/types": "^4.6.0", - "@smithy/util-base64": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.3", + "@smithy/node-http-handler": "^4.4.1", + "@smithy/types": "^4.7.1", + "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", @@ -4076,9 +4075,9 @@ } }, "node_modules/chart.js": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", - "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" @@ -4722,9 +4721,9 @@ } }, "node_modules/dd-trace": { - "version": "5.70.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.70.0.tgz", - "integrity": "sha512-A757IJ3OIrRvFQXqa7bZ8KvwwtnjTEhj/2mNG88mNAbaildJI+FKQHDQWMM02YvQeJHwneeS6dmTj2V1mVnGrg==", + "version": "5.71.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.71.0.tgz", + "integrity": "sha512-mja6sNhRV6W4Pl1yylThAso/F4aeDrmc9ZpD75axXodaMt9bER/c764deuqeuG3XYfHByuZCV4NHoYADXft9ig==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { @@ -6865,13 +6864,13 @@ } }, "node_modules/intuit-oauth": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/intuit-oauth/-/intuit-oauth-4.2.0.tgz", - "integrity": "sha512-FG+A4uiJT9xIm07yLtp4bhAdcOMcHukW7gZs6aJvh+3zHUKKqG/zEAtAIZP1d8YCMbPVHu5SbbnMygeM/OVEvg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/intuit-oauth/-/intuit-oauth-4.2.1.tgz", + "integrity": "sha512-/qmPjlLkSVkI5Q2jalM/fxnQg4QiRSqCOFR/94veCzWaxDf/TmqsdIGP499qXNGUvI6OERxo+IQ69hEE/5TSiQ==", "license": "Apache-2.0", "dependencies": { "atob": "2.1.2", - "axios": "^1.5.1", + "axios": "^1.9.0", "csrf": "^3.0.4", "jsonwebtoken": "^9.0.2", "query-string": "^6.12.1", @@ -10651,9 +10650,9 @@ "license": "Unlicense" }, "node_modules/twilio": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.10.2.tgz", - "integrity": "sha512-pkMdXK0PJHR0elu3GmaDlYt4DDWPkkmuJLVUQjnctehu01IgbAp+VZ2ctbUSh1anDuqKqimAIuMnW9xmKith6w==", + "version": "5.10.3", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.10.3.tgz", + "integrity": "sha512-msve3uADprpG+LRlthOxBUJWZDczGe+mdzotG7Wluaf8nn8fSIK0n2fX3INR26Xedeea/azmAdLK0c2rJhIHpQ==", "license": "MIT", "dependencies": { "axios": "^1.12.0", diff --git a/package.json b/package.json index 4ce6902fd..62f1e6adc 100644 --- a/package.json +++ b/package.json @@ -18,14 +18,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.901.0", - "@aws-sdk/client-elasticache": "^3.901.0", - "@aws-sdk/client-s3": "^3.901.0", - "@aws-sdk/client-secrets-manager": "^3.901.0", - "@aws-sdk/client-ses": "^3.901.0", - "@aws-sdk/credential-provider-node": "^3.901.0", - "@aws-sdk/lib-storage": "^3.903.0", - "@aws-sdk/s3-request-presigner": "^3.901.0", + "@aws-sdk/client-cloudwatch-logs": "^3.908.0", + "@aws-sdk/client-elasticache": "^3.908.0", + "@aws-sdk/client-s3": "^3.908.0", + "@aws-sdk/client-secrets-manager": "^3.908.0", + "@aws-sdk/client-ses": "^3.908.0", + "@aws-sdk/credential-provider-node": "^3.908.0", + "@aws-sdk/lib-storage": "^3.908.0", + "@aws-sdk/s3-request-presigner": "^3.908.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -35,13 +35,13 @@ "axios-curlirize": "^2.0.0", "better-queue": "^3.8.12", "bullmq": "^5.61.0", - "chart.js": "^4.5.0", + "chart.js": "^4.5.1", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.70.0", + "dd-trace": "^5.71.0", "dinero.js": "^1.9.1", "dotenv": "^17.2.3", "express": "^4.21.1", @@ -49,7 +49,7 @@ "firebase-admin": "^13.5.0", "graphql": "^16.11.0", "graphql-request": "^6.1.0", - "intuit-oauth": "^4.2.0", + "intuit-oauth": "^4.2.1", "ioredis": "^5.8.1", "json-2-csv": "^5.5.9", "jsonwebtoken": "^9.0.2", @@ -70,7 +70,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.10.2", + "twilio": "^5.10.3", "uuid": "^11.1.0", "winston": "^3.18.3", "winston-cloudwatch": "^6.3.0", diff --git a/server/rr/rr-calculate-allocations.js b/server/rr/rr-calculate-allocations.js deleted file mode 100644 index fe460b30f..000000000 --- a/server/rr/rr-calculate-allocations.js +++ /dev/null @@ -1,381 +0,0 @@ -// server/rr/rr-calculate-allocations.js -const { GraphQLClient } = require("graphql-request"); -const queries = require("../graphql-client/queries"); -const RRLogger = require("./rr-logger"); -const Dinero = require("dinero.js"); -const _ = require("lodash"); -const WsLogger = require("../web-sockets/createLogEvent").default || require("../web-sockets/createLogEvent"); - -// InstanceManager wiring (same as CDK file) -const InstanceManager = require("../utils/instanceMgr").default; -const { DiscountNotAlreadyCounted } = InstanceManager({ - imex: require("../job/job-totals"), - rome: require("../job/job-totals-USA") -}); - -/** - * HTTP route version (parity with CDK file) - */ -exports.defaultRoute = async function rrAllocationsHttp(req, res) { - try { - WsLogger.createLogEvent(req, "DEBUG", `RR: calculate allocations request for ${req.body.jobid}`); - const jobData = await queryJobData(req, req.BearerToken, req.body.jobid); - return res.status(200).json({ data: calculateAllocations(req, jobData) }); - } catch (error) { - WsLogger.createLogEvent(req, "ERROR", `RR CalculateAllocations error. ${error}`); - res.status(500).json({ error: `RR CalculateAllocations error. ${error}` }); - } -}; - -/** - * Socket version (parity with CDK file) - * @param {Socket} socket - * @param {string} jobid - * @returns {Promise} allocations - */ -exports.default = async function rrCalculateAllocations(socket, jobid) { - try { - const token = "Bearer " + socket.handshake.auth.token; - const jobData = await queryJobData(socket, token, jobid, /* isFortellis */ false); - return calculateAllocations(socket, jobData); - } catch (error) { - RRLogger(socket, "ERROR", `RR CalculateAllocations error. ${error}`); - return []; - } -}; - -async function queryJobData(connectionData, token, jobid /* , isFortellis */) { - WsLogger.createLogEvent(connectionData, "DEBUG", `RR: querying job data for id ${jobid}`); - const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {}); - const result = await client.setHeaders({ Authorization: token }).request(queries.GET_CDK_ALLOCATIONS, { id: jobid }); - WsLogger.createLogEvent(connectionData, "DEBUG", `RR: job data query result ${JSON.stringify(result, null, 2)}`); - return result.jobs_by_pk; -} - -/** - * Core allocation logic – mirrors CDK version, but logs as RR - */ -function calculateAllocations(connectionData, job) { - const { bodyshop } = job; - - // Build tax allocation maps for US (Rome) and IMEX (Canada) contexts - const taxAllocations = InstanceManager({ - executeFunction: true, - deubg: true, - args: [], - imex: () => ({ - state: { - center: bodyshop.md_responsibility_centers.taxes.state.name, - sale: Dinero(job.job_totals.totals.state_tax), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes.state, - costCenter: bodyshop.md_responsibility_centers.taxes.state - }, - federal: { - center: bodyshop.md_responsibility_centers.taxes.federal.name, - sale: Dinero(job.job_totals.totals.federal_tax), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes.federal, - costCenter: bodyshop.md_responsibility_centers.taxes.federal - } - }), - rome: () => ({ - tax_ty1: { - center: bodyshop.md_responsibility_centers.taxes[`tax_ty1`].name, - sale: Dinero(job.job_totals.totals.us_sales_tax_breakdown[`ty1Tax`]), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty1`], - costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty1`] - }, - tax_ty2: { - center: bodyshop.md_responsibility_centers.taxes[`tax_ty2`].name, - sale: Dinero(job.job_totals.totals.us_sales_tax_breakdown[`ty2Tax`]), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty2`], - costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty2`] - }, - tax_ty3: { - center: bodyshop.md_responsibility_centers.taxes[`tax_ty3`].name, - sale: Dinero(job.job_totals.totals.us_sales_tax_breakdown[`ty3Tax`]), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty3`], - costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty3`] - }, - tax_ty4: { - center: bodyshop.md_responsibility_centers.taxes[`tax_ty4`].name, - sale: Dinero(job.job_totals.totals.us_sales_tax_breakdown[`ty4Tax`]), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty4`], - costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty4`] - }, - tax_ty5: { - center: bodyshop.md_responsibility_centers.taxes[`tax_ty5`].name, - sale: Dinero(job.job_totals.totals.us_sales_tax_breakdown[`ty5Tax`]), - cost: Dinero(), - profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty5`], - costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty5`] - } - }) - }); - - // Detect existing MAPA/MASH (Mitchell) lines so we don’t double count - let hasMapaLine = false; - let hasMashLine = false; - - const profitCenterHash = job.joblines.reduce((acc, val) => { - if (val.db_ref === "936008") hasMapaLine = true; // paint materials (MAPA) - if (val.db_ref === "936007") hasMashLine = true; // shop supplies (MASH) - - if (val.profitcenter_part) { - if (!acc[val.profitcenter_part]) acc[val.profitcenter_part] = Dinero(); - - let dineroAmount = Dinero({ amount: Math.round(val.act_price * 100) }).multiply(val.part_qty || 1); - - // Conditional discount add-on if not already counted elsewhere - dineroAmount = dineroAmount.add( - ((val.prt_dsmk_m && val.prt_dsmk_m !== 0) || (val.prt_dsmk_p && val.prt_dsmk_p !== 0)) && - DiscountNotAlreadyCounted(val, job.joblines) - ? val.prt_dsmk_m - ? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) }) - : Dinero({ amount: Math.round(val.act_price * 100) }) - .multiply(val.part_qty || 0) - .percentage(Math.abs(val.prt_dsmk_p || 0)) - .multiply(val.prt_dsmk_p > 0 ? 1 : -1) - : Dinero() - ); - - acc[val.profitcenter_part] = acc[val.profitcenter_part].add(dineroAmount); - } - - if (val.profitcenter_labor && val.mod_lbr_ty) { - if (!acc[val.profitcenter_labor]) acc[val.profitcenter_labor] = Dinero(); - acc[val.profitcenter_labor] = acc[val.profitcenter_labor].add( - Dinero({ amount: Math.round(job[`rate_${val.mod_lbr_ty.toLowerCase()}`] * 100) }).multiply(val.mod_lb_hrs) - ); - } - - return acc; - }, {}); - - const selectedDmsAllocationConfig = bodyshop.md_responsibility_centers.dms_defaults.find( - (d) => d.name === job.dms_allocation - ); - - WsLogger.createLogEvent( - connectionData, - "DEBUG", - `RR: Using DMS Allocation ${selectedDmsAllocationConfig && selectedDmsAllocationConfig.name} for cost export.` - ); - - // Build cost center totals from bills and time tickets - let costCenterHash = {}; - const disableBillWip = !!bodyshop?.pbs_configuration?.disablebillwip; - if (!disableBillWip) { - costCenterHash = job.bills.reduce((billAcc, bill) => { - bill.billlines.forEach((line) => { - const target = selectedDmsAllocationConfig.costs[line.cost_center]; - if (!billAcc[target]) billAcc[target] = Dinero(); - - let lineDinero = Dinero({ amount: Math.round((line.actual_cost || 0) * 100) }) - .multiply(line.quantity) - .multiply(bill.is_credit_memo ? -1 : 1); - - billAcc[target] = billAcc[target].add(lineDinero); - }); - return billAcc; - }, {}); - } - - job.timetickets.forEach((ticket) => { - const ticketTotal = Dinero({ - amount: Math.round( - ticket.rate * - (ticket.employee && ticket.employee.flat_rate ? ticket.productivehrs || 0 : ticket.actualhrs || 0) * - 100 - ) - }); - const target = selectedDmsAllocationConfig.costs[ticket.ciecacode]; - if (!costCenterHash[target]) costCenterHash[target] = Dinero(); - costCenterHash[target] = costCenterHash[target].add(ticketTotal); - }); - - // Add MAPA/MASH lines when not explicitly present - if (!hasMapaLine && job.job_totals.rates.mapa.total.amount > 0) { - const accountName = selectedDmsAllocationConfig.profits.MAPA; - const account = bodyshop.md_responsibility_centers.profits.find((c) => c.name === accountName); - if (account) { - if (!profitCenterHash[accountName]) profitCenterHash[accountName] = Dinero(); - profitCenterHash[accountName] = profitCenterHash[accountName].add(Dinero(job.job_totals.rates.mapa.total)); - } - } - if (!hasMashLine && job.job_totals.rates.mash.total.amount > 0) { - const accountName = selectedDmsAllocationConfig.profits.MASH; - const account = bodyshop.md_responsibility_centers.profits.find((c) => c.name === accountName); - if (account) { - if (!profitCenterHash[accountName]) profitCenterHash[accountName] = Dinero(); - profitCenterHash[accountName] = profitCenterHash[accountName].add(Dinero(job.job_totals.rates.mash.total)); - } - } - - // Optional materials costing (CDK setting reused by RR sites if configured) - if (bodyshop?.cdk_configuration?.sendmaterialscosting) { - const percent = bodyshop.cdk_configuration.sendmaterialscosting; - // Paint Mat - const mapaCostName = selectedDmsAllocationConfig.costs.MAPA; - const mapaCost = bodyshop.md_responsibility_centers.costs.find((c) => c.name === mapaCostName); - if (mapaCost) { - if (!costCenterHash[mapaCostName]) costCenterHash[mapaCostName] = Dinero(); - if (job.bodyshop.use_paint_scale_data === true && job.mixdata.length > 0) { - costCenterHash[mapaCostName] = costCenterHash[mapaCostName].add( - Dinero({ amount: Math.round(((job.mixdata[0] && job.mixdata[0].totalliquidcost) || 0) * 100) }) - ); - } else { - costCenterHash[mapaCostName] = costCenterHash[mapaCostName].add( - Dinero(job.job_totals.rates.mapa.total).percentage(percent) - ); - } - } - // Shop Mat - const mashCostName = selectedDmsAllocationConfig.costs.MASH; - const mashCost = bodyshop.md_responsibility_centers.costs.find((c) => c.name === mashCostName); - if (mashCost) { - if (!costCenterHash[mashCostName]) costCenterHash[mashCostName] = Dinero(); - costCenterHash[mashCostName] = costCenterHash[mashCostName].add( - Dinero(job.job_totals.rates.mash.total).percentage(percent) - ); - } - } - - // Provinical PVRT roll-in (Canada only) - const { ca_bc_pvrt } = job; - if (ca_bc_pvrt) { - taxAllocations.state.sale = taxAllocations.state.sale.add(Dinero({ amount: Math.round((ca_bc_pvrt || 0) * 100) })); - } - - // Towing / Storage / Other adjustments - if (job.towing_payable && job.towing_payable !== 0) { - const name = selectedDmsAllocationConfig.profits.TOW; - const acct = bodyshop.md_responsibility_centers.profits.find((c) => c.name === name); - if (acct) { - if (!profitCenterHash[name]) profitCenterHash[name] = Dinero(); - profitCenterHash[name] = profitCenterHash[name].add( - Dinero({ amount: Math.round((job.towing_payable || 0) * 100) }) - ); - } - } - if (job.storage_payable && job.storage_payable !== 0) { - const name = selectedDmsAllocationConfig.profits.TOW; - const acct = bodyshop.md_responsibility_centers.profits.find((c) => c.name === name); - if (acct) { - if (!profitCenterHash[name]) profitCenterHash[name] = Dinero(); - profitCenterHash[name] = profitCenterHash[name].add( - Dinero({ amount: Math.round((job.storage_payable || 0) * 100) }) - ); - } - } - if (job.adjustment_bottom_line && job.adjustment_bottom_line !== 0) { - const name = selectedDmsAllocationConfig.profits.PAO; - const acct = bodyshop.md_responsibility_centers.profits.find((c) => c.name === name); - if (acct) { - if (!profitCenterHash[name]) profitCenterHash[name] = Dinero(); - profitCenterHash[name] = profitCenterHash[name].add( - Dinero({ amount: Math.round((job.adjustment_bottom_line || 0) * 100) }) - ); - } - } - - // Rome profile-level adjustments for parts / labor / materials - if (InstanceManager({ rome: true })) { - Object.keys(job.job_totals.parts.adjustments).forEach((key) => { - const name = selectedDmsAllocationConfig.profits[key]; - const acct = bodyshop.md_responsibility_centers.profits.find((c) => c.name === name); - if (acct) { - if (!profitCenterHash[name]) profitCenterHash[name] = Dinero(); - profitCenterHash[name] = profitCenterHash[name].add(Dinero(job.job_totals.parts.adjustments[key])); - } else { - WsLogger.createLogEvent(connectionData, "ERROR", `RR CalculateAllocations: missing parts adj account: ${name}`); - } - }); - - Object.keys(job.job_totals.rates).forEach((key) => { - const rate = job.job_totals.rates[key]; - if (rate && rate.adjustment && Dinero(rate.adjustment).isZero() === false) { - const name = selectedDmsAllocationConfig.profits[key.toUpperCase()]; - const acct = bodyshop.md_responsibility_centers.profits.find((c) => c.name === name); - if (acct) { - if (!profitCenterHash[name]) profitCenterHash[name] = Dinero(); - // NOTE: the original code had rate.adjustments (plural). If that’s a bug upstream, fix there. - profitCenterHash[name] = profitCenterHash[name].add(Dinero(rate.adjustments || rate.adjustment)); - } else { - WsLogger.createLogEvent( - connectionData, - "ERROR", - `RR CalculateAllocations: missing rate adj account: ${name}` - ); - } - } - }); - } - - // Merge profit & cost centers - const jobAllocations = _.union(Object.keys(profitCenterHash), Object.keys(costCenterHash)).map((key) => { - const profitCenter = bodyshop.md_responsibility_centers.profits.find((c) => c.name === key); - const costCenter = bodyshop.md_responsibility_centers.costs.find((c) => c.name === key); - return { - center: key, - sale: profitCenterHash[key] ? profitCenterHash[key] : Dinero(), - cost: costCenterHash[key] ? costCenterHash[key] : Dinero(), - profitCenter, - costCenter - }; - }); - - // Add tax centers (non-zero only) - const taxRows = Object.keys(taxAllocations) - .filter((k) => taxAllocations[k].sale.getAmount() > 0 || taxAllocations[k].cost.getAmount() > 0) - .map((k) => { - const base = { ...taxAllocations[k], tax: k }; - // Optional GST override preserved from CDK logic - const override = selectedDmsAllocationConfig.gst_override; - if (k === "federal" && override) { - base.costCenter.dms_acctnumber = override; - base.profitCenter.dms_acctnumber = override; - } - return base; - }); - - // Totals adjustments centers - const extra = []; - if (job.job_totals.totals.ttl_adjustment) { - extra.push({ - center: "SUB ADJ", - sale: Dinero(job.job_totals.totals.ttl_adjustment), - cost: Dinero(), - profitCenter: { - name: "SUB ADJ", - accountdesc: "SUB ADJ", - accountitem: "SUB ADJ", - accountname: "SUB ADJ", - dms_acctnumber: bodyshop.md_responsibility_centers.ttl_adjustment.dms_acctnumber - }, - costCenter: {} - }); - } - if (job.job_totals.totals.ttl_tax_adjustment) { - extra.push({ - center: "TAX ADJ", - sale: Dinero(job.job_totals.totals.ttl_tax_adjustment), - cost: Dinero(), - profitCenter: { - name: "TAX ADJ", - accountdesc: "TAX ADJ", - accountitem: "TAX ADJ", - accountname: "TAX ADJ", - dms_acctnumber: bodyshop.md_responsibility_centers.ttl_tax_adjustment.dms_acctnumber - }, - costCenter: {} - }); - } - - return [...jobAllocations, ...taxRows, ...extra]; -} diff --git a/server/rr/rr-config.js b/server/rr/rr-config.js new file mode 100644 index 000000000..fc8366860 --- /dev/null +++ b/server/rr/rr-config.js @@ -0,0 +1,81 @@ +// server/rr/rr-config.js +const { GraphQLClient, gql } = require("graphql-request"); + +/** + * Fetch the bodyshop row (dealer + per-shop RR json). + * No fallback to env for dealer/store/branch. + */ +async function fetchBodyshopRRRow(bodyshopId) { + if (!bodyshopId) throw new Error("Missing bodyshopId for RR config."); + + const endpoint = process.env.GRAPHQL_ENDPOINT; + if (!endpoint) throw new Error("GRAPHQL_ENDPOINT env var is required."); + + const headers = {}; + if (process.env.HASURA_ADMIN_SECRET) { + headers["x-hasura-admin-secret"] = process.env.HASURA_ADMIN_SECRET; + } else if (process.env.GRAPHQL_BEARER) { + headers["authorization"] = `Bearer ${process.env.GRAPHQL_BEARER}`; + } + + const client = new GraphQLClient(endpoint, { headers }); + + const Q = gql` + query BodyshopRR($id: uuid!) { + bodyshops_by_pk(id: $id) { + rr_dealerid + rr_configuration + } + } + `; + + const { bodyshops_by_pk: bs } = await client.request(Q, { id: bodyshopId }); + if (!bs) throw new Error("Bodyshop not found."); + if (!bs.rr_dealerid) throw new Error("Bodyshop is not configured for RR (missing rr_dealerid)."); + + let cfgJson = bs.rr_configuration || {}; + if (typeof cfgJson === "string") { + try { + cfgJson = JSON.parse(cfgJson); + } catch { + cfgJson = {}; + } + } + + return { + dealerNumber: bs.rr_dealerid, + storeNumber: cfgJson.storeNumber, + branchNumber: cfgJson.branchNumber + }; +} + +/** + * Build the full RR config object used by downstream code. + * - Dealer/Store/Branch: from DB (required) + * - Transport/BaseURL/creds/PPSysId: from env (deployment-wide) + */ +async function getRRConfigForBodyshop(bodyshopId) { + const { dealerNumber, storeNumber, branchNumber } = await fetchBodyshopRRRow(bodyshopId); + + const rrTransport = (process.env.RR_TRANSPORT || "STAR").toUpperCase(); + return { + // Per-bodyshop (DB) + dealerNumber, + storeNumber, + branchNumber, + + // Duplicate snake_case for legacy call-sites that expect it + dealer_number: dealerNumber, + store_number: storeNumber, + branch_number: branchNumber, + + // Deployment-wide (env) + baseUrl: process.env.RR_BASE_URL, + username: process.env.RR_USERNAME, + password: process.env.RR_PASSWORD, + ppsysId: process.env.RR_PPSYSID, + rrTransport + }; +} + +module.exports = { getRRConfigForBodyshop }; diff --git a/server/rr/rr-constants.js b/server/rr/rr-constants.js index 7c65fefed..280bc9396 100644 --- a/server/rr/rr-constants.js +++ b/server/rr/rr-constants.js @@ -1,6 +1,11 @@ /** * STAR-only constants for Reynolds & Reynolds (Rome/RCI) * Used by rr-helpers.js to build and send SOAP requests. + * + * IMPORTANT: + * - Only rr-test.js should fall back to ENV for dealer/store/branch. + * - All runtime code (sockets/routes/jobs) must pass per-bodyshop + * values from the database (see rr-config.js#getRRConfigForBodyshop). */ exports.RR_NS = Object.freeze({ @@ -21,6 +26,8 @@ const RR_SOAP_HEADERS = { "Content-Type": "text/xml; charset=utf-8", SOAPAction: RR_STAR_SOAP_ACTION }; +// Export if other modules need default STAR headers +exports.RR_SOAP_HEADERS = RR_SOAP_HEADERS; // All STAR-supported actions (mapped to Mustache templates) exports.RR_ACTIONS = Object.freeze({ @@ -34,17 +41,37 @@ exports.RR_ACTIONS = Object.freeze({ UpdateRepairOrder: { template: "UpdateRepairOrder" } }); -// Base config loader (environment-driven) +/** + * Base config loader (environment-driven) + * + * ⚠️ Policy: + * - Only rr-test.js should rely on the ENV values for dealer/store/branch. + * - All other call sites must inject per-bodyshop values from DB. + */ exports.getBaseRRConfig = function getBaseRRConfig() { return { baseUrl: process.env.RR_BASE_URL, username: process.env.RR_USERNAME, password: process.env.RR_PASSWORD, ppsysId: process.env.RR_PPSYSID, // optional legacy identifier + + // ❗ These are ONLY for rr-test.js fallback. dealerNumber: process.env.RR_DEALER_NUMBER, storeNumber: process.env.RR_STORE_NUMBER, branchNumber: process.env.RR_BRANCH_NUMBER || "01", + wssePasswordType: process.env.RR_WSSE_PASSWORD_TYPE || "Text", timeout: Number(process.env.RR_TIMEOUT_MS || 30000) }; }; + +/** + * Normalize dealer/store/branch field names (camelCase vs snake_case). + * Safe to use in helpers to tolerate mixed callers during migration. + */ +exports.normalizeRRDealerFields = function normalizeRRDealerFields(cfg = {}) { + const dealerNumber = cfg.dealerNumber ?? cfg.dealer_number; + const storeNumber = cfg.storeNumber ?? cfg.store_number; + const branchNumber = cfg.branchNumber ?? cfg.branch_number; + return { dealerNumber, storeNumber, branchNumber }; +}; diff --git a/server/rr/rr-helpers.js b/server/rr/rr-helpers.js index 01da93983..8f0a59ff4 100644 --- a/server/rr/rr-helpers.js +++ b/server/rr/rr-helpers.js @@ -12,17 +12,20 @@ const axios = require("axios"); const mustache = require("mustache"); const { XMLParser } = require("fast-xml-parser"); const RRLogger = require("./rr-logger"); -const { RR_ACTIONS, RR_SOAP_HEADERS, RR_STAR_SOAP_ACTION, RR_NS, getBaseRRConfig } = require("./rr-constants"); +const { + RR_ACTIONS, + RR_SOAP_HEADERS, + RR_SOAP_ACTION, + RR_NS, + getBaseRRConfig, + normalizeRRDealerFields +} = require("./rr-constants"); const { RrApiError } = require("./rr-error"); const xmlFormatter = require("xml-formatter"); /** - * Remove XML decl, collapse inter-tag whitespace, strip empty lines, - * then pretty-print. Safe for XML because we only touch whitespace - * BETWEEN tags, not inside text nodes. - /** * Collapse Mustache-induced whitespace and pretty print. - * - strips XML decl (inner) + * - strips inner XML decl * - removes lines that are only whitespace * - collapses inter-tag whitespace * - formats with consistent indentation @@ -69,25 +72,37 @@ async function renderXmlTemplate(templateName, data) { return rendered.replace(/^\s*<\?xml[^>]*\?>\s*/i, ""); } -// ---------- Config resolution (STAR only) ---------- +/** + * Resolve RR config for STAR transport. + * + * Policy: + * - Base (transport) settings (baseUrl, username, password, ppsysId, wssePasswordType, timeout) come from env. + * - Dealer identifiers (dealer/store/branch) MUST be provided by the caller (DB-driven). + * - We DO NOT fall back to env for dealer/store/branch here. Only rr-test.js is allowed to do that. + */ async function resolveRRConfig(_socket, bodyshopConfig) { - const envCfg = getBaseRRConfig(); + const baseEnv = getBaseRRConfig(); - if (bodyshopConfig && typeof bodyshopConfig === "object") { - return { - ...envCfg, - baseUrl: bodyshopConfig.baseUrl || envCfg.baseUrl, - username: bodyshopConfig.username || envCfg.username, - password: bodyshopConfig.password || envCfg.password, - ppsysId: bodyshopConfig.ppsysId || envCfg.ppsysId, - dealerNumber: bodyshopConfig.dealer_number || envCfg.dealerNumber, - storeNumber: bodyshopConfig.store_number || envCfg.storeNumber, - branchNumber: bodyshopConfig.branch_number || envCfg.branchNumber, - wssePasswordType: bodyshopConfig.wssePasswordType || envCfg.wssePasswordType || "Text", - timeout: envCfg.timeout - }; + const { dealerNumber, storeNumber, branchNumber } = normalizeRRDealerFields(bodyshopConfig || {}); + if (!dealerNumber || !storeNumber || !branchNumber) { + throw new Error( + "Missing dealer/store/branch in RR config. These must be loaded from the database (no env fallback here)." + ); } - return envCfg; + + return { + baseUrl: bodyshopConfig?.baseUrl || baseEnv.baseUrl, + username: bodyshopConfig?.username || baseEnv.username, + password: bodyshopConfig?.password || baseEnv.password, + ppsysId: bodyshopConfig?.ppsysId || baseEnv.ppsysId, + wssePasswordType: bodyshopConfig?.wssePasswordType || baseEnv.wssePasswordType || "Text", + timeout: baseEnv.timeout, + + // canonical identifiers (DB-driven only) + dealerNumber, + storeNumber, + branchNumber + }; } // ---------- Response parsing ---------- @@ -161,8 +176,7 @@ function parseRRResponse(xml) { // ---------- STAR envelope helpers ---------- function wrapWithApplicationArea(innerXml, { CreationDateTime, BODId, Sender, Destination }) { - // Make sure we inject *inside* the STAR root, not before it. - // 1) Strip any XML declaration just in case (idempotent) + // Strip any inner XML declaration (idempotent) let xml = innerXml.replace(/^\s*<\?xml[^>]*\?>\s*/i, ""); const appArea = ` @@ -182,8 +196,7 @@ function wrapWithApplicationArea(innerXml, { CreationDateTime, BODId, Sender, De `.trim(); - // Inject right after the opening tag of the root element (skip processing instructions) - // e.g. ==> insert ApplicationArea here + // Inject right after the opening tag of the root element xml = xml.replace(/^(\s*<[^!?][^>]*>)/, `$1\n${appArea}\n`); return xml; @@ -229,7 +242,7 @@ async function MakeRRCall({ action, body, socket, - dealerConfig, // optional per-shop overrides + dealerConfig, // required in runtime code; rr-test.js can still pass env-inflated cfg retries = 1, jobid }) { @@ -237,6 +250,7 @@ async function MakeRRCall({ throw new Error(`Invalid RR action: ${action}`); } + // Prefer explicit dealerConfig from caller; otherwise enforce DB-provided config via resolveRRConfig const cfg = dealerConfig || (await resolveRRConfig(socket, undefined)); const baseUrl = cfg.baseUrl; if (!baseUrl) throw new Error("Missing RR base URL"); @@ -246,8 +260,7 @@ async function MakeRRCall({ const renderedBusiness = await renderXmlTemplate(templateName, body?.data || {}); // Build STAR envelope - let envelope = await buildStarEnvelope(renderedBusiness, cfg, body?.appArea); - + const envelope = await buildStarEnvelope(renderedBusiness, cfg, body?.appArea); const formattedEnvelope = prettyPrintXml(envelope); // Guardrails @@ -255,11 +268,11 @@ async function MakeRRCall({ throw new Error("STAR envelope malformed: missing ProcessMessage/ApplicationArea"); } - const headers = { ...RR_SOAP_HEADERS, SOAPAction: RR_STAR_SOAP_ACTION }; + const headers = { ...RR_SOAP_HEADERS, SOAPAction: RR_SOAP_ACTION }; RRLogger(socket, "debug", `Sending RR SOAP request`, { action, - soapAction: RR_STAR_SOAP_ACTION, + soapAction: RR_SOAP_ACTION, endpoint: baseUrl, jobid, mode: "STAR" diff --git a/server/rr/rr-mappers.js b/server/rr/rr-mappers.js index 639d14d31..b986075b9 100644 --- a/server/rr/rr-mappers.js +++ b/server/rr/rr-mappers.js @@ -5,6 +5,7 @@ */ const dayjs = require("dayjs"); +const { normalizeRRDealerFields } = require("./rr-constants"); /** * Utility: formats date/time to R&R’s preferred format (ISO or yyyy-MM-dd). @@ -22,6 +23,15 @@ const num = (val) => (val != null ? String(val) : undefined); const toBoolStr = (v) => (v === true ? "true" : v === false ? "false" : undefined); const hasAny = (obj) => !!obj && Object.values(obj).some((v) => v !== undefined && v !== null && v !== ""); +/** + * Pull canonical Dealer/Store/Branch fields from cfg (tolerate snake_case during migration). + * Enforces DB-provided values upstream (no env fallback here). + */ +function getDSB(cfg) { + const { dealerNumber, storeNumber, branchNumber } = normalizeRRDealerFields(cfg || {}); + return { dealerNumber, storeNumber, branchNumber }; +} + // // ===================== CUSTOMER ===================== // @@ -31,12 +41,13 @@ const hasAny = (obj) => !!obj && Object.values(obj).some((v) => v !== undefined */ function mapCustomerInsert(customer, bodyshopConfig) { if (!customer) return {}; + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); return { DealerCode: bodyshopConfig?.dealer_code || "ROME", - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: `CUST-INSERT-${customer.id}`, Environment: process.env.NODE_ENV, @@ -116,12 +127,13 @@ function mapCustomerUpdate(customer, bodyshopConfig) { */ function mapServiceVehicle(vehicle, ownerCustomer, bodyshopConfig) { if (!vehicle) return {}; + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); return { DealerCode: bodyshopConfig?.dealer_code || "ROME", - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: `VEH-${vehicle.id}`, CustomerId: ownerCustomer?.external_id, @@ -175,15 +187,16 @@ function mapServiceVehicle(vehicle, ownerCustomer, bodyshopConfig) { */ function mapRepairOrderCreate(job, bodyshopConfig) { if (!job) return {}; + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); const cust = job.customer || {}; const veh = job.vehicle || {}; return { DealerCode: bodyshopConfig?.dealer_code || "ROME", - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: `RO-${job.id}`, Environment: process.env.NODE_ENV, @@ -302,11 +315,12 @@ function mapRepairOrderUpdate(job, bodyshopConfig) { // function mapAdvisorLookup(criteria, bodyshopConfig) { + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); return { DealerCode: bodyshopConfig?.dealer_code || "ROME", - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: `LOOKUP-ADVISOR-${Date.now()}`, SearchCriteria: { Department: criteria.department || "Body Shop", @@ -316,11 +330,12 @@ function mapAdvisorLookup(criteria, bodyshopConfig) { } function mapPartsLookup(criteria, bodyshopConfig) { + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); return { DealerCode: bodyshopConfig?.dealer_code || "ROME", - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: `LOOKUP-PART-${Date.now()}`, SearchCriteria: { PartNumber: criteria.part_number, @@ -335,6 +350,8 @@ function mapPartsLookup(criteria, bodyshopConfig) { } function mapCombinedSearch(criteria = {}, bodyshopConfig) { + const { dealerNumber, storeNumber, branchNumber } = getDSB(bodyshopConfig); + // accept nested or flat input const c = criteria || {}; const cust = c.customer || c.Customer || {}; @@ -364,14 +381,11 @@ function mapCombinedSearch(criteria = {}, bodyshopConfig) { }; return { - // Dealer / routing (aligns with your other mappers) - STAR_NS: require("./rr-constants").RR_NS.STAR, - MaxRecs: criteria.maxResults || criteria.MaxResults || 50, DealerCode: bodyshopConfig?.dealer_code || "ROME", DealerName: bodyshopConfig?.dealer_name, - DealerNumber: bodyshopConfig?.dealer_number, - StoreNumber: bodyshopConfig?.store_number, - BranchNumber: bodyshopConfig?.branch_number, + DealerNumber: dealerNumber, + StoreNumber: storeNumber, + BranchNumber: branchNumber, RequestId: c.requestId || `COMBINED-${Date.now()}`, Environment: process.env.NODE_ENV, diff --git a/server/rr/rr-test.js b/server/rr/rr-test.js index 2dd3759fe..a032cf01e 100644 --- a/server/rr/rr-test.js +++ b/server/rr/rr-test.js @@ -6,6 +6,7 @@ const path = require("path"); const fs = require("fs"); const dotenv = require("dotenv"); +const { GraphQLClient, gql } = require("graphql-request"); const { MakeRRCall, renderXmlTemplate, buildStarEnvelope } = require("./rr-helpers"); const { getBaseRRConfig } = require("./rr-constants"); @@ -20,7 +21,7 @@ if (fs.existsSync(defaultEnvPath)) { } } -// Parse CLI args +// ---- CLI args parsing ---- const argv = process.argv.slice(2); const args = { _: [] }; for (let i = 0; i < argv.length; i++) { @@ -37,13 +38,12 @@ for (let i = 0; i < argv.length; i++) { const next = argv[i + 1]; if (next && !next.startsWith("-")) { args[k] = next; - i++; // consume value + i++; } else { - args[k] = true; // boolean flag + args[k] = true; } } } else if (a.startsWith("-") && a.length > 1) { - // simple short flag handling: -a value const k = a.slice(1); const next = argv[i + 1]; if (next && !next.startsWith("-")) { @@ -62,7 +62,65 @@ function toIntOr(defaultVal, maybe) { return Number.isFinite(n) ? n : defaultVal; } -// ✅ fixed guard clause +// ---------------- GraphQL helpers ---------------- + +function buildGqlClient() { + const endpoint = process.env.GRAPHQL_ENDPOINT; + if (!endpoint) throw new Error("GRAPHQL_ENDPOINT env var is required when using --bodyshopId."); + + const headers = {}; + if (process.env.HASURA_ADMIN_SECRET) { + headers["x-hasura-admin-secret"] = process.env.HASURA_ADMIN_SECRET; + } else if (process.env.GRAPHQL_BEARER) { + headers["authorization"] = `Bearer ${process.env.GRAPHQL_BEARER}`; + } + + return new GraphQLClient(endpoint, { headers }); +} + +const Q_BODYSHOPS_BY_PK = gql` + query BodyshopRR($id: uuid!) { + bodyshops_by_pk(id: $id) { + rr_dealerid + rr_configuration + } + } +`; + +function normalizeConfigRecord(rec) { + if (!rec) return null; + let cfg = rec.rr_configuration || {}; + if (typeof cfg === "string") { + try { + cfg = JSON.parse(cfg); + } catch { + cfg = {}; + } + } + return { + dealerNumber: rec.rr_dealerid || undefined, + storeNumber: cfg.storeNumber || undefined, + branchNumber: cfg.branchNumber || undefined + }; +} + +/** + * Load RR config overrides from DB (bodyshops_by_pk only). + */ +async function loadBodyshopRRConfig(bodyshopId) { + if (!bodyshopId) return null; + + const client = buildGqlClient(); + const { bodyshops_by_pk: bs } = await client.request(Q_BODYSHOPS_BY_PK, { id: bodyshopId }); + + if (!bs) throw new Error("Bodyshop not found."); + if (!bs.rr_dealerid) throw new Error("Bodyshop is not configured for RR (missing rr_dealerid)."); + + return normalizeConfigRecord(bs); +} + +// ---------------- rr-test logic ---------------- + function pickActionName(raw) { if (!raw || typeof raw !== "string") return "ping"; const x = raw.toLowerCase(); @@ -142,6 +200,8 @@ function buildBodyForAction(action, args, cfg) { async function main() { const action = pickActionName(args.action || args.a || args._[0]); + const bodyshopId = args.bodyshopId || args.bodyshop || args.b; + const rrAction = action === "ping" ? "GetAdvisors" @@ -153,12 +213,28 @@ async function main() { ? "GetParts" : action; + // Start with env-based defaults… const cfg = getBaseRRConfig(); + + // …then override with per-bodyshop values if provided. + if (bodyshopId) { + try { + const overrides = await loadBodyshopRRConfig(bodyshopId); + if (overrides?.dealerNumber) cfg.dealerNumber = overrides.dealerNumber; + if (overrides?.storeNumber) cfg.storeNumber = overrides.storeNumber; + if (overrides?.branchNumber) cfg.branchNumber = overrides.branchNumber; + console.log("ℹ️ RR config loaded from DB via: bodyshops_by_pk"); + } catch (e) { + console.error("❌ Failed to load per-bodyshop RR config:", e.message); + process.exit(1); + } + } + const body = buildBodyForAction(action, args, cfg); const templateName = body.template || rrAction; try { - const xml = await renderXmlTemplate(templateName, body.data); + await renderXmlTemplate(templateName, body.data); console.log("✅ Templates verified."); } catch (e) { console.error("❌ Template verification failed:", e.message); @@ -186,6 +262,4 @@ async function main() { } } -main().catch((e) => { - process.exit(1); -}); +main().catch(() => process.exit(1)); diff --git a/server/rr/rrRoutes.js b/server/rr/rrRoutes.js index 97ab220de..f497313bb 100644 --- a/server/rr/rrRoutes.js +++ b/server/rr/rrRoutes.js @@ -29,32 +29,57 @@ const { exportJobToRome } = require("./rr-job-export"); // orchestrator // Diagnostics const { listActions, verifyTemplatesExist } = require("./rr-wsdl"); -// Helpers +// DB-driven RR config (no env fallback for dealer/store/branch here) +const { getRRConfigForBodyshop } = require("./rr-config"); + +// -------------------- Helpers -------------------- + function ok(res, payload = {}) { return res.json({ success: true, ...payload }); } + function fail(res, error, status = 400) { const message = error?.message || String(error); return res.status(status).json({ success: false, error: message, code: error?.code }); } -function pickConfig(req) { - // Accept config in either { config } or { bodyshopConfig } - return req.body?.config || req.body?.bodyshopConfig || {}; -} + function socketOf(req) { // If you stash a socket/logging context on the app, grab it; otherwise null return (req.app && req.app.get && req.app.get("socket")) || null; } +/** + * Resolve the per-bodyshop RR config strictly from DB. + * Looks for bodyshopId in: + * - req.body.bodyshopId + * - req.body.job?.shopid + * - x-bodyshop-id header + * Throws if not found. + */ +async function resolveRRConfigHttp(req) { + const candidateHeader = req.get && req.get("x-bodyshop-id"); + const body = req.body || {}; + const bodyshopId = body.bodyshopId || (body.job && (body.job.shopid || body.job.bodyshopId)) || candidateHeader; + + if (!bodyshopId) { + throw new RrApiError( + "Missing bodyshopId (expected in body.bodyshopId, body.job.shopid, or x-bodyshop-id header)", + "BAD_REQUEST" + ); + } + + return getRRConfigForBodyshop(bodyshopId); +} + // -------------------- Customers -------------------- router.post("/rr/customer/insert", async (req, res) => { const socket = socketOf(req); const { customer } = req.body || {}; - const cfg = pickConfig(req); try { if (!customer) throw new RrApiError("Missing 'customer' in request body", "BAD_REQUEST"); + const cfg = await resolveRRConfigHttp(req); // DB-driven, required const result = await customerApi.insertCustomer(socket, customer, cfg); return ok(res, result); } catch (err) { @@ -66,10 +91,10 @@ router.post("/rr/customer/insert", async (req, res) => { router.post("/rr/customer/update", async (req, res) => { const socket = socketOf(req); const { customer } = req.body || {}; - const cfg = pickConfig(req); try { if (!customer) throw new RrApiError("Missing 'customer' in request body", "BAD_REQUEST"); + const cfg = await resolveRRConfigHttp(req); const result = await customerApi.updateCustomer(socket, customer, cfg); return ok(res, result); } catch (err) { @@ -83,10 +108,10 @@ router.post("/rr/customer/update", async (req, res) => { router.post("/rr/repair-order/create", async (req, res) => { const socket = socketOf(req); const { job } = req.body || {}; - const cfg = pickConfig(req); try { if (!job) throw new RrApiError("Missing 'job' in request body", "BAD_REQUEST"); + const cfg = await resolveRRConfigHttp(req); const result = await roApi.createRepairOrder(socket, job, cfg); return ok(res, result); } catch (err) { @@ -98,10 +123,10 @@ router.post("/rr/repair-order/create", async (req, res) => { router.post("/rr/repair-order/update", async (req, res) => { const socket = socketOf(req); const { job } = req.body || {}; - const cfg = pickConfig(req); try { if (!job) throw new RrApiError("Missing 'job' in request body", "BAD_REQUEST"); + const cfg = await resolveRRConfigHttp(req); const result = await roApi.updateRepairOrder(socket, job, cfg); return ok(res, result); } catch (err) { @@ -115,9 +140,9 @@ router.post("/rr/repair-order/update", async (req, res) => { router.post("/rr/lookup/advisors", async (req, res) => { const socket = socketOf(req); const { criteria = {} } = req.body || {}; - const cfg = pickConfig(req); try { + const cfg = await resolveRRConfigHttp(req); const result = await lookupApi.getAdvisors(socket, criteria, cfg); return ok(res, result); } catch (err) { @@ -129,9 +154,9 @@ router.post("/rr/lookup/advisors", async (req, res) => { router.post("/rr/lookup/parts", async (req, res) => { const socket = socketOf(req); const { criteria = {} } = req.body || {}; - const cfg = pickConfig(req); try { + const cfg = await resolveRRConfigHttp(req); const result = await lookupApi.getParts(socket, criteria, cfg); return ok(res, result); } catch (err) { @@ -143,9 +168,9 @@ router.post("/rr/lookup/parts", async (req, res) => { router.post("/rr/lookup/combined-search", async (req, res) => { const socket = socketOf(req); const { criteria = {} } = req.body || {}; - const cfg = pickConfig(req); try { + const cfg = await resolveRRConfigHttp(req); const result = await lookupApi.combinedSearch(socket, criteria, cfg); return ok(res, result); } catch (err) { @@ -159,10 +184,10 @@ router.post("/rr/lookup/combined-search", async (req, res) => { router.post("/rr/export/job", async (req, res) => { const socket = socketOf(req); const { job, options = {} } = req.body || {}; - const cfg = pickConfig(req); try { if (!job) throw new RrApiError("Missing 'job' in request body", "BAD_REQUEST"); + const cfg = await resolveRRConfigHttp(req); const result = await exportJobToRome(socket, job, cfg, options); return ok(res, result); } catch (err) { diff --git a/server/web-sockets/redisSocketEvents.js b/server/web-sockets/redisSocketEvents.js index 131fcbd8f..b130beeb9 100644 --- a/server/web-sockets/redisSocketEvents.js +++ b/server/web-sockets/redisSocketEvents.js @@ -5,21 +5,7 @@ const { FortellisJobExport, FortellisSelectedCustomer } = require("../fortellis/ const CdkCalculateAllocations = require("../cdk/cdk-calculate-allocations").default; const { exportJobToRome } = require("../rr/rr-job-export"); const lookupApi = require("../rr/rr-lookup"); - -function resolveRRConfigFrom(payload = {}) { - // Back-compat: allow txEnvelope.config from old callers - const cfg = payload.config || payload.bodyshopConfig || payload.txEnvelope?.config || {}; - return { - baseUrl: cfg.baseUrl || process.env.RR_BASE_URL, - username: cfg.username || process.env.RR_USERNAME, - password: cfg.password || process.env.RR_PASSWORD, - ppsysId: cfg.ppsysId || process.env.RR_PPSYSID, - dealer_number: cfg.dealer_number || process.env.RR_DEALER_NUMBER, - store_number: cfg.store_number || process.env.RR_STORE_NUMBER, - branch_number: cfg.branch_number || process.env.RR_BRANCH_NUMBER, - rrTransport: (cfg.rrTransport || process.env.RR_TRANSPORT || "STAR").toUpperCase() - }; -} +const { getRRConfigForBodyshop } = require("../rr/rr-config"); const redisSocketEvents = ({ io, @@ -349,7 +335,7 @@ const redisSocketEvents = ({ }); socket.on("task-deleted", (payload) => { - if (!payload || !payload.id) return; + if (!payload?.id) return; const room = getBodyshopRoom(socket.bodyshopId); io.to(room).emit("bodyshop-message", { type: "task-deleted", payload }); }); @@ -359,11 +345,13 @@ const redisSocketEvents = ({ // Orchestrated Export (Customer → Vehicle → Repair Order) socket.on("rr-export-job", async (payload = {}) => { try { - // Back-compat: old callers: { jobid, txEnvelope }; new: { job, config, options } - // Prefer direct job/config, otherwise try txEnvelope.{job,config} + // Back-compat: old callers: { jobid, txEnvelope }; new: { job, options } + // Prefer direct job, otherwise try txEnvelope.job const job = payload.job || payload.txEnvelope?.job; const options = payload.options || payload.txEnvelope?.options || {}; - const cfg = resolveRRConfigFrom(payload); + // Resolve per-bodyshop RR config strictly from DB: + const bodyshopId = payload.bodyshopId || socket.bodyshopId || job?.shopid; + const cfg = await getRRConfigForBodyshop(bodyshopId); if (!job) { RRLogger(socket, "error", "RR export missing job payload"); @@ -383,7 +371,7 @@ const redisSocketEvents = ({ // Combined search socket.on("rr-lookup-combined", async ({ jobid, params } = {}, cb) => { try { - const cfg = resolveRRConfigFrom({}); // if you want per-call overrides, pass them in the payload and merge here + const cfg = await getRRConfigForBodyshop(socket.bodyshopId); const data = await lookupApi.combinedSearch(socket, params || {}, cfg); cb?.(data); } catch (e) { @@ -395,7 +383,7 @@ const redisSocketEvents = ({ // Get Advisors socket.on("rr-get-advisors", async ({ jobid, params } = {}, cb) => { try { - const cfg = resolveRRConfigFrom({}); + const cfg = await getRRConfigForBodyshop(socket.bodyshopId); const data = await lookupApi.getAdvisors(socket, params || {}, cfg); cb?.(data); } catch (e) { @@ -407,7 +395,7 @@ const redisSocketEvents = ({ // Get Parts socket.on("rr-get-parts", async ({ jobid, params } = {}, cb) => { try { - const cfg = resolveRRConfigFrom({}); + const cfg = await getRRConfigForBodyshop(socket.bodyshopId); const data = await lookupApi.getParts(socket, params || {}, cfg); cb?.(data); } catch (e) { @@ -419,9 +407,6 @@ const redisSocketEvents = ({ // (Optional) Selected customer — only keep this if you actually implement it for RR socket.on("rr-selected-customer", async ({ jobid, selectedCustomerId } = {}) => { try { - // If you don’t have an RRSelectedCustomer implementation now, either: - // 1) no-op with a log, or - // 2) emit a structured event UI can handle as "not supported". RRLogger(socket, "info", "rr-selected-customer not implemented for RR (no-op)", { jobid, selectedCustomerId