From b43f520efe84b58d8b9a42973a1752f0a9c12d9e Mon Sep 17 00:00:00 2001 From: amianthus <49116958+SirTenzin@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:01:25 +0000 Subject: [PATCH 01/12] =?UTF-8?q?fix:=20=F0=9F=90=9B=20entity=20scoped=20c?= =?UTF-8?q?ustomer=20balance=20on=20frontend,=20email=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prepareNewBalanceForInsertion.ts | 6 +- vite/src/views/auth/SignIn.tsx | 5 +- .../views/auth/components/PasswordSignIn.tsx | 74 +++++++++---------- .../CustomerFeatureUsageTable.tsx | 34 ++++++--- 4 files changed, 63 insertions(+), 56 deletions(-) diff --git a/server/src/internal/balances/createBalance/prepareNewBalanceForInsertion.ts b/server/src/internal/balances/createBalance/prepareNewBalanceForInsertion.ts index 450e48ee6..f7b805080 100644 --- a/server/src/internal/balances/createBalance/prepareNewBalanceForInsertion.ts +++ b/server/src/internal/balances/createBalance/prepareNewBalanceForInsertion.ts @@ -36,9 +36,9 @@ export const prepareNewBalanceForInsertion = async ({ const entity = fullCustomer.entity; - if (entity) { - newEntitlement.entity_feature_id = entity.feature_id; - } + // NOTE: We do NOT set entity_feature_id here. That field means "per-entity balances" + // (e.g., 10 messages per seat). For entity-scoped loose balances, we only set + // internal_entity_id on the cusEnt to scope the balance to a specific entity. const newEntitlementWithFeature = enrichEntitlementWithFeature({ entitlement: newEntitlement, diff --git a/vite/src/views/auth/SignIn.tsx b/vite/src/views/auth/SignIn.tsx index 804049cbc..890356e25 100644 --- a/vite/src/views/auth/SignIn.tsx +++ b/vite/src/views/auth/SignIn.tsx @@ -4,7 +4,6 @@ import { Mail } from "lucide-react"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router"; import { toast } from "sonner"; -import { z } from "zod"; import { CustomToaster } from "@/components/general/CustomToaster"; import { IconButton } from "@/components/v2/buttons/IconButton"; import { Input } from "@/components/v2/inputs/Input"; @@ -13,7 +12,7 @@ import { authClient, signIn } from "@/lib/auth-client"; import { getBackendErr } from "@/utils/genUtils"; import { OTPSignIn } from "./components/OTPSignIn"; -export const emailSchema = z.email(); +export const emailRegex = /^[^@]+@[^@]+\.[^@]+$/; export const SignIn = () => { const [email, setEmail] = useState(""); @@ -39,7 +38,7 @@ export const SignIn = () => { const handleEmailSignIn = async (e: React.FormEvent) => { e.preventDefault(); - if (!email || !emailSchema.safeParse(email).success) { + if (!email || !emailRegex.test(email)) { toast.error("Please enter a valid email address."); return; } diff --git a/vite/src/views/auth/components/PasswordSignIn.tsx b/vite/src/views/auth/components/PasswordSignIn.tsx index c675924d4..6d0479f5a 100644 --- a/vite/src/views/auth/components/PasswordSignIn.tsx +++ b/vite/src/views/auth/components/PasswordSignIn.tsx @@ -5,7 +5,7 @@ import { CustomToaster } from "@/components/general/CustomToaster"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { authClient, useSession } from "@/lib/auth-client"; -import { emailSchema } from "../SignIn"; +import { emailRegex } from "../SignIn"; export const PasswordSignIn = () => { const [email, setEmail] = useState(""); @@ -25,7 +25,7 @@ export const PasswordSignIn = () => { const handleEmailSignIn = async (e: React.FormEvent) => { e.preventDefault(); - if (!email || !emailSchema.safeParse(email).success) { + if (!email || !emailRegex.test(email)) { toast.error("Please enter a valid email address."); return; } @@ -67,48 +67,46 @@ export const PasswordSignIn = () => { - <> -
-
- setEmail(e.target.value)} - required - className="text-base" - autoComplete="email" - /> - setPassword(e.target.value)} - required - className="text-base" - autoComplete="email" - /> -
- - {/* Sign In Button */} - +
+
+ setEmail(e.target.value)} + required + className="text-base" + autoComplete="email" + /> + setPassword(e.target.value)} + required + className="text-base" + autoComplete="email" + />
- {/* Footer */} - {/*
+ {/* Sign In Button */} + +
+ + {/* Footer */} + {/*
Create an account here
*/} -
); diff --git a/vite/src/views/customers2/components/table/customer-feature-usage/CustomerFeatureUsageTable.tsx b/vite/src/views/customers2/components/table/customer-feature-usage/CustomerFeatureUsageTable.tsx index ae9824f9b..08f22793f 100644 --- a/vite/src/views/customers2/components/table/customer-feature-usage/CustomerFeatureUsageTable.tsx +++ b/vite/src/views/customers2/components/table/customer-feature-usage/CustomerFeatureUsageTable.tsx @@ -31,15 +31,14 @@ export function CustomerFeatureUsageTable() { const [expanded, setExpanded] = useState({}); - const filteredCustomerProducts = useMemo(() => { - if (!entityId) { - return customer?.customer_products ?? []; - } - - const selectedEntity = customer?.entities.find( + const selectedEntity = useMemo(() => { + if (!entityId) return null; + return customer?.entities.find( (e: Entity) => e.id === entityId || e.internal_id === entityId, ); + }, [customer?.entities, entityId]); + const filteredCustomerProducts = useMemo(() => { if (!selectedEntity) { return customer?.customer_products ?? []; } @@ -50,7 +49,7 @@ export function CustomerFeatureUsageTable() { cp.internal_entity_id === selectedEntity.internal_id || cp.entity_id === selectedEntity.id, ); - }, [customer?.customer_products, customer?.entities, entityId]); + }, [customer?.customer_products, selectedEntity]); const cusEnts = useMemo((): FullCusEntWithFullCusProduct[] => { const productEnts = flattenCustomerEntitlements({ @@ -58,15 +57,26 @@ export function CustomerFeatureUsageTable() { }); // Add extra entitlements (loose entitlements not tied to a product) + // Customer level: show ALL loose entitlements (customer can access entity-scoped balances at top level) + // Entity level: show ONLY that entity's loose entitlements const extraEnts: FullCusEntWithFullCusProduct[] = ( customer?.extra_customer_entitlements || [] - ).map((ent: FullCustomerEntitlement) => ({ - ...ent, - customer_product: null, - })); + ) + .filter((ent: FullCustomerEntitlement) => { + // If no entity selected (customer level), show ALL loose entitlements + if (!selectedEntity) { + return true; + } + // If entity selected, show ONLY that entity's loose entitlements + return ent.internal_entity_id === selectedEntity.internal_id; + }) + .map((ent: FullCustomerEntitlement) => ({ + ...ent, + customer_product: null, + })); return [...productEnts, ...extraEnts]; - }, [filteredCustomerProducts, customer?.extra_customer_entitlements]); + }, [filteredCustomerProducts, customer?.extra_customer_entitlements, selectedEntity]); const featuresMap = useMemo( () => createFeaturesMap({ features: features ?? [] }), From d108ee8cb6f589e9cc34979ae888acd2d918147d Mon Sep 17 00:00:00 2001 From: amianthus <49116958+SirTenzin@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:02:50 +0000 Subject: [PATCH 02/12] fix: show entity id for entity-level loose entitlements in Balance List --- .../components/sheets/BalanceSelectionSheet.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/vite/src/views/customers2/components/sheets/BalanceSelectionSheet.tsx b/vite/src/views/customers2/components/sheets/BalanceSelectionSheet.tsx index 98a0fc0f5..4c0b3fc71 100644 --- a/vite/src/views/customers2/components/sheets/BalanceSelectionSheet.tsx +++ b/vite/src/views/customers2/components/sheets/BalanceSelectionSheet.tsx @@ -74,11 +74,19 @@ export function BalanceSelectionSheet() { entityId, }).balance; - const entity = customer?.entities?.find( - (e: Entity) => + // For loose entitlements (no customer_product), check cusEnt.internal_entity_id + // For product entitlements, check cusProduct.internal_entity_id/entity_id + const entity = customer?.entities?.find((e: Entity) => { + // Check for entity-level loose entitlement + if (cusEnt.internal_entity_id) { + return e.internal_id === cusEnt.internal_entity_id; + } + // Check for entity-level product entitlement + return ( e.internal_id === cusProduct?.internal_entity_id || - e.id === cusProduct?.entity_id, - ); + e.id === cusProduct?.entity_id + ); + }); const entitlement = cusEnt.entitlement; const isConsumable = From 20a4829f48ae91857d4a76fad44cd7ad5c5a0a1c Mon Sep 17 00:00:00 2001 From: Ayush Rodrigues Date: Thu, 22 Jan 2026 21:04:00 +0000 Subject: [PATCH 03/12] fix safari and zen pricing agent bug --- server/src/init.ts | 1 + server/src/initHono.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/server/src/init.ts b/server/src/init.ts index 0cde925be..ffb19b3a4 100644 --- a/server/src/init.ts +++ b/server/src/init.ts @@ -110,6 +110,7 @@ const init = async () => { "If-None-Match", "If-Modified-Since", "If-Unmodified-Since", + "User-Agent", // Required for better-auth v1.4.0+ compatibility with Safari/Zen browser ], }), ); diff --git a/server/src/initHono.ts b/server/src/initHono.ts index 661e33f2f..a08657c61 100644 --- a/server/src/initHono.ts +++ b/server/src/initHono.ts @@ -46,6 +46,7 @@ const ALLOWED_HEADERS = [ "If-Unmodified-Since", "idempotency-key", "Idempotency-Key", + "User-Agent", // Required for better-auth v1.4.0+ compatibility with Safari/Zen browser ]; export const createHonoApp = () => { From 88a6757cde63bcfb43f971b9cb8d5d1619956709 Mon Sep 17 00:00:00 2001 From: amianthus <49116958+SirTenzin@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:22:02 +0000 Subject: [PATCH 04/12] fix: show entity id for entity-level loose entitlements in Balance Edit sheet --- .../components/sheets/BalanceEditSheet.tsx | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/vite/src/views/customers2/components/sheets/BalanceEditSheet.tsx b/vite/src/views/customers2/components/sheets/BalanceEditSheet.tsx index ee2516eac..6583b0995 100644 --- a/vite/src/views/customers2/components/sheets/BalanceEditSheet.tsx +++ b/vite/src/views/customers2/components/sheets/BalanceEditSheet.tsx @@ -2,6 +2,7 @@ import { cusEntsToBalance, cusEntsToGrantedBalance, cusEntsToPrepaidQuantity, + type Entity, type FullCusProduct, type FullCustomerEntitlement, type FullCustomerPrice, @@ -240,12 +241,25 @@ export function BalanceEditSheet() {
- {cusProduct?.entity_id && ( - - )} + {(() => { + // For loose entitlements, check selectedCusEnt.internal_entity_id + // For product entitlements, check cusProduct.entity_id + const entity = customer?.entities?.find((e: Entity) => { + if (selectedCusEnt.internal_entity_id) { + return e.internal_id === selectedCusEnt.internal_entity_id; + } + return ( + e.internal_id === cusProduct?.internal_entity_id || + e.id === cusProduct?.entity_id + ); + }); + return entity ? ( + + ) : null; + })()}
From aa02be5bf9945e04acc30b7cfc77e990b77e235e Mon Sep 17 00:00:00 2001 From: Ayush Rodrigues Date: Fri, 23 Jan 2026 00:42:32 +0000 Subject: [PATCH 05/12] rm proration config for usage-based pricing --- .../edit-plan-feature/AdvancedSettings.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/vite/src/views/products/plan/components/edit-plan-feature/AdvancedSettings.tsx b/vite/src/views/products/plan/components/edit-plan-feature/AdvancedSettings.tsx index 51f166cc8..9bc36596a 100644 --- a/vite/src/views/products/plan/components/edit-plan-feature/AdvancedSettings.tsx +++ b/vite/src/views/products/plan/components/edit-plan-feature/AdvancedSettings.tsx @@ -1,5 +1,9 @@ /** biome-ignore-all lint/a11y/noStaticElementInteractions: shush */ -import { FeatureUsageType, isFeaturePriceItem } from "@autumn/shared"; +import { + FeatureUsageType, + isFeaturePriceItem, + UsageModel, +} from "@autumn/shared"; import { AreaCheckbox } from "@/components/v2/checkboxes/AreaCheckbox"; import { SheetAccordion, @@ -41,8 +45,11 @@ export function AdvancedSettings() { const showUsageLimits = isPriced; const showRollover = hasCreditSystem || usageType === FeatureUsageType.Single; const showEntityFeature = hasEntityFeatureId && hasOtherContinuousFeatures; - // Proration shows for priced features (simplified check) - const showProration = isPriced; + // Proration shows for prepaid or continuous use features (not consumable + pay-per-use) + const showProration = + isPriced && + (item.usage_model === UsageModel.Prepaid || + usageType === FeatureUsageType.Continuous); // Hide Advanced section if nothing will render inside it const hasAnyContent = From 36732dbe600f7e5c3200ed8fedf1e80a7d7956ff Mon Sep 17 00:00:00 2001 From: John Yeo Date: Fri, 23 Jan 2026 15:48:00 +0000 Subject: [PATCH 06/12] refreshed bun lock to test resend error --- bun.lock | 239 ++++++++++++++++++++++++++----------------------------- 1 file changed, 115 insertions(+), 124 deletions(-) diff --git a/bun.lock b/bun.lock index f6e4714ca..5958e13e7 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 1, "workspaces": { "": { "name": "autumn", @@ -314,15 +315,15 @@ "stripe": "19.3.0-beta.1", }, "packages": { - "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.18", "", { "dependencies": { "@ai-sdk/provider": "3.0.4", "@ai-sdk/provider-utils": "4.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-eusJVRK3gtXa7ENen9Im5bxwE6tNCPDF/poXyK45u7eLNx1I7aPbfseLqznyh+tjhx6AOK7FTUBV1d36MERPrA=="], + "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.23", "", { "dependencies": { "@ai-sdk/provider": "3.0.5", "@ai-sdk/provider-utils": "4.0.9" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-mu9djDW2kiJS/ihH5BwGy2c/zwSlcTjx1NWPvY/Ug12SWToqzozSyd1EIXRlfXyfwzL2CWrqMNyybqi9OVDXgg=="], - "@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.18", "", { "dependencies": { "@ai-sdk/provider": "3.0.4", "@ai-sdk/provider-utils": "4.0.8", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-WlJ7UkBDYgv+5q9UpGZfbnPrrW3KVnY96lRLaXs8nXy7Ea3QTWXf4Jw43jFzMSVkH4Zhhf0s9ExmG+CiyEBY5A=="], + "@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.22", "", { "dependencies": { "@ai-sdk/provider": "3.0.5", "@ai-sdk/provider-utils": "4.0.9", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-NgnlY73JNuooACHqUIz5uMOEWvqR1MMVbb2soGLMozLY1fgwEIF5iJFDAGa5/YArlzw2ATVU7zQu7HkR/FUjgA=="], - "@ai-sdk/provider": ["@ai-sdk/provider@3.0.4", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-5KXyBOSEX+l67elrEa+wqo/LSsSTtrPj9Uoh3zMbe/ceQX4ucHI3b9nUEfNkGF3Ry1svv90widAt+aiKdIJasQ=="], + "@ai-sdk/provider": ["@ai-sdk/provider@3.0.5", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-2Xmoq6DBJqmSl80U6V9z5jJSJP7ehaJJQMy2iFUqTay06wdCqTnPVBBQbtEL8RCChenL+q5DC5H5WzU3vV3v8w=="], - "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.8", "", { "dependencies": { "@ai-sdk/provider": "3.0.4", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ns9gN7MmpI8vTRandzgz+KK/zNMLzhrriiKECMt4euLtQFSBgNfydtagPOX4j4pS1/3KvHF6RivhT3gNQgBZsg=="], + "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.9", "", { "dependencies": { "@ai-sdk/provider": "3.0.5", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bB4r6nfhBOpmoS9mePxjRoCy+LnzP3AfhyMGCkGL4Mn9clVNlqEeKj26zEKEtB6yoSVcT1IQ0Zh9fytwMCDnow=="], - "@ai-sdk/react": ["@ai-sdk/react@3.0.46", "", { "dependencies": { "@ai-sdk/provider-utils": "4.0.8", "ai": "6.0.44", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" } }, "sha512-0WVvenCr8RymOG3tVP3BESkSjanqAO5yv1pYEz8T80iVI3YpGH19a3lLDiIU58kJm+SE8PIBNKfteXPHAQL0AQ=="], + "@ai-sdk/react": ["@ai-sdk/react@3.0.51", "", { "dependencies": { "@ai-sdk/provider-utils": "4.0.9", "ai": "6.0.49", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" } }, "sha512-7nmCwEJM52NQZB4/ED8qJ4wbDg7EEWh94qJ7K9GSJxD6sWF3GOKrRZ5ivm4qNmKhY+JfCxCAxfghGY5mTKOsxw=="], "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.3", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-jsElTJ0sQ4wHRz+C45tfect76BwbTbgkgKByOzpCN9xG61N5V6u/glvg1CsNJhq2xJIFpKHSwG3D2wPPuEYOrQ=="], @@ -340,7 +341,7 @@ "@amplitude/experiment-core": ["@amplitude/experiment-core@0.12.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-EiLLxcyJD8T3GFsMPxBfWx9n9fBw6rC0RJwccPXLzResE0HnGZZpVWF86ZndnYmEMD1lUUjWi41N1ymEzodI5w=="], - "@amplitude/experiment-js-client": ["@amplitude/experiment-js-client@1.20.1", "", { "dependencies": { "@amplitude/analytics-connector": "^1.6.4", "@amplitude/experiment-core": "^0.12.0", "@amplitude/ua-parser-js": "^0.7.31", "base64-js": "1.5.1", "unfetch": "4.1.0" } }, "sha512-pNcEPVBxhn13x85aDrTo8bEnBvG97v2P7cObMi8snLxNaUAKatkITPC//I0+daU7zwX2M3c+yeGmrU0Fmk08OA=="], + "@amplitude/experiment-js-client": ["@amplitude/experiment-js-client@1.20.2", "", { "dependencies": { "@amplitude/analytics-connector": "^1.6.4", "@amplitude/experiment-core": "^0.12.0", "@amplitude/ua-parser-js": "^0.7.31", "base64-js": "1.5.1", "unfetch": "4.1.0" } }, "sha512-o0d51PI8XzfsP79lDTkkGfoWtuisGOANVEbKa5pWX7SLAaY5vZpM4sZc5ICReQiJjSUwoXSpUd5i3w5pyCBRHQ=="], "@amplitude/plugin-autocapture-browser": ["@amplitude/plugin-autocapture-browser@1.18.0-zen-plus-zoning.2", "", { "dependencies": { "@amplitude/analytics-core": "2.32.0-zen-plus-zoning.2", "tslib": "^2.4.1" } }, "sha512-68pbfyR7SxEvCrCnu4E8KSkr8sWXRxA3O3eFOyatmqSXqCJmyR7Pu7MtKZJy0nsfFaWuRg+vDL9jBiPxSR18OQ=="], @@ -408,11 +409,11 @@ "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.600.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.600.0", "@aws-sdk/client-sts": "3.600.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8dYsnDLiD0rjujRiZZl0E57heUkHqMSFZHBi0YMs57SM8ODPxK3tahwDYZtS7bqanvFKZwGy+o9jIcij7jBOlA=="], - "@aws-sdk/client-iam": ["@aws-sdk/client-iam@3.972.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/credential-provider-node": "3.972.0", "@aws-sdk/middleware-host-header": "3.972.0", "@aws-sdk/middleware-logger": "3.972.0", "@aws-sdk/middleware-recursion-detection": "3.972.0", "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/region-config-resolver": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "3.972.0", "@aws-sdk/util-user-agent-node": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.20.6", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.7", "@smithy/middleware-retry": "^4.4.23", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.22", "@smithy/util-defaults-mode-node": "^4.2.25", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-2Bla8ElNZopJtnvtAPCdwWusmJhHFcdTlYUbZjfmT5qZIu3uaIlrJrY0+azGR3quhIXKxB8rUuo689ohe3VYvQ=="], + "@aws-sdk/client-iam": ["@aws-sdk/client-iam@3.974.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/credential-provider-node": "^3.972.1", "@aws-sdk/middleware-host-header": "^3.972.1", "@aws-sdk/middleware-logger": "^3.972.1", "@aws-sdk/middleware-recursion-detection": "^3.972.1", "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/region-config-resolver": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "^3.972.1", "@aws-sdk/util-user-agent-node": "^3.972.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.21.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-retry": "^4.4.26", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.25", "@smithy/util-defaults-mode-node": "^4.2.28", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-Bcwdt12/ksaF/T7TAqDKivrZEc04Viq7Sl6TM0avyDQknPjz2XDW/XxfUEN8WNDYR4Kt7jwz5p5M1CSb7AfdmA=="], - "@aws-sdk/client-scheduler": ["@aws-sdk/client-scheduler@3.972.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/credential-provider-node": "3.972.0", "@aws-sdk/middleware-host-header": "3.972.0", "@aws-sdk/middleware-logger": "3.972.0", "@aws-sdk/middleware-recursion-detection": "3.972.0", "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/region-config-resolver": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "3.972.0", "@aws-sdk/util-user-agent-node": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.20.6", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.7", "@smithy/middleware-retry": "^4.4.23", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.22", "@smithy/util-defaults-mode-node": "^4.2.25", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7N8U13ZO1VgNVJDnHj+HXkLLeDOml/varnfuYU2LlYIzCkOcPnCj136Uhr9IHU9EeEDWZSpT01iXOylYyLUITQ=="], + "@aws-sdk/client-scheduler": ["@aws-sdk/client-scheduler@3.974.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/credential-provider-node": "^3.972.1", "@aws-sdk/middleware-host-header": "^3.972.1", "@aws-sdk/middleware-logger": "^3.972.1", "@aws-sdk/middleware-recursion-detection": "^3.972.1", "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/region-config-resolver": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "^3.972.1", "@aws-sdk/util-user-agent-node": "^3.972.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.21.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-retry": "^4.4.26", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.25", "@smithy/util-defaults-mode-node": "^4.2.28", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-jzigYeI5fcN01lAho+QLn0PcD/JvG2T71se9cft1OJaIAfL2/HzDhFgl6jpJXrm/5eX/TWuTUlxkQIOsPIG8yg=="], - "@aws-sdk/client-sqs": ["@aws-sdk/client-sqs@3.972.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/credential-provider-node": "3.972.0", "@aws-sdk/middleware-host-header": "3.972.0", "@aws-sdk/middleware-logger": "3.972.0", "@aws-sdk/middleware-recursion-detection": "3.972.0", "@aws-sdk/middleware-sdk-sqs": "3.972.0", "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/region-config-resolver": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "3.972.0", "@aws-sdk/util-user-agent-node": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.20.6", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/md5-js": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.7", "@smithy/middleware-retry": "^4.4.23", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.22", "@smithy/util-defaults-mode-node": "^4.2.25", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-hNXJjqQLjGqq4a+MQy9xl2poVAlHnjFEA26ik+y5ktn2yNZ8SMbyY+Tdn2Ki06XS/yNHubHFdIQomqbcE4t22Q=="], + "@aws-sdk/client-sqs": ["@aws-sdk/client-sqs@3.974.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/credential-provider-node": "^3.972.1", "@aws-sdk/middleware-host-header": "^3.972.1", "@aws-sdk/middleware-logger": "^3.972.1", "@aws-sdk/middleware-recursion-detection": "^3.972.1", "@aws-sdk/middleware-sdk-sqs": "^3.972.1", "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/region-config-resolver": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "^3.972.1", "@aws-sdk/util-user-agent-node": "^3.972.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.21.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/md5-js": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-retry": "^4.4.26", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.25", "@smithy/util-defaults-mode-node": "^4.2.28", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-dfJcrDwEGxOB2fea4IhhMdr7WL7OKY+fWegrlf91ewG7h7Lk0Zws/6yLQP2GCNECoLwveGQkYNZTUT2rfF52Gw=="], "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.598.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw=="], @@ -420,61 +421,61 @@ "@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.600.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.600.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA=="], - "@aws-sdk/core": ["@aws-sdk/core@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@aws-sdk/xml-builder": "3.972.0", "@smithy/core": "^3.20.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-nEeUW2M9F+xdIaD98F5MBcQ4ITtykj3yKbgFZ6J0JtL3bq+Z90szQ6Yy8H/BLPYXTs3V4n9ifnBo8cprRDiE6A=="], + "@aws-sdk/core": ["@aws-sdk/core@3.973.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@aws-sdk/xml-builder": "^3.972.1", "@smithy/core": "^3.21.0", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-qy3Fmt8z4PRInM3ZqJmHihQ2tfCdj/MzbGaZpuHjYjgl1/Gcar4Pyp/zzHXh9hGEb61WNbWgsJcDUhnGIiX1TA=="], "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.600.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.600.0", "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-AIM+B06d1+71EuBrk2UR9ZZgRS3a+ARxE3oZKMZYlfqtZ3kY8w4DkhEt7OVruc6uSsMhkrcQT6nxsOxFSi4RtA=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-kKHoNv+maHlPQOAhYamhap0PObd16SAb3jwaY0KYgNTiSbeXlbGUZPLioo9oA3wU10zItJzx83ClU7d7h40luA=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-/etNHqnx96phy/SjI0HRC588o4vKH5F0xfkZ13yAATV7aNrb+5gYGNE6ePWafP+FuZ3HkULSSlJFj0AxgrAqYw=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" } }, "sha512-xzEi81L7I5jGUbpmqEHCe7zZr54hCABdj4H+3LzktHYuovV/oqnvoDdvZpGFR0e/KAw1+PL38NbGrpG30j6qlA=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/types": "^3.973.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" } }, "sha512-AeopObGW5lpWbDRZ+t4EAtS7wdfSrHPLeFts7jaBzgIaCCD7TL7jAyAB9Y5bCLOPF+17+GL54djCCsjePljUAw=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/credential-provider-env": "3.972.0", "@aws-sdk/credential-provider-http": "3.972.0", "@aws-sdk/credential-provider-login": "3.972.0", "@aws-sdk/credential-provider-process": "3.972.0", "@aws-sdk/credential-provider-sso": "3.972.0", "@aws-sdk/credential-provider-web-identity": "3.972.0", "@aws-sdk/nested-clients": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-ruhAMceUIq2aknFd3jhWxmO0P0Efab5efjyIXOkI9i80g+zDY5VekeSxfqRKStEEJSKSCHDLQuOu0BnAn4Rzew=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/credential-provider-env": "^3.972.1", "@aws-sdk/credential-provider-http": "^3.972.1", "@aws-sdk/credential-provider-login": "^3.972.1", "@aws-sdk/credential-provider-process": "^3.972.1", "@aws-sdk/credential-provider-sso": "^3.972.1", "@aws-sdk/credential-provider-web-identity": "^3.972.1", "@aws-sdk/nested-clients": "3.974.0", "@aws-sdk/types": "^3.973.0", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-OdbJA3v+XlNDsrYzNPRUwr8l7gw1r/nR8l4r96MDzSBDU8WEo8T6C06SvwaXR8SpzsjO3sq5KMP86wXWg7Rj4g=="], - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/nested-clients": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-SsrsFJsEYAJHO4N/r2P0aK6o8si6f1lprR+Ej8J731XJqTckSGs/HFHcbxOyW/iKt+LNUvZa59/VlJmjhF4bEQ=="], + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/nested-clients": "3.974.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-CccqDGL6ZrF3/EFWZefvKW7QwwRdxlHUO8NVBKNVcNq6womrPDvqB6xc9icACtE0XB0a7PLoSTkAg8bQVkTO2w=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.972.0", "@aws-sdk/credential-provider-http": "3.972.0", "@aws-sdk/credential-provider-ini": "3.972.0", "@aws-sdk/credential-provider-process": "3.972.0", "@aws-sdk/credential-provider-sso": "3.972.0", "@aws-sdk/credential-provider-web-identity": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-wwJDpEGl6+sOygic8QKu0OHVB8SiodqF1fr5jvUlSFfS6tJss/E9vBc2aFjl7zI6KpAIYfIzIgM006lRrZtWCQ=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.1", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.1", "@aws-sdk/credential-provider-http": "^3.972.1", "@aws-sdk/credential-provider-ini": "^3.972.1", "@aws-sdk/credential-provider-process": "^3.972.1", "@aws-sdk/credential-provider-sso": "^3.972.1", "@aws-sdk/credential-provider-web-identity": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwXPk9GfuU/xG9tmCyXFVkCr6X3W8ZCoL5Ptb0pbltEx1/LCcg7T+PBqDlPiiinNCD6ilIoMJDWsnJ8ikzZA7Q=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-nmzYhamLDJ8K+v3zWck79IaKMc350xZnWsf/GeaXO6E3MewSzd3lYkTiMi7lEp3/UwDm9NHfPguoPm+mhlSWQQ=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-bi47Zigu3692SJwdBvo8y1dEwE6B61stCwCFnuRWJVTfiM84B+VTSCV661CSWJmIZzmcy7J5J3kWyxL02iHj0w=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.972.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/token-providers": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-6mYyfk1SrMZ15cH9T53yAF4YSnvq4yU1Xlgm3nqV1gZVQzmF5kr4t/F3BU3ygbvzi4uSwWxG3I3TYYS5eMlAyg=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.1", "", { "dependencies": { "@aws-sdk/client-sso": "3.974.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/token-providers": "3.974.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-dLZVNhM7wSgVUFsgVYgI5hb5Z/9PUkT46pk/SHrSmUqfx6YDvoV4YcPtaiRqviPpEGGiRtdQMEadyOKIRqulUQ=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/nested-clients": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-vsJXBGL8H54kz4T6do3p5elATj5d1izVGUXMluRJntm9/I0be/zUYtdd4oDTM2kSUmd4Zhyw3fMQ9lw7CVhd4A=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/nested-clients": "3.974.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-YMDeYgi0u687Ay0dAq/pFPKuijrlKTgsaB/UATbxCs/FzZfMiG4If5ksywHmmW7MiYUF8VVv+uou3TczvLrN4w=="], "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.600.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.600.0", "@aws-sdk/client-sso": "3.598.0", "@aws-sdk/client-sts": "3.600.0", "@aws-sdk/credential-provider-cognito-identity": "3.600.0", "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-ini": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-cC9uqmX0rgx1efiJGqeR+i0EXr8RQ5SAzH7M45WNBZpYiLEe6reWgIYJY9hmOxuaoMdWSi8kekuN3IjTIORRjw=="], - "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-3eztFI6F9/eHtkIaWKN3nT+PM+eQ6p1MALDuNshFk323ixuCZzOOVT8oUqtZa30Z6dycNXJwhlIq7NhUVFfimw=="], + "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-/R82lXLPmZ9JaUGSUdKtBp2k/5xQxvBT3zZWyKiBOhyulFotlfvdlrO8TnqstBimsl4lYEYySDL+W6ldFh6ALg=="], - "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-ZvdyVRwzK+ra31v1pQrgbqR/KsLD+wwJjHgko6JfoKUBIcEfAwJzQKO6HspHxdHWTVUz6MgvwskheR/TTYZl2g=="], + "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-JGgFl6cHg9G2FHu4lyFIzmFN8KESBiRr84gLC3Aeni0Gt1nKm+KxWLBuha/RPcXxJygGXCcMM4AykkIwxor8RA=="], - "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-F2SmUeO+S6l1h6dydNet3BQIk173uAkcfU1HDkw/bUdRLAnh15D3HP9vCZ7oCPBNcdEICbXYDmx0BR9rRUHGlQ=="], + "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-taGzNRe8vPHjnliqXIHp9kBgIemLE/xCaRTMH1NH0cncHeaPcjxtnCroAAM9aOlPuKvBe2CpZESyvM1+D8oI7Q=="], - "@aws-sdk/middleware-sdk-sqs": ["@aws-sdk/middleware-sdk-sqs@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Sdada+JFqE0O14RsXeHoEfubh5WkPCzzXXjZTxAfSRIpmPCPwNjiPopKF1Y90OFiUiIzM2DThEEV+L2/fPCZng=="], + "@aws-sdk/middleware-sdk-sqs": ["@aws-sdk/middleware-sdk-sqs@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-cCxez59SFBqEuqWqD0nB9QJQDl17t17fB077RCKHaJuXwb+oGaWLdwhxGBijY64WqhcVisBz2GrC4/XInPI1sg=="], - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@smithy/core": "^3.20.6", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-kFHQm2OCBJCzGWRafgdWHGFjitUXY/OxXngymcX4l8CiyiNDZB27HDDBg2yLj3OUJc4z4fexLMmP8r9vgag19g=="], + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.1", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@smithy/core": "^3.21.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-6SVg4pY/9Oq9MLzO48xuM3lsOb8Rxg55qprEtFRpkUmuvKij31f5SQHEGxuiZ4RqIKrfjr2WMuIgXvqJ0eJsPA=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.972.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/middleware-host-header": "3.972.0", "@aws-sdk/middleware-logger": "3.972.0", "@aws-sdk/middleware-recursion-detection": "3.972.0", "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/region-config-resolver": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "3.972.0", "@aws-sdk/util-user-agent-node": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.20.6", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.7", "@smithy/middleware-retry": "^4.4.23", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.22", "@smithy/util-defaults-mode-node": "^4.2.25", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QGlbnuGzSQJVG6bR9Qw6G0Blh6abFR4VxNa61ttMbzy9jt28xmk2iGtrYLrQPlCCPhY6enHqjTWm3n3LOb0wAw=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.974.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/middleware-host-header": "^3.972.1", "@aws-sdk/middleware-logger": "^3.972.1", "@aws-sdk/middleware-recursion-detection": "^3.972.1", "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/region-config-resolver": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "^3.972.1", "@aws-sdk/util-user-agent-node": "^3.972.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.21.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-retry": "^4.4.26", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.25", "@smithy/util-defaults-mode-node": "^4.2.28", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k3dwdo/vOiHMJc9gMnkPl1BA5aQfTrZbz+8fiDkWrPagqAioZgmo5oiaOaeX0grObfJQKDtcpPFR4iWf8cgl8Q=="], "@aws-sdk/protocol-http": ["@aws-sdk/protocol-http@3.374.0", "", { "dependencies": { "@smithy/protocol-http": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-9WpRUbINdGroV3HiZZIBoJvL2ndoWk39OfwxWs2otxByppJZNN14bg/lvCx5e8ggHUti7IBk5rb0nqQZ4m05pg=="], - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-JyOf+R/6vJW8OEVFCAyzEOn2reri/Q+L0z9zx4JQSKWvTmJ1qeFO25sOm8VIfB8URKhfGRTQF30pfYaH2zxt/A=="], + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-voIY8RORpxLAEgEkYaTFnkaIuRwVBEc+RjVZYcSSllPV+ZEKAacai6kNhJeE3D70Le+JCfvRb52tng/AVHY+jQ=="], "@aws-sdk/signature-v4": ["@aws-sdk/signature-v4@3.374.0", "", { "dependencies": { "@smithy/signature-v4": "^1.0.1", "tslib": "^2.5.0" } }, "sha512-2xLJvSdzcZZAg0lsDLUAuSQuihzK0dcxIK7WmfuJeF7DGKJFmp9czQmz5f3qiDz6IDQzvgK1M9vtJSVCslJbyQ=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.972.0", "", { "dependencies": { "@aws-sdk/core": "3.972.0", "@aws-sdk/nested-clients": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-kWlXG+y5nZhgXGEtb72Je+EvqepBPs8E3vZse//1PYLWs2speFqbGE/ywCXmzEJgHgVqSB/u/lqBvs5WlYmSqQ=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.974.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.0", "@aws-sdk/nested-clients": "3.974.0", "@aws-sdk/types": "^3.973.0", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-cBykL0LiccKIgNhGWvQRTPvsBLPZxnmJU3pYxG538jpFX8lQtrCy1L7mmIHNEdxIdIGEPgAEHF8/JQxgBToqUQ=="], - "@aws-sdk/types": ["@aws-sdk/types@3.972.0", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-U7xBIbLSetONxb2bNzHyDgND3oKGoIfmknrEVnoEU4GUSs+0augUOIn9DIWGUO2ETcRFdsRUnmx9KhPT9Ojbug=="], + "@aws-sdk/types": ["@aws-sdk/types@3.973.0", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-jYIdB7a7jhRTvyb378nsjyvJh1Si+zVduJ6urMNGpz8RjkmHZ+9vM2H07XaIB2Cfq0GhJRZYOfUCH8uqQhqBkQ=="], "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-6JHsl1V/a1ZW8D8AFfd4R52fwZPnZ5H4U6DS8m/bWT8qad72NvbOFAC7U2cDtFs2TShqUO3TEiX/EJibtY3ijg=="], "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-FNUqAjlKAGA7GM05kywE99q8wiPHPZqrzhq3wXRga6PRD6A0kzT85Pb0AzYBVTBRpSrKyyr6M92Y6bnSBVp2BA=="], - "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.0", "", { "dependencies": { "@aws-sdk/types": "3.972.0", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eOLdkQyoRbDgioTS3Orr7iVsVEutJyMZxvyZ6WAF95IrF0kfWx5Rd/KXnfbnG/VKa2CvjZiitWfouLzfVEyvJA=="], + "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.0", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-IgF55NFmJX8d9Wql9M0nEpk2eYbuD8G4781FN4/fFgwTXBn86DvlZJuRWDCMcMqZymnBVX7HW9r+3r9ylqfW0w=="], - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/types": "3.972.0", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-GOy+AiSrE9kGiojiwlZvVVSXwylu4+fmP0MJfvras/MwP09RB/YtQuOVR1E0fKQc6OMwaTNBjgAbOEhxuWFbAw=="], + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.1", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-oIs4JFcADzoZ0c915R83XvK2HltWupxNsXUIuZse2rgk7b97zTpkxaqXiH0h9ylh31qtgo/t8hp4tIqcsMrEbQ=="], "@aws-sdk/util-utf8-browser": ["@aws-sdk/util-utf8-browser@3.259.0", "", { "dependencies": { "tslib": "^2.3.1" } }, "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw=="], - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.0", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-POaGMcXnozzqBUyJM3HLUZ9GR6OKJWPGJEmhtTnxZXt8B6JcJ/6K3xRJ5H/j8oovVLz8Wg6vFxAHv8lvuASxMg=="], + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-6zZGlPOqn7Xb+25MAXGb1JhgvaC5HjZj6GzszuVrnEgbhvzBRFGKYemuHBV4bho+dtqeYKPgaZUv7/e80hIGNg=="], "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.3", "", {}, "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw=="], @@ -996,7 +997,7 @@ "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.202.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.202.0", "@opentelemetry/core": "2.0.1", "@opentelemetry/resources": "2.0.1", "@opentelemetry/sdk-logs": "0.202.0", "@opentelemetry/sdk-metrics": "2.0.1", "@opentelemetry/sdk-trace-base": "2.0.1", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-5XO77QFzs9WkexvJQL9ksxL8oVFb/dfi9NWQSq7Sv0Efr9x3N+nb1iklP1TeVgxqJ7m1xWiC/Uv3wupiQGevMw=="], - "@opentelemetry/propagation-utils": ["@opentelemetry/propagation-utils@0.31.13", "", { "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-PJfTjWkJRYQyLy+lXwkRs7UJRpNMJbmF6N2qO38q3xNGPdL2Nc5YSnVYkMKxwOWgiobNWSg7GGQO3sITPFVNTg=="], + "@opentelemetry/propagation-utils": ["@opentelemetry/propagation-utils@0.31.14", "", { "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-h6KSRDTh3A8u2HpYUQf+Ia4P5WvzHohqrblLtIuYTLWtv1Klw7I+UC/cEooOsqFz8PDt++KkfkywFtYKH84/KQ=="], "@opentelemetry/propagator-b3": ["@opentelemetry/propagator-b3@2.0.1", "", { "dependencies": { "@opentelemetry/core": "2.0.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-Hc09CaQ8Tf5AGLmf449H726uRoBNGPBL4bjr7AnnUpzWMvhdn61F78z9qb6IqB737TffBsokGAK1XykFEZ1igw=="], @@ -1006,7 +1007,7 @@ "@opentelemetry/resource-detector-alibaba-cloud": ["@opentelemetry/resource-detector-alibaba-cloud@0.31.11", "", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/resources": "^2.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-R/asn6dAOWMfkLeEwqHCUz0cNbb9oiHVyd11iwlypeT/p9bR1lCX5juu5g/trOwxo62dbuFcDbBdKCJd3O2Edg=="], - "@opentelemetry/resource-detector-aws": ["@opentelemetry/resource-detector-aws@2.10.0", "", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-WKNpVKeDPCxNNAFfhGfO+ka7yYQa5utNLxsDaqxyatM1WzAKz4Ce8Hov9gBCD5laGp5pS7+CWh5XVZZlQN4xeQ=="], + "@opentelemetry/resource-detector-aws": ["@opentelemetry/resource-detector-aws@2.11.0", "", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-Wphbm9fGyinMLC8BiLU/5aK6yG191ws2q2SN4biCcQZQCTo6yEij4ka+fXQXAiLMGSzb5w8wa/FxOn/7KWPiSQ=="], "@opentelemetry/resource-detector-azure": ["@opentelemetry/resource-detector-azure@0.9.0", "", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "sha512-5wJwAAW2vhbqIhgaRisU1y0F5mUco59F/dKgmnnnT6YNbxjrbdUZYxKF5Wl7deJoACVdL5wi/3N97GCXPEwwCQ=="], @@ -1052,7 +1053,7 @@ "@posthog/core": ["@posthog/core@1.13.0", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-knjncrk7qRmssFRbGzBl1Tunt21GRpe0Wv+uVelyL0Rh7PdQUsgguulzXFTps8hA6wPwTU4kq85qnbAJ3eH6Wg=="], - "@posthog/types": ["@posthog/types@1.333.0", "", {}, "sha512-9Wg/2ez+EZh6NmtOjhtYSkBHz/yIq8WMS0QSIizUoggh35hHVg4BTMXl3rz/tPearJNKU/8oRjEyuZ0OYTEDOA=="], + "@posthog/types": ["@posthog/types@1.335.0", "", {}, "sha512-KvxF9Dd9bM/LJyFTm7j8NM8EV6Mect4N8A0Q/gSQknu5pAgOfplToN9hLg+v8aWvtIEDlPHV7mBMKLUE19kVBA=="], "@prisma/instrumentation": ["@prisma/instrumentation@6.15.0", "", { "dependencies": { "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" }, "peerDependencies": { "@opentelemetry/api": "^1.8" } }, "sha512-6TXaH6OmDkMOQvOxwLZ8XS51hU2v4A3vmE2pSijCIiGRJYyNeMcL6nMHQMyYdZRD8wl7LF3Wzc+AMPMV/9Oo7A=="], @@ -1222,55 +1223,55 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.55.3", "", { "os": "android", "cpu": "arm" }, "sha512-qyX8+93kK/7R5BEXPC2PjUt0+fS/VO2BVHjEHyIEWiYn88rcRBHmdLgoJjktBltgAf+NY7RfCGB1SoyKS/p9kg=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.56.0", "", { "os": "android", "cpu": "arm" }, "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.55.3", "", { "os": "android", "cpu": "arm64" }, "sha512-6sHrL42bjt5dHQzJ12Q4vMKfN+kUnZ0atHHnv4V0Wd9JMTk7FDzSY35+7qbz3ypQYMBPANbpGK7JpnWNnhGt8g=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.56.0", "", { "os": "android", "cpu": "arm64" }, "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.55.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1ht2SpGIjEl2igJ9AbNpPIKzb1B5goXOcmtD0RFxnwNuMxqkR6AUaaErZz+4o+FKmzxcSNBOLrzsICZVNYa1Rw=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.56.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.55.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-FYZ4iVunXxtT+CZqQoPVwPhH7549e/Gy7PIRRtq4t5f/vt54pX6eG9ebttRH6QSH7r/zxAFA4EZGlQ0h0FvXiA=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.56.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.55.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-M/mwDCJ4wLsIgyxv2Lj7Len+UMHd4zAXu4GQ2UaCdksStglWhP61U3uowkaYBQBhVoNpwx5Hputo8eSqM7K82Q=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.56.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.55.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5jZT2c7jBCrMegKYTYTpni8mg8y3uY8gzeq2ndFOANwNuC/xJbVAoGKR9LhMDA0H3nIhvaqUoBEuJoICBudFrA=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.56.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.55.3", "", { "os": "linux", "cpu": "arm" }, "sha512-YeGUhkN1oA+iSPzzhEjVPS29YbViOr8s4lSsFaZKLHswgqP911xx25fPOyE9+khmN6W4VeM0aevbDp4kkEoHiA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.55.3", "", { "os": "linux", "cpu": "arm" }, "sha512-eo0iOIOvcAlWB3Z3eh8pVM8hZ0oVkK3AjEM9nSrkSug2l15qHzF3TOwT0747omI6+CJJvl7drwZepT+re6Fy/w=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.55.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-DJay3ep76bKUDImmn//W5SvpjRN5LmK/ntWyeJs/dcnwiiHESd3N4uteK9FDLf0S0W8E6Y0sVRXpOCoQclQqNg=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.55.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-BKKWQkY2WgJ5MC/ayvIJTHjy0JUGb5efaHCUiG/39sSUvAYRBaO3+/EK0AZT1RF3pSj86O24GLLik9mAYu0IJg=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.55.3", "", { "os": "linux", "cpu": "none" }, "sha512-Q9nVlWtKAG7ISW80OiZGxTr6rYtyDSkauHUtvkQI6TNOJjFvpj4gcH+KaJihqYInnAzEEUetPQubRwHef4exVg=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg=="], - "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.55.3", "", { "os": "linux", "cpu": "none" }, "sha512-2H5LmhzrpC4fFRNwknzmmTvvyJPHwESoJgyReXeFoYYuIDfBhP29TEXOkCJE/KxHi27mj7wDUClNq78ue3QEBQ=="], + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.55.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9S542V0ie9LCTznPYlvaeySwBeIEa7rDBgLHKZ5S9DBgcqdJYburabm8TqiqG6mrdTzfV5uttQRHcbKff9lWtA=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.56.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw=="], - "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.55.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ukxw+YH3XXpcezLgbJeasgxyTbdpnNAkrIlFGDl7t+pgCxZ89/6n1a+MxlY7CegU+nDgrgdqDelPRNQ/47zs0g=="], + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.56.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.55.3", "", { "os": "linux", "cpu": "none" }, "sha512-Iauw9UsTTvlF++FhghFJjqYxyXdggXsOqGpFBylaRopVpcbfyIIsNvkf9oGwfgIcf57z3m8+/oSYTo6HutBFNw=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.55.3", "", { "os": "linux", "cpu": "none" }, "sha512-3OqKAHSEQXKdq9mQ4eajqUgNIK27VZPW3I26EP8miIzuKzCJ3aW3oEn2pzF+4/Hj/Moc0YDsOtBgT5bZ56/vcA=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.55.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-0CM8dSVzVIaqMcXIFej8zZrSFLnGrAE8qlNbbHfTw1EEPnFTg1U1ekI0JdzjPyzSfUsHWtodilQQG/RA55berA=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.56.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.55.3", "", { "os": "linux", "cpu": "x64" }, "sha512-+fgJE12FZMIgBaKIAGd45rxf+5ftcycANJRWk8Vz0NnMTM5rADPGuRFTYar+Mqs560xuART7XsX2lSACa1iOmQ=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.55.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tMD7NnbAolWPzQlJQJjVFh/fNH3K/KnA7K8gv2dJWCwwnaK6DFCYST1QXYWfu5V0cDwarWC8Sf/cfMHniNq21A=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA=="], - "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.55.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u5KsqxOxjEeIbn7bUK1MPM34jrnPwjeqgyin4/N6e/KzXKfpE9Mi0nCxcQjaM9lLmPcHmn/xx1yOjgTMtu1jWQ=="], + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.56.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.55.3", "", { "os": "none", "cpu": "arm64" }, "sha512-vo54aXwjpTtsAnb3ca7Yxs9t2INZg7QdXN/7yaoG7nPGbOBXYXQY41Km+S1Ov26vzOAzLcAjmMdjyEqS1JkVhw=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.56.0", "", { "os": "none", "cpu": "arm64" }, "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.55.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-HI+PIVZ+m+9AgpnY3pt6rinUdRYrGHvmVdsNQ4odNqQ/eRF78DVpMR7mOq7nW06QxpczibwBmeQzB68wJ+4W4A=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.56.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.55.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-vRByotbdMo3Wdi+8oC2nVxtc3RkkFKrGaok+a62AT8lz/YBuQjaVYAS5Zcs3tPzW43Vsf9J0wehJbUY5xRSekA=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.56.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.55.3", "", { "os": "win32", "cpu": "x64" }, "sha512-POZHq7UeuzMJljC5NjKi8vKMFN6/5EOqcX1yGntNLp7rUTpBAXQ1hW8kWPFxYLv07QMcNM75xqVLGPWQq6TKFA=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.55.3", "", { "os": "win32", "cpu": "x64" }, "sha512-aPFONczE4fUFKNXszdvnd2GqKEYQdV5oEsIbKPujJmWlCI9zEsv1Otig8RKK+X9bed9gFUN6LAeN4ZcNuu4zjg=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g=="], "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="], @@ -1338,7 +1339,7 @@ "@smithy/config-resolver": ["@smithy/config-resolver@4.4.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ=="], - "@smithy/core": ["@smithy/core@3.21.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.9", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-bg2TfzgsERyETAxc/Ims/eJX8eAnIeTi4r4LHpMpfF/2NyO6RsWis0rjKcCPaGksljmOb23BZRiCeT/3NvwkXw=="], + "@smithy/core": ["@smithy/core@3.21.1", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.9", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-NUH8R4O6FkN8HKMojzbGg/5pNjsfTjlMmeFclyPfPaXXUrbr5TzhWgbf7t92wfrpCHRgpjyz7ffASIS3wX28aA=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw=="], @@ -1356,9 +1357,9 @@ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.10", "", { "dependencies": { "@smithy/core": "^3.21.0", "@smithy/middleware-serde": "^4.2.9", "@smithy/node-config-provider": "^4.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-kwWpNltpxrvPabnjEFvwSmA+66l6s2ReCvgVSzW/z92LU4T28fTdgZ18IdYRYOrisu2NMQ0jUndRScbO65A/zg=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.11", "", { "dependencies": { "@smithy/core": "^3.21.1", "@smithy/middleware-serde": "^4.2.9", "@smithy/node-config-provider": "^4.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-/WqsrycweGGfb9sSzME4CrsuayjJF6BueBmkKlcbeU5q18OhxRrvvKlmfw3tpDsK5ilx2XUJvoukwxHB0nHs/Q=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.26", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/protocol-http": "^5.3.8", "@smithy/service-error-classification": "^4.2.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-ozZMoTAr+B2aVYfLYfkssFvc8ZV3p/vLpVQ7/k277xxUOA9ykSPe5obL2j6yHfbdrM/SZV7qj0uk/hSqavHrLw=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.27", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/protocol-http": "^5.3.8", "@smithy/service-error-classification": "^4.2.8", "@smithy/smithy-client": "^4.10.12", "@smithy/types": "^4.12.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-xFUYCGRVsfgiN5EjsJJSzih9+yjStgMTCLANPlf0LVQkPDYCe0hz97qbdTZosFOiYlGBlHYityGRxrQ/hxhfVQ=="], "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.9", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ=="], @@ -1382,7 +1383,7 @@ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.8", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.10.11", "", { "dependencies": { "@smithy/core": "^3.21.0", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-stack": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" } }, "sha512-6o804SCyHGMXAb5mFJ+iTy9kVKv7F91a9szN0J+9X6p8A0NrdpUxdaC57aye2ipQkP2C4IAqETEpGZ0Zj77Haw=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.10.12", "", { "dependencies": { "@smithy/core": "^3.21.1", "@smithy/middleware-endpoint": "^4.4.11", "@smithy/middleware-stack": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" } }, "sha512-VKO/HKoQ5OrSHW6AJUmEnUKeXI1/5LfCwO9cwyao7CmLvGnZeM1i36Lyful3LK1XU7HwTVieTqO1y2C/6t3qtA=="], "@smithy/types": ["@smithy/types@4.12.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw=="], @@ -1398,9 +1399,9 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.25", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-8ugoNMtss2dJHsXnqsibGPqoaafvWJPACmYKxJ4E6QWaDrixsAemmiMMAVbvwYadjR0H9G2+AlzsInSzRi8PSw=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.26", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.10.12", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-vva0dzYUTgn7DdE0uaha10uEdAgmdLnNFowKFjpMm6p2R0XDk5FHPX3CBJLzWQkQXuEprsb0hGz9YwbicNWhjw=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.28", "", { "dependencies": { "@smithy/config-resolver": "^4.4.6", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-mjUdcP8h3E0K/XvNMi9oBXRV3DMCzeRiYIieZ1LQ7jq5tu6GH/GTWym7a1xIIE0pKSoLcpGsaImuQhGPSIJzAA=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.29", "", { "dependencies": { "@smithy/config-resolver": "^4.4.6", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.10.12", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-c6D7IUBsZt/aNnTBHMTf+OVh+h/JcxUUgfTcIJaWRe6zhOum1X+pNKSZtZ+7fbOn5I99XVFtmrnXKv8yHHErTQ=="], "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw=="], @@ -1434,19 +1435,19 @@ "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], - "@supabase/auth-js": ["@supabase/auth-js@2.91.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-9ywvsKLsxTwv7fvN5fXzP3UfRreqrX2waylTBDu0lkmeHXa8WtSQS9e0WV9FBduiazYqQbgfBQXBNPRPsRgWOQ=="], + "@supabase/auth-js": ["@supabase/auth-js@2.91.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-3gFGMPuif2BOuAHXLAGsoOlDa64PROct1v7G94pMnvUAhh75u6+vnx4MYz1wyoyDBN5lCkJPGQNg5+RIgqxnpA=="], - "@supabase/functions-js": ["@supabase/functions-js@2.91.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-WaakXOqLK1mLtBNFXp5o5T+LlI6KZuADSeXz+9ofPRG5OpVSvW148LVJB1DRZ16Phck1a0YqIUswOUgxCz6vMw=="], + "@supabase/functions-js": ["@supabase/functions-js@2.91.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-xKepd3HZ6K6rKibriehKggIegsoz+jjV67tikN51q/YQq3AlUAkjUMSnMrqs8t5LMlAi+a3dJU812acXanR0cw=="], - "@supabase/postgrest-js": ["@supabase/postgrest-js@2.91.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-5S41zv2euNpGucvtM4Wy+xOmLznqt/XO+Lh823LOFEQ00ov7QJfvqb6VzIxufvzhooZpmGR0BxvMcJtWxCIFdQ=="], + "@supabase/postgrest-js": ["@supabase/postgrest-js@2.91.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-UKumTC6SGHd65G/5Gj0V58u+SkUyiH4zEJ8OP2eb06+Tqnges1E/3Tl7lyq2qbcMP8nEyH/0M7m2bYjrn++haw=="], - "@supabase/realtime-js": ["@supabase/realtime-js@2.91.0", "", { "dependencies": { "@types/phoenix": "^1.6.6", "@types/ws": "^8.18.1", "tslib": "2.8.1", "ws": "^8.18.2" } }, "sha512-u2YuJFG35umw8DO9beC27L/jYXm3KhF+73WQwbynMpV0tXsFIA0DOGRM0NgRyy03hJIdO6mxTTwe8efW3yx3Tg=="], + "@supabase/realtime-js": ["@supabase/realtime-js@2.91.1", "", { "dependencies": { "@types/phoenix": "^1.6.6", "@types/ws": "^8.18.1", "tslib": "2.8.1", "ws": "^8.18.2" } }, "sha512-Y4rifuvzekFgd2hUfiEvcMoh/JU3s1hmpWYS7tNGL2QHuFfWg8a4w/qg5qoSMVDvgGRz6G4L6yB1FaQRTplENQ=="], "@supabase/ssr": ["@supabase/ssr@0.5.2", "", { "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.7.0" }, "peerDependencies": { "@supabase/supabase-js": "^2.43.4" } }, "sha512-n3plRhr2Bs8Xun1o4S3k1CDv17iH5QY9YcoEvXX3bxV1/5XSasA0mNXYycFmADIdtdE6BG9MRjP5CGIs8qxC8A=="], - "@supabase/storage-js": ["@supabase/storage-js@2.91.0", "", { "dependencies": { "iceberg-js": "^0.8.1", "tslib": "2.8.1" } }, "sha512-CI7fsVIBQHfNObqU9kmyQ1GWr+Ug44y4rSpvxT4LdQB9tlhg1NTBov6z7Dlmt8d6lGi/8a9lf/epCDxyWI792g=="], + "@supabase/storage-js": ["@supabase/storage-js@2.91.1", "", { "dependencies": { "iceberg-js": "^0.8.1", "tslib": "2.8.1" } }, "sha512-hMJNT2tSleOrWwx4FmHTpihIA2PRDixAsWflECuQ4YDkeduBZGX5m2txnstMnteWW+H+mm+92WRRFLuidXqbfA=="], - "@supabase/supabase-js": ["@supabase/supabase-js@2.91.0", "", { "dependencies": { "@supabase/auth-js": "2.91.0", "@supabase/functions-js": "2.91.0", "@supabase/postgrest-js": "2.91.0", "@supabase/realtime-js": "2.91.0", "@supabase/storage-js": "2.91.0" } }, "sha512-Rjb0QqkKrmXMVwUOdEqysPBZ0ZDZakeptTkUa6k2d8r3strBdbWVDqjOdkCjAmvvZMtXecBeyTyMEXD1Zzjfvg=="], + "@supabase/supabase-js": ["@supabase/supabase-js@2.91.1", "", { "dependencies": { "@supabase/auth-js": "2.91.1", "@supabase/functions-js": "2.91.1", "@supabase/postgrest-js": "2.91.1", "@supabase/realtime-js": "2.91.1", "@supabase/storage-js": "2.91.1" } }, "sha512-57Fb4s5nfLn5ed2a1rPtl+LI1Wbtms8MS4qcUa0w6luaStBlFhmSeD2TLBgJWdMIupWRF6iFTH4QTrO2+pG/ZQ=="], "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], @@ -1488,13 +1489,13 @@ "@tanstack/pacer-lite": ["@tanstack/pacer-lite@0.1.1", "", {}, "sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w=="], - "@tanstack/query-core": ["@tanstack/query-core@5.90.19", "", {}, "sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="], "@tanstack/query-devtools": ["@tanstack/query-devtools@5.92.0", "", {}, "sha512-N8D27KH1vEpVacvZgJL27xC6yPFUy0Zkezn5gnB3L3gRCxlDeSuiya7fKge8Y91uMTnC8aSxBQhcK6ocY7alpQ=="], "@tanstack/react-form": ["@tanstack/react-form@1.27.7", "", { "dependencies": { "@tanstack/form-core": "1.27.7", "@tanstack/react-store": "^0.8.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-xTg4qrUY0fuLaSnkATLZcK3BWlnwLp7IuAb6UTbZKngiDEvvDCNTvVvHgPlgef1O2qN4klZxInRyRY6oEkXZ2A=="], - "@tanstack/react-query": ["@tanstack/react-query@5.90.19", "", { "dependencies": { "@tanstack/query-core": "5.90.19" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ=="], + "@tanstack/react-query": ["@tanstack/react-query@5.90.20", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw=="], "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.2", "", { "dependencies": { "@tanstack/query-devtools": "5.92.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.14", "react": "^18 || ^19" } }, "sha512-ZJ1503ay5fFeEYFUdo7LMNFzZryi6B0Cacrgr2h1JRkvikK1khgIq6Nq2EcblqEdIlgB/r7XDW8f8DQ89RuUgg=="], @@ -1748,21 +1749,21 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.53.1", "", { "dependencies": { "@typescript-eslint/types": "8.53.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260120.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260120.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260120.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260120.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260120.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260120.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260120.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260120.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-nnEf37C9ue7OBRnF2zmV/OCBmV5Y7T/K4mCHa+nxgiXcF/1w8sA0cgdFl+gHQ0mysqUJ+Bu5btAMeWgpLyjrgg=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260122.4", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260122.4", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260122.4", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260122.4", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260122.4", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260122.4", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260122.4", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260122.4" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-lboRukXxL3jeIyMKc4EjNHI4QThjOrrT5jjCyaNOUFkrk3JiObrR4z7Z6Z+m+WM/gbSW2tqaRBRFBRMsZGsxKQ=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260120.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-r3pWFuR2H7mn6ScwpH5jJljKQqKto0npVuJSk6pRwFwexpTyxOGmJTZJ1V0AWiisaNxU2+CNAqWFJSJYIE/QTg=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260122.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8hIIPe6LoY+FmUBRvhX7IbsZCr4Puwps0Ok+ez+rzg7d+sJCVuJ37ZxFh1pcNJEM39eII2o5TZ9dTCIT7/aAWA=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260120.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cuC1+wLbUP+Ip2UT94G134fqRdp5w3b3dhcCO6/FQ4yXxvRNyv/WK+upHBUFDaeSOeHgDTyO9/QFYUWwC4If1A=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260122.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-kJNpVzPW9jcFuRco+QwSHToEFHmfovNmwLo9PY97DLMqGnrvxkSy+k5sClHscEThIdzSRQbi7uZJUVBwgohNmA=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260120.1", "", { "os": "linux", "cpu": "arm" }, "sha512-vN6OYVySol/kQZjJGmAzd6L30SyVlCgmCXS8WjUYtE5clN0YrzQHop16RK29fYZHMxpkOniVBtRPxUYQANZBlQ=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260122.4", "", { "os": "linux", "cpu": "arm" }, "sha512-ImSMhsrB9QMK/cT2s4yCWkWOBUGZ+1L6vBaMMdyw3eNrU4tQo85Z3AqTn12M8WRbefLL89OmP6zJppP2TH3PAQ=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260120.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-zZGvEGY7wcHYefMZ87KNmvjN3NLIhsCMHEpHZiGCS3khKf+8z6ZsanrzCjOTodvL01VPyBzHxV1EtkSxAcLiQg=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260122.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-QsSNK3PbRyNviv0xru21jGV8fgzTVJ26oMnQwoK0IcyGabXtcLHJe5I5y4lwvLNjZPCbKDNThawso54Fo72FJQ=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260120.1", "", { "os": "linux", "cpu": "x64" }, "sha512-JBfNhWd/asd5MDeS3VgRvE24pGKBkmvLub6tsux6ypr+Yhy+o0WaAEzVpmlRYZUqss2ai5tvOu4dzPBXzZAtFw=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260122.4", "", { "os": "linux", "cpu": "x64" }, "sha512-0OyzmbZ2Zq039RPLCyEjcrBhDkCXDfIrwbMJfoOrCyEO9XrK9Icwqzogm7H4bLyhcfuZIgugYSP2mQflaDvOVg=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260120.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-tTndRtYCq2xwgE0VkTi9ACNiJaV43+PqvBqCxk8ceYi3X36Ve+CCnwlZfZJ4k9NxZthtrAwF/kUmpC9iIYbq1w=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260122.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-FSRZ0iylGKbrYiimfkqKBXRlhR+PwOz5Jcb57dAU7wzr/7xSGON9bfywb0BhoF31GjYAnZ5Xv+1fuQOiB2HBYw=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260120.1", "", { "os": "win32", "cpu": "x64" }, "sha512-oZia7hFL6k9pVepfonuPI86Jmyz6WlJKR57tWCDwRNmpA7odxuTq1PbvcYgy1z4+wHF1nnKKJY0PMAiq6ac18w=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260122.4", "", { "os": "win32", "cpu": "x64" }, "sha512-vAzRnS4nMBAd2XduzdmrhsCAAVSbCzZxVGMIKVvRcL9ljO5+fooggiYq7sk798TIZ1ov7A0rZk5k+o0Wyx2nXA=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], @@ -1820,7 +1821,7 @@ "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], - "ai": ["ai@6.0.44", "", { "dependencies": { "@ai-sdk/gateway": "3.0.18", "@ai-sdk/provider": "3.0.4", "@ai-sdk/provider-utils": "4.0.8", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-fOyssuNfSB3i3ODuDeLaWambfJY+gE3LRHQf4nmWEPDrQhfiB+fcpVMVi77LbFRBfoG/h5BrmX0heVqz4Hl7ug=="], + "ai": ["ai@6.0.49", "", { "dependencies": { "@ai-sdk/gateway": "3.0.22", "@ai-sdk/provider": "3.0.5", "@ai-sdk/provider-utils": "4.0.9", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-LABniBX/0R6Tv+iUK5keUZhZLaZUe4YjP5M2rZ4wAdZ8iKV3EfTAoJxuL1aaWTSJKIilKa9QUEkCgnp89/32bw=="], "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], @@ -1864,7 +1865,7 @@ "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], - "autumn-js": ["autumn-js@0.1.69", "", { "dependencies": { "query-string": "^9.2.2", "rou3": "^0.6.1", "swr": "^2.3.3", "zod": "^4.0.0" }, "peerDependencies": { "better-auth": "^1.3.17", "better-call": "^1.0.12", "convex": "^1.25.4" }, "optionalPeers": ["better-auth", "better-call", "convex"] }, "sha512-rCauyN0HwksA3K1/6sW70TVcb/jV0AWEC7lukgkW8bs1Qly0DZGdN8mIo96Hrb1G0ZvHbzFb5kFf4uxHpmre5Q=="], + "autumn-js": ["autumn-js@0.1.70", "", { "dependencies": { "query-string": "^9.2.2", "rou3": "^0.6.1", "swr": "^2.3.3", "zod": "^4.0.0" }, "peerDependencies": { "better-auth": "^1.3.17", "better-call": "^1.0.12", "convex": "^1.25.4" }, "optionalPeers": ["better-auth", "better-call", "convex"] }, "sha512-W3RJdqhJX8+tO2ADtfMnPybjVmQgJrdxi/Ka4TSVruN1ZqXc1N1/HCy90ibtC0awTXk7AH/BIZ5vDl1M42QPug=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], @@ -1954,7 +1955,7 @@ "builtin-status-codes": ["builtin-status-codes@3.0.0", "", {}, "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ=="], - "bullmq": ["bullmq@5.66.5", "", { "dependencies": { "cron-parser": "4.9.0", "ioredis": "5.9.1", "msgpackr": "1.11.5", "node-abort-controller": "3.1.1", "semver": "7.7.3", "tslib": "2.8.1", "uuid": "11.1.0" } }, "sha512-DC1E7P03L+TfNHv+2SGxwNYvtb0oJPODWSKkWdfis0heU5zFW16vjM7fCjwlxMdGWw2w28EI3mTRfYLEHeQQSw=="], + "bullmq": ["bullmq@5.66.7", "", { "dependencies": { "cron-parser": "4.9.0", "ioredis": "5.9.2", "msgpackr": "1.11.5", "node-abort-controller": "3.1.1", "semver": "7.7.3", "tslib": "2.8.1", "uuid": "11.1.0" } }, "sha512-X6YIjTXVN9fFjrMCKBppu74XZBnfWf0OgvwSVcpJE99irlszpGMKyyBcAOzd3126Lh9PwKygSfmHL4UfYrrIUQ=="], "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="], @@ -1972,7 +1973,7 @@ "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001765", "", {}, "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001766", "", {}, "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -2002,7 +2003,7 @@ "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], - "chromium-bidi": ["chromium-bidi@12.0.1", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-fGg+6jr0xjQhzpy5N4ErZxQ4wF7KLEvhGZXD6EgvZKDhu7iOhZXnZhcDxPJDcwTcrD48NPzOCo84RP2lv3Z+Cg=="], + "chromium-bidi": ["chromium-bidi@13.0.1", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-c+RLxH0Vg2x2syS9wPw378oJgiJNXtYXUvnVAldUlt5uaHekn0CCU7gPksNgHjrH1qFhmjVXQj4esvuthuC7OQ=="], "cipher-base": ["cipher-base@1.0.7", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.2" } }, "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA=="], @@ -2084,7 +2085,7 @@ "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], - "cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="], + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="], @@ -2260,7 +2261,7 @@ "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - "devtools-protocol": ["devtools-protocol@0.0.1534754", "", {}, "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ=="], + "devtools-protocol": ["devtools-protocol@0.0.1551306", "", {}, "sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg=="], "dezalgo": ["dezalgo@1.0.4", "", { "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig=="], @@ -2306,7 +2307,7 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "electron-to-chromium": ["electron-to-chromium@1.5.267", "", {}, "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw=="], + "electron-to-chromium": ["electron-to-chromium@1.5.278", "", {}, "sha512-dQ0tM1svDRQOwxnXxm+twlGTjr9Upvt8UFWAgmLsxEzFQxhbti4VwxmMjsDxVC51Zo84swW7FVCXEV+VAkhuPw=="], "elliptic": ["elliptic@6.6.1", "", { "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g=="], @@ -2474,7 +2475,7 @@ "forwarded-parse": ["forwarded-parse@2.1.2", "", {}, "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw=="], - "framer-motion": ["framer-motion@12.28.1", "", { "dependencies": { "motion-dom": "^12.28.1", "motion-utils": "^12.27.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-72GkO7DS4FfcSjf26wx0v+rzkW8Fhn4Djh04aDbuEg7NYG8X8MhJZc6/5weG/YeEgIP+fCo8FS2y1HnXH8k8fQ=="], + "framer-motion": ["framer-motion@12.29.0", "", { "dependencies": { "motion-dom": "^12.29.0", "motion-utils": "^12.27.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-1gEFGXHYV2BD42ZPTFmSU9buehppU+bCuOnHU0AD18DKh9j4DuTx47MvqY5ax+NNWRtK32qIcJf1UxKo1WwjWg=="], "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], @@ -2808,11 +2809,11 @@ "kysely": ["kysely@0.28.10", "", {}, "sha512-ksNxfzIW77OcZ+QWSAPC7yDqUSaIVwkTWnTPNiIy//vifNbwsSgQ57OkkncHxxpcBHM3LRfLAZVEh7kjq5twVA=="], - "langchain": ["langchain@1.2.11", "", { "dependencies": { "@langchain/langgraph": "^1.0.0", "@langchain/langgraph-checkpoint": "^1.0.0", "langsmith": ">=0.4.0 <1.0.0", "uuid": "^10.0.0", "zod": "^3.25.76 || ^4" }, "peerDependencies": { "@langchain/core": "1.1.16" } }, "sha512-vLDlibIbcaVt+H4Jw4lDCrHnSCGhcg/U5oELp9tdfoCkGpuDsrU9qv1wW0WW+ClypLCEbWiD5qJ+IqrOm6UiBQ=="], + "langchain": ["langchain@1.2.12", "", { "dependencies": { "@langchain/langgraph": "^1.0.0", "@langchain/langgraph-checkpoint": "^1.0.0", "langsmith": ">=0.4.0 <1.0.0", "uuid": "^10.0.0", "zod": "^3.25.76 || ^4" }, "peerDependencies": { "@langchain/core": "1.1.16" } }, "sha512-08UubBUAU6scuHBlz7O1b4FQQd4YArt/M+nH5FH3cRj2UF64ii8LqfnxopZvTnXYzw8HBurd3v0n738njqzPRg=="], "langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="], - "langsmith": ["langsmith@0.4.7", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/exporter-trace-otlp-proto", "@opentelemetry/sdk-trace-base", "openai"] }, "sha512-Esv5g/J8wwRwbGQr10PB9+bLsNk0mWbrXc7nnEreQDhh0azbU57I7epSnT7GC4sS4EOWavhbxk+6p8PTXtreHw=="], + "langsmith": ["langsmith@0.4.8", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/exporter-trace-otlp-proto", "@opentelemetry/sdk-trace-base", "openai"] }, "sha512-zyhQ4zp/TJqITfoQvtk8ehUmdIkxj24dTA76nEnMw63lb04/JKZgs29r/epH1pmEwbt0nUlQWKlE8n2g6BabUA=="], "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], @@ -3036,9 +3037,9 @@ "moo": ["moo@0.5.1", "", {}, "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w=="], - "motion": ["motion@12.28.1", "", { "dependencies": { "framer-motion": "^12.28.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-qGq5+6r4IMivHbT2EUhCwxz2NgFBuba3sWDrxcHt06+nYqKMevYJiVh/N90nMRof+vIUpiq8C22ZeOXwkWWiZg=="], + "motion": ["motion@12.29.0", "", { "dependencies": { "framer-motion": "^12.29.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rjB5CP2N9S2ESAyEFnAFMgTec6X8yvfxLNcz8n12gPq3M48R7ZbBeVYkDOTj8SPMwfvGIFI801SiPSr1+HCr9g=="], - "motion-dom": ["motion-dom@12.28.1", "", { "dependencies": { "motion-utils": "^12.27.2" } }, "sha512-xqgID69syDvXwFJnUd5bW6ajGUAr/qevRoUe/EqpsXUbVIopyWrAOiwQOhpgVQD+B7Ra60zTdj5gVkmwncebMg=="], + "motion-dom": ["motion-dom@12.29.0", "", { "dependencies": { "motion-utils": "^12.27.2" } }, "sha512-3eiz9bb32yvY8Q6XNM4AwkSOBPgU//EIKTZwsSWgA9uzbPBhZJeScCVcBuwwYVqhfamewpv7ZNmVKTGp5qnzkA=="], "motion-utils": ["motion-utils@12.27.2", "", {}, "sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q=="], @@ -3248,7 +3249,7 @@ "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], - "posthog-js": ["posthog-js@1.333.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@posthog/core": "1.13.0", "@posthog/types": "1.333.0", "core-js": "^3.38.1", "dompurify": "^3.3.1", "fflate": "^0.4.8", "preact": "^10.28.0", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^4.2.4" } }, "sha512-c7vquERMedjuGE2GnaDDJW/V1BIMMQG7BlYKrH0z8O7fc3WpEsQ/IyQ+9aD9+DLxlDCFpzrwgoxVDWi9K37mdA=="], + "posthog-js": ["posthog-js@1.335.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@posthog/core": "1.13.0", "@posthog/types": "1.335.0", "core-js": "^3.38.1", "dompurify": "^3.3.1", "fflate": "^0.4.8", "preact": "^10.28.0", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^5.1.0" } }, "sha512-gWNcSb3RZIpzKu8zDWIPzEaMmGxsRKtCCbW0iTCI153PtBVOmiEsYdmMfg7weWUcf8QYc7yWNPl2AhhydnBDMA=="], "posthog-node": ["posthog-node@5.24.1", "", { "dependencies": { "@posthog/core": "1.13.0" } }, "sha512-1+wsosb5fjuor9zpp3h2uq0xKYY7rDz8gpw/10Scz8Ob/uVNrsHSwGy76D9rgt4cfyaEgpJwyYv+hPi2+YjWtw=="], @@ -3294,7 +3295,7 @@ "punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="], - "puppeteer-core": ["puppeteer-core@24.35.0", "", { "dependencies": { "@puppeteer/browsers": "2.11.1", "chromium-bidi": "12.0.1", "debug": "^4.4.3", "devtools-protocol": "0.0.1534754", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.3.10", "ws": "^8.19.0" } }, "sha512-vt1zc2ME0kHBn7ZDOqLvgvrYD5bqNv5y2ZNXzYnCv8DEtZGw/zKhljlrGuImxptZ4rq+QI9dFGrUIYqG4/IQzA=="], + "puppeteer-core": ["puppeteer-core@24.36.0", "", { "dependencies": { "@puppeteer/browsers": "2.11.1", "chromium-bidi": "13.0.1", "debug": "^4.4.3", "devtools-protocol": "0.0.1551306", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.4.0", "ws": "^8.19.0" } }, "sha512-P3Ou0MAFDCQ0dK1d9F9+8jTrg6JvXjUacgG0YkJQP4kbEnUOGokSDEMmMId5ZhXD5HwsHM202E9VwEpEjWfwxg=="], "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="], @@ -3366,7 +3367,7 @@ "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], - "recharts": ["recharts@3.6.0", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-L5bjxvQRAe26RlToBAziKUB7whaGKEwD3znoM6fz3DrTowCIC/FnJYnuq1GEzB8Zv2kdTfaxQfi5GoH0tBinyg=="], + "recharts": ["recharts@3.7.0", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-l2VCsy3XXeraxIID9fx23eCb6iCBsxUQDnE8tWm6DFdszVAO7WVY/ChAD9wVit01y6B2PMupYiMmQwhgPHc9Ew=="], "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], @@ -3440,7 +3441,7 @@ "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="], - "rollup": ["rollup@4.55.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.55.3", "@rollup/rollup-android-arm64": "4.55.3", "@rollup/rollup-darwin-arm64": "4.55.3", "@rollup/rollup-darwin-x64": "4.55.3", "@rollup/rollup-freebsd-arm64": "4.55.3", "@rollup/rollup-freebsd-x64": "4.55.3", "@rollup/rollup-linux-arm-gnueabihf": "4.55.3", "@rollup/rollup-linux-arm-musleabihf": "4.55.3", "@rollup/rollup-linux-arm64-gnu": "4.55.3", "@rollup/rollup-linux-arm64-musl": "4.55.3", "@rollup/rollup-linux-loong64-gnu": "4.55.3", "@rollup/rollup-linux-loong64-musl": "4.55.3", "@rollup/rollup-linux-ppc64-gnu": "4.55.3", "@rollup/rollup-linux-ppc64-musl": "4.55.3", "@rollup/rollup-linux-riscv64-gnu": "4.55.3", "@rollup/rollup-linux-riscv64-musl": "4.55.3", "@rollup/rollup-linux-s390x-gnu": "4.55.3", "@rollup/rollup-linux-x64-gnu": "4.55.3", "@rollup/rollup-linux-x64-musl": "4.55.3", "@rollup/rollup-openbsd-x64": "4.55.3", "@rollup/rollup-openharmony-arm64": "4.55.3", "@rollup/rollup-win32-arm64-msvc": "4.55.3", "@rollup/rollup-win32-ia32-msvc": "4.55.3", "@rollup/rollup-win32-x64-gnu": "4.55.3", "@rollup/rollup-win32-x64-msvc": "4.55.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-y9yUpfQvetAjiDLtNMf1hL9NXchIJgWt6zIKeoB+tCd3npX08Eqfzg60V9DhIGVMtQ0AlMkFw5xa+AQ37zxnAA=="], + "rollup": ["rollup@4.56.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.56.0", "@rollup/rollup-android-arm64": "4.56.0", "@rollup/rollup-darwin-arm64": "4.56.0", "@rollup/rollup-darwin-x64": "4.56.0", "@rollup/rollup-freebsd-arm64": "4.56.0", "@rollup/rollup-freebsd-x64": "4.56.0", "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", "@rollup/rollup-linux-arm-musleabihf": "4.56.0", "@rollup/rollup-linux-arm64-gnu": "4.56.0", "@rollup/rollup-linux-arm64-musl": "4.56.0", "@rollup/rollup-linux-loong64-gnu": "4.56.0", "@rollup/rollup-linux-loong64-musl": "4.56.0", "@rollup/rollup-linux-ppc64-gnu": "4.56.0", "@rollup/rollup-linux-ppc64-musl": "4.56.0", "@rollup/rollup-linux-riscv64-gnu": "4.56.0", "@rollup/rollup-linux-riscv64-musl": "4.56.0", "@rollup/rollup-linux-s390x-gnu": "4.56.0", "@rollup/rollup-linux-x64-gnu": "4.56.0", "@rollup/rollup-linux-x64-musl": "4.56.0", "@rollup/rollup-openbsd-x64": "4.56.0", "@rollup/rollup-openharmony-arm64": "4.56.0", "@rollup/rollup-win32-arm64-msvc": "4.56.0", "@rollup/rollup-win32-ia32-msvc": "4.56.0", "@rollup/rollup-win32-x64-gnu": "4.56.0", "@rollup/rollup-win32-x64-msvc": "4.56.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg=="], "rou3": ["rou3@0.6.3", "", {}, "sha512-1HSG1ENTj7Kkm5muMnXuzzfdDOf7CFnbSYFA+H3Fp/rB9lOCxCPgy1jlZxTKyFoC5jJay8Mmc+VbPLYRjzYLrA=="], @@ -3736,7 +3737,7 @@ "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], - "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], @@ -3804,7 +3805,7 @@ "vscode-oniguruma": ["vscode-oniguruma@2.0.1", "", {}, "sha512-poJU8iHIWnC3vgphJnrLZyI3YdqRlR27xzqDmpPXYzA93R4Gk8z7T6oqDzDoHjoikA2aS82crdXFkjELCdJsjQ=="], - "vscode-textmate": ["vscode-textmate@9.3.1", "", {}, "sha512-U19nFkCraZF9/bkQKQYsb9mRqM9NwpToQQFl40nGiioZTH9gRtdtCHwp48cubayVfreX3ivnoxgxQgNwrTVmQg=="], + "vscode-textmate": ["vscode-textmate@9.3.2", "", {}, "sha512-n2uGbUcrjhUEBH16uGA0TvUfhWwliFZ1e3+pTjrkim1Mt7ydB41lV08aUvsi70OlzDWp6X7Bx3w/x3fAXIsN0Q=="], "vscode-uri": ["vscode-uri@3.0.8", "", {}, "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="], @@ -3812,9 +3813,9 @@ "web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], - "web-vitals": ["web-vitals@4.2.4", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="], + "web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="], - "webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.3.10", "", {}, "sha512-5LAE43jAVLOhB/QqX4bwSiv0Hg1HBfMmOuwBSXHdvg4GMGu9Y0lIq7p4R/yySu6w74WmaR4GM4H9t2IwLW7hgw=="], + "webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.4.0", "", {}, "sha512-U9VIlNRrq94d1xxR9JrCEAx5Gv/2W7ERSv8oWRoNe/QYbfccS0V3h/H6qeNeCRJxXGMhhnkqvwNrvPAYeuP9VA=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], @@ -3890,8 +3891,6 @@ "@amplitude/plugin-session-replay-browser/@amplitude/analytics-types": ["@amplitude/analytics-types@2.11.1", "", {}, "sha512-wFEgb0t99ly2uJKm5oZ28Lti0Kh5RecR5XBkwfUpDzn84IoCIZ8GJTsMw/nThu8FZFc7xFDA4UAt76zhZKrs9A=="], - "@amplitude/plugin-web-vitals-browser/web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="], - "@amplitude/rrweb/@amplitude/rrweb-types": ["@amplitude/rrweb-types@2.0.0-alpha.35", "", {}, "sha512-cR/xlN5fu7Cw6Zh9O6iEgNleqT92wJ3HO2mV19yQE6SRqLGKXXeDeTrUBd5FKCZnXvRsv3JtK+VR4u9vmZze3g=="], "@amplitude/rrweb/@amplitude/rrweb-utils": ["@amplitude/rrweb-utils@2.0.0-alpha.35", "", {}, "sha512-/OpyKKHYGwoy2fvWDg5jiH1LzWag4wlFTQjd2DUgndxlXccQF1+yxYljCDdM+J1GBeZ7DaLZa9qe2JUUtoNOOw=="], @@ -3920,7 +3919,7 @@ "@autumn/vite/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], - "@autumn/vite/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@autumn/vite/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@aws-crypto/crc32/@aws-crypto/util": ["@aws-crypto/util@3.0.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w=="], @@ -4222,7 +4221,7 @@ "@aws-sdk/credential-provider-cognito-identity/@smithy/types": ["@smithy/types@3.7.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg=="], - "@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.972.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.972.0", "@aws-sdk/middleware-host-header": "3.972.0", "@aws-sdk/middleware-logger": "3.972.0", "@aws-sdk/middleware-recursion-detection": "3.972.0", "@aws-sdk/middleware-user-agent": "3.972.0", "@aws-sdk/region-config-resolver": "3.972.0", "@aws-sdk/types": "3.972.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "3.972.0", "@aws-sdk/util-user-agent-node": "3.972.0", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.20.6", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.7", "@smithy/middleware-retry": "^4.4.23", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.22", "@smithy/util-defaults-mode-node": "^4.2.25", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-5qw6qLiRE4SUiz0hWy878dSR13tSVhbTWhsvFT8mGHe37NRRiaobm5MA2sWD0deRAuO98djSiV+dhWXa1xIFNw=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.974.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.0", "@aws-sdk/middleware-host-header": "^3.972.1", "@aws-sdk/middleware-logger": "^3.972.1", "@aws-sdk/middleware-recursion-detection": "^3.972.1", "@aws-sdk/middleware-user-agent": "^3.972.1", "@aws-sdk/region-config-resolver": "^3.972.1", "@aws-sdk/types": "^3.973.0", "@aws-sdk/util-endpoints": "3.972.0", "@aws-sdk/util-user-agent-browser": "^3.972.1", "@aws-sdk/util-user-agent-node": "^3.972.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.21.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.10", "@smithy/middleware-retry": "^4.4.26", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.10.11", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.25", "@smithy/util-defaults-mode-node": "^4.2.28", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ci+GiM0c4ULo4D79UMcY06LcOLcfvUfiyt8PzNY0vbt5O8BfCPYf4QomwVgkNcLLCYmroO4ge2Yy1EsLUlcD6g=="], "@aws-sdk/credential-providers/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w=="], @@ -4250,6 +4249,8 @@ "@aws-sdk/signature-v4/@smithy/signature-v4": ["@smithy/signature-v4@1.1.0", "", { "dependencies": { "@smithy/eventstream-codec": "^1.1.0", "@smithy/is-array-buffer": "^1.1.0", "@smithy/types": "^1.2.0", "@smithy/util-hex-encoding": "^1.1.0", "@smithy/util-middleware": "^1.1.0", "@smithy/util-uri-escape": "^1.1.0", "@smithy/util-utf8": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-fDo3m7YqXBs7neciOePPd/X9LPm5QLlDMdIC4m1H6dgNLnXfLMFNIxEfPyohGA8VW9Wn4X8lygnPSGxDZSmp0Q=="], + "@aws-sdk/util-endpoints/@aws-sdk/types": ["@aws-sdk/types@3.972.0", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-U7xBIbLSetONxb2bNzHyDgND3oKGoIfmknrEVnoEU4GUSs+0augUOIn9DIWGUO2ETcRFdsRUnmx9KhPT9Ojbug=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], @@ -4260,9 +4261,9 @@ "@better-auth/core/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@better-auth/core/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@better-auth/core/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "@better-auth/stripe/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@better-auth/stripe/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@chevrotain/cst-dts-gen/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], @@ -4306,7 +4307,7 @@ "@langchain/core/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], - "@langchain/core/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@langchain/core/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@langchain/langgraph/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], @@ -4322,7 +4323,7 @@ "@modelcontextprotocol/sdk/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], - "@modelcontextprotocol/sdk/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@modelcontextprotocol/sdk/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@opentelemetry/auto-instrumentations-node/@opentelemetry/instrumentation-ioredis": ["@opentelemetry/instrumentation-ioredis@0.50.1", "", { "dependencies": { "@opentelemetry/instrumentation": "^0.202.0", "@opentelemetry/redis-common": "^0.38.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-HKrWKOM23qNwqNjWfzkw7mePversmcH5ac6T1dUdiRyJVYaLr4qfydyYkgKIGWHOF2TKvQGobXo3CjvxABQWVw=="], @@ -4432,7 +4433,7 @@ "@posthog/ai/openai": ["openai@6.16.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-fZ1uBqjFUjXzbGc35fFtYKEOxd20kd9fDpFeqWtsOZWiubY8CZ1NAlXHW3iathaFvqmNtCWMIsosCuyeI7Joxg=="], - "@posthog/ai/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@posthog/ai/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@prisma/instrumentation/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.57.2", "", { "dependencies": { "@opentelemetry/api-logs": "0.57.2", "@types/shimmer": "^1.2.0", "import-in-the-middle": "^1.8.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg=="], @@ -4552,7 +4553,7 @@ "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@vercel/sdk/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "@vercel/sdk/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@xyflow/react/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], @@ -4564,9 +4565,9 @@ "asn1.js/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], - "autumn-js/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "autumn-js/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "better-auth/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "better-auth/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "better-call/rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], @@ -4574,8 +4575,6 @@ "browserify-sign/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], - "bullmq/ioredis": ["ioredis@5.9.1", "", { "dependencies": { "@ioredis/commands": "1.5.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-BXNqFQ66oOsR82g9ajFFsR8ZKrjVvYCLyeML9IvSMAsP56XH2VXBdZjmI11p65nXXJxTEt1hie3J2QeFJVgrtQ=="], - "chevrotain/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -4654,7 +4653,7 @@ "langchain/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], - "langchain/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], + "langchain/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "langsmith/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], @@ -4662,8 +4661,6 @@ "md-to-react-email/marked": ["marked@7.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ=="], - "md5.js/hash-base": ["hash-base@3.1.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.1" } }, "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg=="], - "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -5280,8 +5277,6 @@ "langsmith/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], - "md5.js/hash-base/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], - "mocha/log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "mocha/log-symbols/is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], @@ -5650,10 +5645,6 @@ "css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], - "md5.js/hash-base/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - - "md5.js/hash-base/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "mocha/log-symbols/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "mocha/log-symbols/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], From f9069772694a4cb8dbfc8b8c24caf3d717b08c4c Mon Sep 17 00:00:00 2001 From: Ayush Rodrigues Date: Fri, 23 Jan 2026 16:15:06 +0000 Subject: [PATCH 07/12] fix: exclude archived features from selection dropdowns --- .../views/products/plan/components/SelectFeatureSheet.tsx | 8 +++++--- .../advanced-settings/EntityFeatureConfig.tsx | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/vite/src/views/products/plan/components/SelectFeatureSheet.tsx b/vite/src/views/products/plan/components/SelectFeatureSheet.tsx index a3121f9aa..523bf0938 100644 --- a/vite/src/views/products/plan/components/SelectFeatureSheet.tsx +++ b/vite/src/views/products/plan/components/SelectFeatureSheet.tsx @@ -49,9 +49,11 @@ export function SelectFeatureSheet({ } }, [selectOpen]); - // Filter features based on search - const filteredFeatures = features.filter((feature: Feature) => - feature.name.toLowerCase().includes(searchValue.toLowerCase()), + // Filter features based on search and exclude archived features + const filteredFeatures = features.filter( + (feature: Feature) => + !feature.archived && + feature.name.toLowerCase().includes(searchValue.toLowerCase()), ); const handleFeatureSelect = (featureId: string) => { diff --git a/vite/src/views/products/plan/components/edit-plan-feature/advanced-settings/EntityFeatureConfig.tsx b/vite/src/views/products/plan/components/edit-plan-feature/advanced-settings/EntityFeatureConfig.tsx index 1346075f3..04740a1b2 100644 --- a/vite/src/views/products/plan/components/edit-plan-feature/advanced-settings/EntityFeatureConfig.tsx +++ b/vite/src/views/products/plan/components/edit-plan-feature/advanced-settings/EntityFeatureConfig.tsx @@ -18,9 +18,10 @@ export function EntityFeatureConfig() { if (!item) return null; - // Filter for continuous use features, excluding the current feature (can't link to itself) + // Filter for continuous use features, excluding the current feature (can't link to itself) and archived features const continuousUseFeatures = features.filter( (f) => + !f.archived && f.config?.usage_type === FeatureUsageType.Continuous && f.id !== item.feature_id, ); From c8b6156313be31f7af3cc550c14db80e01fdb006 Mon Sep 17 00:00:00 2001 From: Ayush Rodrigues Date: Fri, 23 Jan 2026 18:28:51 +0000 Subject: [PATCH 08/12] fix: use stable empty object reference for product counts to prevent re-renders --- vite/src/hooks/queries/useProductsQuery.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vite/src/hooks/queries/useProductsQuery.tsx b/vite/src/hooks/queries/useProductsQuery.tsx index 701a3a241..c6fdba4e7 100644 --- a/vite/src/hooks/queries/useProductsQuery.tsx +++ b/vite/src/hooks/queries/useProductsQuery.tsx @@ -2,6 +2,9 @@ import type { FullProduct, ProductCounts, ProductV2 } from "@autumn/shared"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useAxiosInstance } from "@/services/useAxiosInstance"; +// Stable empty object reference to prevent infinite re-renders +const EMPTY_COUNTS: Record = {}; + /** * Fetch all products for the current org. */ @@ -48,7 +51,7 @@ export const useProductsQuery = () => { return { products: data?.products || [], - counts: countsData || {}, + counts: countsData ?? EMPTY_COUNTS, groupToDefaults: data?.groupToDefaults || {}, isLoading, isCountsLoading, From 0f9b67c0e65e34d10e706aac67255b13dc440d9b Mon Sep 17 00:00:00 2001 From: John Yeo Date: Sat, 24 Jan 2026 19:19:39 +0000 Subject: [PATCH 09/12] feat: allow users to pass in auto_enable_plan_id to create customer to ensure that they can selectively choose which customers have which product auto enabled. --- .claude/settings.json | 15 - .../setup/setupCreateCustomer.ts | 2 +- .../setup/setupDefaultProductsContext.ts | 57 ++ .../create-customer-defaults.test.ts | 66 ++ .../customers/create-customer-errors.test.ts | 30 + .../crud/customers/list-customers.test.ts | 924 +++++++++--------- server/tests/utils/fixtures/products.ts | 5 +- .../testProductUtils/testProductUtils.ts | 5 +- shared/api/common/customerData.ts | 4 + 9 files changed, 628 insertions(+), 480 deletions(-) delete mode 100644 .claude/settings.json create mode 100644 server/tests/integration/crud/customers/create-customer-errors.test.ts diff --git a/.claude/settings.json b/.claude/settings.json deleted file mode 100644 index 3c9d8b4a8..000000000 --- a/.claude/settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Edit|Write", - "hooks": [ - { - "type": "command", - "command": "npx ultracite fix" - } - ] - } - ] - } -} \ No newline at end of file diff --git a/server/src/internal/customers/actions/createWithDefaults/setup/setupCreateCustomer.ts b/server/src/internal/customers/actions/createWithDefaults/setup/setupCreateCustomer.ts index 7914c7d3c..af036de2e 100644 --- a/server/src/internal/customers/actions/createWithDefaults/setup/setupCreateCustomer.ts +++ b/server/src/internal/customers/actions/createWithDefaults/setup/setupCreateCustomer.ts @@ -39,7 +39,7 @@ export const setupCreateCustomer = async ({ // 3. Fetch default products const { fullProducts, paidProducts, hasPaidProducts } = - await setupDefaultProductsContext({ ctx, internalOptions }); + await setupDefaultProductsContext({ ctx, customerData, internalOptions }); const currentEpochMs = Date.now(); diff --git a/server/src/internal/customers/actions/createWithDefaults/setup/setupDefaultProductsContext.ts b/server/src/internal/customers/actions/createWithDefaults/setup/setupDefaultProductsContext.ts index 536fd89d2..38439c408 100644 --- a/server/src/internal/customers/actions/createWithDefaults/setup/setupDefaultProductsContext.ts +++ b/server/src/internal/customers/actions/createWithDefaults/setup/setupDefaultProductsContext.ts @@ -1,7 +1,10 @@ import { type CreateCustomerInternalOptions, + type CustomerData, type FullProduct, isFreeProduct, + ProductNotFoundError, + RecaseError, } from "@autumn/shared"; import type { AutumnContext } from "@/honoUtils/HonoEnv.js"; import { ProductService } from "@/internal/products/ProductService.js"; @@ -13,15 +16,69 @@ export interface DefaultProductsContext { hasPaidProducts: boolean; } +const getOverrideAutoEnableProduct = async ({ + ctx, + customerData, +}: { + ctx: AutumnContext; + customerData?: CustomerData; +}): Promise => { + const { db, org, env } = ctx; + + if (!customerData?.auto_enable_plan_id) return undefined; + + const plan = await ProductService.getFull({ + db, + orgId: org.id, + env, + idOrInternalId: customerData.auto_enable_plan_id, + }); + + if (!plan) + throw new ProductNotFoundError({ + productId: customerData.auto_enable_plan_id, + }); + + if ( + !isFreeProduct({ prices: plan.prices }) && + !isDefaultTrialFullProduct({ product: plan }) + ) { + throw new RecaseError({ + message: `Auto-enable plan must be a free product, or have a free trial with 'card_required' as false`, + }); + } + + return plan; +}; + export const setupDefaultProductsContext = async ({ ctx, + customerData, internalOptions, }: { ctx: AutumnContext; + customerData?: CustomerData; internalOptions?: CreateCustomerInternalOptions; }): Promise => { const { db, org, env } = ctx; + const autoEnableProduct = await getOverrideAutoEnableProduct({ + ctx, + customerData, + }); + + if (autoEnableProduct) { + const autoEnableIsPaid = !isFreeProduct({ + prices: autoEnableProduct.prices, + }); + + return { + fullProducts: [autoEnableProduct], + paidProducts: autoEnableIsPaid ? [autoEnableProduct] : [], + hasPaidProducts: autoEnableIsPaid, + }; + } + const defaultProds = await ProductService.listDefault({ db, orgId: org.id, diff --git a/server/tests/integration/crud/customers/create-customer-defaults.test.ts b/server/tests/integration/crud/customers/create-customer-defaults.test.ts index e065e56bc..182f74cf9 100644 --- a/server/tests/integration/crud/customers/create-customer-defaults.test.ts +++ b/server/tests/integration/crud/customers/create-customer-defaults.test.ts @@ -6,6 +6,7 @@ import { expectProductTrialing, } from "@tests/integration/billing/utils/expectCustomerProductTrialing.js"; import { TestFeature } from "@tests/setup/v2Features.js"; +import { expectProductNotAttached } from "@tests/utils/expectUtils/expectProductAttached"; import { items } from "@tests/utils/fixtures/items.js"; import { products } from "@tests/utils/fixtures/products.js"; import { initScenario, s } from "@tests/utils/testInitUtils/initScenario.js"; @@ -80,3 +81,68 @@ test.concurrent(`${chalk.yellowBright("defaults: free product with 7-day trial") // Verify feature balance is still available during trial expect(customer.features[TestFeature.Messages].balance).toBe(100); }); + +// ═══════════════════════════════════════════════════════════════════════════════ +// AUTO-ENABLE PLAN OVERRIDE TESTS +// ═══════════════════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("defaults: auto-enable plan override")}`, async () => { + const messagesItem = items.monthlyMessages({ includedUsage: 100 }); + const messagesItemB = items.monthlyMessages({ includedUsage: 200 }); + + const autoEnableProductA = products.base({ + id: "auto-enable-a", + items: [messagesItem], + group: "auto-enable-group-a", + isDefault: true, + }); + + const autoEnableProductB = products.base({ + id: "auto-enable-b", + items: [messagesItemB], + group: "auto-enable-group-b", + isDefault: true, + }); + + const customerIdA = "auto-enable-override-a"; + const customerIdB = "auto-enable-override-b"; + + const { autumnV1 } = await initScenario({ + setup: [ + s.deleteCustomer({ customerId: customerIdA }), + s.deleteCustomer({ customerId: customerIdB }), + s.products({ list: [autoEnableProductA, autoEnableProductB] }), + ], + actions: [], + }); + + const customerA = await autumnV1.customers.create({ + id: customerIdA, + auto_enable_plan_id: autoEnableProductA.id, + }); + + const customerB = await autumnV1.customers.create({ + id: customerIdB, + auto_enable_plan_id: autoEnableProductB.id, + }); + + expectProductActive({ + customer: customerA, + productId: autoEnableProductA.id, + }); + + expectProductNotAttached({ + customer: customerA, + productId: autoEnableProductB.id, + }); + + expectProductActive({ + customer: customerB, + productId: autoEnableProductB.id, + }); + + expectProductNotAttached({ + customer: customerB, + productId: autoEnableProductA.id, + }); +}); diff --git a/server/tests/integration/crud/customers/create-customer-errors.test.ts b/server/tests/integration/crud/customers/create-customer-errors.test.ts new file mode 100644 index 000000000..db8094d58 --- /dev/null +++ b/server/tests/integration/crud/customers/create-customer-errors.test.ts @@ -0,0 +1,30 @@ +import { test } from "bun:test"; +import { ErrCode } from "@autumn/shared"; +import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js"; +import { initScenario, s } from "@tests/utils/testInitUtils/initScenario.js"; +import chalk from "chalk"; + +// ═══════════════════════════════════════════════════════════════════════════════ +// AUTO-ENABLE PLAN ERROR TESTS +// ═══════════════════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("errors: auto_enable_plan_id with non-existent product")}`, async () => { + const customerId = "error-auto-enable-nonexistent"; + + const { autumnV1 } = await initScenario({ + setup: [ + s.deleteCustomer({ customerId }), + ], + actions: [], + }); + + await expectAutumnError({ + errCode: ErrCode.ProductNotFound, + func: async () => { + await autumnV1.customers.create({ + id: customerId, + auto_enable_plan_id: "non-existent-product-id", + }); + }, + }); +}); diff --git a/server/tests/integration/crud/customers/list-customers.test.ts b/server/tests/integration/crud/customers/list-customers.test.ts index c5969be45..0dc8b8172 100644 --- a/server/tests/integration/crud/customers/list-customers.test.ts +++ b/server/tests/integration/crud/customers/list-customers.test.ts @@ -1,462 +1,462 @@ -import { beforeAll, describe, expect, test } from "bun:test"; -import { - type ApiCustomer, - ApiVersion, - ProductItemInterval, -} from "@autumn/shared"; -import { TestFeature } from "@tests/setup/v2Features.js"; -import ctx from "@tests/utils/testInitUtils/createTestContext.js"; -import chalk from "chalk"; -import { AutumnInt } from "@/external/autumn/autumnCli.js"; -import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js"; -import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js"; -import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js"; -import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js"; - -const testCase = "list-customers"; - -// Different products for testing multi-plan filtering -const productA = constructProduct({ - id: `${testCase}-product-a`, - type: "free", - isDefault: false, - version: 1, - items: [ - constructFeatureItem({ - featureId: TestFeature.Messages, - includedUsage: 100, - interval: ProductItemInterval.Month, - }), - ], -}); - -const productB = constructProduct({ - id: `${testCase}-product-b`, - type: "free", - isDefault: false, - version: 1, - items: [ - constructFeatureItem({ - featureId: TestFeature.Messages, - includedUsage: 200, - interval: ProductItemInterval.Month, - }), - ], -}); - -const otherProduct = constructProduct({ - id: `${testCase}-other-product`, - type: "free", - isDefault: false, - items: [ - constructFeatureItem({ - featureId: TestFeature.Dashboard, - isBoolean: true, - }), - ], -}); - -const customerIds = { - withProductA: `${testCase}-cus-a`, - withProductB: `${testCase}-cus-b`, - withOtherProduct: `${testCase}-cus-other`, - searchable: `${testCase}-searchable-john`, -}; - -describe(`${chalk.yellowBright("list-customers: Testing list customers endpoint")}`, () => { - const autumn = new AutumnInt({ - secretKey: ctx.orgSecretKey, - version: ApiVersion.V1_2, - }); - - beforeAll(async () => { - // Create products - await initProductsV0({ - ctx, - products: [productA, productB, otherProduct], - prefix: "", - customerId: customerIds.withProductA, - }); - - // Create customers - for (const customerId of Object.values(customerIds)) { - await initCustomerV3({ - ctx, - customerId, - withTestClock: false, - withDefault: false, - }); - } - - // Attach products to customers - await autumn.attach({ - customer_id: customerIds.withProductA, - product_id: productA.id, - }); - - await autumn.attach({ - customer_id: customerIds.withProductB, - product_id: productB.id, - }); - - await autumn.attach({ - customer_id: customerIds.withOtherProduct, - product_id: otherProduct.id, - }); - - // Attach product to searchable customer so it's not filtered out by default status - await autumn.attach({ - customer_id: customerIds.searchable, - product_id: productA.id, - }); - }); - - // Pagination Tests - describe("pagination", () => { - test("should return customers with default pagination", async () => { - const result = await autumn.customers.list(); - - expect(result.list).toBeDefined(); - expect(Array.isArray(result.list)).toBe(true); - expect(result.limit).toBe(10); - expect(result.offset).toBe(0); - expect(typeof result.total).toBe("number"); - }); - - test("should respect custom limit", async () => { - const result = await autumn.customers.list({ limit: 20 }); - - expect(result.limit).toBe(20); - }); - - test("should respect offset", async () => { - const result = await autumn.customers.list({ offset: 5 }); - - expect(result.offset).toBe(5); - }); - - test("should respect max limit of 100", async () => { - const result = await autumn.customers.list({ limit: 100 }); - - expect(result.limit).toBe(100); - }); - }); - - // Search Tests (V2) - describe("search", () => { - test("should search by customer ID", async () => { - const result = await autumn.customers.listV2({ - search: "searchable-john", - }); - - expect(result.list.length).toBeGreaterThanOrEqual(1); - const found = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.searchable, - ); - expect(found).toBeDefined(); - }); - - test("should search by customer email", async () => { - const result = await autumn.customers.listV2({ - search: "searchable-john@example", - }); - - expect(result.list.length).toBeGreaterThanOrEqual(1); - const found = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.searchable, - ); - expect(found).toBeDefined(); - }); - - test("should return empty list for non-matching search", async () => { - const result = await autumn.customers.listV2({ - search: "nonexistent-customer-xyz-123", - }); - - expect(result.list.length).toBe(0); - }); - - test("should be case-insensitive", async () => { - const result = await autumn.customers.listV2({ - search: "SEARCHABLE-JOHN", - }); - - expect(result.list.length).toBeGreaterThanOrEqual(1); - }); - }); - - // Response Structure Tests - describe("response structure", () => { - test("should have correct response structure", async () => { - const result = await autumn.customers.list(); - - expect(result).toHaveProperty("list"); - expect(result).toHaveProperty("total"); - expect(result).toHaveProperty("limit"); - expect(result).toHaveProperty("offset"); - }); - - test("each customer should have expected fields", async () => { - const result = await autumn.customers.list({ limit: 10 }); - - if (result.list.length > 0) { - const customer = result.list[0]; - expect(customer).toHaveProperty("id"); - expect(customer).toHaveProperty("created_at"); - expect(customer).toHaveProperty("products"); - expect(customer).toHaveProperty("features"); - } - }); - }); - - // V2 Plans Filter Tests - describe("plans filter (V2)", () => { - test("should filter by single plan and exclude non-matching customers", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }], - }); - - // Should find customers with productA (withProductA and searchable) - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - const foundSearchable = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.searchable, - ); - expect(foundA).toBeDefined(); - expect(foundSearchable).toBeDefined(); - - // Should NOT find customers with other products - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - const foundOther = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, - ); - expect(foundB).toBeUndefined(); - expect(foundOther).toBeUndefined(); - }); - - test("should filter by single plan with specific version", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id, versions: [1] }], - }); - - const found = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - expect(found).toBeDefined(); - - // Should NOT find customers with productB (different product) - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundB).toBeUndefined(); - }); - - test("should return empty list for non-matching version", async () => { - // All products are version 1, so filtering for version 999 should return empty - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id, versions: [999] }], - }); - - expect(result.list.length).toBe(0); - }); - - test("should filter by multiple plans (OR logic)", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }, { id: productB.id }], - }); - - // Should find customers with productA OR productB - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundA).toBeDefined(); - expect(foundB).toBeDefined(); - - // Should NOT find customer with otherProduct (not in filter) - const foundOther = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, - ); - expect(foundOther).toBeUndefined(); - }); - - test("should filter by multiple plans including other product", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }, { id: otherProduct.id }], - }); - - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - const foundOther = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, - ); - expect(foundA).toBeDefined(); - expect(foundOther).toBeDefined(); - - // Should NOT find customer with productB - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundB).toBeUndefined(); - }); - - test("should filter by plan with version constraint", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id, versions: [1] }, { id: otherProduct.id }], - }); - - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - const foundOther = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, - ); - expect(foundA).toBeDefined(); - expect(foundOther).toBeDefined(); - - // Should NOT find customer with productB - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundB).toBeUndefined(); - }); - - test("should combine plans filter with search", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }], - search: "cus-a", - }); - - // Should find exactly the customer matching both criteria - expect(result.list.length).toBe(1); - expect(result.list[0].id).toBe(customerIds.withProductA); - }); - - test("should return empty list for non-existent plan", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: "nonexistent-plan-xyz" }], - }); - - expect(result.list.length).toBe(0); - }); - - test("should return empty list for non-existent version", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id, versions: [999] }], - }); - - expect(result.list.length).toBe(0); - }); - - test("should have correct response structure", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }], - }); - - expect(result).toHaveProperty("list"); - expect(result).toHaveProperty("total"); - expect(result).toHaveProperty("limit"); - expect(result).toHaveProperty("offset"); - }); - - test("should return plan_version in product response", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }], - }); - - const found = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - expect(found).toBeDefined(); - - // Check that version is returned correctly (V1.2 returns as 'products' with 'version' field) - const products = (found as any).products; - expect(products).toBeDefined(); - expect(Array.isArray(products)).toBe(true); - - const matchingProduct = products.find((p: any) => p.id === productA.id); - expect(matchingProduct).toBeDefined(); - expect(matchingProduct.version).toBe(1); - }); - }); - - // V2 Subscription Status Filter Tests - describe("subscription_status filter (V2)", () => { - test("should filter by active status", async () => { - const result = await autumn.customers.listV2({ - subscription_status: ["active"], - }); - - // All our test customers have active products - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundA).toBeDefined(); - expect(foundB).toBeDefined(); - }); - - test("should filter by multiple statuses", async () => { - const result = await autumn.customers.listV2({ - subscription_status: ["active", "scheduled"], - }); - - // Should include active customers - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - expect(foundA).toBeDefined(); - }); - - test("should combine subscription_status with plans filter (AND logic)", async () => { - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id }], - subscription_status: ["active"], - }); - - // Should find customers with productA AND active status - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - expect(foundA).toBeDefined(); - - // Should NOT find customers with other products even if active - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - const foundOther = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, - ); - expect(foundB).toBeUndefined(); - expect(foundOther).toBeUndefined(); - }); - - test("should require BOTH plan AND status to match when combined", async () => { - // Filter for productA with active status - const result = await autumn.customers.listV2({ - plans: [{ id: productA.id, versions: [1] }], - subscription_status: ["active"], - }); - - // Only customers with productA v1 AND active status should be returned - const foundA = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductA, - ); - expect(foundA).toBeDefined(); - - // ProductB customer should NOT be returned (wrong product) - const foundB = result.list.find( - (customer: ApiCustomer) => customer.id === customerIds.withProductB, - ); - expect(foundB).toBeUndefined(); - }); - }); -}); +// import { beforeAll, describe, expect, test } from "bun:test"; +// import { +// type ApiCustomer, +// ApiVersion, +// ProductItemInterval, +// } from "@autumn/shared"; +// import { TestFeature } from "@tests/setup/v2Features.js"; +// import ctx from "@tests/utils/testInitUtils/createTestContext.js"; +// import chalk from "chalk"; +// import { AutumnInt } from "@/external/autumn/autumnCli.js"; +// import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js"; +// import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js"; +// import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js"; +// import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js"; + +// const testCase = "list-customers"; + +// // Different products for testing multi-plan filtering +// const productA = constructProduct({ +// id: `${testCase}-product-a`, +// type: "free", +// isDefault: false, +// version: 1, +// items: [ +// constructFeatureItem({ +// featureId: TestFeature.Messages, +// includedUsage: 100, +// interval: ProductItemInterval.Month, +// }), +// ], +// }); + +// const productB = constructProduct({ +// id: `${testCase}-product-b`, +// type: "free", +// isDefault: false, +// version: 1, +// items: [ +// constructFeatureItem({ +// featureId: TestFeature.Messages, +// includedUsage: 200, +// interval: ProductItemInterval.Month, +// }), +// ], +// }); + +// const otherProduct = constructProduct({ +// id: `${testCase}-other-product`, +// type: "free", +// isDefault: false, +// items: [ +// constructFeatureItem({ +// featureId: TestFeature.Dashboard, +// isBoolean: true, +// }), +// ], +// }); + +// const customerIds = { +// withProductA: `${testCase}-cus-a`, +// withProductB: `${testCase}-cus-b`, +// withOtherProduct: `${testCase}-cus-other`, +// searchable: `${testCase}-searchable-john`, +// }; + +// describe(`${chalk.yellowBright("list-customers: Testing list customers endpoint")}`, () => { +// const autumn = new AutumnInt({ +// secretKey: ctx.orgSecretKey, +// version: ApiVersion.V1_2, +// }); + +// beforeAll(async () => { +// // Create products +// await initProductsV0({ +// ctx, +// products: [productA, productB, otherProduct], +// prefix: "", +// customerId: customerIds.withProductA, +// }); + +// // Create customers +// for (const customerId of Object.values(customerIds)) { +// await initCustomerV3({ +// ctx, +// customerId, +// withTestClock: false, +// withDefault: false, +// }); +// } + +// // Attach products to customers +// await autumn.attach({ +// customer_id: customerIds.withProductA, +// product_id: productA.id, +// }); + +// await autumn.attach({ +// customer_id: customerIds.withProductB, +// product_id: productB.id, +// }); + +// await autumn.attach({ +// customer_id: customerIds.withOtherProduct, +// product_id: otherProduct.id, +// }); + +// // Attach product to searchable customer so it's not filtered out by default status +// await autumn.attach({ +// customer_id: customerIds.searchable, +// product_id: productA.id, +// }); +// }); + +// // Pagination Tests +// describe("pagination", () => { +// test("should return customers with default pagination", async () => { +// const result = await autumn.customers.list(); + +// expect(result.list).toBeDefined(); +// expect(Array.isArray(result.list)).toBe(true); +// expect(result.limit).toBe(10); +// expect(result.offset).toBe(0); +// expect(typeof result.total).toBe("number"); +// }); + +// test("should respect custom limit", async () => { +// const result = await autumn.customers.list({ limit: 20 }); + +// expect(result.limit).toBe(20); +// }); + +// test("should respect offset", async () => { +// const result = await autumn.customers.list({ offset: 5 }); + +// expect(result.offset).toBe(5); +// }); + +// test("should respect max limit of 100", async () => { +// const result = await autumn.customers.list({ limit: 100 }); + +// expect(result.limit).toBe(100); +// }); +// }); + +// // Search Tests (V2) +// describe("search", () => { +// test("should search by customer ID", async () => { +// const result = await autumn.customers.listV2({ +// search: "searchable-john", +// }); + +// expect(result.list.length).toBeGreaterThanOrEqual(1); +// const found = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.searchable, +// ); +// expect(found).toBeDefined(); +// }); + +// test("should search by customer email", async () => { +// const result = await autumn.customers.listV2({ +// search: "searchable-john@example", +// }); + +// expect(result.list.length).toBeGreaterThanOrEqual(1); +// const found = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.searchable, +// ); +// expect(found).toBeDefined(); +// }); + +// test("should return empty list for non-matching search", async () => { +// const result = await autumn.customers.listV2({ +// search: "nonexistent-customer-xyz-123", +// }); + +// expect(result.list.length).toBe(0); +// }); + +// test("should be case-insensitive", async () => { +// const result = await autumn.customers.listV2({ +// search: "SEARCHABLE-JOHN", +// }); + +// expect(result.list.length).toBeGreaterThanOrEqual(1); +// }); +// }); + +// // Response Structure Tests +// describe("response structure", () => { +// test("should have correct response structure", async () => { +// const result = await autumn.customers.list(); + +// expect(result).toHaveProperty("list"); +// expect(result).toHaveProperty("total"); +// expect(result).toHaveProperty("limit"); +// expect(result).toHaveProperty("offset"); +// }); + +// test("each customer should have expected fields", async () => { +// const result = await autumn.customers.list({ limit: 10 }); + +// if (result.list.length > 0) { +// const customer = result.list[0]; +// expect(customer).toHaveProperty("id"); +// expect(customer).toHaveProperty("created_at"); +// expect(customer).toHaveProperty("products"); +// expect(customer).toHaveProperty("features"); +// } +// }); +// }); + +// // V2 Plans Filter Tests +// describe("plans filter (V2)", () => { +// test("should filter by single plan and exclude non-matching customers", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }], +// }); + +// // Should find customers with productA (withProductA and searchable) +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// const foundSearchable = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.searchable, +// ); +// expect(foundA).toBeDefined(); +// expect(foundSearchable).toBeDefined(); + +// // Should NOT find customers with other products +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// const foundOther = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, +// ); +// expect(foundB).toBeUndefined(); +// expect(foundOther).toBeUndefined(); +// }); + +// test("should filter by single plan with specific version", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id, versions: [1] }], +// }); + +// const found = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// expect(found).toBeDefined(); + +// // Should NOT find customers with productB (different product) +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundB).toBeUndefined(); +// }); + +// test("should return empty list for non-matching version", async () => { +// // All products are version 1, so filtering for version 999 should return empty +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id, versions: [999] }], +// }); + +// expect(result.list.length).toBe(0); +// }); + +// test("should filter by multiple plans (OR logic)", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }, { id: productB.id }], +// }); + +// // Should find customers with productA OR productB +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundA).toBeDefined(); +// expect(foundB).toBeDefined(); + +// // Should NOT find customer with otherProduct (not in filter) +// const foundOther = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, +// ); +// expect(foundOther).toBeUndefined(); +// }); + +// test("should filter by multiple plans including other product", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }, { id: otherProduct.id }], +// }); + +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// const foundOther = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, +// ); +// expect(foundA).toBeDefined(); +// expect(foundOther).toBeDefined(); + +// // Should NOT find customer with productB +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundB).toBeUndefined(); +// }); + +// test("should filter by plan with version constraint", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id, versions: [1] }, { id: otherProduct.id }], +// }); + +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// const foundOther = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, +// ); +// expect(foundA).toBeDefined(); +// expect(foundOther).toBeDefined(); + +// // Should NOT find customer with productB +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundB).toBeUndefined(); +// }); + +// test("should combine plans filter with search", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }], +// search: "cus-a", +// }); + +// // Should find exactly the customer matching both criteria +// expect(result.list.length).toBe(1); +// expect(result.list[0].id).toBe(customerIds.withProductA); +// }); + +// test("should return empty list for non-existent plan", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: "nonexistent-plan-xyz" }], +// }); + +// expect(result.list.length).toBe(0); +// }); + +// test("should return empty list for non-existent version", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id, versions: [999] }], +// }); + +// expect(result.list.length).toBe(0); +// }); + +// test("should have correct response structure", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }], +// }); + +// expect(result).toHaveProperty("list"); +// expect(result).toHaveProperty("total"); +// expect(result).toHaveProperty("limit"); +// expect(result).toHaveProperty("offset"); +// }); + +// test("should return plan_version in product response", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }], +// }); + +// const found = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// expect(found).toBeDefined(); + +// // Check that version is returned correctly (V1.2 returns as 'products' with 'version' field) +// const products = (found as any).products; +// expect(products).toBeDefined(); +// expect(Array.isArray(products)).toBe(true); + +// const matchingProduct = products.find((p: any) => p.id === productA.id); +// expect(matchingProduct).toBeDefined(); +// expect(matchingProduct.version).toBe(1); +// }); +// }); + +// // V2 Subscription Status Filter Tests +// describe("subscription_status filter (V2)", () => { +// test("should filter by active status", async () => { +// const result = await autumn.customers.listV2({ +// subscription_status: ["active"], +// }); + +// // All our test customers have active products +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundA).toBeDefined(); +// expect(foundB).toBeDefined(); +// }); + +// test("should filter by multiple statuses", async () => { +// const result = await autumn.customers.listV2({ +// subscription_status: ["active", "scheduled"], +// }); + +// // Should include active customers +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// expect(foundA).toBeDefined(); +// }); + +// test("should combine subscription_status with plans filter (AND logic)", async () => { +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id }], +// subscription_status: ["active"], +// }); + +// // Should find customers with productA AND active status +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// expect(foundA).toBeDefined(); + +// // Should NOT find customers with other products even if active +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// const foundOther = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withOtherProduct, +// ); +// expect(foundB).toBeUndefined(); +// expect(foundOther).toBeUndefined(); +// }); + +// test("should require BOTH plan AND status to match when combined", async () => { +// // Filter for productA with active status +// const result = await autumn.customers.listV2({ +// plans: [{ id: productA.id, versions: [1] }], +// subscription_status: ["active"], +// }); + +// // Only customers with productA v1 AND active status should be returned +// const foundA = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductA, +// ); +// expect(foundA).toBeDefined(); + +// // ProductB customer should NOT be returned (wrong product) +// const foundB = result.list.find( +// (customer: ApiCustomer) => customer.id === customerIds.withProductB, +// ); +// expect(foundB).toBeUndefined(); +// }); +// }); +// }); diff --git a/server/tests/utils/fixtures/products.ts b/server/tests/utils/fixtures/products.ts index c5474f206..cb4aff684 100644 --- a/server/tests/utils/fixtures/products.ts +++ b/server/tests/utils/fixtures/products.ts @@ -16,6 +16,7 @@ import { * @param items - Product items (features) * @param id - Product ID (default: "base") * @param isDefault - Whether this is a default product (default: false) + * @param group - Optional product group (if set, won't be overridden by test prefix) * @param trialDays - Optional number of trial days (shorthand) * @param freeTrial - Optional full free trial config (overrides trialDays) */ @@ -24,6 +25,7 @@ const base = ({ id = "base", isDefault = false, isAddOn = false, + group, trialDays, freeTrial, }: { @@ -31,6 +33,7 @@ const base = ({ id?: string; isDefault?: boolean; isAddOn?: boolean; + group?: string; trialDays?: number; freeTrial?: { length: number; @@ -39,7 +42,7 @@ const base = ({ uniqueFingerprint?: boolean; }; }): ProductV2 => ({ - ...constructRawProduct({ id, items, isAddOn }), + ...constructRawProduct({ id, items, isAddOn, group }), is_default: isDefault, ...(freeTrial ? { diff --git a/server/tests/utils/testProductUtils/testProductUtils.ts b/server/tests/utils/testProductUtils/testProductUtils.ts index f32af7b81..5f335c2de 100644 --- a/server/tests/utils/testProductUtils/testProductUtils.ts +++ b/server/tests/utils/testProductUtils/testProductUtils.ts @@ -20,7 +20,10 @@ export const addPrefixToProducts = ({ for (const product of products) { product.id = `${product.id}_${prefix}`; product.name = `${product.name} ${prefix}`; - product.group = prefix; + // Only set group to prefix if not already defined + if (!product.group) { + product.group = prefix; + } } return products; diff --git a/shared/api/common/customerData.ts b/shared/api/common/customerData.ts index 57b5212b9..549e06d5f 100644 --- a/shared/api/common/customerData.ts +++ b/shared/api/common/customerData.ts @@ -27,6 +27,10 @@ export const CustomerDataSchema = z description: "Whether to create the customer in Stripe", }), + auto_enable_plan_id: z.string().optional().meta({ + description: "The ID of the free plan to auto-enable for the customer", + }), + processors: ExternalProcessorsSchema.nullish().meta({ internal: true, description: "External processors for the customer", From 141d4ea5afe9944bfb2bc7b4ffa8c7243e2c3024 Mon Sep 17 00:00:00 2001 From: John Yeo Date: Mon, 26 Jan 2026 08:36:22 +0000 Subject: [PATCH 10/12] fix: versioning track / events request body --- scripts/testGroups/g1.sh | 1 + .../honoMiddlewares/idempotencyMiddleware.ts | 20 +- .../internal/balances/handlers/handleTrack.ts | 22 +- .../src/internal/balances/track/runTrackV2.ts | 1 - .../track/utils/handleEventIdempotencyKey.ts | 43 +-- .../balances/track/utils/runRedisTrack.ts | 2 +- .../misc/idempotency/checkIdempotencyKey.ts | 52 +++ .../balances/track/basic/track-basic6.test.ts | 21 +- .../track-paid-allocated7.test.ts | 2 +- .../balances/track/track-misc.test.ts | 330 ++++++++++++++++++ .../track/prevVersions/trackParamsV0.ts | 38 ++ .../requestChanges/V1.2_TrackParamsChange.ts | 72 ++++ shared/api/models.ts | 1 + .../versionChangeRegistry.ts | 2 + 14 files changed, 550 insertions(+), 57 deletions(-) create mode 100644 server/src/internal/misc/idempotency/checkIdempotencyKey.ts create mode 100644 server/tests/integration/balances/track/track-misc.test.ts create mode 100644 shared/api/balances/track/prevVersions/trackParamsV0.ts create mode 100644 shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts diff --git a/scripts/testGroups/g1.sh b/scripts/testGroups/g1.sh index ddb90b7dc..a2904d13f 100755 --- a/scripts/testGroups/g1.sh +++ b/scripts/testGroups/g1.sh @@ -13,6 +13,7 @@ source "$(dirname "$0")/config.sh" BUN_PARALLEL_V2 \ 'integration/balances/check' \ + 'integration/balances/track' \ 'balances/track/basic' \ 'balances/track/concurrency' \ 'balances/track/breakdown' \ diff --git a/server/src/honoMiddlewares/idempotencyMiddleware.ts b/server/src/honoMiddlewares/idempotencyMiddleware.ts index f7cbea336..baa9cbf54 100644 --- a/server/src/honoMiddlewares/idempotencyMiddleware.ts +++ b/server/src/honoMiddlewares/idempotencyMiddleware.ts @@ -1,8 +1,6 @@ -import { ErrCode, RecaseError } from "@autumn/shared"; import type { Context, Next } from "hono"; -import { redis } from "@/external/redis/initRedis.js"; import type { HonoEnv } from "@/honoUtils/HonoEnv.js"; -import { tryRedisWrite } from "@/utils/cacheUtils/cacheUtils"; +import { checkIdempotencyKey } from "@/internal/misc/idempotency/checkIdempotencyKey.js"; /** * Middleware that checks for idempotence in a request @@ -17,19 +15,11 @@ export const idempotencyMiddleware = async ( headers["idempotency-key"] || headers["Idempotency-Key"]; if (idempotencyKey) { - const redisKey = `${ctx.org.id}:${ctx.env}:idempotency:${idempotencyKey}`; - // Use SET NX (set if not exists) for atomic check-and-set to prevent race conditions - const wasSet = await tryRedisWrite(() => { - return redis.set(redisKey, "1", "PX", 1000 * 60 * 60 * 24, "NX"); // 24 hours, only set if not exists + await checkIdempotencyKey({ + orgId: ctx.org.id, + env: ctx.env, + idempotencyKey, }); - - if (!wasSet) { - throw new RecaseError({ - message: `Another request with idempotency key ${idempotencyKey} has already been received`, - code: ErrCode.DuplicateIdempotencyKey, - statusCode: 409, - }); - } } await next(); diff --git a/server/src/internal/balances/handlers/handleTrack.ts b/server/src/internal/balances/handlers/handleTrack.ts index 3a92e54b1..ae364db62 100644 --- a/server/src/internal/balances/handlers/handleTrack.ts +++ b/server/src/internal/balances/handlers/handleTrack.ts @@ -1,4 +1,10 @@ -import { TrackParamsSchema, TrackQuerySchema } from "@autumn/shared"; +import { + AffectedResource, + ApiVersion, + TrackParamsSchema, + TrackParamsV0Schema, + TrackQuerySchema, +} from "@autumn/shared"; import { createRoute } from "@/honoMiddlewares/routeHandler.js"; import { runTrackV2 } from "@/internal/balances/track/runTrackV2.js"; import { @@ -8,19 +14,15 @@ import { export const handleTrack = createRoute({ query: TrackQuerySchema, - body: TrackParamsSchema, + versionedBody: { + latest: TrackParamsSchema, + [ApiVersion.V1_Beta]: TrackParamsV0Schema, + }, + resource: AffectedResource.Track, handler: async (c) => { const body = c.req.valid("json"); const ctx = c.get("ctx"); - // Legacy: support value in properties - if (body.properties?.value) { - const parsedValue = Number(body.properties.value); - if (!Number.isNaN(parsedValue)) { - body.value = parsedValue; - } - } - // Build feature deductions const featureDeductions = body.feature_id ? getTrackFeatureDeductions({ diff --git a/server/src/internal/balances/track/runTrackV2.ts b/server/src/internal/balances/track/runTrackV2.ts index ea607e8e3..2eccaa150 100644 --- a/server/src/internal/balances/track/runTrackV2.ts +++ b/server/src/internal/balances/track/runTrackV2.ts @@ -47,7 +47,6 @@ export const runTrackV2 = async ({ await handleEventIdempotencyKey({ ctx, body, - fullCustomer, }); } diff --git a/server/src/internal/balances/track/utils/handleEventIdempotencyKey.ts b/server/src/internal/balances/track/utils/handleEventIdempotencyKey.ts index e1179c330..2004f1de9 100644 --- a/server/src/internal/balances/track/utils/handleEventIdempotencyKey.ts +++ b/server/src/internal/balances/track/utils/handleEventIdempotencyKey.ts @@ -1,32 +1,35 @@ -import type { FullCustomer, TrackParams } from "@autumn/shared"; -import type { AutumnContext } from "../../../../honoUtils/HonoEnv"; -import { EventService } from "../../../api/events/EventService"; -import { buildEventInfo, initEvent } from "../../events/initEvent"; +import type { TrackParams } from "@autumn/shared"; +import { checkIdempotencyKey } from "@/internal/misc/idempotency/checkIdempotencyKey.js"; +import type { AutumnContext } from "../../../../honoUtils/HonoEnv.js"; export const handleEventIdempotencyKey = async ({ ctx, body, - fullCustomer, }: { ctx: AutumnContext; body: TrackParams; - fullCustomer: FullCustomer; }) => { - const eventInfo = buildEventInfo(body); - - const newEvent = initEvent({ - ctx, - eventInfo, - internalCustomerId: fullCustomer.internal_id, - internalEntityId: fullCustomer.entity?.internal_id ?? undefined, - customerId: body.customer_id, - entityId: body.entity_id, + await checkIdempotencyKey({ + orgId: ctx.org.id, + env: ctx.env, + idempotencyKey: `track:${body.idempotency_key}`, }); - await EventService.insert({ - db: ctx.db, - event: newEvent, - }); + // const eventInfo = buildEventInfo(body); - body.skip_event = true; + // const newEvent = initEvent({ + // ctx, + // eventInfo, + // internalCustomerId: fullCustomer.internal_id, + // internalEntityId: fullCustomer.entity?.internal_id ?? undefined, + // customerId: body.customer_id, + // entityId: body.entity_id, + // }); + + // await EventService.insert({ + // db: ctx.db, + // event: newEvent, + // }); + + // body.skip_event = true; }; diff --git a/server/src/internal/balances/track/utils/runRedisTrack.ts b/server/src/internal/balances/track/utils/runRedisTrack.ts index 12005c626..13f850fa6 100644 --- a/server/src/internal/balances/track/utils/runRedisTrack.ts +++ b/server/src/internal/balances/track/utils/runRedisTrack.ts @@ -53,7 +53,7 @@ const queueEvent = ({ body: TrackParams; fullCustomer: FullCustomer; }): void => { - if (body.skip_event || body.idempotency_key) return; + if (body.skip_event) return; const eventInfo = buildEventInfo(body); diff --git a/server/src/internal/misc/idempotency/checkIdempotencyKey.ts b/server/src/internal/misc/idempotency/checkIdempotencyKey.ts new file mode 100644 index 000000000..7769ea2ee --- /dev/null +++ b/server/src/internal/misc/idempotency/checkIdempotencyKey.ts @@ -0,0 +1,52 @@ +import { ErrCode, RecaseError } from "@autumn/shared"; +import { redis } from "@/external/redis/initRedis.js"; + +const IDEMPOTENCY_TTL_MS = 1000 * 60 * 60 * 24; // 24 hours + +/** + * Checks and sets an idempotency key in Redis using atomic SET NX operation. + * If Redis is not ready, allows the request to proceed (fail-open). + * Throws if the key already exists (duplicate request). + */ +export const checkIdempotencyKey = async ({ + orgId, + env, + idempotencyKey, +}: { + orgId: string; + env: string; + idempotencyKey: string; +}): Promise => { + // Fail-open: if Redis is not ready, allow the request + if (redis.status !== "ready") { + return; + } + + const redisKey = `${orgId}:${env}:idempotency:${idempotencyKey}`; + + try { + // Use SET NX (set if not exists) for atomic check-and-set to prevent race conditions + const wasSet = await redis.set( + redisKey, + "1", + "PX", + IDEMPOTENCY_TTL_MS, + "NX", + ); + + if (!wasSet) { + throw new RecaseError({ + message: `Another request with idempotency key ${idempotencyKey} has already been received`, + code: ErrCode.DuplicateIdempotencyKey, + statusCode: 409, + }); + } + } catch (error) { + // Re-throw RecaseError (duplicate key) + if (error instanceof RecaseError) { + throw error; + } + // For other Redis errors, fail-open (allow request) + return; + } +}; diff --git a/server/tests/balances/track/basic/track-basic6.test.ts b/server/tests/balances/track/basic/track-basic6.test.ts index ca300bfea..25852cd0c 100644 --- a/server/tests/balances/track/basic/track-basic6.test.ts +++ b/server/tests/balances/track/basic/track-basic6.test.ts @@ -26,9 +26,14 @@ const freeProd = constructProduct({ const testCase = "track-basic6"; +// Generate unique idempotency keys per test run to avoid Redis TTL conflicts +const testRunId = Date.now().toString(36); + describe(`${chalk.yellowBright("track-basic6: test idempotency key prevents duplicate tracks")}`, () => { const customerId = "track-basic6"; const autumnV1: AutumnInt = new AutumnInt({ version: ApiVersion.V1_2 }); + const idempotencyKey1 = `test-idempotency-key-1-${testRunId}`; + const idempotencyKey2 = `test-idempotency-key-2-${testRunId}`; beforeAll(async () => { await initCustomerV3({ @@ -58,13 +63,12 @@ describe(`${chalk.yellowBright("track-basic6: test idempotency key prevents dupl test("should process first track with idempotency key", async () => { const deductValue = 25.5; - const idempotencyKey = "test-idempotency-key-1"; await autumnV1.track({ customer_id: customerId, feature_id: TestFeature.Messages, value: deductValue, - idempotency_key: idempotencyKey, + idempotency_key: idempotencyKey1, }); const customer = await autumnV1.customers.get(customerId); @@ -76,28 +80,28 @@ describe(`${chalk.yellowBright("track-basic6: test idempotency key prevents dupl expect(balance).toBe(expectedBalance); expect(usage).toBe(deductValue); + await timeout(2000); const eventsList = await getCustomerEvents({ customerId }); expect(eventsList).toHaveLength(1); - expect(eventsList?.[0].idempotency_key).toBe(idempotencyKey); + expect(eventsList?.[0].idempotency_key).toBe(idempotencyKey1); expect(eventsList?.[0].value).toBe(deductValue); }); test("should reject second track with same idempotency key", async () => { const deductValue = 30.75; // Different value - const idempotencyKey = "test-idempotency-key-1"; // Same key // Get balance before attempting duplicate track const customerBefore = await autumnV1.customers.get(customerId); const balanceBefore = customerBefore.features[TestFeature.Messages].balance; // This should fail or be rejected due to duplicate idempotency key await expectAutumnError({ - errCode: ErrCode.DuplicateEvent, + errCode: ErrCode.DuplicateIdempotencyKey, func: async () => { await autumnV1.track({ customer_id: customerId, feature_id: TestFeature.Messages, value: deductValue, - idempotency_key: idempotencyKey, + idempotency_key: idempotencyKey1, // Same key as first test }); }, }); @@ -117,12 +121,11 @@ describe(`${chalk.yellowBright("track-basic6: test idempotency key prevents dupl const eventsList = await getCustomerEvents({ customerId }); expect(eventsList).toHaveLength(1); - expect(eventsList?.[0].idempotency_key).toBe(idempotencyKey); + expect(eventsList?.[0].idempotency_key).toBe(idempotencyKey1); }); test("should process track with different idempotency key", async () => { const deductValue = 15.25; - const idempotencyKey = "test-idempotency-key-2"; // Different key const customerBefore = await autumnV1.customers.get(customerId); const balanceBefore = customerBefore.features[TestFeature.Messages].balance; @@ -131,7 +134,7 @@ describe(`${chalk.yellowBright("track-basic6: test idempotency key prevents dupl customer_id: customerId, feature_id: TestFeature.Messages, value: deductValue, - idempotency_key: idempotencyKey, + idempotency_key: idempotencyKey2, // Different key }); const customer = await autumnV1.customers.get(customerId); diff --git a/server/tests/balances/track/paid-allocated/track-paid-allocated7.test.ts b/server/tests/balances/track/paid-allocated/track-paid-allocated7.test.ts index cf255e920..47f905f63 100644 --- a/server/tests/balances/track/paid-allocated/track-paid-allocated7.test.ts +++ b/server/tests/balances/track/paid-allocated/track-paid-allocated7.test.ts @@ -24,7 +24,7 @@ test( items: [allocatedUsersItem, priceItem], }); - const uniqueId = `paid-alloc-lock-${Date.now()}`; + const uniqueId = `paid-alloc-lock`; const { customerId, autumnV2 } = await initScenario({ customerId: uniqueId, setup: [ diff --git a/server/tests/integration/balances/track/track-misc.test.ts b/server/tests/integration/balances/track/track-misc.test.ts new file mode 100644 index 000000000..f553ebe6b --- /dev/null +++ b/server/tests/integration/balances/track/track-misc.test.ts @@ -0,0 +1,330 @@ +import { expect, test } from "bun:test"; + +import { + type ApiCustomerV3, + type ApiEntityV0, + CusExpand, + type TrackResponseV2, +} from "@autumn/shared"; +import { TestFeature } from "@tests/setup/v2Features.js"; +import { items } from "@tests/utils/fixtures/items.js"; +import { products } from "@tests/utils/fixtures/products.js"; +import { timeout } from "@tests/utils/genUtils.js"; +import ctx from "@tests/utils/testInitUtils/createTestContext.js"; +import { initScenario, s } from "@tests/utils/testInitUtils/initScenario.js"; +import chalk from "chalk"; +import { Decimal } from "decimal.js"; +import { EventService } from "@/internal/api/events/EventService.js"; + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC1: Auto-create customer and entity via track +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc1: track auto-creates customer and entity")}`, async () => { + const messagesItem = items.monthlyMessages({ includedUsage: 100 }); + const freeProd = products.base({ + id: "free", + items: [messagesItem], + }); + + const customerId = "track-misc1"; + + const { autumnV1 } = await initScenario({ + setup: [ + s.deleteCustomer({ customerId: "track-misc1" }), + s.products({ list: [freeProd], prefix: customerId }), + ], + actions: [], + }); + + const entityId = `${customerId}-entity-1`; + + await autumnV1.track({ + customer_id: customerId, + customer_data: { + name: "Test Customer", + email: "test@test.com", + }, + feature_id: TestFeature.Messages, + entity_id: entityId, + entity_data: { + name: "Test Entity", + feature_id: TestFeature.Users, + }, + value: 5, + }); + + // Verify customer was created with provided data + const customer = await autumnV1.customers.get(customerId); + expect(customer).toMatchObject({ + id: customerId, + name: "Test Customer", + email: "test@test.com", + }); + + // Verify entity was created with provided data + const entity = await autumnV1.entities.get(customerId, entityId); + expect(entity).toMatchObject({ + id: entityId, + name: "Test Entity", + }); + + // Verify customer.entities includes the created entity + const customerWithEntities = await autumnV1.customers.get( + customerId, + { expand: [CusExpand.Entities] }, + ); + expect(customerWithEntities.entities).toBeDefined(); + expect(customerWithEntities.entities).toHaveLength(1); + expect(customerWithEntities.entities?.[0].id).toBe(entityId); + expect(customerWithEntities.entities?.[0].name).toBe("Test Entity"); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC2: Track event stores properties +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc2: track event stores custom properties")}`, async () => { + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc2", + setup: [s.customer({ testClock: false })], + actions: [], + }); + + await autumnV1.track({ + customer_id: customerId, + customer_data: { + name: "track-misc2", + email: "track-misc2@test.com", + }, + feature_id: TestFeature.Messages, + value: 5, + properties: { + hello: "world", + foo: "bar", + }, + }); + + const customer = await autumnV1.customers.get(customerId, { + with_autumn_id: true, + }); + + await timeout(2000); + + const events = await EventService.getByCustomerId({ + db: ctx.db, + orgId: ctx.org.id, + internalCustomerId: customer.autumn_id!, + env: ctx.env, + }); + + expect(events).toHaveLength(1); + expect(events?.[0].properties).toMatchObject({ + hello: "world", + foo: "bar", + }); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC3: Track creates events when balance is empty +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc3: track creates events when customer has no balance")}`, async () => { + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc3", + setup: [s.customer({ testClock: false })], + actions: [], + }); + + const trackCount = Math.floor(Math.random() * 10) + 1; + let totalValue = 0; + + await Promise.all( + Array.from({ length: trackCount }, () => { + const trackValue = Math.random() * 10; + totalValue += trackValue; + return autumnV1.track({ + customer_id: customerId, + feature_id: TestFeature.Messages, + value: trackValue, + }); + }), + ); + + const customer = await autumnV1.customers.get(customerId, { + with_autumn_id: true, + }); + + await timeout(2000); + + const events = await EventService.getByCustomerId({ + db: ctx.db, + orgId: ctx.org.id, + internalCustomerId: customer.autumn_id ?? "", + env: ctx.env, + }); + + expect(events).toHaveLength(trackCount); + expect(events.reduce((acc, event) => acc + (event.value ?? 0), 0)).toBe( + totalValue, + ); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC4: Track v1.2 response format +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc4: track returns correct v1.2 response format")}`, async () => { + const messagesItem = items.monthlyMessages({ includedUsage: 100 }); + const freeProd = products.base({ + id: "free", + items: [messagesItem], + }); + + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc4", + setup: [s.customer({ testClock: false }), s.products({ list: [freeProd] })], + actions: [s.attach({ productId: freeProd.id })], + }); + + const trackRes: TrackResponseV2 = await autumnV1.track({ + customer_id: customerId, + feature_id: TestFeature.Messages, + value: 20, + }); + + expect(trackRes).toMatchObject({ + id: "placeholder", + code: "event_received", + customer_id: customerId, + feature_id: TestFeature.Messages, + }); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC5: V1.2 properties.value maps to value field +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc5: V1.2 properties.value maps to value field")}`, async () => { + const messagesItem = items.monthlyMessages({ includedUsage: 100 }); + const freeProd = products.base({ + id: "free", + items: [messagesItem], + }); + + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc5", + setup: [s.customer({ testClock: false }), s.products({ list: [freeProd] })], + actions: [s.attach({ productId: freeProd.id })], + }); + + // Track using V1.2 legacy format with properties.value + await autumnV1.track({ + customer_id: customerId, + feature_id: TestFeature.Messages, + properties: { + value: 42.1532, + }, + }); + + const customer = await autumnV1.customers.get(customerId, { + with_autumn_id: true, + }); + + // Verify balance was deducted correctly + expect(customer.features[TestFeature.Messages].balance).toBe( + new Decimal(100).sub(42.1532).toNumber(), + ); + expect(customer.features[TestFeature.Messages].usage).toBe(42.1532); + + await timeout(2000); + + const events = await EventService.getByCustomerId({ + db: ctx.db, + orgId: ctx.org.id, + internalCustomerId: customer.autumn_id!, + env: ctx.env, + }); + + expect(events).toHaveLength(1); + expect(events[0].value).toBe(42.1532); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC7: Track defaults to value: 1 when no value provided +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc7: track defaults to value 1 when no value provided")}`, async () => { + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc7", + setup: [s.customer({ testClock: false })], + actions: [], + }); + + // Track without providing any value + await autumnV1.track({ + customer_id: customerId, + feature_id: TestFeature.Messages, + }); + + const customer = await autumnV1.customers.get(customerId, { + with_autumn_id: true, + }); + + await timeout(2000); + + const events = await EventService.getByCustomerId({ + db: ctx.db, + orgId: ctx.org.id, + internalCustomerId: customer.autumn_id!, + env: ctx.env, + }); + + expect(events).toHaveLength(1); + expect(events[0].value).toBe(1); +}); + +// ═══════════════════════════════════════════════════════════════════ +// TRACK-MISC8: V1.2 properties.value is removed from properties after extraction +// ═══════════════════════════════════════════════════════════════════ + +test.concurrent(`${chalk.yellowBright("track-misc8: V1.2 properties.value is removed from stored properties")}`, async () => { + const { customerId, autumnV1 } = await initScenario({ + customerId: "track-misc8", + setup: [s.customer({ testClock: false })], + actions: [], + }); + + // Track using V1.2 legacy format with properties.value and other properties + await autumnV1.track({ + customer_id: customerId, + feature_id: TestFeature.Messages, + properties: { + value: 25, + hello: "world", + foo: "bar", + }, + }); + + const customer = await autumnV1.customers.get(customerId, { + with_autumn_id: true, + }); + + await timeout(2000); + + const events = await EventService.getByCustomerId({ + db: ctx.db, + orgId: ctx.org.id, + internalCustomerId: customer.autumn_id!, + env: ctx.env, + }); + + expect(events).toHaveLength(1); + expect(events[0].value).toBe(25); + // Verify value was removed from properties but other props remain + expect(events[0].properties).toMatchObject({ + hello: "world", + foo: "bar", + }); + expect(events[0].properties).not.toHaveProperty("value"); +}); diff --git a/shared/api/balances/track/prevVersions/trackParamsV0.ts b/shared/api/balances/track/prevVersions/trackParamsV0.ts new file mode 100644 index 000000000..bdc571e62 --- /dev/null +++ b/shared/api/balances/track/prevVersions/trackParamsV0.ts @@ -0,0 +1,38 @@ +import { z } from "zod/v4"; +import { CustomerDataSchema } from "../../../common/customerData.js"; +import { EntityDataSchema } from "../../../common/entityData.js"; + +/** + * TrackParamsV0Schema - V1.2 and earlier format + * + * In V1.2, the `value` field could be passed either as a top-level field OR + * inside `properties.value`. This schema supports both, with the transformation + * extracting `properties.value` only if top-level `value` is not provided. + */ +export const TrackParamsV0Schema = z + .object({ + customer_id: z.string().nonempty(), + feature_id: z.string().optional(), + event_name: z.string().nonempty().optional(), + value: z.number().optional(), + properties: z.record(z.string(), z.any()).optional(), + timestamp: z.number().optional(), + idempotency_key: z.string().optional(), + customer_data: CustomerDataSchema.optional(), + entity_id: z.string().optional(), + entity_data: EntityDataSchema.optional(), + overage_behavior: z.enum(["cap", "reject"]).optional(), + skip_event: z.boolean().optional(), + }) + .refine( + (data) => { + if (data.feature_id && data.event_name) return false; + if (!data.feature_id && !data.event_name) return false; + return true; + }, + { + message: "Either feature_id or event_name must be provided", + }, + ); + +export type TrackParamsV0 = z.infer; diff --git a/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts b/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts new file mode 100644 index 000000000..50027b2bc --- /dev/null +++ b/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts @@ -0,0 +1,72 @@ +import { ApiVersion } from "@api/versionUtils/ApiVersion.js"; +import { + AffectedResource, + defineVersionChange, +} from "@api/versionUtils/versionChangeUtils/VersionChange.js"; +import type { z } from "zod/v4"; +import { TrackParamsV0Schema } from "../prevVersions/trackParamsV0.js"; +import { TrackParamsSchema } from "../trackParams.js"; + +/** + * V1_2_TrackParamsChange: Transforms track request body TO latest format + * + * Applied when: sourceVersion <= V1.2 + * + * Breaking changes introduced in V2.0 (that we transform here): + * + * 1. Value field location: + * - V1.2: `properties.value` (value passed inside properties object) + * - V2.0+: `value` (top-level field) + * + * This transformation extracts `properties.value` and maps it to the + * top-level `value` field for V1.2 clients, ensuring they can continue + * using the legacy format. + * + * Input: TrackParamsV0 (V1.2 format with properties.value) + * Output: TrackParamsV1 (V2.0+ format with top-level value) + */ +export const V1_2_TrackParamsChange = defineVersionChange({ + name: "V1_2 Track Params Change", + newVersion: ApiVersion.V2_0, + oldVersion: ApiVersion.V1_Beta, + description: [ + "Maps properties.value to top-level value field for V1.2 clients", + ], + affectedResources: [AffectedResource.Track], + newSchema: TrackParamsSchema, + oldSchema: TrackParamsV0Schema, + + affectsRequest: true, + affectsResponse: false, + + // Request: V1.2 → V2.0 (extract properties.value to value if not already set) + transformRequest: ({ + input, + }: { + input: z.infer; + }): z.infer => { + // Keep original value if provided, otherwise extract from properties.value + let value = input.value; + let properties = input.properties; + + if (input.properties?.value !== undefined) { + // Only use properties.value if top-level value is not set + if (value === undefined) { + const parsedValue = Number(input.properties.value); + if (!Number.isNaN(parsedValue)) { + value = parsedValue; + } + } + + // Always remove value from properties after processing + const { value: _, ...restProperties } = input.properties; + properties = Object.keys(restProperties).length > 0 ? restProperties : {}; + } + + return { + ...input, + properties, + value, + }; + }, +}); diff --git a/shared/api/models.ts b/shared/api/models.ts index cc6fc12f8..df36ed168 100644 --- a/shared/api/models.ts +++ b/shared/api/models.ts @@ -66,6 +66,7 @@ export * from "./balances/check/prevVersions/CheckResponseV0.js"; export * from "./balances/check/prevVersions/CheckResponseV1.js"; export * from "./balances/create/createBalanceParams.js"; export * from "./balances/prevVersions/legacyUpdateBalanceModels.js"; +export * from "./balances/track/prevVersions/trackParamsV0.js"; export * from "./balances/track/prevVersions/trackResponseV1.js"; export * from "./balances/track/trackParams.js"; export * from "./balances/track/trackResponseV2.js"; diff --git a/shared/api/versionUtils/versionChangeUtils/versionChangeRegistry.ts b/shared/api/versionUtils/versionChangeUtils/versionChangeRegistry.ts index f44ba2e6f..3cdaa0717 100644 --- a/shared/api/versionUtils/versionChangeUtils/versionChangeRegistry.ts +++ b/shared/api/versionUtils/versionChangeUtils/versionChangeRegistry.ts @@ -25,6 +25,7 @@ import { V0_2_CheckChange } from "../../balances/check/changes/V0.2_CheckChange. import { V1_2_CheckChange } from "../../balances/check/changes/V1.2_CheckChange.js"; import { V1_2_CheckQueryChange } from "../../balances/check/changes/V1.2_CheckQueryChange.js"; import { V1_2_TrackChange } from "../../balances/track/changes/V1.2_TrackChange.js"; +import { V1_2_TrackParamsChange } from "../../balances/track/requestChanges/V1.2_TrackParamsChange.js"; // Import attach changes import { V0_2_AttachChange } from "../../billing/attach/changes/V0.2_AttachChange.js"; import { ApiVersion } from "../ApiVersion.js"; @@ -42,6 +43,7 @@ export const V2_CHANGES: VersionChangeConstructor[] = [ V1_2_CheckChange, // Transforms Check TO V1.2 format from V0.2 format V1_2_CheckQueryChange, // Transforms Check Query TO V2.0 format (adds expand options) V1_2_TrackChange, // Transforms Track TO V1.2 format from V0.2 format + V1_2_TrackParamsChange, // Transforms Track params TO V2.0 (maps properties.value → value) V1_2_FeatureChange, // Transforms Feature TO V1_Beta format (V0) from V2 format (V1) V1_2_CreateFeatureChange, // Transforms Create Feature params TO V1_Beta From 176a7877ca6c661a6f37086bd2aa4bd3cb9ac1a0 Mon Sep 17 00:00:00 2001 From: John Yeo Date: Mon, 26 Jan 2026 10:46:08 +0000 Subject: [PATCH 11/12] removed trackparams v0 --- scripts/testGroups/g2.sh | 24 ++++++------ .../internal/balances/handlers/handleTrack.ts | 3 +- .../tests/attach/checkout/checkout6.test.ts | 1 - .../balances/track/track-misc.test.ts | 5 +-- .../track/prevVersions/trackParamsV0.ts | 38 ------------------- .../requestChanges/V1.2_TrackParamsChange.ts | 20 +++------- shared/api/models.ts | 1 - 7 files changed, 20 insertions(+), 72 deletions(-) delete mode 100644 shared/api/balances/track/prevVersions/trackParamsV0.ts diff --git a/scripts/testGroups/g2.sh b/scripts/testGroups/g2.sh index a20d0f9a7..29567addd 100755 --- a/scripts/testGroups/g2.sh +++ b/scripts/testGroups/g2.sh @@ -4,18 +4,18 @@ source "$(dirname "$0")/config.sh" -# BUN_PARALLEL_V2 \ -# 'server/tests/attach/basic' \ -# 'server/tests/attach/upgrade' \ -# 'server/tests/attach/downgrade' \ -# 'server/tests/attach/free' \ -# 'server/tests/attach/addOn' \ -# 'server/tests/attach/checkout' \ -# 'server/tests/attach/misc' \ -# 'server/tests/integration/billing/invoice-action-required' \ -# 'server/tests/integration/billing/cancel' \ -# 'server/tests/integration/billing/cancel/add-ons' \ -# --max=6 +BUN_PARALLEL_V2 \ + 'server/tests/attach/basic' \ + 'server/tests/attach/upgrade' \ + 'server/tests/attach/downgrade' \ + 'server/tests/attach/free' \ + 'server/tests/attach/addOn' \ + 'server/tests/attach/checkout' \ + 'server/tests/attach/misc' \ + 'server/tests/integration/billing/invoice-action-required' \ + 'server/tests/integration/billing/cancel' \ + 'server/tests/integration/billing/cancel/add-ons' \ + --max=6 BUN_PARALLEL_V2 \ 'server/tests/attach/entities' \ diff --git a/server/src/internal/balances/handlers/handleTrack.ts b/server/src/internal/balances/handlers/handleTrack.ts index ae364db62..0ac583cc5 100644 --- a/server/src/internal/balances/handlers/handleTrack.ts +++ b/server/src/internal/balances/handlers/handleTrack.ts @@ -2,7 +2,6 @@ import { AffectedResource, ApiVersion, TrackParamsSchema, - TrackParamsV0Schema, TrackQuerySchema, } from "@autumn/shared"; import { createRoute } from "@/honoMiddlewares/routeHandler.js"; @@ -16,7 +15,7 @@ export const handleTrack = createRoute({ query: TrackQuerySchema, versionedBody: { latest: TrackParamsSchema, - [ApiVersion.V1_Beta]: TrackParamsV0Schema, + [ApiVersion.V1_Beta]: TrackParamsSchema, }, resource: AffectedResource.Track, handler: async (c) => { diff --git a/server/tests/attach/checkout/checkout6.test.ts b/server/tests/attach/checkout/checkout6.test.ts index 076dacf4f..a818b0193 100644 --- a/server/tests/attach/checkout/checkout6.test.ts +++ b/server/tests/attach/checkout/checkout6.test.ts @@ -79,7 +79,6 @@ describe(`${chalk.yellowBright(`${testCase}: Testing invoice checkout via checko product: pro, }); }); - return; test("should have no URL returned if try to attach premium (with invoice true)", async () => { await expectAutumnError({ diff --git a/server/tests/integration/balances/track/track-misc.test.ts b/server/tests/integration/balances/track/track-misc.test.ts index f553ebe6b..6c3f0ef16 100644 --- a/server/tests/integration/balances/track/track-misc.test.ts +++ b/server/tests/integration/balances/track/track-misc.test.ts @@ -4,6 +4,7 @@ import { type ApiCustomerV3, type ApiEntityV0, CusExpand, + sumValues, type TrackResponseV2, } from "@autumn/shared"; import { TestFeature } from "@tests/setup/v2Features.js"; @@ -165,9 +166,7 @@ test.concurrent(`${chalk.yellowBright("track-misc3: track creates events when cu }); expect(events).toHaveLength(trackCount); - expect(events.reduce((acc, event) => acc + (event.value ?? 0), 0)).toBe( - totalValue, - ); + expect(sumValues(events.map((event) => event.value ?? 0))).toBe(totalValue); }); // ═══════════════════════════════════════════════════════════════════ diff --git a/shared/api/balances/track/prevVersions/trackParamsV0.ts b/shared/api/balances/track/prevVersions/trackParamsV0.ts deleted file mode 100644 index bdc571e62..000000000 --- a/shared/api/balances/track/prevVersions/trackParamsV0.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { z } from "zod/v4"; -import { CustomerDataSchema } from "../../../common/customerData.js"; -import { EntityDataSchema } from "../../../common/entityData.js"; - -/** - * TrackParamsV0Schema - V1.2 and earlier format - * - * In V1.2, the `value` field could be passed either as a top-level field OR - * inside `properties.value`. This schema supports both, with the transformation - * extracting `properties.value` only if top-level `value` is not provided. - */ -export const TrackParamsV0Schema = z - .object({ - customer_id: z.string().nonempty(), - feature_id: z.string().optional(), - event_name: z.string().nonempty().optional(), - value: z.number().optional(), - properties: z.record(z.string(), z.any()).optional(), - timestamp: z.number().optional(), - idempotency_key: z.string().optional(), - customer_data: CustomerDataSchema.optional(), - entity_id: z.string().optional(), - entity_data: EntityDataSchema.optional(), - overage_behavior: z.enum(["cap", "reject"]).optional(), - skip_event: z.boolean().optional(), - }) - .refine( - (data) => { - if (data.feature_id && data.event_name) return false; - if (!data.feature_id && !data.event_name) return false; - return true; - }, - { - message: "Either feature_id or event_name must be provided", - }, - ); - -export type TrackParamsV0 = z.infer; diff --git a/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts b/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts index 50027b2bc..262be59f5 100644 --- a/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts +++ b/shared/api/balances/track/requestChanges/V1.2_TrackParamsChange.ts @@ -4,7 +4,6 @@ import { defineVersionChange, } from "@api/versionUtils/versionChangeUtils/VersionChange.js"; import type { z } from "zod/v4"; -import { TrackParamsV0Schema } from "../prevVersions/trackParamsV0.js"; import { TrackParamsSchema } from "../trackParams.js"; /** @@ -12,18 +11,9 @@ import { TrackParamsSchema } from "../trackParams.js"; * * Applied when: sourceVersion <= V1.2 * - * Breaking changes introduced in V2.0 (that we transform here): - * - * 1. Value field location: - * - V1.2: `properties.value` (value passed inside properties object) - * - V2.0+: `value` (top-level field) - * - * This transformation extracts `properties.value` and maps it to the - * top-level `value` field for V1.2 clients, ensuring they can continue - * using the legacy format. - * - * Input: TrackParamsV0 (V1.2 format with properties.value) - * Output: TrackParamsV1 (V2.0+ format with top-level value) + * In V1.2, `value` could be passed via `properties.value` as a legacy pattern. + * This transformation extracts `properties.value` and maps it to the top-level + * `value` field (only if `value` is not already provided). */ export const V1_2_TrackParamsChange = defineVersionChange({ name: "V1_2 Track Params Change", @@ -34,7 +24,7 @@ export const V1_2_TrackParamsChange = defineVersionChange({ ], affectedResources: [AffectedResource.Track], newSchema: TrackParamsSchema, - oldSchema: TrackParamsV0Schema, + oldSchema: TrackParamsSchema, affectsRequest: true, affectsResponse: false, @@ -43,7 +33,7 @@ export const V1_2_TrackParamsChange = defineVersionChange({ transformRequest: ({ input, }: { - input: z.infer; + input: z.infer; }): z.infer => { // Keep original value if provided, otherwise extract from properties.value let value = input.value; diff --git a/shared/api/models.ts b/shared/api/models.ts index df36ed168..cc6fc12f8 100644 --- a/shared/api/models.ts +++ b/shared/api/models.ts @@ -66,7 +66,6 @@ export * from "./balances/check/prevVersions/CheckResponseV0.js"; export * from "./balances/check/prevVersions/CheckResponseV1.js"; export * from "./balances/create/createBalanceParams.js"; export * from "./balances/prevVersions/legacyUpdateBalanceModels.js"; -export * from "./balances/track/prevVersions/trackParamsV0.js"; export * from "./balances/track/prevVersions/trackResponseV1.js"; export * from "./balances/track/trackParams.js"; export * from "./balances/track/trackResponseV2.js"; From 25d78f5e06230040683faf2cfd43fffc5b6799d8 Mon Sep 17 00:00:00 2001 From: John Yeo Date: Mon, 26 Jan 2026 13:19:23 +0000 Subject: [PATCH 12/12] fix: stripe canceling condition in update sub --- .../attachFunctions/addProductFlow/handlePaidProduct.ts | 4 ++-- .../attach/attachFunctions/upgradeFlow/updateStripeSub2.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/internal/customers/attach/attachFunctions/addProductFlow/handlePaidProduct.ts b/server/src/internal/customers/attach/attachFunctions/addProductFlow/handlePaidProduct.ts index 3617a15cb..836124025 100644 --- a/server/src/internal/customers/attach/attachFunctions/addProductFlow/handlePaidProduct.ts +++ b/server/src/internal/customers/attach/attachFunctions/addProductFlow/handlePaidProduct.ts @@ -12,7 +12,7 @@ import { addMinutes } from "date-fns"; import type Stripe from "stripe"; import { getEarliestPeriodEnd } from "@/external/stripe/stripeSubUtils/convertSubUtils.js"; import { getStripeSubItems2 } from "@/external/stripe/stripeSubUtils/getStripeSubItems.js"; -import { isStripeSubscriptionCanceled } from "@/external/stripe/subscriptions/utils/classifyStripeSubscriptionUtils.js"; +import { isStripeSubscriptionCanceling } from "@/external/stripe/subscriptions/utils/classifyStripeSubscriptionUtils.js"; import { attachParamsToMetadata } from "@/internal/billing/attach/utils/attachParamsToMetadata.js"; import { createFullCusProduct } from "@/internal/customers/add-product/createFullCusProduct.js"; @@ -129,7 +129,7 @@ export const handlePaidProduct = async ({ }); } - if (isStripeSubscriptionCanceled(mergeSub)) { + if (isStripeSubscriptionCanceling(mergeSub)) { logger.info("ADD PRODUCT FLOW, CREATING NEW SCHEDULE"); schedule = await subToNewSchedule({ ctx, diff --git a/server/src/internal/customers/attach/attachFunctions/upgradeFlow/updateStripeSub2.ts b/server/src/internal/customers/attach/attachFunctions/upgradeFlow/updateStripeSub2.ts index 42d7af7c1..f3e6d9f61 100644 --- a/server/src/internal/customers/attach/attachFunctions/upgradeFlow/updateStripeSub2.ts +++ b/server/src/internal/customers/attach/attachFunctions/upgradeFlow/updateStripeSub2.ts @@ -14,7 +14,7 @@ import { SubService } from "@/internal/subscriptions/SubService.js"; import { nullish } from "@/utils/genUtils.js"; import type { ItemSet } from "@/utils/models/ItemSet.js"; import { createProrationInvoice } from "../../../../../external/stripe/stripeSubUtils/updateStripeSub/createProrationinvoice.js"; -import { isStripeSubscriptionCanceled } from "../../../../../external/stripe/subscriptions/utils/classifyStripeSubscriptionUtils.js"; +import { isStripeSubscriptionCanceling } from "../../../../../external/stripe/subscriptions/utils/classifyStripeSubscriptionUtils.js"; import type { AutumnContext } from "../../../../../honoUtils/HonoEnv.js"; import { attachParamsToCurCusProduct } from "../../attachUtils/convertAttachParams.js"; @@ -92,7 +92,7 @@ export const updateStripeSub2 = async ({ // cancel_at_period_end: false, // TODO: will error if sub managed by a schedule cancel_at_period_end: - isStripeSubscriptionCanceled(curSub) && + isStripeSubscriptionCanceling(curSub) && !( branch === AttachBranch.SameCustomEnts || branch === AttachBranch.NewVersion