diff --git a/.github/workflows/translation-check.yml b/.github/workflows/translation-check.yml index c901eb5832..30e90872ec 100644 --- a/.github/workflows/translation-check.yml +++ b/.github/workflows/translation-check.yml @@ -32,21 +32,20 @@ jobs: with: egress-policy: audit - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Setup Node.js - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - node-version: 18 + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: Setup pnpm - uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 + - name: Setup Node.js 22.x + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af with: - version: 9.15.9 + node-version: 22.x + + - name: Install pnpm + uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 - name: Install dependencies - run: pnpm install --frozen-lockfile + run: pnpm install --config.platform=linux --config.architecture=x64 - name: Validate translation keys run: | diff --git a/docs/docs.json b/docs/docs.json index b223bf5809..eac96985ff 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -80,7 +80,8 @@ "xm-and-surveys/surveys/general-features/email-followups", "xm-and-surveys/surveys/general-features/quota-management", "xm-and-surveys/surveys/general-features/spam-protection", - "xm-and-surveys/surveys/general-features/tags" + "xm-and-surveys/surveys/general-features/tags", + "xm-and-surveys/surveys/general-features/validation-rules" ] }, { @@ -161,6 +162,7 @@ "xm-and-surveys/core-features/integrations/activepieces", "xm-and-surveys/core-features/integrations/airtable", "xm-and-surveys/core-features/integrations/google-sheets", + "xm-and-surveys/core-features/integrations/hubspot", "xm-and-surveys/core-features/integrations/make", "xm-and-surveys/core-features/integrations/n8n", "xm-and-surveys/core-features/integrations/notion", diff --git a/docs/images/xm-and-surveys/core-features/validation-rules/editor.webp b/docs/images/xm-and-surveys/core-features/validation-rules/editor.webp new file mode 100644 index 0000000000..80610ff4a2 Binary files /dev/null and b/docs/images/xm-and-surveys/core-features/validation-rules/editor.webp differ diff --git a/docs/xm-and-surveys/core-features/integrations/hubspot.mdx b/docs/xm-and-surveys/core-features/integrations/hubspot.mdx new file mode 100644 index 0000000000..130f4c64d1 --- /dev/null +++ b/docs/xm-and-surveys/core-features/integrations/hubspot.mdx @@ -0,0 +1,183 @@ +--- +title: "HubSpot" +description: "Learn how to integrate Formbricks with HubSpot to automatically create or update contacts when survey responses are submitted." +--- + + + Formbricks doesn't have a native HubSpot integration yet. This guide shows you how to connect Formbricks with HubSpot using automation platforms (Make.com, n8n) or custom webhooks. + + +## Prerequisites + +Before setting up the integration, you'll need: + +1. **A Formbricks account** with at least one survey that collects email addresses +2. **A HubSpot account** with API access +3. **HubSpot API credentials** (see authentication options below) +4. **Automation service** like Make, n8n, or ActivePieces (for no-code methods) + +### HubSpot Authentication Options + +HubSpot offers two main ways to authenticate API requests: + +#### Option A: OAuth 2.0 via Public App (Recommended) + +OAuth is the recommended approach for production integrations. When using Make.com or n8n, they handle OAuth authentication for you through their built-in HubSpot connectors. + +#### Option B: Legacy Private Apps (Simple Setup) + +For custom webhook handlers, you can use a Legacy Private App which provides a static access token. While marked as "legacy," these apps remain fully supported by HubSpot. + +To create a Legacy Private App: + + + + Go to your HubSpot account **Settings** and navigate to **Integrations** → **Private Apps**. + + + Click **Create a private app** and give it a name (e.g., "Formbricks Integration"). + + + Under **Scopes**, add `crm.objects.contacts.write` and `crm.objects.contacts.read`. + + + Click **Create app** and copy the access token. + + + + + For more information on HubSpot's authentication options, see the [HubSpot Authentication Overview](https://developers.hubspot.com/docs/guides/apps/authentication/intro-to-auth). + + +--- + +## Method 1: Using Make.com (Recommended for No-Code) + + + Before starting, ensure your survey has clear `questionId` values set. You can only update these before publishing. If your survey is already published, duplicate it and update the question IDs in the copy. + + + + + Make sure your survey has meaningful `questionId` values for each question. This makes mapping responses to HubSpot fields easier. + + ![Update Question ID](/images/xm-and-surveys/core-features/integrations/make/update-question-id.webp) + + + Go to [Make.com](https://make.com) and create a new scenario. Search for **Formbricks** and select it as your trigger, then choose **Response Finished** as the trigger event. + + ![Search Formbricks](/images/xm-and-surveys/core-features/integrations/make/search-formbricks.webp) + + + Click **Create a webhook**, enter your Formbricks API Host (default: `https://app.formbricks.com`), add your Formbricks API Key (see [API Key Setup](/api-reference/rest-api#how-to-generate-an-api-key)), and select the survey you want to connect. + + ![Enter API Key](/images/xm-and-surveys/core-features/integrations/make/enter-api-key-and-host.webp) + + + Click the **+** button after the Formbricks trigger, search for **HubSpot**, choose **Create or Update a Contact** as the action, and connect your HubSpot account. + + + Map the Formbricks response fields to HubSpot contact properties: + + | HubSpot Field | Formbricks Field | + | ------------- | ---------------- | + | Email | `data.email` (your email question ID) | + | First Name | `data.firstName` (if collected) | + | Last Name | `data.lastName` (if collected) | + | Custom Property | Any other `data.*` field | + + You can also map metadata: `meta.country`, `meta.userAgent.browser`, `survey.title`. + + + Submit a test response to your Formbricks survey, verify the contact appears in HubSpot, and turn on your Make scenario. + + + +--- + +## Method 2: Using n8n (Self-Hosted Option) + + + The Formbricks n8n node is available as a community node. Install it via **Settings** → **Community Nodes** → install `@formbricks/n8n-nodes-formbricks`. + + + + + Create a new workflow in n8n, add the **Formbricks** trigger node, connect it with your Formbricks API Key and host, select **Response Finished** as the event, and choose your survey. + + ![Add Formbricks Trigger](/images/xm-and-surveys/core-features/integrations/n8n/add-formbricks-trigger.webp) + + + Add a new node and search for **HubSpot**, select **Create/Update Contact** as the operation, and connect your HubSpot account (n8n supports both OAuth and access token authentication). + + + In the HubSpot node, map the fields: + + ``` + Email: {{ $json.data.email }} + First Name: {{ $json.data.firstName }} + Last Name: {{ $json.data.lastName }} + ``` + + For custom HubSpot properties, use the **Additional Fields** section to add mappings like `survey_source`, `response_id`, and `submission_date`. + + + Click **Listen for event** in the Formbricks trigger, submit a test survey response, verify the data flows through to HubSpot, and activate your workflow. + + + +--- + +## Method 3: Using Webhooks (Custom Integration) + +For maximum flexibility, you can use Formbricks webhooks with a custom endpoint that calls the HubSpot API directly. This approach is ideal for developers who want full control. + + + This method requires a HubSpot access token. You can use a Legacy Private App token (simplest) or implement OAuth 2.0 for production applications. + + + + + Go to **Configuration** → **Integrations** in Formbricks, click **Manage Webhooks** → **Add Webhook**, enter your endpoint URL, select **Response Finished** as the trigger, and choose the surveys to monitor. + + ![Integrations Tab](/images/xm-and-surveys/core-features/integrations/webhooks/integrations-tab.webp) + + + Your webhook handler needs to: + - **Receive the Formbricks webhook** - Accept POST requests with the survey response payload + - **Extract contact data** - Parse the email and other fields from `data.data` (keyed by your `questionId` values) + - **Call the HubSpot API** - Use the [HubSpot Contacts API](https://developers.hubspot.com/docs/api/crm/contacts) to create or update contacts + - **Handle duplicates** - HubSpot returns a 409 error if a contact with that email exists; search and update instead + + You can deploy using serverless functions (Vercel, AWS Lambda, Cloudflare Workers), traditional servers, or low-code platforms. For webhook signature verification, see the [Webhooks documentation](/xm-and-surveys/core-features/integrations/webhooks). + + + Deploy your webhook handler to a publicly accessible URL, add the URL to your Formbricks webhook configuration, submit a test survey response, and verify the contact appears in HubSpot. + + + +--- + +## Troubleshooting + +### Contact Not Created in HubSpot + +1. **Check the email field**: Ensure your survey has an email question and you're mapping the correct `questionId` +2. **Verify API token**: Make sure your HubSpot access token has the required scopes (`crm.objects.contacts.write` and `crm.objects.contacts.read`) +3. **Check for duplicates**: HubSpot returns a 409 error if a contact with that email already exists + +### Webhook Not Triggering + +1. Verify the webhook URL is publicly accessible +2. Check that **Response Finished** trigger is selected +3. Ensure the survey is linked to the webhook + +### Testing Your Integration + +1. Use a unique test email for each test +2. Check HubSpot's **Contacts** page after submitting a response +3. Review your webhook handler logs for errors + +--- + +Still struggling or something not working as expected? [Join our GitHub Discussions](https://github.com/formbricks/formbricks/discussions) and we're happy to help! diff --git a/docs/xm-and-surveys/core-features/integrations/overview.mdx b/docs/xm-and-surveys/core-features/integrations/overview.mdx index 40889dfb19..258378864b 100644 --- a/docs/xm-and-surveys/core-features/integrations/overview.mdx +++ b/docs/xm-and-surveys/core-features/integrations/overview.mdx @@ -15,6 +15,8 @@ At Formbricks, we understand the importance of integrating with third-party appl * [Google Sheets](/xm-and-surveys/core-features/integrations/google-sheets): Automatically send responses to a Google Sheet of your choice. +* [HubSpot](/xm-and-surveys/core-features/integrations/hubspot): Create or update HubSpot contacts automatically when survey responses are submitted. + * [Make](/xm-and-surveys/core-features/integrations/make): Leverage Make's powerful automation capabilities to automate your workflows. * [n8n](/xm-and-surveys/core-features/integrations/n8n)(Open Source): Automate workflows with n8n's no-code automation tool diff --git a/docs/xm-and-surveys/surveys/general-features/validation-rules.mdx b/docs/xm-and-surveys/surveys/general-features/validation-rules.mdx new file mode 100644 index 0000000000..eb38ec581c --- /dev/null +++ b/docs/xm-and-surveys/surveys/general-features/validation-rules.mdx @@ -0,0 +1,185 @@ +--- +title: "Validation Rules" +description: "Validation rules help you ensure that respondents provide data in the correct format and within expected constraints" +icon: "check-double" +--- + +By adding validation rules to your questions, you can improve data quality, reduce errors, and create a better survey experience. + +![Validation Rules Editor](/images/xm-and-surveys/core-features/validation-rules/editor.webp) + +## How Validation Rules Work + +Validation rules are evaluated when a respondent submits their answer. If the answer doesn't meet the validation criteria, an error message is displayed and the respondent must correct their input before proceeding. + +You can combine multiple validation rules using **All are true** or **Any is true** logic: +- **All are true**: All rules must pass for the response to be valid +- **Any is true**: At least one rule must pass for the response to be valid + +## Available Validation Rules by Question Type + +### Free Text Questions + +Free text questions support different validation rules based on the input type: + +#### Text Input Type + +| Rule | Description | Example | +|------|-------------|---------| +| At least (characters) | Requires at least N characters | At least 10 characters for detailed feedback | +| At most (characters) | Limits response to N characters | At most 500 characters for short answers | +| Matches Regex Pattern | Matches a regular expression pattern | Custom format validation | +| Is | Exact match required | Must equal "CONFIRM" | +| Is not | Must not match the value | Cannot be "N/A" | +| Contains | Must include the substring | Must contain "@company.com" | +| Does not contain | Must not include the substring | Cannot contain profanity | + +#### Email Input Type + +Email input automatically validates email format. Additional rules available: +- At least, At most (characters) +- Matches Regex Pattern, Is, Is not +- Contains, Does not contain + +#### URL Input Type + +URL input automatically validates URL format. Additional rules available: +- At least, At most (characters) +- Matches Regex Pattern, Is, Is not +- Contains, Does not contain + +#### Phone Input Type + +Phone input automatically validates phone number format. Additional rules available: +- At least, At most (characters) +- Matches Regex Pattern, Is, Is not +- Contains, Does not contain + +#### Number Input Type + +| Rule | Description | Example | +|------|-------------|---------| +| At least | Number must be at least N | Age must be at least 18 | +| At most | Number cannot exceed N | Quantity at most 100 | +| Is | Number must equal N | Quantity is 1 | +| Is not | Number must not equal N | Cannot be 0 | + +### Multiple Choice (Multi-Select) Questions + +| Rule | Description | Example | +|------|-------------|---------| +| At least (options selected) | Require at least N selections | At least 2 options selected | +| At most (options selected) | Limit to N selections | At most 3 options selected | + +### Picture Selection Questions + +| Rule | Description | Example | +|------|-------------|---------| +| At least (options selected) | Require at least N pictures | At least 1 design selected | +| At most (options selected) | Limit to N pictures | At most 2 favorites selected | + +### Date Questions + +| Rule | Description | Example | +|------|-------------|---------| +| Is later than | Date must be after specified date | Must be after today | +| Is earlier than | Date must be before specified date | Must be before Dec 31, 2025 | +| Is between | Date must be within range | Between Jan 1 and Dec 31 | +| Is not between | Date must be outside range | Cannot be during holidays | + + + Date values should be specified in YYYY-MM-DD format (e.g., 2025-01-15). + + +### Matrix Questions + +| Rule | Description | Example | +|------|-------------|---------| +| Minimum rows answered | Require at least N rows to be answered | Answer at least 3 rows | +| Answer all rows | All rows must have a selection | Complete the entire matrix | + +### Ranking Questions + +| Rule | Description | Example | +|------|-------------|---------| +| Minimum options ranked | Require at least N items to be ranked | Rank your top 3 | +| Rank all options | All options must be ranked | Rank all 5 items | + +### File Upload Questions + +| Rule | Description | Example | +|------|-------------|---------| +| File extension is | Only allow specific file types | Only .pdf, .docx allowed | +| File extension is not | Block specific file types | No .exe files | + + + File size limits are configured separately in the question settings using the "Maximum file size" option. + + +### Address Questions + +Each address field (Address Line 1, Address Line 2, City, State, ZIP, Country) can have its own validation rules: +- At least, At most (characters) +- Matches Regex Pattern +- Is, Is not +- Contains, Does not contain + +### Contact Info Questions + +Each contact field can have specific validation rules: + +**First Name, Last Name, Company**: +- At least, At most (characters) +- Matches Regex Pattern, Is, Is not +- Contains, Does not contain + +**Email**: Automatically validates email format, plus text rules above + +**Phone**: Automatically validates phone format, plus text rules above + +## Adding Validation Rules + + + + Click on the question you want to validate to open its settings panel. + + + Scroll down to find the "Validation Rules" section and click to expand it. + + + Click the "Add rule" button to add a new validation rule. + + + Select the rule type from the dropdown and enter the required value (if applicable). + + + If you have multiple rules, choose whether they should be combined with "All are true" or "Any is true" logic. + + + Click "Save" to apply the validation rules to your survey. + + + +## Error Messages + +Formbricks automatically generates user-friendly error messages based on your validation rules. Error messages are displayed below the input field when validation fails. + +Example error messages: +- "Must be at least 10 characters" +- "Must be a valid email address" +- "Please select at least 2 options" +- "Date must be after 2025-01-01" + +## Multi-Language Support + +Validation rules work with multi-language surveys. Error messages are automatically displayed in the respondent's selected language. + +## Combining Multiple Rules + +When using multiple validation rules: + +**All are true**: Use when all conditions must be met. +- Example: Text must be at least 10 characters AND contain "@email.com" + +**Any is true**: Use when any condition is acceptable. +- Example: Date is earlier than 2025-01-01 OR is later than 2025-12-31 diff --git a/package.json b/package.json index 27c385d3e8..fba63a59d6 100644 --- a/package.json +++ b/package.json @@ -91,11 +91,12 @@ "typeorm": ">=0.3.26", "systeminformation": "5.27.14", "qs": ">=6.14.1", + "preact": ">=10.26.10", "fast-xml-parser": ">=5.3.4", "diff": ">=8.0.3" }, "comments": { - "overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: axios (CVE-2025-58754) - awaiting @boxyhq/saml-jackson update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | tar-fs (Dependabot #205) - awaiting upstream dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | systeminformation (Dependabot #241) - awaiting @opentelemetry/host-metrics update | qs (Dependabot #245) - awaiting googleapis-common and stripe updates | fast-xml-parser (Dependabot #270) - awaiting @boxyhq/saml-jackson update | diff (Dependabot #269) - awaiting @microsoft/api-extractor update" + "overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: axios (CVE-2025-58754) - awaiting @boxyhq/saml-jackson update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | tar-fs (Dependabot #205) - awaiting upstream dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | systeminformation (Dependabot #241) - awaiting @opentelemetry/host-metrics update | qs (Dependabot #245) - awaiting googleapis-common and stripe updates | preact (Dependabot #247) - awaiting next-auth update | fast-xml-parser (Dependabot #270) - awaiting @boxyhq/saml-jackson update | diff (Dependabot #269) - awaiting @microsoft/api-extractor update" }, "patchedDependencies": { "next-auth@4.24.12": "patches/next-auth@4.24.12.patch" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ae27ddb8d..fa2788291c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,7 @@ overrides: typeorm: '>=0.3.26' systeminformation: 5.27.14 qs: '>=6.14.1' + preact: '>=10.26.10' fast-xml-parser: '>=5.3.4' diff: '>=8.0.3' @@ -986,7 +987,7 @@ importers: specifier: 2.33.0 version: 2.33.0 preact: - specifier: 10.28.2 + specifier: '>=10.26.10' version: 10.28.2 react-i18next: specifier: 15.7.3 @@ -3349,7 +3350,7 @@ packages: '@prefresh/core@1.5.9': resolution: {integrity: sha512-IKBKCPaz34OFVC+adiQ2qaTF5qdztO2/4ZPf4KsRTgjKosWqxVXmEbxCiUydYZRY8GVie+DQlKzQr9gt6HQ+EQ==} peerDependencies: - preact: ^10.0.0 || ^11.0.0-0 + preact: '>=10.26.10' '@prefresh/utils@1.2.1': resolution: {integrity: sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==} @@ -3357,7 +3358,7 @@ packages: '@prefresh/vite@2.4.11': resolution: {integrity: sha512-/XjURQqdRiCG3NpMmWqE9kJwrg9IchIOWHzulCfqg2sRe/8oQ1g5De7xrk9lbqPIQLn7ntBkKdqWXIj4E9YXyg==} peerDependencies: - preact: ^10.4.0 || ^11.0.0-0 + preact: '>=10.26.10' vite: '>=2.0.0' '@prisma/client@6.14.0': @@ -4540,8 +4541,8 @@ packages: resolution: {integrity: sha512-WsSHCPq/neD5G/MkK4csLI5Y5Pkd9c1NMfpYEKeghSGaD4Ja1qLIohRQf2D5c1Uy5aXp76DeKHkzWZ9KAlHroQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.22.0': - resolution: {integrity: sha512-6vjCHD6vaY8KubeNw2Fg3EK0KLGQYdldG4fYgQmA0xSW0dJ8G2xFhSOdrlUakWVoP5JuWHtFODg3PNd/DN3FDA==} + '@smithy/core@3.22.1': + resolution: {integrity: sha512-x3ie6Crr58MWrm4viHqqy2Du2rHYZjwu8BekasrQx4ca+Y24dzVAwq3yErdqIbc2G3I0kLQA13PQ+/rde+u65g==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.2.7': @@ -4628,16 +4629,16 @@ packages: resolution: {integrity: sha512-gpLspUAoe6f1M6H0u4cVuFzxZBrsGZmjx2O9SigurTx4PbntYa4AJ+o0G0oGm1L2oSX6oBhcGHwrfJHup2JnJg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.12': - resolution: {integrity: sha512-9JMKHVJtW9RysTNjcBZQHDwB0p3iTP6B1IfQV4m+uCevkVd/VuLgwfqk5cnI4RHcp4cPwoIvxQqN4B1sxeHo8Q==} + '@smithy/middleware-endpoint@4.4.13': + resolution: {integrity: sha512-x6vn0PjYmGdNuKh/juUJJewZh7MoQ46jYaJ2mvekF4EesMuFfrl4LaW/k97Zjf8PTCPQmPgMvwewg7eNoH9n5w==} engines: {node: '>=18.0.0'} '@smithy/middleware-retry@4.4.17': resolution: {integrity: sha512-MqbXK6Y9uq17h+4r0ogu/sBT6V/rdV+5NvYL7ZV444BKfQygYe8wAhDrVXagVebN6w2RE0Fm245l69mOsPGZzg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.29': - resolution: {integrity: sha512-bmTn75a4tmKRkC5w61yYQLb3DmxNzB8qSVu9SbTYqW6GAL0WXO2bDZuMAn/GJSbOdHEdjZvWxe+9Kk015bw6Cg==} + '@smithy/middleware-retry@4.4.30': + resolution: {integrity: sha512-CBGyFvN0f8hlnqKH/jckRDz78Snrp345+PVk8Ux7pnkUCW97Iinse59lY78hBt04h1GZ6hjBN94BRwZy1xC8Bg==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@4.2.8': @@ -4668,8 +4669,8 @@ packages: resolution: {integrity: sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.4.8': - resolution: {integrity: sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==} + '@smithy/node-http-handler@4.4.9': + resolution: {integrity: sha512-KX5Wml5mF+luxm1szW4QDz32e3NObgJ4Fyw+irhph4I/2geXwUy4jkIMUs5ZPGflRBeR6BUkC2wqIab4Llgm3w==} engines: {node: '>=18.0.0'} '@smithy/property-provider@4.2.7': @@ -4732,8 +4733,8 @@ packages: resolution: {integrity: sha512-D5z79xQWpgrGpAHb054Fn2CCTQZpog7JELbVQ6XAvXs5MNKWf28U9gzSBlJkOyMl9LA1TZEjRtwvGXfP0Sl90g==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.11.1': - resolution: {integrity: sha512-SERgNg5Z1U+jfR6/2xPYjSEHY1t3pyTHC/Ma3YQl6qWtmiL42bvNId3W/oMUWIwu7ekL2FMPdqAmwbQegM7HeQ==} + '@smithy/smithy-client@4.11.2': + resolution: {integrity: sha512-SCkGmFak/xC1n7hKRsUr6wOnBTJ3L22Qd4e8H1fQIuKTAjntwgU8lrdMe7uHdiT2mJAOWA/60qaW9tiMu69n1A==} engines: {node: '>=18.0.0'} '@smithy/types@4.11.0': @@ -4780,16 +4781,16 @@ packages: resolution: {integrity: sha512-/eiSP3mzY3TsvUOYMeL4EqUX6fgUOj2eUOU4rMMgVbq67TiRLyxT7Xsjxq0bW3OwuzK009qOwF0L2OgJqperAQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.28': - resolution: {integrity: sha512-/9zcatsCao9h6g18p/9vH9NIi5PSqhCkxQ/tb7pMgRFnqYp9XUOyOlGPDMHzr8n5ih6yYgwJEY2MLEobUgi47w==} + '@smithy/util-defaults-mode-browser@4.3.29': + resolution: {integrity: sha512-nIGy3DNRmOjaYaaKcQDzmWsro9uxlaqUOhZDHQed9MW/GmkBZPtnU70Pu1+GT9IBmUXwRdDuiyaeiy9Xtpn3+Q==} engines: {node: '>=18.0.0'} '@smithy/util-defaults-mode-node@4.2.19': resolution: {integrity: sha512-3a4+4mhf6VycEJyHIQLypRbiwG6aJvbQAeRAVXydMmfweEPnLLabRbdyo/Pjw8Rew9vjsh5WCdhmDaHkQnhhhA==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.31': - resolution: {integrity: sha512-JTvoApUXA5kbpceI2vuqQzRjeTbLpx1eoa5R/YEZbTgtxvIB7AQZxFJ0SEyfCpgPCyVV9IT7we+ytSeIB3CyWA==} + '@smithy/util-defaults-mode-node@4.2.32': + resolution: {integrity: sha512-7dtFff6pu5fsjqrVve0YMhrnzJtccCWDacNKOkiZjJ++fmjGExmmSu341x+WU6Oc1IccL7lDuaUj7SfrHpWc5Q==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.2.7': @@ -4820,8 +4821,8 @@ packages: resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.10': - resolution: {integrity: sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==} + '@smithy/util-stream@4.5.11': + resolution: {integrity: sha512-lKmZ0S/3Qj2OF5H1+VzvDLb6kRxGzZHq6f3rAsoSu5cTLGsn3v3VQBA8czkNNXlLjoFEtVu3OQT2jEeOtOE2CA==} engines: {node: '>=18.0.0'} '@smithy/util-stream@4.5.8': @@ -5278,7 +5279,7 @@ packages: resolution: {integrity: sha512-F+kJ243LP6VmEK1M809unzTE/ijg+bsMNuiRN0JEDIJBELKKDNhdgC/WrUSZ7klwJvtlO3wQZ9ix+jhObG07Fg==} engines: {node: '>= 12'} peerDependencies: - preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0' + preact: '>=10.26.10' '@testing-library/react@16.3.0': resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} @@ -9329,10 +9330,7 @@ packages: preact-render-to-string@5.2.6: resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: - preact: '>=10' - - preact@10.26.6: - resolution: {integrity: sha512-5SRRBinwpwkaD+OqlBDeITlRgvd8I8QlxHJw9AxSdMNV6O+LodN9nUyYGpSF7sadHjs6RzeFShMexC6DbtWr9g==} + preact: '>=10.26.10' preact@10.28.2: resolution: {integrity: sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==} @@ -11454,7 +11452,7 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.969.0 '@aws-sdk/util-user-agent-node': 3.971.0 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@smithy/eventstream-serde-browser': 4.2.8 '@smithy/eventstream-serde-config-resolver': 4.3.8 '@smithy/eventstream-serde-node': 4.2.8 @@ -11465,25 +11463,25 @@ snapshots: '@smithy/invalid-dependency': 4.2.8 '@smithy/md5-js': 4.2.8 '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.12 - '@smithy/middleware-retry': 4.4.29 + '@smithy/middleware-endpoint': 4.4.13 + '@smithy/middleware-retry': 4.4.30 '@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/node-http-handler': 4.4.9 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@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.28 - '@smithy/util-defaults-mode-node': 4.2.31 + '@smithy/util-defaults-mode-browser': 4.3.29 + '@smithy/util-defaults-mode-node': 4.2.32 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 - '@smithy/util-stream': 4.5.10 + '@smithy/util-stream': 4.5.11 '@smithy/util-utf8': 4.2.0 '@smithy/util-waiter': 4.2.8 tslib: 2.8.1 @@ -11636,26 +11634,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.969.0 '@aws-sdk/util-user-agent-node': 3.971.0 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@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.12 - '@smithy/middleware-retry': 4.4.29 + '@smithy/middleware-endpoint': 4.4.13 + '@smithy/middleware-retry': 4.4.30 '@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/node-http-handler': 4.4.9 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@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.28 - '@smithy/util-defaults-mode-node': 4.2.31 + '@smithy/util-defaults-mode-browser': 4.3.29 + '@smithy/util-defaults-mode-node': 4.2.32 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -11698,12 +11696,12 @@ snapshots: dependencies: '@aws-sdk/types': 3.969.0 '@aws-sdk/xml-builder': 3.969.0 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@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.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 '@smithy/util-base64': 4.3.0 '@smithy/util-middleware': 4.2.8 @@ -11780,12 +11778,12 @@ snapshots: '@aws-sdk/core': 3.970.0 '@aws-sdk/types': 3.969.0 '@smithy/fetch-http-handler': 5.3.9 - '@smithy/node-http-handler': 4.4.8 + '@smithy/node-http-handler': 4.4.9 '@smithy/property-provider': 4.2.8 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 - '@smithy/util-stream': 4.5.10 + '@smithy/util-stream': 4.5.11 tslib: 2.8.1 '@aws-sdk/credential-provider-ini@3.817.0': @@ -12090,7 +12088,7 @@ snapshots: '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 '@smithy/util-middleware': 4.2.8 - '@smithy/util-stream': 4.5.10 + '@smithy/util-stream': 4.5.11 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 @@ -12184,15 +12182,15 @@ snapshots: '@aws-sdk/core': 3.970.0 '@aws-sdk/types': 3.969.0 '@aws-sdk/util-arn-parser': 3.968.0 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@smithy/node-config-provider': 4.3.8 '@smithy/protocol-http': 5.3.8 '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 '@smithy/util-config-provider': 4.2.0 '@smithy/util-middleware': 4.2.8 - '@smithy/util-stream': 4.5.10 + '@smithy/util-stream': 4.5.11 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 @@ -12227,7 +12225,7 @@ snapshots: '@aws-sdk/core': 3.970.0 '@aws-sdk/types': 3.969.0 '@aws-sdk/util-endpoints': 3.970.0 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 @@ -12333,26 +12331,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.969.0 '@aws-sdk/util-user-agent-node': 3.971.0 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@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.12 - '@smithy/middleware-retry': 4.4.29 + '@smithy/middleware-endpoint': 4.4.13 + '@smithy/middleware-retry': 4.4.30 '@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/node-http-handler': 4.4.9 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@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.28 - '@smithy/util-defaults-mode-node': 4.2.31 + '@smithy/util-defaults-mode-browser': 4.3.29 + '@smithy/util-defaults-mode-node': 4.2.32 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -12391,7 +12389,7 @@ snapshots: '@aws-sdk/client-s3': 3.971.0 '@aws-sdk/types': 3.969.0 '@aws-sdk/util-format-url': 3.969.0 - '@smithy/middleware-endpoint': 4.4.12 + '@smithy/middleware-endpoint': 4.4.13 '@smithy/signature-v4': 5.3.8 '@smithy/types': 4.12.0 '@smithy/util-hex-encoding': 4.2.0 @@ -12405,9 +12403,9 @@ snapshots: '@aws-sdk/signature-v4-multi-region': 3.970.0 '@aws-sdk/types': 3.969.0 '@aws-sdk/util-format-url': 3.969.0 - '@smithy/middleware-endpoint': 4.4.12 + '@smithy/middleware-endpoint': 4.4.13 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 tslib: 2.8.1 @@ -16007,7 +16005,7 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/core@3.22.0': + '@smithy/core@3.22.1': dependencies: '@smithy/middleware-serde': 4.2.9 '@smithy/protocol-http': 5.3.8 @@ -16015,7 +16013,7 @@ snapshots: '@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-stream': 4.5.11 '@smithy/util-utf8': 4.2.0 '@smithy/uuid': 1.1.0 tslib: 2.8.1 @@ -16156,9 +16154,9 @@ snapshots: '@smithy/util-middleware': 4.2.7 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.12': + '@smithy/middleware-endpoint@4.4.13': dependencies: - '@smithy/core': 3.22.0 + '@smithy/core': 3.22.1 '@smithy/middleware-serde': 4.2.9 '@smithy/node-config-provider': 4.3.8 '@smithy/shared-ini-file-loader': 4.4.3 @@ -16179,12 +16177,12 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.29': + '@smithy/middleware-retry@4.4.30': 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.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -16235,7 +16233,7 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.4.8': + '@smithy/node-http-handler@4.4.9': dependencies: '@smithy/abort-controller': 4.2.8 '@smithy/protocol-http': 5.3.8 @@ -16335,14 +16333,14 @@ snapshots: '@smithy/util-stream': 4.5.8 tslib: 2.8.1 - '@smithy/smithy-client@4.11.1': + '@smithy/smithy-client@4.11.2': dependencies: - '@smithy/core': 3.22.0 - '@smithy/middleware-endpoint': 4.4.12 + '@smithy/core': 3.22.1 + '@smithy/middleware-endpoint': 4.4.13 '@smithy/middleware-stack': 4.2.8 '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 - '@smithy/util-stream': 4.5.10 + '@smithy/util-stream': 4.5.11 tslib: 2.8.1 '@smithy/types@4.11.0': @@ -16400,10 +16398,10 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.28': + '@smithy/util-defaults-mode-browser@4.3.29': dependencies: '@smithy/property-provider': 4.2.8 - '@smithy/smithy-client': 4.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 tslib: 2.8.1 @@ -16417,13 +16415,13 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.31': + '@smithy/util-defaults-mode-node@4.2.32': 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.11.1 + '@smithy/smithy-client': 4.11.2 '@smithy/types': 4.12.0 tslib: 2.8.1 @@ -16465,10 +16463,10 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@smithy/util-stream@4.5.10': + '@smithy/util-stream@4.5.11': dependencies: '@smithy/fetch-http-handler': 5.3.9 - '@smithy/node-http-handler': 4.4.8 + '@smithy/node-http-handler': 4.4.9 '@smithy/types': 4.12.0 '@smithy/util-base64': 4.3.0 '@smithy/util-buffer-from': 4.2.0 @@ -20936,8 +20934,8 @@ snapshots: next: 16.1.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) oauth: 0.9.15 openid-client: 5.7.1 - preact: 10.26.6 - preact-render-to-string: 5.2.6(preact@10.26.6) + preact: 10.28.2 + preact-render-to-string: 5.2.6(preact@10.28.2) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) uuid: 11.1.0 @@ -21487,13 +21485,11 @@ snapshots: dependencies: xtend: 4.0.2 - preact-render-to-string@5.2.6(preact@10.26.6): + preact-render-to-string@5.2.6(preact@10.28.2): dependencies: - preact: 10.26.6 + preact: 10.28.2 pretty-format: 3.8.0 - preact@10.26.6: {} - preact@10.28.2: {} prebuild-install@7.1.3: